What is MCP?

The Model Context Protocol (MCP) is Anthropic's open specification for connecting AI models to external data sources, tools, and services. If you've used Claude Desktop with file access or GitHub integration, you've used MCP — it's the underlying protocol that lets models interact with real-world systems beyond their training data.

MCP has become the de-facto standard for AI tool integration in 2026, with adoption accelerating across the industry. Major players including Block, Cedar, and GitHub have built MCP servers for their platforms. The result: production AI systems are increasingly built on MCP connections — and when those connections fail, your AI assistant goes dark.

Monitoring MCP is now a critical infrastructure concern.

This guide covers what MCP monitoring looks like in production, what metrics matter, and how to build observability into your MCP-powered stack.


Why MCP Changes Observability Requirements

Traditional AI applications are self-contained. You send a prompt, the model responds, you log the interaction. Simple.

MCP breaks that model. When an LLM uses an MCP server to fetch real-time data, execute tools, or query databases, the response latency and reliability depend on external systems you don't directly control.

Consider what can go wrong:

  • MCP server goes down → The model loses access to tools and starts failing or returning degraded answers
  • Server response latency spikes → Every user query becomes slow, and you won't know until complaints roll in
  • Rate limit exceeded → Your AI assistant silently starts refusing requests
  • Server returns malformed data → The model receives corrupted context and produces wrong outputs
  • Network partition → The model appears to hang indefinitely

Without monitoring, you have no visibility into any of this. Your users experience a "broken AI" without you knowing why.

The MCP Architecture

A typical MCP setup has three components:

  1. MCP Host — The AI application (Claude Desktop, an AI agent framework, your custom app)
  2. MCP Client — The client library that manages connections to servers
  3. MCP Server — The server exposing tools/resources via the MCP specification

When a model calls a tool (like github.create_issue or filesystem.read_file), the request flows through this chain. Monitoring must cover each hop.


Core Metrics for MCP Observability

1. Server Availability and Uptime

Track whether your MCP servers are reachable. This sounds obvious but MCP servers are often stateless services that can crash or become unreachable without alerting.

What to monitor:

  • HTTP health endpoint (/health or similar)
  • Connection success rate from MCP client
  • Server process health (if running as a local server)

Alerting threshold: If a server is unreachable for > 30 seconds, alert on-call.

2. Request Volume and Error Rates

Count MCP calls and categorize outcomes:

Metric Description
mcp.requests.total Total MCP requests (by server, by tool)
mcp.errors.total Failed requests (4xx, 5xx, timeouts)
mcp.error_rate errors / requests ratio
mcp.tool_usage Per-tool call frequency

High error rates on specific tools indicate problems — either the tool is broken or the upstream service (e.g., GitHub API) is having issues.

3. Response Latency

MCP tool calls add latency to every AI response. If a tool call takes 5 seconds, the user's AI response is delayed by at least 5 seconds.

What to monitor:

  • mcp.latency.p50, p95, p99 by server and tool
  • Slow tool calls (> 2s) flagged separately
  • Latency breakdown: network vs server processing

Target: p99 MCP tool call latency < 1 second. Anything above 3s is a user experience problem.

4. Tool Availability

When an MCP server is up but certain tools are throttled or returning errors, that's different from server-down. You need tool-level availability tracking:

  • Which tools are throwing errors?
  • Which tools are returning rate limit errors (429)?
  • Are there tools that have been completely removed from a server?

5. Context Size and Token Usage

MCP resources add context to LLM requests. A single file read might add 10,000 tokens to your context. Monitor:

  • Average context size per MCP request
  • Token cost attribution by MCP server and tool
  • Context size outliers (> 50k tokens per request)

Large context = higher LLM costs. Know what's driving your token bills.


Implementing MCP Observability

Option 1: Custom Instrumentation with OpenTelemetry

The cleanest approach is instrumenting your MCP client with OpenTelemetry. Most MCP SDKs support this.

from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider

# Instrument your MCP client
tracer = trace.get_tracer(__name__)

class ObservedMCPClient:
    def __init__(self, server_url):
        self.client = MCPClient(server_url)
    
    async def call_tool(self, tool_name, params):
        with tracer.start_as_current_span(f"mcp.{tool_name}") as span:
            span.set_attribute("mcp.server", self.server_url)
            span.set_attribute("mcp.tool", tool_name)
            
            start = time.time()
            try:
                result = await self.client.call_tool(tool_name, params)
                span.set_attribute("mcp.success", True)
                return result
            except Exception as e:
                span.set_attribute("mcp.success", False)
                span.set_attribute("mcp.error", str(e))
                raise
            finally:
                duration = time.time() - start
                span.set_attribute("mcp.duration_ms", duration * 1000)

Send spans to your observability backend (Grafana, Datadog, Honeycomb).

Option 2: MCP Server Middleware

If you control the MCP server, add middleware that emits metrics for every request:

# Example MCP server middleware (Python)
from functools import wraps

def metrics_middleware(next_handler):
    @wraps(next_handler)
    async def handler(request, ctx):
        start = time.time()
        try:
            result = await next_handler(request, ctx)
            METRICS["requests_total"].labels(
                server=ctx.server_name,
                tool=request.tool,
                status="success"
            ).inc()
            return result
        except Exception as e:
            METRICS["requests_total"].labels(
                server=ctx.server_name,
                tool=request.tool,
                status="error"
            ).inc()
            raise
        finally:
            METRICS["request_duration"].labels(
                server=ctx.server_name,
                tool=request.tool
            ).observe(time.time() - start)
    return handler

Option 3: Use an MCP-Powered Observability Platform

Several platforms have already built MCP servers for their own tools — meaning you can use an LLM to query your observability data via MCP. This is meta but useful:

  • Grafana MCP Server — Query dashboards and alerts via AI
  • PagerDuty MCP Server — Manage incidents via AI
  • Datadog MCP Server — Query metrics and logs conversationally

If you're already using these platforms, their MCP servers let you build AI-powered incident investigation workflows — with the MCP server itself being something to monitor.


Common MCP Failure Patterns and How to Detect Them

Pattern 1: Cascade Failure from Upstream API

An MCP server wraps a third-party API (GitHub, Slack, a database). When that API goes down or rate-limits, the MCP server starts returning errors. The LLM keeps calling it, generating error logs but no useful output.

Detection:

  • mcp.errors spikes with rate_limit or upstream_unavailable labels
  • Server is up (HTTP 200) but tools return 429 or 503

Response:

  • Alert on rate limit errors specifically
  • Consider circuit-breaking the MCP server when upstream is degraded

Pattern 2: Stale Context from Long-Poll Resources

MCP resources like file systems or database queries can return stale data. If a resource is cached and the underlying data changes, the model operates on outdated information.

Detection:

  • Monitor the mcp.resource.age metric — how old is the cached resource data?
  • Log resource refresh events and compare with data change events in the upstream system

Response:

  • Implement TTL-based cache invalidation on MCP servers
  • Alert when resource.age exceeds threshold for critical resources

Pattern 3: Tool Call Storms

A model with retry logic might repeatedly call a failing tool, generating a traffic spike on the MCP server and the upstream API.

Detection:

  • mcp.tool_calls_per_minute spikes unusually
  • Same tool called > 10 times in a 60-second window

Response:

  • Implement exponential backoff in the MCP client
  • Add per-tool rate limiting with feedback to the model ("rate limited, retry after 30s")

Pattern 4: Latency Regression After Server Update

MCP servers are often independently deployed services. An update might introduce a regression that slows down all tool calls by 2-3x.

Detection:

  • Track mcp.latency.p95 over time per server version
  • Alert when p95 latency increases > 50% week-over-week

Response:

  • Tag MCP server deployments with version numbers in metrics
  • Use canary deployments for MCP servers

Building an MCP Monitoring Dashboard

Here's the minimum viable dashboard for MCP observability:

Row 1 — Overview

  • Total MCP requests/minute
  • Error rate (% of requests that failed)
  • p99 latency

Row 2 — Per-Server Metrics

  • Requests per server (bar chart)
  • Error rate per server
  • Latency per server

Row 3 — Tool-Level Breakdown

  • Top 10 most-used MCP tools
  • Tools with highest error rates
  • Slowest tools (p99 > 2s)

Row 4 — Context Usage

  • Average tokens per MCP request
  • Servers/tools driving highest token usage

Alerting Rules for MCP

Alert Condition Severity
MCP server down Server unreachable for > 60s P1
High error rate mcp.error_rate > 5% over 5 min P2
Slow response mcp.latency.p99 > 5s over 10 min P2
Rate limit hit Any 429 response from MCP server P2
Tool unavailable Tool returns error for > 10% of calls P2
Token usage spike mcp.tokens_per_hour > 2x baseline P3

The MCP Observability Stack

Most teams building serious MCP infrastructure use:

  • Prometheus + Grafana — Open-source metrics and dashboards
  • OpenTelemetry — Trace instrumentation for MCP calls
  • Grafana Tempo — Distributed tracing for cross-service requests
  • PagerDuty — Alert routing for MCP-related incidents

If you're using Datadog, the Datadog Agent can auto-discover MCP servers running on your infrastructure and start collecting metrics without additional configuration.


Cloudflare MCP v2: the Stateless Protocol Primitive

On 2026-08-06, Cloudflare published "The next generation of MCP", reframing MCP from a stateful JSON-RPC protocol into a stateless HTTP-native primitive that fits Cloudflare Workers' edge-routing model. The shift matters because the original MCP specification assumes a long-lived session between host and server — which is awkward to scale across edge regions and harder to monitor when sessions can hang for unrelated reasons (network blips, container restarts, MCP server version skew).

Cloudflare's v2 framing pushes MCP into the same operational shape as a normal HTTPS endpoint:

  • Stateless transport. Each MCP request is its own HTTPS round-trip; the protocol no longer requires a persistent connection. This kills the "MCP server appears to hang indefinitely" failure mode from the patterns above — every request has a discrete timeout and a discrete error response.
  • Edge-routable. Because requests are HTTP-native, Cloudflare Workers can route MCP traffic the same way it routes any other API call: per-region latency-based routing, automatic failover, edge-side rate limiting. This is the part that changes the monitoring shape: instead of needing to instrument every MCP server replica, you instrument the edge layer once.
  • Cache-friendly. Read-only MCP calls (the resources/read path) can be served from edge cache, eliminating the origin-server latency tail entirely. The metrics that matter shift from "origin p99" to "cache-hit ratio + edge p99."

What this means for monitoring: if you're deploying MCP through Cloudflare Workers (or considering it), the existing analytics.worker + analytics_engine products give you per-request spans for free, without the OTel instrumentation shown earlier in this article. If you're running MCP on your own infrastructure, the v2 protocol is still relevant — the HTTP-native shape simplifies the client-side retry budget and makes the request_count / error_rate / p99_latency metrics from the "Core Metrics" section above the canonical instrumentation, without the session-state caveats the v1 spec dragged in.

The v2 announcement also folds in Cloudflare's "agentic behaviors" framing — the position that agent endpoints should be treated as first-class HTTP citizens, not as long-lived RPC sessions. That framing is what motivates the next two primitives: a browser built for agents (Kitesurf) and an endpoint-local detection layer (numbat).


Cloudflare Kitesurf: the Browser-for-Agents Primitive

On 2026-08-08, Cloudflare launched Kitesurf, a closed-source cloud-hosted browser built specifically for AI agents (TechCrunch coverage). This is not a Chromium wrapper for end users — it's an "agent-browser-as-API" surface that exposes the browser's DOM, navigation, and screenshot primitives over HTTP, in a shape an LLM agent can call directly.

Why this matters for MCP monitoring:

  • Browser tooling is now a server-side dependency. When an agent uses a browser to scrape a page or fill a form, the browser becomes another MCP server — with all the same monitoring requirements. Server availability, request volume, latency, and error rates apply identically.
  • Cost shape changes. A headless browser session is 10-100x more expensive per minute than a typical HTTP call. If your agent fleet uses Kitesurf for any non-trivial workflow, cost_per_task becomes a first-class monitoring signal alongside latency. Without it, a single runaway agent loop can rack up hundreds of dollars in browser-time before anyone notices.
  • Cloud-hosted = new failure modes. Kitesurf is closed-source and cloud-only; you cannot self-host. That trades operational simplicity (no browser fleet to maintain) for vendor dependency (Kitesurf outages = your agents are blind). Monitoring the vendor's status page is no longer optional.

If you're instrumenting an agent fleet that uses Kitesurf, the metric set you'd add on top of the existing MCP stack is:

Metric Why it matters Alert threshold
kitesurf.session.duration_seconds Browser sessions are expensive; long sessions often mean stuck loops p99 > 120s
kitesurf.session.cost_usd Runaway loops can rack up hundreds of dollars in minutes > $5 per task
kitesurf.request.error_rate DOM changes, anti-bot blocks, network timeouts > 5% over 5 min
kitesurf.vendor.uptime Closed-source; you cannot self-recover < 99.5% monthly

Kitesurf pairs with numbat below as the browser-side primitive in the agent-detection stack.


Perplexity numbat: the Endpoint-Local AI-Agent Detection Primitive

On 2026-08-12, Perplexity open-sourced numbat — endpoint-local visibility into AI agent activity, with optional pre-action blocking and forensic reconstruction. The launch hit Hacker News the same day. Unlike Cloudflare Kitesurf, numbat runs on the user's machine (endpoint-side), not at the network edge.

What numbat actually does, in the order that matters for monitoring:

  1. Detect agents on the endpoint. numbat hooks into Claude Code, Cursor, Gemini CLI, Codex, and custom agents via local hooks, plugins, and OTLP/HTTP log exporters. It normalizes all of that into one event model — so your detection rules don't have to be re-written per agent.
  2. Run a CEL rule engine. Built-in rules + custom YAML rules, evaluated against the normalized event stream. CEL (Common Expression Language) is the same rule syntax Google's IAM and many other systems use, so the rule-writing curve is small for teams that already have CEL familiarity.
  3. Optional pre-action blocking. Opt-in, monitor-only by default. A rule marked enforce: true can block a tool call before it lands. Use this for the cases where you genuinely want to stop an agent action (e.g. git push --force to main, outbound POST to an unapproved domain) — not for everything, because blocking every tool call defeats the point of an autonomous agent.
  4. Forensic reconstruction. numbat reads on-disk session artifacts from supported agents and reconstructs what happened, even on machines that weren't running numbat at the time. This is the part that matters for incident response: three days after an agent did something unexpected, you can still pull the timeline.

Why this is structurally adjacent to MCP monitoring:

  • Endpoint-local, not edge-local. Where MCP monitoring asks "what did my MCP server do?", numbat asks "what did the agent on this machine do?" The two views are complementary, not overlapping. The MCP server log shows you the call landed; the numbat log shows you what the user typed, what the model decided, and what tool was invoked.
  • Open-source vs Cloudflare's closed-source. numbat is Apache-licensed and self-hostable. Cloudflare Kitesurf is closed-source. If your compliance posture requires inspecting the agent-detection layer's source, numbat is the only option in this category as of 2026-08.
  • The category is new. "Endpoint-local AI agent observability with CEL-rule-based pre-action blocking" is not a phrase that existed before numbat's launch. The 4-layer observability stack (logs/metrics/traces/events) that the original article above describes has a missing fifth layer — endpoint-side agent detection — and numbat is the first open-source primitive to fill it.

What to monitor if you deploy numbat:

Metric Why it matters Alert threshold
numbat.rules.matched_per_min Spike in rule matches = anomalous agent activity or rule bug > 3x baseline
numbat.enforce.blocks_per_min Pre-action blocks firing = either real risk or over-aggressive rule > 0 sustained
numbat.coverage.agents_active How many agents on the fleet numbat can see < 100% of declared
numbat.forensic.reconstructions_run Tracks incident-response usage — underused = process gap n/a (track weekly)

The Endpoint-Local + Edge-Network Agent Detection Stack

Three primitives now define the agent-detection category, and they pair into a coherent stack rather than overlapping:

Layer Primitive Side Source What it answers
Browser Cloudflare Kitesurf Cloud-hosted Closed-source What did the agent's browser do?
Endpoint Perplexity numbat User machine Open-source (Apache) What did the agent on this machine do?
Edge network Cloudflare Precursor (future-batch) Cloudflare network Closed-source What did the agent's network traffic do?

Each layer covers a different surface. A production agent fleet in 2026 should pick at least one layer per surface they care about — for most teams that means numbat on the endpoint + Kitesurf if you run browser automation. Cloudflare Precursor (the edge-network layer) is on the roadmap as a future-batch pillar in this corpus; for now, the canonical-link surfaces are numbat and Kitesurf.

This pairs with the broader agent-sandbox category covered in Agent Sandbox vs Agent Substrate 2026 — same-week body refresh, same sister-link surface. The agent-detection primitives above define what an agent is allowed to do; the agent-sandbox primitives define where the agent runs.


Conclusion

MCP is moving from novelty to production infrastructure in 2026. As AI systems become more deeply integrated with external tools and data sources, the reliability of those integrations becomes critical.

The monitoring patterns are straightforward — availability, latency, error rates, and context size — but most teams haven't implemented them yet. Building MCP observability now means you're ahead of the curve when MCP becomes as standard as REST APIs in production AI systems.


Related Articles


Affiliate Disclosure: This article contains affiliate links to tools and services we recommend. We may earn a commission at no additional cost to you if you sign up through our links.