Tyk lets you apply middleware to individual MCP primitives (specific tools, resources, and prompts), giving you the same granular control over AI agent traffic that you have over conventional API endpoints. You can rate limit an expensive tool, block a sensitive prompt, set a circuit breaker on an unreliable resource, or apply a custom plugin to inspect tool call arguments before they reach the upstream. This page describes each middleware capability available for MCP proxies, when to use it, and how to configure it.Documentation Index
Fetch the complete documentation index at: https://tyk.io/docs/llms.txt
Use this file to discover all available pages before exploring further.
For an explanation of how middleware fits into the overall MCP API definition structure (the three levels, their evaluation order, and how they interact), see MCP definitions.
Configuration paths
Middleware can be configured in three ways, depending on the level at which it applies and whether you are using the Dashboard UI or editing the definition directly.Dashboard: Settings tab (proxy level)
The Settings tab on the MCP Designer exposes middleware that applies to all requests through the proxy, regardless of which primitive is invoked. These options map tox-tyk-api-gateway.middleware.global in the definition:
| Middleware | Maps to |
|---|---|
| CORS | middleware.global.cors |
| Transform Request Headers | middleware.global.transformRequestHeaders |
| Transform Response Headers | middleware.global.transformResponseHeaders |
| Context Variables | middleware.global.contextVariables |
| Traffic Logs | middleware.global.trafficLogs |
| Plugin Config / Bundle | middleware.global.pluginConfig |
Dashboard: Primitives tab (primitive level)
The Primitives tab lets you add middleware to individual tools, resources, and prompts. Click a primitive and then Add Middleware. These options map to the primitive’s entry inmcpTools, mcpResources, or mcpPrompts. See Managing MCP proxies using the Dashboard for the full UI walkthrough.
| Middleware | Maps to |
|---|---|
| Allow, Block | allow, block |
| Ignore Authentication | ignoreAuthentication |
| Rate Limit | rateLimit |
| Request Size Limit | requestSizeLimit |
| Circuit Breaker | circuitBreaker |
| Transform Request Headers | transformRequestHeaders |
| Transform Response Headers | transformResponseHeaders |
| Virtual Endpoint | virtualEndpoint |
| Track Endpoint, Do Not Track Endpoint | trackEndpoint, doNotTrackEndpoint |
| Post Plugins | postPlugins |
MCP definition (all levels)
All middleware options (including those not exposed in the Dashboard) can be configured by editing the proxy definition directly. Open the definition editor via Actions → View MCP Proxy Definition in the Dashboard, or submit the definition via the API. The following options are only available this way:transformRequestBody: Request body transformation (supported)urlRewrite,transformRequestMethod: Accepted by the schema but silently ignored at runtime; they have no effect on MCP primitives. See the warnings in the request transformation section below.middleware.operations: Method-level middleware applying to all calls of a given JSON-RPC method (for example, alltools/callrequests), evaluated before primitive-level middleware
Caching and mock responses are not supported for MCP primitives.
mcpTools, mcpResources, or mcpPrompts maps unless otherwise noted.
How primitive middleware is resolved
Middleware for MCP primitives is configured inx-tyk-api-gateway.middleware inside one of three maps:
mcpTools: Keyed by tool name (theparams.namevalue in atools/callrequest)mcpResources: Keyed by resource URI or URI wildcard pattern (theparams.urivalue in aresources/readrequest)mcpPrompts: Keyed by prompt name (theparams.namevalue in aprompts/getrequest)
tools/call, resources/read, or prompts/get request, it extracts the primitive identifier from the JSON-RPC body, finds the matching entry in the relevant map, and executes the configured middleware before proxying to the upstream.
The middleware.operations map applies middleware at the JSON-RPC method level rather than the individual primitive level. Method-level middleware evaluates before primitive-level middleware.
Access control
Access control middleware determines which primitives a client is allowed to invoke. It is the most commonly configured middleware for MCP proxies, because MCP servers typically expose more capabilities than you want to make available through the gateway.allow
Theallow middleware adds a primitive to an explicit allowlist. When any primitive within a category has allow enabled, Tyk switches that entire category into allowlist mode: only the explicitly listed primitives are accessible, and all others are rejected with a JSON-RPC error.
get-weather and get-forecast are accessible. A request to any other tool name returns an error without reaching the upstream. Resources and prompts are unaffected; the three categories are evaluated independently, so allowlisting tools does not restrict resource or prompt access.
Allowlist mode is the recommended approach when you have a known set of primitives to expose. It ensures that new tools added to the upstream MCP server are not automatically accessible through the gateway; you must explicitly add them to the allowlist.
block
Theblock middleware explicitly denies access to a primitive. Tyk returns a JSON-RPC error without forwarding the request to the upstream. Use block when all primitives should be accessible by default except a specific subset.
allow rules exist in the category, all primitives are accessible by default. Block rules apply on top of this open default. If allow rules are also present, block rules take precedence.
ignoreAuthentication
TheignoreAuthentication middleware exempts a primitive from the API’s authentication checks, allowing unauthenticated access to that specific primitive while the rest of the API remains protected.
Traffic management
Traffic management middleware protects your upstream MCP server from overload and controls the quality of service for individual primitives.rateLimit
TherateLimit middleware applies a rate limit to a specific primitive, counted separately from any method-level or MCP server-level rate limits. Use it when different tools have meaningfully different costs: for example, a resource-intensive tool should have a tighter limit than one that reads static metadata.
rate field is the maximum number of requests allowed in the time window specified by per (in seconds, or as a shorthand string such as "1m" or "30s"). Primitive-level rate limits are additive with method-level limits; a request must pass both.
Rate limits configured in mcpTools, mcpResources, and mcpPrompts apply to all consumers of the proxy; they are shared ceilings. For per-consumer primitive rate limits that track each consumer key independently, use the mcp_primitives field in a security policy. Both can be active simultaneously: the middleware limit protects the upstream from aggregate overload; the policy limit enforces each consumer’s individual entitlement. See MCP proxy policies.
requestSizeLimit
TherequestSizeLimit middleware restricts the maximum size of the JSON-RPC request body for a specific primitive. Use it for tools that accept large argument payloads, where oversized requests could cause performance problems upstream.
value field is in bytes. Requests that exceed the limit are rejected before reaching the upstream.
circuitBreaker
ThecircuitBreaker middleware monitors the failure rate for a specific primitive and temporarily stops forwarding requests when the error rate exceeds a threshold. This protects the upstream from cascading failures and gives it time to recover.
threshold: The ratio of failed requests (0.0 to 1.0) that trips the breaker.0.5means the breaker trips when more than 50% of recent requests fail.sampleSize: The number of requests in the evaluation window. The threshold is checked after each window.coolDownPeriod: Seconds to wait with the breaker open before attempting recovery.halfOpenStateEnabled: Whentrue, allows a small number of probe requests through during the cool-down period to test whether the upstream has recovered, rather than waiting for the full period to elapse before reopening.
cache
Thecache field is accepted in the configuration schema but does not activate caching for MCP primitives. Any cache configuration you set on an entry in mcpTools, mcpResources, or mcpPrompts is silently ignored at runtime. The limitation is architectural: Tyk’s cache middleware derives cache keys from the HTTP URL path, which is the same for every MCP request (/mcp). It does not inspect the JSON-RPC request body, so it cannot distinguish a resources/read call for weather://current from a tools/call to get_forecast; they resolve to the same cache key. Caching MCP traffic meaningfully would require cache key derivation from the JSON-RPC method and primitive identifier, which is not currently implemented.
Request transformation
Request transformation middleware modifies requests before they reach the upstream MCP server. You can add or remove headers, rewrite the upstream URL, or replace the request body.transformRequestHeaders
ThetransformRequestHeaders middleware adds, removes, or modifies HTTP headers on the request forwarded to the upstream.
transformRequestBody
ThetransformRequestBody middleware transforms the JSON-RPC request body before it is forwarded to the upstream, using a Go template. This allows you to reshape the request, for example to translate between different argument schemas or to inject values from the gateway context.
urlRewrite
transformRequestMethod
Response transformation
transformResponseHeaders
ThetransformResponseHeaders middleware adds, removes, or modifies HTTP headers on the response returned to the client.
Response body transformation (
transformResponseBody) is not available for MCP primitives. MCP responses are JSON-RPC 2.0 messages and must be returned to the client unmodified to maintain protocol compliance. Response body transformation remains available for entries in middleware.operations if you need to transform at the method level, but the same protocol compliance constraint applies, so use with care.Testing and development
mockResponse
ThemockResponse field is accepted in the configuration schema but does not intercept or replace responses for MCP primitives.
virtualEndpoint
ThevirtualEndpoint middleware executes a JavaScript function in place of the upstream proxy. Use it to implement simple primitives directly in the gateway, for example a tool that aggregates data from a Tyk context variable, performs a simple calculation, or returns a dynamically constructed response without needing a dedicated upstream service.
proxyOnError to true to fall back to the upstream if the virtual endpoint function throws an error.
Observability
trackEndpoint and doNotTrackEndpoint
By default, Tyk records analytics for all requests. These two middleware options let you override tracking behavior at the primitive level.trackEndpoint enables detailed analytics for a primitive that might otherwise be excluded:
doNotTrackEndpoint excludes a primitive from analytics logs and dashboards. Use this for high-volume or sensitive primitives where capturing every request creates noise or a compliance concern:
Plugins
postPlugins
ThepostPlugins field executes one or more custom plugin functions after the main middleware chain completes, immediately before the request is proxied to the upstream. Use custom plugins when the built-in middleware capabilities are insufficient, for example to validate request arguments against an external schema, to enrich the request with data from a third-party service, or to implement custom access control logic.
pluginConfig section. See Custom plugins for the full plugin development guide.
Resource URI matching
Resources in themcpResources map are matched against the params.uri value in incoming resources/read requests. Tyk resolves the match in this order:
- Exact match: If the request URI matches a key exactly, that entry’s middleware is applied.
- Wildcard match: If no exact match is found, Tyk checks for entries containing
*. When multiple patterns match, the longest prefix wins. - No match: If neither an exact nor wildcard match is found, the request is handled by the default middleware chain (all primitives are accessible unless the category is in allowlist mode).
file:///config/database.json matches the exact entry and gets a 1-hour cache. A request for file:///config/settings.json matches the file:///config/* pattern and gets a 5-minute cache. A request for file:///logs/app.log matches the file:///* fallback and is allowed but not cached.
Middleware capability reference
The following table summarises every middleware capability available for MCP proxies and where it can be configured.| Middleware | Field | Dashboard: Settings tab | Dashboard: Primitives tab | Definition |
|---|---|---|---|---|
| Allowlist | allow | — | Yes | Yes |
| Blocklist | block | — | Yes | Yes |
| Ignore authentication | ignoreAuthentication | — | Yes | Yes |
| Rate limiting | rateLimit | — | Yes | Yes |
| Request size limit | requestSizeLimit | — | Yes | Yes |
| Circuit breaker | circuitBreaker | — | Yes | Yes |
| Cache | cache | — | — | No, disabled for protocol compliance |
| Transform request headers (global) | middleware.global.transformRequestHeaders | Yes | — | Yes |
| Transform request headers (primitive) | transformRequestHeaders | — | Yes | Yes |
| Transform request body | transformRequestBody | — | — | Yes |
| URL rewrite | urlRewrite | — | — | No, silently ignored for protocol compliance |
| Transform request method | transformRequestMethod | — | — | No, silently ignored for protocol compliance |
| Transform response headers (global) | middleware.global.transformResponseHeaders | Yes | — | Yes |
| Transform response headers (primitive) | transformResponseHeaders | — | Yes | Yes |
| Transform response body | transformResponseBody | — | — | No, disabled for protocol compliance |
| Mock response | mockResponse | — | — | No, disabled for protocol compliance |
| Virtual endpoint | virtualEndpoint | — | Yes | Yes |
| Track endpoint | trackEndpoint | — | Yes | Yes |
| Do not track | doNotTrackEndpoint | — | Yes | Yes |
| Post plugins | postPlugins | — | Yes | Yes |
| CORS | middleware.global.cors | Yes | — | Yes |
| Context variables | middleware.global.contextVariables | Yes | — | Yes |
| Traffic logs | middleware.global.trafficLogs | Yes | — | Yes |
| Plugin config / bundle | middleware.global.pluginConfig | Yes | — | Yes |