> ## 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.

# MCP Gateway Observability Overview

> An overview of the observability signals Tyk Gateway emits for MCP traffic: metrics dimensions, structured access log fields, distributed tracing, and the Dashboard analytics.

Tyk Gateway emits three categories of observability signal for MCP traffic: custom metrics dimensions, structured access log fields, and distributed tracing spans. All three are enriched with the same set of MCP-specific fields, letting you monitor tool call volumes, track latency per primitive, classify errors, and correlate usage across sessions, through the same observability infrastructure you use for your REST APIs.

## Prerequisites

OpenTelemetry must be enabled on your Tyk Gateway. See [OpenTelemetry configuration](https://tyk.io/docs/api-management/traces.md) for setup instructions.

## MCP Fields

Tyk derives four fields from the JSON-RPC payload of each MCP request: `mcp_method`, `mcp_primitive_type`, `mcp_primitive_name`, and `mcp_error_code`. For their values in access logs, see [MCP fields](https://tyk.io/docs/ai-management/mcp-gateway/mcp-access-logs.md#mcp-fields). For their values as metric dimensions, see [MCP metrics](https://tyk.io/docs/ai-management/mcp-gateway/mcp-metrics.md).

## Observability Signals

| Signal | What it covers | Doc |
| - | - | - |
| **Metrics** | Custom OTel metric instruments with MCP dimensions for counters and histograms | [MCP metrics](https://tyk.io/docs/ai-management/mcp-gateway/mcp-metrics.md) |
| **Access logs** | Structured per-request log records with MCP fields included when non-empty | [MCP access logs](https://tyk.io/docs/ai-management/mcp-gateway/mcp-access-logs.md) |
| **Distributed tracing** | Spans stamped with MCP attributes, with trace context carried in the JSON-RPC body as well as HTTP headers | [Distributed tracing](#distributed-tracing), below |

## Distributed Tracing

When [OpenTelemetry tracing](https://tyk.io/docs/api-management/traces.md) is enabled, Tyk stamps every MCP request's span with MCP-specific attributes and propagates trace context over both the standard HTTP `traceparent` header and the MCP JSON-RPC body, so a trace stays intact even through MCP clients or servers that don't preserve custom headers.

### Span Attributes

| Attribute | Description |
| - | - |
| `mcp.method.name` | JSON-RPC method invoked |
| `mcp.tool.name`, `mcp.resource.name`, or `mcp.prompt.name` | Name of the specific primitive, keyed by its type |
| `mcp.trace_source` | Which channel(s) carried the inbound trace context: `none`, `header`, `meta` (the JSON-RPC body's `params._meta` field), or `both` |

### Trace Context Propagation

Not every MCP client library preserves custom HTTP headers, so the MCP specification allows a client to carry its W3C trace context inside the JSON-RPC request body instead, under `params._meta`. Tyk reads both channels, in a configurable, first-match-wins order set under `opentelemetry.traces.mcp.read_sources` in the gateway config. The default order, the HTTP header first and then the body, matches Tyk's existing header-based behavior, so tracing works unchanged if you don't set this.

Whichever channel Tyk resolves the inbound trace context from, it writes its own current trace context back into the outbound JSON-RPC body before forwarding the request, so a downstream MCP server that reads the body rather than the header joins the same trace. This is the body-channel equivalent of the `traceparent` header Tyk already injects on ordinary proxied requests.

> [!NOTE]
>
> This applies to every MCP proxy. For a [REST API to MCP proxy](https://tyk.io/docs/ai-management/mcps/api-to-mcp.md), the trace continues into the call to the source REST API. See [Access logs when the proxy fronts a Tyk-managed REST API](https://tyk.io/docs/ai-management/mcp-gateway/mcp-access-logs.md#access-logs-when-the-proxy-fronts-a-tyk-managed-rest-api).

## Protocol Versions in Analytics Records

Each MCP analytics record that Tyk Gateway sends to Tyk Pump carries the protocol version of the request, so you can measure how much of your traffic uses `2026-07-28`.

| Field | Description | Example values |
| - | - | - |
| `effective_protocol_version` | The protocol version Tyk used to handle the request | `2026-07-28`, `2025-11-25` |
| `declared_protocol_version` | The version the client declared, if it declared one. Kept even when Tyk rejects the request | `2026-07-28` |
| `protocol_version_source` | How Tyk found the version | `header_body`, `header`, `body`, `session`, `legacy_fallback` |
| `jsonrpc_error_code` | JSON-RPC error code of a failed request, or `0` on success | `-33004` |

Use `protocol_version_source` to tell clients that declared a version from clients that didn't. `legacy_fallback` means the client sent no version and Tyk assumed one.

The `mongo-mcp` and `sql-mcp` pumps store these as top-level fields, and the Elasticsearch pump writes them with the same names. Records from earlier Tyk Gateway versions have empty values. The aggregate pumps behind the **Activity by MCP** page don't aggregate these fields.

Tyk Pump stores these fields from version 1.18.0. An earlier Tyk Pump ignores them.

## Dashboard Analytics

Alongside these OpenTelemetry signals, Tyk Dashboard has a dedicated **Activity by MCP** analytics page, covering proxy-level and primitive-level traffic and error charts. See [MCP Analytics](https://tyk.io/docs/ai-management/mcp-gateway/mcp-analytics.md).

> [!NOTE]
>
> For a [REST API to MCP proxy](https://tyk.io/docs/ai-management/mcps/api-to-mcp.md), these charts show only the proxy's own traffic. The internal call to the source REST API counts as that API's traffic. See [Access logs when the proxy fronts a Tyk-managed REST API](https://tyk.io/docs/ai-management/mcp-gateway/mcp-access-logs.md#access-logs-when-the-proxy-fronts-a-tyk-managed-rest-api).
