> For the complete documentation index, see [llms.txt](/llms.txt). Markdown versions of all docs pages are available by appending .md to any docs URL.

# Connect to an agent

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

## Before you begin

[Install and set up an agentgateway proxy](https://agentgateway.dev/docs/kubernetes/latest/quickstart/install).

## Step 1: Set up routing to an A2A server

Deploy an A2A server, then create the resources that route traffic to it. You can route through an `AgentgatewayBackend` resource, or directly to the Service that exposes the server.

For most cases, use the `AgentgatewayBackend` approach. The `a2a` backend type represents the A2A server as a dedicated backend that you can further configure, such as by attaching policies, and it can select A2A servers that run outside your cluster. The Service-based approach requires an update to your app (the `appProtocol` setting) and is the legacy way from an earlier version of agentgateway.

**Option: tabs-tab-tabs-02-0**

Because the backend's `a2a` type signals the A2A protocol, the Service does not need the `appProtocol` setting.

1. Deploy the A2A server with a Deployment and a Service.
   
   ```yaml
   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: gcr.io/solo-public/docs/test-a2a-agent:latest
             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
   EOF
   ```
2. Create an `AgentgatewayBackend` resource that defines the A2A server as a backend. The `a2a` type configures agentgateway to use the A2A protocol when it connects to the `host` and `port` that you specify.
   
   ```yaml
   kubectl apply -f- <<EOF
   apiVersion: agentgateway.dev/v1alpha1
   kind: AgentgatewayBackend
   metadata:
     name: a2a-backend
   spec:
     a2a:
       host: a2a-agent.default.svc.cluster.local
       port: 9090
   EOF
   ```
3. Create an HTTPRoute that routes traffic along the `/myagent` prefix path to the `AgentgatewayBackend`. The prefix path exposes the A2A server under a unique address on the gateway. However, because the A2A server requires traffic to be sent along the root path (`/`), you add a `URLRewrite` filter to the HTTPRoute that rewrites the `/myagent` prefix to `/`.
   
   ```yaml
   kubectl apply -f- <<EOF
   apiVersion: gateway.networking.k8s.io/v1
   kind: HTTPRoute
   metadata:
     name: a2a
   spec:
     parentRefs:
     - name: agentgateway-proxy
       namespace: agentgateway-system
     rules:
     - matches:
       - path:
           type: PathPrefix
           value: /myagent
       filters:
       - type: URLRewrite
         urlRewrite:
           path:
             type: ReplacePrefixMatch
             replacePrefixMatch: /
       backendRefs:
         - name: a2a-backend
           group: agentgateway.dev
           kind: AgentgatewayBackend
   EOF
   ```

**Option: tabs-tab-tabs-02-1**

1. Deploy the A2A server with a Deployment and a Service. Notice that the Service uses the `appProtocol: kgateway.dev/a2a` setting.
   
   ```yaml
   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: gcr.io/solo-public/docs/test-a2a-agent:latest
             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
   ```
2. Create an HTTPRoute that routes traffic along the `/myagent` prefix path directly to the Service that exposes your agent. Note that this configuration requires the `appProtocol: kgateway.dev/a2a` setting on the Service, which configures agentgateway to use the A2A protocol when connecting to the Service. The `/myagent` prefix path exposes the A2A server under a unique address on the gateway. However, because the A2A server requires traffic to be sent along the root path (`/`), you add a `URLRewrite` filter to the HTTPRoute that rewrites the `/myagent` prefix to `/`.
   
   ```yaml
   kubectl apply -f- <<EOF
   apiVersion: gateway.networking.k8s.io/v1
   kind: HTTPRoute
   metadata:
     name: a2a
   spec:
     parentRefs:
     - name: agentgateway-proxy
       namespace: agentgateway-system
     rules:
     - matches:
       - path:
           type: PathPrefix
           value: /myagent
       filters:
       - type: URLRewrite
         urlRewrite:
           path:
             type: ReplacePrefixMatch
             replacePrefixMatch: /
       backendRefs:
         - name: a2a-agent
           port: 9090
   EOF
   ```

## Step 2: Verify the connection

1. Get the agentgateway address.
   
   **Option: tabs-tab-tabs-10-0**
   
   ```sh
   export INGRESS_GW_ADDRESS=$(kubectl get gateway agentgateway-proxy -n agentgateway-system -o=jsonpath="{.status.addresses[0].value}")
   echo $INGRESS_GW_ADDRESS
   ```
   
   **Option: tabs-tab-tabs-10-1**
   
   ```sh
   kubectl port-forward deployment/agentgateway-proxy -n agentgateway-system 8080:80
   ```

<!--THE END-->

2. As a user, send a request to the A2A server. As an assistant, the agent echoes back the message that you sent.
   
   **Option: tabs-tab-tabs-12-0**
   
   ```sh
   curl -X POST http://$INGRESS_GW_ADDRESS/myagent \
     -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!"
           }
         ]
       }
     }
     }' | jq
   ```
   
   **Option: tabs-tab-tabs-12-1**
   
   ```sh
   curl -X POST http://localhost:8080/myagent \
     -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!"
           }
         ]
       }
     }
     }' | jq
   ```
   
   Example output:
   
   ```json
   {
     "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.

```sh
kubectl delete Deployment a2a-agent --ignore-not-found
kubectl delete Service a2a-agent --ignore-not-found
kubectl delete HTTPRoute a2a --ignore-not-found
kubectl delete AgentgatewayBackend a2a-backend --ignore-not-found
```
