Update MCP Routing
Endpoint
PUT /apiops/projects/{projectName}/apiProxies/{apiProxyName}/mcp-routing/
uyarı
This endpoint returns HTTP 400 for API proxies whose type is not MCP — mcpRouting can only be set on MCP proxies. To create a new MCP proxy in one call, use Create MCP API Proxy — this endpoint only updates the routing config of a proxy that already exists.
Authentication
Requires a Personal API Access Token.
Permission: API_MANAGEMENT × MANAGE (consistent with the Update AI Routing endpoint).
Header
Authorization: Bearer YOUR_TOKEN
Request
Headers
| Header | Value | Required |
|---|---|---|
| Authorization | Bearer {token} | Yes |
| Content-Type | application/json | Yes |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| projectName | string | Yes | Project name |
| apiProxyName | string | Yes | MCP API Proxy name |
Request Body
The body is the full McpRouting object — it replaces the proxy's current MCP routing configuration.
Full JSON Body Example (TOOL_EXPOSE)
{
"routingMode": "TOOL_EXPOSE",
"protocolVersion": "2025-06-18",
"exposedTools": [
{
"proxyId": "665f1c2e8b3a4d0012ab34cd",
"toolName": "order_lookup",
"toolDescription": "Looks up an order by id",
"apiMethodHttpMethod": "GET",
"apiMethodPath": "/orders/{id}",
"requiredScopes": ["orders.read"],
"argumentConstraints": []
}
],
"identityAcl": [],
"argumentConstraints": [],
"callQuota": null,
"tokenForwardSettings": null
}
Full JSON Body Example (PASSTHROUGH, inline backend server)
{
"routingMode": "PASSTHROUGH",
"backendServers": [
{
"name": "internal-mcp-server",
"endpoint": "https://mcp.example.com/mcp",
"transport": "HTTP_SSE",
"authScheme": "BEARER",
"bearerToken": "raw-token-in-transit-only",
"driftPolicy": "WARN_ONLY"
}
],
"allowedToolNames": ["search", "fetch_document"],
"toolOutputFilter": null,
"identityAcl": [],
"callQuota": null
}
Field Reference
| Field | Type | Description |
|---|---|---|
| routingMode | string | TOOL_EXPOSE (expose selected Apinizer proxies as MCP tools) or PASSTHROUGH (proxy one or more external backend MCP servers) |
| protocolVersion | string | MCP protocol version: 2024-11-05, 2025-06-18 (default) or 2026-07-28 |
| exposedTools | array | TOOL_EXPOSE only. Tool definitions — proxyId (target ApiProxy id), toolName, toolDescription, optional overrideSchema, apiMethodHttpMethod/apiMethodPath (pin to a specific method), requiredScopes, per-tool argumentConstraints |
| backendServers | array | PASSTHROUGH only. The only way to configure a backend target — there is no reference-based alternative. Inline MCP server definitions — up to 10. Each entry is a full connection object: name, endpoint, transport (HTTP_SSE), authScheme (BEARER | OAUTH2_CLIENT_CREDENTIALS | MTLS | NONE) plus the matching credential fields (bearerToken, or credentialRef/tokenEndpoint/clientId/clientSecret/scope, or mTLSSettings), driftPolicy (WARN_ONLY | FAIL_CLOSED), allowPrivateNetworkEgress. Server-managed fields (id, discoveredTools, toolsParsedAt, healthStatus, lastHealthCheckAt, pinnedCatalogHash, driftDetected) are always read from the server's own persisted state — a client-supplied value for any of them is ignored, never trusted. Multiple entries aggregate behind one endpoint (see Multi-Target Aggregation). PASSTHROUGH mode requires at least one entry |
| allowedToolNames | array | PASSTHROUGH tool filter — only listed backend tools are exposed |
| toolOutputFilter | object | PASSTHROUGH tool output filtering rules |
| identityAcl | array | Per-principal allow rules (principalType: CREDENTIAL | ROLE | ORGANIZATION). Enforced on the PASSTHROUGH dispatch path |
| argumentConstraints | array | Routing-level tool argument constraint rules |
| callQuota | object | Call quota config (scoped counters) |
| tokenForwardSettings | object | Explicit opt-in client-token forwarding. The legacy forwardClientToken boolean is a no-op (logged with WARN) — forwarding happens only through these settings |
Behavior
- The configuration is validated (
McpA2aRoutingValidator) before save; invalid mode/field combinations return HTTP 400. - Updating an existing
backendServersentry: to update rather than replace a server, send back theidfrom a prior read (GET/getApiProxy) unchanged — a matchingidis treated as an update and its server-managed fields (discovered catalog, health, drift) are preserved. An entry whoseidis blank, or doesn't match anything currently persisted, is always treated as brand-new: a fresh id is minted server-side and any client-suppliedidis discarded. - Secret fields on
backendServersentries (bearerToken,clientSecret) follow the platform's standard blank-preserves-existing convention: omit the field (or send it unset) to keep the currently stored secret, send a non-blank value to replace it. There is no separate boolean presence flag on this write path — unlike a read, which never returns the secret's plaintext. - Every environment the proxy is currently deployed to is marked redeploy required — redeploy to activate the new configuration.
Response
Success Response (200 OK)
{
"result": {
"success": true
}
}
Error Responses
| Status | Condition |
|---|---|
| 400 | Blank apiProxyName, empty body, proxy not found, proxy is not an MCP proxy, backendServers exceeds 10 entries, or validation failure |
| 401 | Invalid or missing token |
| 500 | Unexpected server error |
Related Documentation
- Update AI Routing
- Create MCP API Proxy
- Update A2A Routing
- Discover MCP Tools for a Policy
- API Proxies
- MCP Gateway — concepts, inline server model, governance