Exposing agents through A2A protocol#
Every AI agent created with kagent implements the A2A protocol and can be invoked by an A2A client.
Let's look at how this works in kagent!
Prerequisites#
Install kagent by following the quick start guide.
Creating an AI agent that supports A2A#
Create a simple agent (k8s-a2a-agent
) that can retrieve resources from a Kubernetes cluster. Note the definition of the agent follows the Agent CRD with the a2aConfig
section added that describes the skills the agent can perform.
kubectl apply -f - <<EOFapiVersion: kagent.dev/v1alpha2kind: Agentmetadata:name: k8s-a2a-agentnamespace: kagentspec:description: An example A2A agent that knows how to use Kubernetes tools.type: Declarativedeclarative:modelConfig: default-model-configsystemMessage: |-You are an expert Kubernetes agent that uses tools to help users.tools:- type: McpServermcpServer:name: kagent-tool-serverkind: RemoteMCPServertoolNames:- k8s_get_resources- k8s_get_available_api_resourcesa2aConfig:skills:- id: get-resources-skillname: Get Resourcesdescription: Get resources in the Kubernetes clusterinputModes:- textoutputModes:- texttags:- k8s- resourcesexamples:- "Get all resources in the Kubernetes cluster"- "Get the pods in the default namespace"- "Get the services in the istio-system namespace"- "Get the deployments in the istio-system namespace"- "Get the jobs in the istio-system namespace"- "Get the cronjobs in the istio-system namespace"- "Get the statefulsets in the istio-system namespace"EOF
Testing the A2A endpoint#
The A2A endpoint is exposed on the port 8083
of the kagent controller service.
-
Enable port-forwarding on the
kagent-controller
service.Note that you could also expose the A2A endpoint publicly by using a gateway.
kubectl port-forward svc/kagent-controller 8083:8083 -n kagent -
To test that the agent is available and has an agent card, send a request to the
.well-known/agent.json
endpoint. Note the API endpoint follows the pattern/api/a2a/{namespace}/{agent-name}/.well-known/agent.json
.curl localhost:8083/api/a2a/kagent/k8s-a2a-agent/.well-known/agent.jsonExample output: This JSON object describes the agent as per the A2A protocol.
{"name": "k8s_a2a_agent","description": "An example A2A agent that knows how to use Kubernetes tools.","url": "http://127.0.0.1:8083/api/a2a/kagent/k8s-a2a-agent/","version": "","capabilities": {"streaming": true,"pushNotifications": false,"stateTransitionHistory": true},"defaultInputModes": ["text"],"defaultOutputModes": ["text"],"skills": [{"id": "get-resources-skill","name": "Get Resources","description": "Get resources in the Kubernetes cluster","tags": ["k8s","resources"],"examples": ["Get all resources in the Kubernetes cluster","Get the pods in the default namespace","Get the services in the istio-system namespace","Get the deployments in the istio-system namespace","Get the jobs in the istio-system namespace","Get the cronjobs in the istio-system namespace","Get the statefulsets in the istio-system namespace"],"inputModes": ["text"],"outputModes": ["text"]}]}
Invoking the agent#
You can invoke the agent in several ways, including the kagent dashboard, kagent CLI, and the A2A host CLI.
Dashboard#
Launch the dashboard with kagent dashboard
, find your k8s-a2a-agent
, and start chatting. For complete steps, see the Your First Agent guide.
kagent CLI#
To use the kagent CLI, make sure that the controller is still being port-forwarded.
Then, use the invoke command. For more options, run kagent help invoke
.
kagent invoke --agent k8s-a2a-agent --task "Get the pods in the kagent namespace"
Example output: The output includes both the response as well as the details of the response. The formatting is in JSON but can be quite long, depending on the call and the agent configuration.
{"artifacts": [{"artifactId": "c08e6186-6e6b-4b93-9042-bf9121863707","parts": [{"kind": "text","text": "There are 59 pods in your cluster."}]}]...}
A2A host CLI#
You can use the A2A host CLI to invoke the agent. This CLI is part of the A2A samples repository.
-
Clone the A2A samples repository.
git clone https://github.com/a2aproject/a2a-samples.git -
From the
a2a-samples/samples/python/hosts/cli
directory, point the CLI to the kagent endpoint.cd a2a-samples/samples/python/hosts/cliuv run . --agent http://127.0.0.1:8083/api/a2a/kagent/k8s-a2a-agentExample output: The CLI connects to the kagent, displays the agent card and prompts you for input.
======= Agent Card ========{"name":"my-a2a-agent","description":"An example A2A agent that knows how to use Kubernetes tools.","url":"http://127.0.0.1:8083/api/a2a/kagent/my-a2a-agent","version":"1","capabilities":{"streaming":false,"pushNotifications":false,"stateTransitionHistory":false},"defaultInputModes":["text"],"defaultOutputModes":["text"],"skills":[{"id":"kagent-k8s-agent","name":"Get Resources","description":"Get resources in the Kubernetes cluster","examples":["Get all resources in the Kubernetes cluster","Get the pods in the default namespace","Get the services in the istio-system namespace","Get the deployments in the istio-system namespace","Get the jobs in the istio-system namespace","Get the cronjobs in the istio-system namespace","Get the statefulsets in the istio-system namespace"],"inputModes":["text"],"outputModes":["text"]}]}========= starting a new task ========What do you want to send to the agent? (:q or quit to exit): -
Send the task
"Get the pods in the kagent namespace"
to the agent. You'll be also prompted to optionally attach a file to the request, but just hit enter to skip this step.Example output: The
result
section contains the result of the task and theartifacts
section contains the output of the task and it shows the pods running inside the kagent namespace.{"jsonrpc": "2.0","id": "0df6761ed3394b43a2dee2bd6572bc94","result": {"id": "89bae00376e44ed094a2174e163da9f6","sessionId": "d966626d06ab42b19bd3999e65333311","status": {"state": "completed","message": {"role": "agent","parts": [{"type": "text","text": "Processed result: There is one pod running in the \"kagent\" namespace:\n\n- Pod Name: kagent-748fb675c6-9ddsz\n- Status: Running\n- Ready Containers: 3 out of 3\n- Restarts: 0\n- Age: 31 minutes\n- Pod IP: 10.244.0.11\n- Node: kagent-control-plane\n\nLet me know if you need more details or want to perform any actions on this pod."}]},"timestamp": "2025-05-06T22:27:31+00:00"},"artifacts": [{"name": "Task Result","description": "The result of the task processing","parts": [{"type": "text","text": "There is one pod running in the \"kagent\" namespace:\n\n- Pod Name: kagent-748fb675c6-9ddsz\n- Status: Running\n- Ready Containers: 3 out of 3\n- Restarts: 0\n- Age: 31 minutes\n- Pod IP: 10.244.0.11\n- Node: kagent-control-plane\n\nLet me know if you need more details or want to perform any actions on this pod."}],"index": 0,"lastChunk": true}]}}
The agent has processed the request and returned the result.