kagent#2933 added an HTTP/JSON-RPC A2A transport alongside the existing gRPC one, with a discoverable Agent Card per AgentInstance. examples/a2a-agents.md uses grpcurl throughout and documents no HTTP path, so a reader who wants an ordinary HTTP client has nothing to follow.
Upstream wrote docs/architecture/a2a-transports.md as the endpoint contract. It is an architecture document rather than a task guide, so treat it as the source.
The endpoint surface
Both transports are served on the controller's API listener, port 8083 by default, and share the same AgentInstance authorization, durable tasks, history, and runtime lifecycle.
| Operation |
Path |
| Read the Agent Card |
GET /agents/{instance-id}/.well-known/agent-card.json |
| Call JSON-RPC, including streaming |
POST /agents/{instance-id} |
The URL selects the instance. An HTTP client does not send x-kagent-agent-instance-id, and supplying it cannot override the URL. gRPC clients still send that header on the existing service. There is no deployment-wide Agent Card, because the gateway serves many agents.
JSON-RPC uses the pinned upstream A2A v1 SDK and supports SendMessage, SendStreamingMessage, GetTask, ListTasks, CancelTask, SubscribeToTask, and GetExtendedAgentCard. Those are the v1 names for the operations older clients called message/send, message/stream, tasks/get, tasks/list, tasks/cancel, and tasks/resubscribe, which is worth stating for anyone arriving with a pre-v1 client.
Behavior the API does not announce
controller.a2aGatewayUrl changed meaning. It was the public gRPC URL advertised by Agent Cards. It is now the gateway base URL for both transports, and HTTP interfaces append /agents/{instance-id} to it, preserving any deployment prefix. Its default is still the controller's cluster Service URL.
- An ingress with a prefix must strip it before forwarding to the core listener, and must forward streaming responses without buffering. Both are operator responsibilities that no chart value enforces.
- The card orders its interfaces. It comes from the instance's pinned template revision and advertises JSON-RPC first, then gRPC, while retaining runtime extensions and reporting the gateway's streaming capabilities.
- Share tokens grade by permission. A validated
X-Share-Token supplements the authenticated user's access: a read-only share permits card and task reads and subscriptions, and a read-write share also permits messages and cancellation. Cards are not publicly cached.
The conflict to resolve before writing
substrate-runtime/identity.md carries a warning against exposing port 8083 outside the cluster, because the open source build's authenticator admits every request and its authorizer permits every check. The new HTTP transport is served on that same listener, and the architecture document describes setting a2aGatewayUrl and putting an ingress in front precisely so agents can be reached from outside.
Both statements are true, and a reader meeting them on different pages will not know what to do. Decide how the doc set reconciles them before writing the guide, and say which argument won. This is the main open question in this issue, not a detail to note at the end.
What to check before starting
- Read
docs/architecture/a2a-transports.md in the kagent repository.
- Run the existing
examples/a2a-agents.md guide as written, so the gRPC path on the page is known to still work before an HTTP path joins it.
- Fetch a card over HTTP and confirm the interface ordering and the extensions it retains.
- Exercise streaming over JSON-RPC, and confirm what a client sees when an ingress buffers.
- Confirm the share-token grading through both transports rather than inferring it.
Done when
kagent#2933 added an HTTP/JSON-RPC A2A transport alongside the existing gRPC one, with a discoverable Agent Card per AgentInstance.
examples/a2a-agents.mdusesgrpcurlthroughout and documents no HTTP path, so a reader who wants an ordinary HTTP client has nothing to follow.Upstream wrote
docs/architecture/a2a-transports.mdas the endpoint contract. It is an architecture document rather than a task guide, so treat it as the source.The endpoint surface
Both transports are served on the controller's API listener, port
8083by default, and share the same AgentInstance authorization, durable tasks, history, and runtime lifecycle.GET /agents/{instance-id}/.well-known/agent-card.jsonPOST /agents/{instance-id}The URL selects the instance. An HTTP client does not send
x-kagent-agent-instance-id, and supplying it cannot override the URL. gRPC clients still send that header on the existing service. There is no deployment-wide Agent Card, because the gateway serves many agents.JSON-RPC uses the pinned upstream A2A v1 SDK and supports
SendMessage,SendStreamingMessage,GetTask,ListTasks,CancelTask,SubscribeToTask, andGetExtendedAgentCard. Those are the v1 names for the operations older clients calledmessage/send,message/stream,tasks/get,tasks/list,tasks/cancel, andtasks/resubscribe, which is worth stating for anyone arriving with a pre-v1 client.Behavior the API does not announce
controller.a2aGatewayUrlchanged meaning. It was the public gRPC URL advertised by Agent Cards. It is now the gateway base URL for both transports, and HTTP interfaces append/agents/{instance-id}to it, preserving any deployment prefix. Its default is still the controller's cluster Service URL.X-Share-Tokensupplements the authenticated user's access: a read-only share permits card and task reads and subscriptions, and a read-write share also permits messages and cancellation. Cards are not publicly cached.The conflict to resolve before writing
substrate-runtime/identity.mdcarries a warning against exposing port8083outside the cluster, because the open source build's authenticator admits every request and its authorizer permits every check. The new HTTP transport is served on that same listener, and the architecture document describes settinga2aGatewayUrland putting an ingress in front precisely so agents can be reached from outside.Both statements are true, and a reader meeting them on different pages will not know what to do. Decide how the doc set reconciles them before writing the guide, and say which argument won. This is the main open question in this issue, not a detail to note at the end.
What to check before starting
docs/architecture/a2a-transports.mdin the kagent repository.examples/a2a-agents.mdguide as written, so the gRPC path on the page is known to still work before an HTTP path joins it.Done when
curlexample for the card and for a JSON-RPC call.a2aGatewayUrlchange of meaning is covered wherever that value is documented.identity.mdis resolved rather than left for the reader.