Agent-to-agent (A2A)

Agent-to-agent (A2A)

With agentgateway, you can route to agent-to-agent (A2A) servers and expose their tools securely.

Before you begin

  1. Follow the Get started guide to install kgateway with agentgateway enabled.

  2. Make sure that agentgateway is enabled in kgateway.

    helm get values kgateway -n kgateway-system -o yaml

    Example output:

    
    agentgateway:
      enabled: true

Step 1: Deploy an A2A server

Deploy an A2A server that you want agentgateway to proxy traffic to.

  1. Clone the kgateway repository.

    git clone https://github.com/kgateway-dev/kgateway.git
  2. From the root directory, build the sample A2A server.

    VERSION=2.1.0-main make test-a2a-agent-docker
  3. Load the image into your cluster. The following make command assumes that you are using a local Kind cluster.

    CLUSTER_NAME=<your-cluster-name> VERSION=2.1.0-main make kind-load-test-a2a-agent
  4. Deploy the A2A server. Notice that the Service uses the appProtocol: kgateway.dev/a2a setting. This way, kgateway configures the agentgateway proxy to use the A2A protocol.

    kubectl apply -f- <<EOF
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: a2a-agent
      labels:
        app: a2a-agent
    spec:
      selector:
        matchLabels:
          app: a2a-agent
      template:
        metadata:
          labels:
            app: a2a-agent
        spec:
          containers:
            - name: a2a-agent
              image: ghcr.io/kgateway-dev/test-a2a-agent:2.1.0-main
              ports:
                - containerPort: 9090
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: a2a-agent
    spec:
      selector:
        app: a2a-agent
      type: ClusterIP
      ports:
        - protocol: TCP
          port: 9090
          targetPort: 9090
          appProtocol: kgateway.dev/a2a
    EOF

Step 2: Route with agentgateway

Route to the A2A server with agentgateway.

  1. Create a Gateway resource that uses the agentgateway GatewayClass. Kgateway automatically creates an agentgateway proxy for you.

    kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: agentgateway
    spec:
      gatewayClassName: agentgateway
      listeners:
      - protocol: HTTP
        port: 8080
        name: http
    EOF
  2. Verify that the Gateway is created successfully. You can also review the external address that is assigned to the Gateway. Note that depending on your environment it might take a few minutes for the load balancer service to be assigned an external address. If you are using a local Kind cluster without a load balancer such as metallb, you might not have an external address.

    kubectl get gateway agentgateway

    Example output:

    NAME           CLASS          ADDRESS                                  PROGRAMMED   AGE
    agentgateway   agentgateway   1234567890.us-east-2.elb.amazonaws.com   True         93s
  3. Create an HTTPRoute resource that routes incoming traffic to the A2A server.

    kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: a2a
    spec:
      parentRefs:
        - name: agentgateway
          namespace: default
      rules:
        - backendRefs:
            - name: a2a-agent
              port: 9090
    EOF

Step 3: Verify the connection

  1. Get the agentgateway address.

    export INGRESS_GW_ADDRESS=$(kubectl get gateway agentgateway -o=jsonpath="{.status.addresses[0].value}")
    echo $INGRESS_GW_ADDRESS
    kubectl port-forward deployment/agentgateway 8080:8080
  2. Send a request to the A2A server.

    curl -X POST http://$INGRESS_GW_ADDRESS:8080/ \
      -H "Content-Type: application/json" \
        -v \
        -d '{
      "jsonrpc": "2.0",
      "id": "1",
      "method": "tasks/send",
      "params": {
        "id": "1",
        "message": {
          "role": "user",
          "parts": [
            {
              "type": "text",
              "text": "hello gateway!"
            }
          ]
        }
      }
      }'
    curl -X POST http://localhost:8080/ \
      -H "Content-Type: application/json" \
        -v \
        -d '{
      "jsonrpc": "2.0",
      "id": "1",
      "method": "tasks/send",
      "params": {
        "id": "1",
        "message": {
          "role": "user",
          "parts": [
            {
              "type": "text",
              "text": "hello gateway!"
            }
          ]
        }
      }
      }'

    Example output:

    {
      "jsonrpc": "2.0",
      "id": "1",
      "result": {
        "id": "1",
        "message": {
          "role": "assistant",
          "parts": [
            {
              "type": "text",
              "text": "hello gateway!"
            }
          ]
        }
      }
    }

Cleanup

You can remove the resources that you created in this guide.
kubectl delete Deployment a2a-agent
kubectl delete Service a2a-agent
kubectl delete Gateway agentgateway
kubectl delete HTTPRoute a2a