MCP egress
Route MCP traffic through static or dynamically resolved destinations in Orca AI Gateway.
An MCP destination proxies JSON-RPC requests to an MCP server and injects the upstream credential from a vault. Select a static destination by name, or configure a wildcard destination that resolves the URL and credential binding from a trusted control plane.
MCP traffic uses these data-plane endpoints:
| Method and path | Purpose |
|---|---|
POST /v1/mcp | Send one JSON-RPC request or batch. |
GET /v1/mcp | Open a Streamable HTTP server-push channel. |
GET /v1/mcp/sse | Open the dedicated SSE path. |
Every request needs X-Orca-Backend. An exact destination name wins before the "*" wildcard.
The legacy /mcp path remains an alias but emits a deprecation warning.
Configure a static server
Use a named destination when every caller reaches the same MCP URL:
destinations:
github:
kind: mcp
base_url: https://api.githubcopilot.com/mcp/
credentials:
vault: github-token
vaults:
- name: github-token
resolver: env
env_var: GITHUB_MCP_TOKEN
scheme: bearerSend the backend name and credential id with the JSON-RPC request:
curl http://localhost:8080/v1/mcp \
-H 'Content-Type: application/json' \
-H 'X-Orca-Backend: github' \
-H 'X-Orca-Credential-Id: github' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'The static MCP runtime resolves the credential id from X-Orca-Credential-Id. When the header is
missing or invalid, it forwards the request without an injected authorization credential.
destinations.<name>.credentials.credential_id is not read for static MCP traffic. Require and
authorize X-Orca-Credential-Id when the selected vault needs a logical credential id.
Resolve servers dynamically
Use the wildcard destination when an authenticated scope determines the server and credential. The following shape works with the Agent Engine registry:
vaults:
- name: registry-vaults
resolver: http
url_template: "http://orca-registry:8081/internal/v1/workspaces/{scope.workspace_id}/sessions/{scope.session_id}/vault-credentials/{credential_id}/resolve"
bearer_token_file: /var/run/secrets/orca/registry/token
timeout_ms: 5000
destinations:
"*":
kind: mcp
destination_resolver:
kind: http
url_template: "http://orca-registry:8081/internal/v1/workspaces/{scope.workspace_id}/sessions/{scope.session_id}/mcp-destination/resolve"
bearer_token_file: /var/run/secrets/orca/registry/token
timeout_ms: 5000
egress_policy:
dns_timeout_ms: 3000
connect_timeout_ms: 5000
response_timeout_ms: 120000
credentials:
vault: registry-vaultsOnly verified principal attributes can fill {scope.*} placeholders. Map workspace_id and
session_id from a JWT or API-key validator before using this configuration.
For each request, the destination resolver receives the requested backend:
{"backend":"github"}It must return a URL, an authoritative credential id or null, and a positive revision:
{
"url": "https://api.githubcopilot.com/mcp/",
"credential_id": "vcrd_github",
"revision": 42
}The returned credential id selects the vault secret. A client-supplied X-Orca-Credential-Id is
advisory for wildcard dispatch and does not override the resolver response. When an injected
credential receives an upstream 401, the gateway invalidates its vault cache entry, resolves the
credential again, and retries once against the same destination.
See Connect Agent Engine for the complete JWT claim mapping and ACL that binds MCP server and credential grants to an Agent Engine session.
Control dynamic egress
Dynamic targets must use HTTP or HTTPS. By default, the gateway allows public HTTPS destinations
and rejects plaintext HTTP, private addresses, link-local addresses, and other special ranges.
allowed_private_hosts admits an exact hostname or a leading-wildcard hostname such as
*.mcp.svc.cluster.local; it also permits plaintext HTTP for that host.
The dynamic client pins the resolved address for the connection, ignores ambient proxy variables,
does not follow redirects, and converts upstream 3xx responses to 502. Non-SSE responses are
limited to 8 MiB and must finish within response_timeout_ms. For SSE, that timeout covers response
headers rather than the lifetime of the stream.
Keep allowed_private_hosts as narrow as possible. A wildcard destination gives the resolver
control over egress, so protect the resolver with a workload token and keep its URL on a trusted
network path. Use HTTPS or service-mesh mTLS; plain HTTP otherwise sends that token in cleartext.
Authorize the request
Configure an authorizer for MCP traffic that
denies anonymous principals and limits
each caller to the backends and credentials it may use. A YAML ACL can compare X-Orca-Backend and
X-Orca-Credential-Id with signed scope lists; the
Agent Engine integration guide contains a
complete example.
Make retries explicit
MCP tool calls can have side effects. The gateway does not automatically replay a failed MCP call.
When a caller supplies Idempotency-Key, successful buffered responses are cached and a later
matching request can receive that response without another upstream call. SSE responses are never
cached. Dynamic destination resolution and egress admission still run before a cached response is
returned.