The gateway role
Without a gateway, AI agents connect directly to MCP servers over HTTP. Each server is responsible for its own authentication, access control, and rate limiting, or has none at all. There is no central point to see which agents are calling which tools, no consistent way to revoke access, and no protection against a slow or unavailable server. For the full picture of why this creates operational risk at scale, see MCP Gateway overview. Tyk sits between MCP clients and your upstream MCP servers. Unlike a generic reverse proxy that treats all traffic as an opaque HTTP stream, Tyk understands the MCP protocol. It parses the JSON-RPC request body on everyPOST /mcp to identify the method being called and the specific primitive being accessed. This is what makes primitive-level control possible.
Because Tyk knows that a particular request is a tools/call for get_current_weather (not just a POST to /mcp), it can:
- Rate limit that tool independently, without affecting other tools on the same server
- Block access to a specific resource URI without restricting the entire resources category
- Enforce a timeout on a slow tool without affecting fast tools
- Strip that tool from
tools/listresponses for consumers whose policy does not permit it - Record the exact tool name in analytics so you can see precisely which primitives agents are calling
GET /weather differently from GET /weather/forecast. MCP routes all traffic through a single endpoint and identifies the operation from the request body:
MCP definitions are supported in Tyk OAS format only. They are not available as Tyk Classic API definitions.
Transport
MCP uses Streamable HTTP as its transport. The MCP specification defines a single endpoint path (/mcp) that supports two HTTP methods with distinct roles. Tyk proxies both.
POST /mcp: JSON-RPC messages. Clients send JSON-RPC 2.0 messages to POST /mcp. The upstream MCP server can respond with:
200 application/json: a single JSON-RPC response, for operations that complete immediately.200 text/event-stream: a Server-Sent Events stream carrying multiple JSON-RPC messages, used when the server streams results or sends progress notifications.202 Accepted: an acknowledgement for JSON-RPC notifications that do not expect a response body.
POST request (authenticating, applying rate limits, checking allowlists) and then proxies it to the upstream. Tyk preserves the response content type and streams SSE responses through to the client without buffering or transforming the body.
GET /mcp: Server-Sent Events. Clients open a persistent GET /mcp connection to receive server-initiated messages. The upstream MCP server uses this channel to push progress notifications, resource update notifications, and server-to-client requests such as sampling/createMessage. Tyk proxies the SSE stream transparently, maintaining the long-lived connection for the duration of the session.
Protocol headers
MCP defines several protocol-specific headers that Tyk passes through unchanged in both directions:
The client and upstream MCP server handle version negotiation and session management. Tyk does not modify any MCP protocol headers.
What is MCP?
The Model Context Protocol (MCP) is an open standard that defines how AI applications connect to external tools, data sources, and services. It uses a client-server model: an MCP client (an AI agent, LLM orchestration framework, or application) connects to an MCP server that exposes capabilities, and the two communicate using JSON-RPC 2.0 messages carried over HTTP. Tyk supports the2025-11-25 revision of the MCP specification.
Primitives
MCP servers expose three types of capability, collectively called primitives.
Each primitive has a name (or URI for resources) that uniquely identifies it within the server:
- A
tools/callrequest names the tool inparams.name - A
resources/readrequest names the resource URI inparams.uri - A
prompts/getrequest names the prompt inparams.name
Client-side primitives
MCP also defines primitives that run in the opposite direction: capabilities that servers can request from clients rather than expose themselves.Tyk passes client-side primitive messages through to the upstream and back. Primitive-level middleware configuration (rate limits, access control, timeouts) applies to server-side primitives only.
The request format
Every MCP operation is a JSON-RPC 2.0 message sent toPOST /mcp. Each message carries a method field that identifies the operation and, for invocation requests, a params object that names the specific primitive being accessed.
A typical tool call looks like this:
method field identifies the category of operation: tools/call in this example. The params.name field identifies the specific tool. Tyk reads both fields on every incoming POST /mcp request to determine which middleware to execute before forwarding to the upstream.
JSON-RPC methods
The MCP specification defines a fixed set of JSON-RPC method names, grouped into four categories.
Tyk can apply rate limits, access control, and middleware at the method level (for example, capping all
tools/call requests) and at the primitive level (for example, rate limiting a specific named tool). The distinction matters: method-level controls apply to every invocation of that method regardless of which primitive is named; primitive-level controls apply only when that specific tool, resource, or prompt is requested.
Session lifecycle
MCP is a stateful protocol. When a client sends aninitialize request, the upstream server responds with an Mcp-Session-Id header. The client includes this identifier on all subsequent requests, allowing the server to associate them with the established session context. Tyk passes the header through unmodified and does not maintain session state itself.
A typical session proceeds through four phases.
- Handshake: the client and server negotiate capabilities and establish a session identifier.
- Discovery: the client queries the server’s available tools, resources, and prompts.
- Invocation: the client calls primitives; Tyk applies rate limiting, access control, and observability on each request.
- Session close: the client terminates the session; the session identifier is invalidated.
Handshake
Tyk authenticates theinitialize request before proxying it to the upstream. The upstream responds with an Mcp-Session-Id header that Tyk passes through to the client unchanged. The client confirms readiness with a notifications/initialized message, and the session is established.
Discovery
Once the session is open, the client callstools/list (and optionally resources/list and prompts/list) to learn what the server exposes. Tyk intercepts the upstream’s response and strips any primitives the consumer is not permitted to see, based on the policy attached to their key. The client receives a filtered view of the server’s capabilities.
Invocation
Each primitive call passes through Tyk’s full middleware chain. Rate limiting, access control, and observability all fire on everytools/call request. If scope enforcement is configured, Tyk validates the inbound token’s scopes against the primitive’s requirements before proxying. If token exchange is configured, Tyk exchanges the inbound token for a backend-scoped token — the inbound SSO token never reaches the upstream MCP server. If the consumer’s policy permits the named tool and rate limits allow the request, Tyk proxies it to the upstream and returns the response. This phase repeats for every tool, resource, or prompt the client invokes.
Session close
When the client has finished, it sendsDELETE /mcp with the Mcp-Session-Id header. Tyk proxies the request to the upstream, which terminates the session. After session close, the Mcp-Session-Id is invalid; a new initialize request is required to open a new session.
If the GET /mcp SSE connection drops, the client can reconnect by opening a new GET /mcp request with the Last-Event-ID header set to the ID of the last event received. Tyk passes this through to the upstream, which resumes the stream from that point.
The proxy definition
The MCP proxy definition is the configuration object that describes the proxy. It is a Tyk OAS API definition, an OpenAPI 3.0 document extended withx-tyk-api-gateway, and it is both the single source of truth for everything about the proxy and its registry entry: the listen path, the upstream URL, authentication, middleware, and versioning.
The x-tyk-api-gateway extension has four top-level sections:
A minimal MCP proxy definition looks like this:
https://my-gateway.example.com/weather/mcp. Tyk authenticates the request, applies any configured middleware, and proxies it to https://weather-mcp.example.com/mcp. Tyk serves both the POST and GET transport endpoints under the same listen path.
You manage MCP proxy definitions through the Tyk Gateway API (at /tyk/mcps) or the Tyk Dashboard. For the full definition structure and field reference, see MCP OAS definitions.
Tool naming and discovery
Every tool, resource, and prompt on an MCP server has a name (or URI for resources) that uniquely identifies it within that server. Understanding how names are assigned, and how Tyk uses them, is a prerequisite for configuring primitive-level middleware, blocking specific tools, or writing policies with allowlists and blocklists. In MCP Proxy pass-through mode (Tyk proxying an existing MCP server), tool names come from the upstream server verbatim. Tyk does not modify or namespace them. If the upstream server exposes a tool namedget-weather, that is the name Tyk uses for middleware matching, policy rules, and analytics.
In HTTP-to-MCP translation mode (Tyk converting a REST API into MCP tools via AI Studio), tool names are derived from the operationId field of each OpenAPI operation. An operation with operationId: getWeatherForecast becomes a tool named getWeatherForecast. If your OpenAPI spec does not set operationId on every operation, Tyk cannot create a stable tool name. Adding operationId values to every exposed operation is a prerequisite for this mode.
Discovery filtering applies at the tools/list, resources/list, and prompts/list level. When a client requests the list of available primitives, Tyk intercepts the upstream’s response and removes any entries that the consumer’s policy does not permit. The client only sees and can only call the primitives its key is authorized to access.
Name collisions: When proxying multiple MCP servers behind a single gateway, or when combining proxy pass-through and HTTP-to-MCP translation, tool names from different upstream servers may collide. Each MCP proxy definition is a separate Tyk API with its own listen path, so collisions are isolated per proxy: a tool named search on one proxy does not conflict with search on another. However, if you are using a single proxy to aggregate multiple upstream MCP servers (via the mcp-registry plugin), ensure that upstream tool names do not overlap, or use the plugin’s namespacing configuration to prefix tool names per upstream.
Middleware
Tyk applies middleware to MCP traffic at three levels, all configured in thex-tyk-api-gateway.middleware section of the proxy definition. The levels are evaluated in order from broadest to most specific.
Global middleware
Global middleware applies to every request that reaches the proxy, before any method-level or primitive-level processing. Use it for server-wide concerns: CORS configuration, traffic logging, header injection into upstream requests, or custom plugins that should run on all traffic.Operation middleware
Operation middleware applies to all requests for a specific JSON-RPC method, regardless of which primitive is called. Configure it inmiddleware.operations, keyed by the JSON-RPC method name with its HTTP method suffix (for example, tools/callPOST). Use it for method-wide policies, such as a rate limit that applies to all tools/call requests without distinguishing between individual tools.
tools/call request, regardless of which tool is named in params.
Primitive middleware
Primitive middleware applies to a specific tool, resource, or prompt. Configure it in one of three maps (middleware.mcpTools, middleware.mcpResources, or middleware.mcpPrompts), keyed by the primitive’s identifier: the tool name, resource URI (or URI pattern), or prompt name. In addition to the standard middleware capabilities, two OAuth 2.0 features operate at this level: scopeCheck validates the inbound token’s scopes against the primitive’s security: requirements, and exchange replaces the Authorization header with a backend-scoped token before the request reaches the upstream (see Token exchange).
execute-query tool and applies a rate limit of 10 requests per minute, independently of any other tools on the same proxy.
When both operation-level and primitive-level middleware are configured, both apply. A tools/call request to execute-query must pass the operation-level limit (500/min for all tool calls) and the primitive-level limit (10/min for this tool). Access control follows the same pattern: allowlisting specific tools in mcpTools puts the entire tools category into allowlist mode, blocking any tool not explicitly listed.
Tyk evaluates the three primitive categories (tools, resources, and prompts) independently. Allowlisting a tool has no effect on whether resources or prompts are accessible.
See MCP middleware for the full list of available capabilities: access control, request and response transformation, traffic management (rate limiting, timeouts, circuit breakers), virtual endpoints, and observability controls.
Policies
A Tyk security policy is a reusable template of access rights and usage limits that you apply to one or more API keys. You define a policy once and issue keys that inherit its rules automatically, rather than configuring each key individually. When you update the policy, every key bound to it picks up the change. Policies give you per-consumer control at every level of the MCP protocol:- Proxy access: control which MCP proxies a consumer key can reach
- JSON-RPC method access: restrict which protocol operations a consumer can use (for example, allow
tools/callbut blocksampling/createMessage) - Primitive access: define per-consumer allowlists and blocklists for individual tools, resources, and prompts, using regular expressions to match by name
- Per-primitive rate limits: set independent rate limits on specific primitives, so a consumer exhausting their quota on one tool does not affect their access to others
- Quotas: cap total call volume over a renewal period
tools/call, resources/read, and prompts/get requests against the consumer’s permitted primitives. Blocked calls return a JSON-RPC error before the request reaches the upstream.
At discovery time: Tyk intercepts tools/list, resources/list, and prompts/list responses from the upstream and strips out any primitives the consumer cannot see. Each consumer receives a filtered view of the server’s capabilities from the moment they connect.
Policies versus middleware
Both middleware and policies can enforce limits on MCP primitives, but they operate on different subjects. Middleware applies to all traffic through the proxy: a primitive rate limit inmcpTools caps the call rate for a tool across every caller combined. It protects the upstream from overload.
Policies apply per consumer. A primitive rate limit in a policy caps the call rate for one specific key, with each consumer’s counters tracked independently. This is how you enforce different entitlements for different consumers: a standard tier with read-only access and lower limits, a premium tier with access to sensitive tools and higher quotas.
The two work together: middleware sets the ceiling for all traffic, policies determine what each consumer is entitled to within that ceiling.
Tyk also supports scope-based access control via the oauth2 scheme’s scopeCheck feature. This is complementary to policy-based access control: policies control which primitives a consumer key can reach; scope check validates that the inbound token carries the required OAuth scopes for each primitive. The two can be combined — a consumer must both hold a key permitted by policy and present a token with the required scopes. See OAuth 2.0 (External IdP) for configuration details.
See MCP proxy policies for the full configuration reference, Dashboard UI walkthrough, and API examples.