---
title: 'Monitor MCP Servers'
description: 'Set up uptime and correctness monitoring for a Model Context Protocol server: handshake checks, expected tools, tool-call assertions, and schema-drift detection.'
section: 'Guides'
canonical_url: 'https://yorkermonitoring.com/docs/guides/monitor-mcp-servers'
---

# Monitor MCP Servers

An MCP server can return HTTP 200 while being unusable to every agent that depends on it. The process is listening, but the initialize handshake fails, a tool your agents rely on has vanished from the catalog, or a tool's input schema changed shape underneath a caller that worked yesterday. None of those move an HTTP status code.

MCP monitors exercise the server the way a real client does. Every run executes the full JSON-RPC session over Streamable HTTP:

1. Sends `initialize` and asserts the response carries `protocolVersion` and `capabilities`, capturing any `Mcp-Session-Id` for the rest of the session.
2. Sends the `notifications/initialized` notification.
3. Calls `tools/list` and verifies every tool in `expectedTools` is present (if configured).
4. Runs each `testCalls` entry: invokes the tool and checks the result contains `expectedOutputContains` (if provided).
5. Hashes each tool's input schema and reports tools added, removed, or modified since the previous run (when `detectSchemaDrift` is enabled).

A failure names the phase that broke (handshake, missing tool, drift, wrong output), not a generic timeout.

## Before you start

- Your server must speak the **Streamable HTTP transport**. This is the standard remote transport; a typical endpoint looks like `https://example.com/mcp`. Servers that only run over stdio are local processes and cannot be monitored externally.
- If the server requires auth, have the credential ready. Yorker supports `basic`, `bearer`, and `api-key` auth, with secrets pulled from your team's secret store so tokens never live in config files.

## Create the monitor (Web UI)

1. Open the dashboard, click **Create Monitor**, and select the **MCP** tab.
2. Enter the Streamable HTTP endpoint URL.
3. Optionally list the tool names your agents require. A missing tool fails the check.
4. Optionally add test calls: a tool name, arguments, and a substring the result must contain.
5. Choose locations and frequency, then click **Create**. The first run starts immediately.

## Create the monitor (YAML)

```yaml
monitors:
  - name: Docs MCP Server
    type: mcp
    endpoint: https://mcp.example.com/mcp
    frequency: 5m
    locations:
      - loc_us_east
    auth:
      type: bearer
      token: "{{secrets.MCP_TOKEN}}"
    expectedTools:
      - search_docs
      - fetch_page
    testCalls:
      - toolName: search_docs
        arguments:
          query: "pricing"
        expectedOutputContains: "Plans"
    detectSchemaDrift: true
```

Deploy with `yorker deploy`. The full field reference is in [Configuration](/docs/reference/configuration). Note that MCP monitors cannot be executed locally with `yorker test`; deploy them and watch results with `yorker results tail` or the dashboard.

## What schema drift catches

When `detectSchemaDrift` is enabled (the default), each tool's `inputSchema` is hashed with a deterministic, key-sorted JSON representation, so equivalent schemas always hash identically regardless of key order. Each run diffs the current hashes against the previous run's and reports every tool as added, removed, or modified. The first run has no baseline, so it seeds one and reports no drift.

This is the failure mode that breaks agents quietly: the server is up, the tool exists, but its arguments changed shape and every caller built against the old schema now fails. Drift surfaces that as a reportable change the moment it ships, instead of leaving your agents to discover it.

## Alerting and telemetry

MCP monitors plug into the same alert rules as HTTP and browser monitors: consecutive failures, multi-location correlation, and notification channels are configured identically. See [Set Up Alerts](/docs/guides/set-up-alerts).

Results emit as standard OTLP to your configured backend, with per-phase timing for the initialize, tools/list, and test-call phases, the discovered tool catalog, and the computed drift. When a run detects drift and your team has an OTLP endpoint configured, Yorker forwards a `synthetics.mcp.schema_drift` event carrying per-change-type counts (`synthetics.mcp.drift.added_count`, `removed_count`, `modified_count`, `total_count`) and the affected tool names (capped at 50 per list). The event fires only when drift is present.

## Billing

A full MCP session (handshake, tool catalog, schema hashing, and any tool calls you configure) bills as **one run at the HTTP rate**: 10,000 HTTP + MCP runs a month on the free tier, unlimited on the paid plan.

## Troubleshooting

- **"Streamable HTTP transport may not be supported"**: the endpoint answered with HTML or a non-JSON content type. Check that the URL is the MCP endpoint itself (commonly `/mcp`), not a documentation page or an SSE-only path.
- **Handshake fails with a valid endpoint**: the response must be a JSON-RPC success carrying `protocolVersion` and `capabilities`. Yorker sends `Accept: application/json` on every request; a server that insists on `text/event-stream` in the Accept header before answering will fail at this phase. A server that rejects the initialize payload fails with the JSON-RPC error surfaced in the result.
- **HTTP 401/403**: the server requires auth. Add an `auth` block; for a bearer-token server, use `type: bearer` with the token stored as a team secret.
- **Expected tool missing intermittently**: some servers assemble their catalog from downstream services. Pair `expectedTools` with a multi-location alert rule so a single flaky assembly does not page you.
