> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/agentgateway/agentgateway/llms.txt
> Use this file to discover all available pages before exploring further.

# Backends

> Configure upstream targets — MCP servers, A2A agents, HTTP services, and OpenAPI endpoints.

Backends define where agentgateway forwards matched traffic. They appear inside [routes](/reference/routes) as inline configurations. agentgateway supports four backend types: `mcp`, `host` (plain HTTP/A2A), and named backend references defined at the top-level `backends` list.

## Backend types

Each entry in `routes[].backends` must be exactly one of:

| Field     | Description                                                                             |
| --------- | --------------------------------------------------------------------------------------- |
| `mcp`     | Connect to one or more MCP servers (stdio, HTTP/SSE, or OpenAPI).                       |
| `ai`      | Proxy to an LLM provider (OpenAI, Gemini, Anthropic, Bedrock, Azure OpenAI, Vertex AI). |
| `host`    | Plain HTTP hostname or A2A agent address.                                               |
| `aws`     | AWS-native backends such as AWS Bedrock AgentCore.                                      |
| `backend` | Reference to a named backend in the top-level `backends` list.                          |
| `service` | Reference to a Kubernetes service (control-plane environments).                         |

***

## MCP backend

The `mcp` backend type proxies traffic to one or more MCP (Model Context Protocol) servers. Multiple targets are aggregated: the gateway exposes all tools, resources, and prompts as a single unified MCP server to clients.

<Note>
  When multiple targets are configured, each tool name is prefixed with `<target-name>_` to avoid collisions between servers.
</Note>

```yaml theme={null}
backends:
  - mcp:
      targets:
        - name: <target-name>
          # One of: stdio, sse, mcp, openapi
```

### MCP target fields

<ParamField path="mcp.targets[].name" type="string" required>
  A unique name for this MCP target. Used to prefix tool names when multiple targets are aggregated (e.g., `weather_get_forecast`).
</ParamField>

<ParamField path="mcp.targets[].policies" type="object">
  Per-target policies (header modification, backend TLS, authentication, etc.). These merge with and can override route-level policies for this specific target.
</ParamField>

### Stdio transport

Agentgateway spawns a local process and communicates over its standard input/output. Use this for MCP servers distributed as CLI tools.

<ParamField path="mcp.targets[].stdio.cmd" type="string" required>
  The command to execute. The process is started when the first client connects.
</ParamField>

<ParamField path="mcp.targets[].stdio.args" type="string[]">
  Arguments to pass to the command.
</ParamField>

<ParamField path="mcp.targets[].stdio.env" type="object">
  Environment variables to set for the spawned process. Key-value string pairs.
</ParamField>

<CodeGroup>
  ```yaml single server (stdio) theme={null}
  binds:
    - port: 3000
      listeners:
        - routes:
            - backends:
                - mcp:
                    targets:
                      - name: everything
                        stdio:
                          cmd: npx
                          args: ["@modelcontextprotocol/server-everything"]
  ```

  ```yaml multiple servers aggregated theme={null}
  binds:
    - port: 3000
      listeners:
        - routes:
            - backends:
                - mcp:
                    targets:
                      - name: time
                        stdio:
                          cmd: uvx
                          args: ["mcp-server-time"]
                      - name: everything
                        stdio:
                          cmd: npx
                          args: ["@modelcontextprotocol/server-everything"]
  ```
</CodeGroup>

### HTTP/SSE transport

Agentgateway connects to an already-running MCP server over HTTP. Two sub-types are supported:

**SSE transport** (`sse`) — connects to an MCP server using the legacy Server-Sent Events transport.

<ParamField path="mcp.targets[].sse.host" type="string" required>
  Hostname or IP address of the MCP server.
</ParamField>

<ParamField path="mcp.targets[].sse.port" type="number">
  Port of the MCP server.
</ParamField>

<ParamField path="mcp.targets[].sse.path" type="string">
  URL path prefix, e.g. `/sse`.
</ParamField>

**Streamable HTTP transport** (`mcp`) — connects to an MCP server using the modern streamable HTTP transport.

<ParamField path="mcp.targets[].mcp.host" type="string" required>
  Hostname or IP address of the MCP server.
</ParamField>

<ParamField path="mcp.targets[].mcp.port" type="number">
  Port of the MCP server.
</ParamField>

<ParamField path="mcp.targets[].mcp.path" type="string">
  URL path prefix, e.g. `/mcp`.
</ParamField>

```yaml theme={null}
backends:
  - mcp:
      targets:
        - name: remote-tools
          mcp:
            host: tools.internal
            port: 3001
            path: /mcp
```

### OpenAPI transport

Agentgateway converts an OpenAPI specification into MCP tools, enabling any REST API to be used by AI agents over the MCP protocol.

<ParamField path="mcp.targets[].openapi.host" type="string" required>
  Hostname of the REST API.
</ParamField>

<ParamField path="mcp.targets[].openapi.port" type="number">
  Port of the REST API.
</ParamField>

<ParamField path="mcp.targets[].openapi.path" type="string">
  Base path for the API.
</ParamField>

<ParamField path="mcp.targets[].openapi.schema" type="object" required>
  The OpenAPI schema to use. Provide either a `file` path or a `url`.

  <Expandable title="schema sources">
    <ParamField path="openapi.schema.file" type="string">
      Local file path to the OpenAPI YAML or JSON specification.
    </ParamField>

    <ParamField path="openapi.schema.url" type="string">
      URL to fetch the OpenAPI specification from at startup.
    </ParamField>
  </Expandable>
</ParamField>

```yaml theme={null}
backends:
  - mcp:
      targets:
        - name: petstore
          openapi:
            host: api.example.com
            port: 443
            path: /v3
            schema:
              url: https://api.example.com/v3/openapi.json
```

***

## HTTP / A2A backend

Use `host` to forward traffic to any HTTP service or A2A (Agent-to-Agent) endpoint. This is the simplest backend type and requires only a hostname and optional port.

<ParamField path="host" type="string" required>
  The upstream hostname or `host:port` address to forward requests to.

  Examples: `127.0.0.1:8080`, `backend.internal:9000`, `localhost:9999`.
</ParamField>

```yaml plain HTTP theme={null}
binds:
  - port: 3000
    listeners:
      - protocol: HTTP
        routes:
          - backends:
              - host: 127.0.0.1:8080
```

### A2A traffic

For A2A (Agent-to-Agent protocol) traffic, use `host` combined with the `a2a: {}` route policy. The policy enables A2A-specific processing, telemetry, and tracing.

```yaml a2a/config.yaml theme={null}
binds:
  - port: 3000
    listeners:
      - routes:
          - policies:
              cors:
                allowOrigins:
                  - "*"
                allowHeaders:
                  - content-type
              # Mark this route as A2A traffic
              a2a: {}
            backends:
              - host: localhost:9999
```

***

## Top-level named backends

The top-level `backends` list defines named backend resources that can be referenced by routes using `backend: <name>`.

<ParamField path="backends[].name" type="string" required>
  A unique name for this backend. Referenced from routes as `backend: <name>`.
</ParamField>

<ParamField path="backends[].host" type="string">
  The upstream hostname or `host:port`.
</ParamField>

<ParamField path="backends[].policies" type="object">
  Policies attached to this backend (TLS, auth, health, HTTP settings, etc.). These apply whenever this backend is referenced from any route.
</ParamField>

```yaml theme={null}
backends:
  - name: api-backend
    host: api.internal:8080
    policies:
      backendTLS:
        root: /etc/certs/ca.crt
      backendAuth:
        key: "Bearer ${API_KEY}"

binds:
  - port: 3000
    listeners:
      - routes:
          - backends:
              - backend: api-backend
```

***

## Backend TLS (`backendTLS`)

Configure TLS for connections agentgateway makes **to** the upstream backend.

<ParamField path="policies.backendTLS" type="object">
  Send TLS to the backend.

  <Expandable title="backendTLS fields">
    <ParamField path="backendTLS.cert" type="string">
      Path to the PEM client certificate for mTLS connections to the backend.
    </ParamField>

    <ParamField path="backendTLS.key" type="string">
      Path to the PEM private key for the client certificate.
    </ParamField>

    <ParamField path="backendTLS.root" type="string">
      Path to the PEM CA bundle used to verify the backend's server certificate. When omitted, the system root CAs are used.
    </ParamField>

    <ParamField path="backendTLS.hostname" type="string">
      Override the SNI hostname used during TLS handshake. Defaults to the backend host.
    </ParamField>

    <ParamField path="backendTLS.insecure" type="boolean">
      Skip all TLS verification. Not recommended for production.
    </ParamField>

    <ParamField path="backendTLS.insecureHost" type="boolean">
      Skip hostname verification only. The certificate is still validated.
    </ParamField>

    <ParamField path="backendTLS.alpn" type="string[]">
      ALPN protocols to advertise during the TLS handshake, e.g. `["h2", "http/1.1"]`.
    </ParamField>

    <ParamField path="backendTLS.subjectAltNames" type="string[]">
      Acceptable Subject Alternative Names in the backend certificate. Overrides the default hostname check.
    </ParamField>
  </Expandable>
</ParamField>

```yaml theme={null}
policies:
  backendTLS:
    root: /etc/certs/ca.crt
    hostname: api.internal
```

***

## Backend auth (`backendAuth`)

Authenticate agentgateway to upstream services. Exactly one auth variant must be set.

<AccordionGroup>
  <Accordion title="passthrough — forward client credentials">
    Pass the incoming request's `Authorization` header directly to the backend without modification.

    ```yaml theme={null}
    policies:
      backendAuth:
        passthrough: {}
    ```
  </Accordion>

  <Accordion title="key — static API key or bearer token">
    Attach a static key as the `Authorization` header on every upstream request. The key value can be an inline string or loaded from a file.

    ```yaml inline key theme={null}
    policies:
      backendAuth:
        key: "Bearer sk-proj-abc123"
    ```

    ```yaml key from file theme={null}
    policies:
      backendAuth:
        key:
          file: /run/secrets/api-key
    ```
  </Accordion>

  <Accordion title="gcp — Google Cloud identity token">
    Obtain a GCP identity or access token from the instance metadata service (or a service account) and attach it to upstream requests.

    ```yaml theme={null}
    policies:
      backendAuth:
        gcp:
          type: identityToken   # or accessToken
          audience: https://backend.example.com
    ```

    * `type` — `identityToken` or `accessToken`.
    * `audience` — Audience for the token. Defaults to the backend host when omitted.
  </Accordion>

  <Accordion title="aws — AWS SigV4 request signing">
    Sign upstream requests using AWS Signature Version 4.

    ```yaml theme={null}
    policies:
      backendAuth:
        aws:
          accessKeyId: AKIAIOSFODNN7EXAMPLE
          secretAccessKey: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
          region: us-east-1
          sessionToken: optional-session-token
    ```
  </Accordion>

  <Accordion title="azure — Azure managed identity or service principal">
    Obtain an Azure access token and attach it to upstream requests. Supports explicit service principal credentials, managed identity, workload identity, and developer implicit credentials.

    ```yaml client secret (service principal) theme={null}
    policies:
      backendAuth:
        azure:
          explicitConfig:
            clientSecret:
              tenant_id: "<tenant-id>"
              client_id: "<client-id>"
              client_secret: "<client-secret>"
    ```

    ```yaml managed identity theme={null}
    policies:
      backendAuth:
        azure:
          explicitConfig:
            managedIdentity:
              userAssignedIdentity:
                clientId: "<client-id>"
    ```

    ```yaml workload identity theme={null}
    policies:
      backendAuth:
        azure:
          explicitConfig:
            workloadIdentity: {}
    ```

    ```yaml developer implicit (local dev) theme={null}
    policies:
      backendAuth:
        azure:
          developerImplicit: {}
    ```
  </Accordion>
</AccordionGroup>

***

## Complete examples

### MCP backend with API key auth and TLS

```yaml theme={null}
binds:
  - port: 3000
    listeners:
      - routes:
          - backends:
              - mcp:
                  targets:
                    - name: remote-api
                      mcp:
                        host: mcp.example.com
                        port: 443
                      policies:
                        backendTLS:
                          root: /etc/certs/ca.crt
                        backendAuth:
                          key: "Bearer sk-secret"
```

### A2A backend with CORS

```yaml theme={null}
binds:
  - port: 3000
    listeners:
      - routes:
          - policies:
              cors:
                allowOrigins: ["*"]
                allowHeaders: ["content-type", "cache-control"]
              a2a: {}
            backends:
              - host: localhost:9999
```

### OpenAPI backend

```yaml theme={null}
binds:
  - port: 3000
    listeners:
      - routes:
          - backends:
              - mcp:
                  targets:
                    - name: petstore
                      openapi:
                        host: petstore.swagger.io
                        port: 443
                        schema:
                          url: https://petstore.swagger.io/v2/swagger.json
```

***

## AI backend

The `ai` backend proxies traffic to an LLM provider. It enables AI-specific policies like prompt guard and prompt enrichment, and exposes LLM-specific telemetry (token counts, model used, streaming status).

```yaml theme={null}
backends:
- ai:
    name: openai
    provider:
      openAI:
        model: gpt-4o-mini
```

### Supported providers

<Tabs>
  <Tab title="OpenAI">
    ```yaml theme={null}
    backends:
    - ai:
        name: openai
        provider:
          openAI:
            model: gpt-4o-mini
    ```

    Authenticate using `backendAuth.key` set to your `OPENAI_API_KEY` environment variable:

    ```yaml theme={null}
    policies:
      backendAuth:
        key: $OPENAI_API_KEY
    ```
  </Tab>

  <Tab title="Google Gemini">
    ```yaml theme={null}
    backends:
    - ai:
        name: gemini
        provider:
          gemini:
            model: gemini-1.5-flash
    ```
  </Tab>

  <Tab title="Anthropic">
    ```yaml theme={null}
    backends:
    - ai:
        name: anthropic
        provider:
          anthropic:
            model: claude-3-5-sonnet-20241022
    ```
  </Tab>

  <Tab title="Google Vertex AI">
    ```yaml theme={null}
    backends:
    - ai:
        name: vertex
        provider:
          vertex:
            model: gemini-1.5-flash
            region: us-central1
            projectId: my-gcp-project
    ```
  </Tab>

  <Tab title="AWS Bedrock">
    ```yaml theme={null}
    backends:
    - ai:
        name: bedrock
        provider:
          bedrock:
            model: anthropic.claude-3-5-sonnet-20241022-v2:0
            region: us-east-1
    ```
  </Tab>

  <Tab title="Azure OpenAI">
    ```yaml theme={null}
    backends:
    - ai:
        name: azure-openai
        provider:
          azureOpenAI:
            model: gpt-4o
            host: https://my-resource.openai.azure.com
            apiVersion: "2024-02-01"
    ```
  </Tab>
</Tabs>

### AI backend fields

<ParamField body="ai.name" type="string" required>
  A unique name for this AI backend instance. Used in telemetry and logging.
</ParamField>

<ParamField body="ai.provider" type="object" required>
  The LLM provider configuration. Exactly one provider must be specified: `openAI`, `gemini`, `anthropic`, `vertex`, `bedrock`, or `azureOpenAI`.
</ParamField>

### AI-specific policies

When using an `ai` backend, the following additional policies are available:

| Policy                    | Description                                  |
| ------------------------- | -------------------------------------------- |
| `policies.ai.promptGuard` | Inspect and filter LLM prompts and responses |
| `policies.ai.prompts`     | Append or prepend system prompts             |
| `policies.ai.routes`      | Map URL paths to LLM operation types         |
| `policies.backendAuth`    | Provide API keys for the LLM provider        |

See the [Prompt Guard guide](/guides/prompt-guard) for configuration details.

***

## AWS backend

The `aws` backend type handles AWS-native integrations such as AWS Bedrock AgentCore.

```yaml theme={null}
backends:
- aws:
    agentCore:
      agentRuntimeArn: "arn:aws:bedrock-agentcore:us-west-2:123456789:runtime/agent-id"
  policies:
    transformations:
      request:
        set:
          X-Amzn-Bedrock-AgentCore-Runtime-User-Id: "user-foo"
```

<Note>
  AWS backends use IAM/SigV4 authentication by default. Configure `backendAuth.aws` with explicit credentials, or rely on the instance's IAM role for implicit authentication.
</Note>
