Local configuration defines the full runtime behavior of the gateway: which ports to listen on, how to route traffic, which backends to proxy to, and what policies to apply. It lives in the same YAML or JSON file as static configuration , alongside or below the config key.
The gateway watches the config file for changes. When you save an update, it reloads local configuration automatically — no restart required.
File structure
A complete config file has two top-level sections:
config — static global settings (optional; see static config )
binds — array of port bindings with listeners, routes, and backends
# Global static settings (optional)
config :
logging :
level : info
format : json
# Runtime configuration
binds :
- port : 3000
listeners :
- routes :
- backends :
- mcp :
targets :
- name : my-server
stdio :
cmd : npx
args : [ "@modelcontextprotocol/server-everything" ]
YAML vs JSON
Both formats are supported. Use YAML for human-authored configs — it supports comments and is less verbose. Use JSON when generating configs programmatically.
binds :
- port : 3000
listeners :
- name : default
protocol : HTTPS
tls :
cert : certs/cert.pem
key : certs/key.pem
routes :
- backends :
- host : localhost:8080
Top-level structure
Array of port bindings. Each bind defines a port and the listeners attached to it. The TCP port to listen on.
Array of listeners attached to this port. Each listener can match a specific hostname and defines its own routes. See Listeners reference →
Binds and listeners
A bind opens a TCP port. Each bind can have one or more listeners that match traffic by hostname and protocol. Each listener defines a set of routes that map requests to backends .
binds
└── port: 3000
└── listeners
└── hostname: "*.example.com", protocol: HTTPS
└── routes
└── path: /api → backend: api-server
└── path: /mcp → backend: mcp-server
Listener fields
Optional name for the listener. Used for identification in logs and metrics.
binds[].listeners[].namespace
Namespace for the listener resource. Used in multi-tenant and Kubernetes deployments.
binds[].listeners[].hostname
Hostname this listener matches. Supports wildcards, for example *.example.com. When not set, the listener matches all hostnames on the port.
binds[].listeners[].protocol
Protocol for this listener. Accepted values: HTTP, HTTPS. When using HTTPS, provide a tls block.
TLS configuration. Required when protocol is HTTPS. binds[].listeners[].tls.cert
Path to the PEM-encoded certificate file.
binds[].listeners[].tls.key
Path to the PEM-encoded private key file.
binds[].listeners[].tls.root
Path to the root CA certificate bundle for mTLS client verification.
binds[].listeners[].tls.cipherSuites
Optional allowlist of TLS cipher suites. Order is preserved.
binds[].listeners[].tls.minTLSVersion
Minimum TLS version to accept. Supported values: TLS1_2, TLS1_3.
binds[].listeners[].tls.maxTLSVersion
Maximum TLS version to accept. Supported values: TLS1_2, TLS1_3.
binds[].listeners[].routes
Array of routes for this listener. Routes are evaluated in order; the first match wins. See Routes reference →
Routes
A route matches incoming requests and forwards them to one or more backends. Routes support matching on path, headers, method, and query parameters.
routes :
- name : mcp-route
matches :
- path :
pathPrefix : /mcp
policies :
cors :
allowOrigins :
- "*"
allowHeaders :
- content-type
backends :
- mcp :
targets :
- name : my-server
stdio :
cmd : npx
args : [ "@modelcontextprotocol/server-everything" ]
See the Routes reference for full match and policy options.
Backends
Backends define where traffic is sent. The local config supports several backend types:
Routes traffic to one or more MCP servers. Each server is defined as a target with a name and transport (stdio or SSE). backends :
- mcp :
targets :
- name : filesystem
stdio :
cmd : npx
args : [ "@modelcontextprotocol/server-filesystem" , "/data" ]
- name : github
sse :
host : https://mcp.github.com
Route to a plain HTTP upstream using a host shorthand. The gateway resolves this into a full backend definition. backends :
- host : localhost:9999
Route A2A agent traffic. Mark the route with a2a: {} to enable A2A processing and telemetry. routes :
- policies :
a2a : {}
backends :
- host : localhost:9999
See the Backends reference for the full backend schema.
Hot reload behavior
Agentgateway uses filesystem watching to detect config file changes. When the file is saved:
The new configuration is parsed and validated.
If validation passes, the runtime configuration is updated atomically.
Existing in-flight requests complete against the old configuration.
New requests use the updated configuration immediately.
If the updated file contains a syntax error or invalid field, the gateway logs an error and continues running with the previous configuration.
Static configuration fields (under config) are not reloaded on file change. Only binds, listeners, routes, backends, and policies are hot-reloaded.
Complete examples
MCP proxy
A2A proxy
TLS termination
Multi-backend
A minimal MCP proxy with CORS enabled for browser-based clients: # yaml-language-server: $schema=https://agentgateway.dev/schema/config
binds :
- port : 3000
listeners :
- routes :
- policies :
cors :
allowOrigins :
- "*"
allowHeaders :
- mcp-protocol-version
- content-type
- cache-control
exposeHeaders :
- "Mcp-Session-Id"
backends :
- mcp :
targets :
- name : everything
stdio :
cmd : npx
args : [ "@modelcontextprotocol/server-everything" ]
An A2A proxy with JSON logging and access log annotations: config :
logging :
format : json
frontendPolicies :
accessLog :
add :
backend : backend
binds :
- port : 3000
listeners :
- routes :
- policies :
cors :
allowOrigins :
- "*"
allowHeaders :
- content-type
- cache-control
a2a : {}
backends :
- host : localhost:9999
HTTPS listener with TLS termination: # yaml-language-server: $schema=https://agentgateway.dev/schema/config
binds :
- port : 3000
listeners :
- name : default
protocol : HTTPS
tls :
cert : certs/cert.pem
key : certs/key.pem
routes :
- backends :
- mcp :
targets :
- name : everything
stdio :
cmd : npx
args : [ "@modelcontextprotocol/server-everything" ]
Multiple MCP backends on a single port with per-path routing: config :
logging :
level : info
format : json
adminAddr : "0.0.0.0:15000"
statsAddr : "0.0.0.0:15020"
binds :
- port : 3000
listeners :
- routes :
- name : filesystem-route
matches :
- path :
pathPrefix : /fs
policies :
cors :
allowOrigins :
- "*"
allowHeaders :
- content-type
- mcp-protocol-version
backends :
- mcp :
targets :
- name : filesystem
stdio :
cmd : npx
args :
- "@modelcontextprotocol/server-filesystem"
- "/data"
- name : github-route
matches :
- path :
pathPrefix : /github
policies :
cors :
allowOrigins :
- "*"
allowHeaders :
- content-type
- mcp-protocol-version
- authorization
backends :
- mcp :
targets :
- name : github
sse :
host : https://mcp.github.com
Mapping to internal representation
Local configuration translates into an internal representation (IR) shared with XDS. Most fields map directly, but some are transformed for ergonomics:
Local config field IR behavior host: localhost:9999Expanded into a full backend definition with hostname and port mcp.targets[].sse.hostResolved to a backend + TLS configuration based on the URL scheme tls.cert / tls.keyFile paths are read at load time and stored as PEM bytes in the IR Route policies Merged and applied at runtime; precedence handled by the proxy, not the control plane
This translation layer means you can use convenient shorthands in local config that would not be valid in XDS, which expects fully resolved values.