Configure Model Context Protocol

This document describes how to configure API Gateway to act as a remote Model Context Protocol (MCP) server.

Before you begin

  • Ensure you have a valid OpenAPI 3.x specification for your API. MCP is not supported for OpenAPI 2.0.
  • Ensure you understand the basics of API Gateway.

Configuration validation

When you upload your OpenAPI specification, API Gateway performs the following validations for MCP configuration:

  • Location: The x-google-mcp-tool extension must only be specified at the individual operation level.
  • HTTP Method: Only GET, POST, PUT, PATCH, and DELETE operations can be exposed as MCP tools.
  • Tool Name: Tool names must match [A-Za-z0-9_.-]{1,128} and be unique across the specification.
  • Description: Every tool must resolve to a non-empty description (taken from the operation's description, summary, or override). Operations without a resolvable description are rejected.
  • Security: If you configure authentication for tools/list, you must name exactly one JWT security scheme defined under components.securitySchemes. API key security is not supported for tools/list in Public Preview.

Authentication model

API Gateway applies different authentication rules depending on the MCP method called:

  • Protocol Lifecycle: The initialize and notifications/initialized methods are unauthenticated.
  • Tool Invocation (tools/call): Reuses the authentication policies defined for the underlying operation in your OpenAPI specification. It enforces the same API key or JWT requirements as calling the REST endpoint directly.
  • Tool Discovery (tools/list): By default, this method is unauthenticated. However, as a security best practice, it is strongly recommended to protect tool discovery by enabling authentication for this method using tools-list.security. If you choose to enable authentication, you must use a JWT security scheme. API key authentication is not supported for tools/list.

Steps to configure MCP

Follow these steps to expose your API as MCP tools:

1. Identify operations to expose

Review your OpenAPI specification and decide which operations should be available to AI agents.

2. Update your OpenAPI specification

You can enable MCP globally for all eligible operations, or configure it on a per-operation basis.

Global enablement

Enable MCP globally by adding the mcp field to x-google-api-management at the document level:

openapi: 3.0.3
info:
  title: Bookstore API
  version: 1.0.0
x-google-api-management:
  mcp: true
  backends:
    bookstore-backend:
      address: https://bookstore-backend-12345678.us-central1.run.app

When globally enabled, all eligible operations (based on HTTP method and path) are exposed as MCP tools. By default, the tool name is the operation's operationId, and the description is the operation's description or summary.

Per-operation configuration

You can override global settings or selectively expose operations using x-google-mcp-tool:

paths:
  /v1/shelves/{shelf}:
    delete:
      operationId: deleteShelf
      summary: Delete a shelf.
      x-google-backend: bookstore-backend
      x-google-mcp-tool:
        name: delete_shelf
        description: "Permanently delete a shelf and every book on it."

You can also opt-out an operation when globally enabled by setting x-google-mcp-tool: false.

By default, the tools/list method (which enumerates available tools) is unauthenticated. As a security best practice, it is strongly recommended to enforce authentication by configuring tools-list.security under x-google-api-management/mcp. You must use a JWT scheme; API keys are not supported for this method.

x-google-api-management:
  mcp:
    tools-list:
      security:
        myJWT: []

4. Create and deploy the API config

Create an API config from your annotated specification and deploy it to a gateway using the standard flow. See Deploying an API to a gateway for details.

5. Verify MCP support

Once deployed, you can verify that the gateway is serving MCP requests.

Handshake

Send an initialization request to establish protocol version and capabilities:

curl -X POST https://my-gateway-12345.uc.a.run.app/mcp \
  -H "Content-Type: application/json" \
  -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-11-25",
    "capabilities": {},
    "clientInfo": {"name": "demo-client", "version": "1.0.0"}
  }
}'

Acknowledge handshake

Acknowledge the initialization. The gateway responds with HTTP 202 Accepted:

curl -X POST https://my-gateway-12345.uc.a.run.app/mcp \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2025-11-25" \
  -d '{"jsonrpc": "2.0", "method": "notifications/initialized"}'

Discover tools

List the available tools:

curl -X POST https://my-gateway-12345.uc.a.run.app/mcp \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2025-11-25" \
  -d '{"jsonrpc": "2.0", "id": 2, "method": "tools/list"}'

How arguments map to the REST request

The arguments passed to a tool are mapped to the underlying REST request based on the OpenAPI specification:

  • Path and query parameters: Become top-level properties in the arguments object, keyed by their OpenAPI parameter names.
  • Request body: Nested under a single property named body. For example, to create a resource, you pass {"body": {"fieldName": "value"}}.
  • Headers: Also become top-level properties. The gateway injects them as standard HTTP headers in the backend call.

The transcoded backend request is indistinguishable from a direct REST request to your backend service. Backend services cannot programmatically distinguish between a direct REST call and one transcoded from MCP.

Invoke a tool

Invoke a specific tool. Ensure you include any required authentication tokens if the underlying REST operation requires them:

curl -X POST https://my-gateway-12345.uc.a.run.app/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -H "MCP-Protocol-Version: 2025-11-25" \
  -d '{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "delete_shelf",
    "arguments": {"shelf": "sci-fi"}
  }
}'

Observability

MCP requests yield standard API Gateway metrics and logs. You can distinguish MCP traffic from standard REST traffic by inspecting the request path (typically ending in /mcp) or by configuring custom metrics.

Troubleshooting MCP failures

MCP distinguishes between transport failures and protocol failures. The gateway returns HTTP 200 with a JSON-RPC error object for protocol and application errors, as non-200 responses can cause many MCP clients to fail at the transport layer.

The following table describes common symptoms and fixes:

Symptom JSON-RPC Code HTTP Status Meaning and Typical Fix
Method Not Allowed n/a 405 A non-POST request reached /mcp. Only HTTP POST is supported.
JSON parse error -32700 400 The request body is not valid JSON.
Missing/Invalid Method or ID -32600 200 The body is valid JSON but not a valid JSON-RPC request. Check required fields (jsonrpc, method, id).
Method is not supported -32601 200 The method is outside the supported scope (e.g., ping).
Unsupported protocol version -32602 200 The protocolVersion names a version the gateway does not support.
Missing Protocol Version -32602 200 The initialize params omit protocolVersion or it is not a string.
Unknown tool -32602 200 Tool name not found. Clean client cache or verify deployment.
Invalid tool arguments -32602 200 Arguments are missing or invalid. Verify the body key nesting.
Body too large -32000 200 The response payload exceeded size limits.
Transport body too large n/a 413 The raw HTTP request body exceeded gateway transport limits.
Server error -32000 200 Unparseable backend response. Check logs.
Unauthorized / Forbidden n/a 401 / 403 Authentication failure. The response carries a WWW-Authenticate header pointing at protected resource metadata.

Backend application errors typically surface as a successful JSON-RPC response (HTTP 200) with result.isError: true containing the backend error body.

What's next