MCP Server Test Harness: Conformance + Test Cases for CI

Catch the MCP server bugs clients hit (bad schemas, wrong error codes, print() on stdout, crashes) before your users do.

MCP Server Test Harness: Conformance + Test Cases for CI product illustration

What it does

Test any MCP server before you ship it: stdio or Streamable HTTP, against MCP 2026-07-28 (stateless, server/discover) and the 2025-11-25 initialize handshake. One Python file, standard library only, Python 3.9+. Works with servers written in any language.

What you get

The screenshot is real output from the kit’s own commands. Tested from a fresh download of this exact zip: ./run_tests.sh ran 19 tests OK on Python 3.13 and 3.10.

Real terminal output from MCP Server Test Harness: Conformance + Test Cases for CI: demo and passing tests

What it checks

mcptest check runs these without any test cases:

CheckWhat fails it
handshakeserver/discover (2026-07-28) or initialize (2025-11-25) errors, hangs or returns an unknown protocol version; missing serverInfo
tools/listerrors; pagination with nextCursor is followed (up to 50 pages)
tool definitionsnames outside A-Z a-z 0-9 _ - . (1-128 chars), duplicate names, no description, inputSchema not type: "object", required naming a property that does not exist, undocumented parameters (warning), bad outputSchema
2026-07-28 rulesresultType: "complete" on results, ttlMs + cacheScope on tools/list, serverInfo in _meta, -32022 UnsupportedProtocolVersion for an unknown version, stable tool order
error handlingunknown method must be -32601; unknown tool should be -32602; a tool called without its required arguments must return an error, not hang or crash the process; malformed JSON should get -32700 and the server must keep answering
stdio hygieneany non-JSON line on stdout (the classic print() bug that corrupts the stream)
HTTPJSON and text/event-stream (SSE) replies are both parsed; Mcp-Method / Mcp-Name headers are sent on 2026-07-28 requests, Mcp-Session-Id is echoed for older servers

Quick start

./tools/demo.sh                                              # see it on a good and a deliberately broken server
python3 tools/mcptest.py check -- python3 path/to/server.py  # your stdio server (era auto-detected)
python3 tools/mcptest.py check --era both -- node dist/index.js
python3 tools/mcptest.py check --url http://127.0.0.1:8000/mcp

Exit codes: 0 all passed, 1 a check or case failed, 2 the server could not be started/reached or the suite is invalid. --strict also fails on warnings.

Test your tools (suite file)

python3 tools/mcptest.py init -- python3 server.py > mcp.tests.yaml   # one smoke case per tool, from tools/list
python3 tools/mcptest.py run mcp.tests.yaml --junit report.xml
server:
  command: [python3, server.py]     # or  url: http://127.0.0.1:8000/mcp  (+ headers: {Authorization: "Bearer ..."})
  env: {API_BASE: "http://localhost:9000"}
  cwd: .                            # optional, relative to this file
era: both                           # auto | modern | legacy | both
cases:
  - name: search returns results
    tool: search
    args: {query: "mcp", limit: 3}
    expect:
      json: {count: 3}              # subset match on structuredContent (or JSON text)
      text_contains: [mcp]
      regex: '"title": ".+"'
      max_ms: 1500
  - name: empty query is a tool error
    tool: search
    args: {query: ""}
    expect: {is_error: true}
  - name: wrong argument is refused
    tool: search
    args: {q: "x"}
    expect: {protocol_error: -32602}

Before each call, mcptest validates the case's args against the tool's inputSchema (so a broken test case is reported as such), and if the tool declares an outputSchema it validates structuredContent against it. JSON Schema support is a practical subset: type, properties, required, additionalProperties, items, enum, const, min/max, lengths, pattern, item counts, anyOf/oneOf/allOf (no $ref).

CI

.github/workflows/mcp-tests.yml runs the suite on every push and PR and uploads the JUnit report. --json out.json writes a machine-readable result too.

Claude Code

This folder is a Claude Code plugin with an mcp-test skill: claude --plugin-dir ./mcp-server-test-harness, then ask "test my MCP server".

Files

  • tools/mcptest.py the harness (+ miniyaml.py, a small YAML reader)
  • examples/good_server.py a well-behaved demo server; examples/buggy_server.py has 8 common bugs, all caught; examples/http_server.py serves the demo over HTTP (--sse for event-stream replies)
  • examples/demo.tests.yaml a 5-case suite run on both eras
  • tests/ 19 tests: schema validator, both eras over stdio, HTTP JSON + SSE, header checks, every bug in the buggy server, suites, JUnit, init

Honest limits

  • It tests the protocol surface and your cases; it is not a full schema-level certification of the MCP spec, and it is not affiliated with or endorsed by the MCP project or Anthropic.
  • No OAuth flow: pass a ready token with headers: in the suite.
  • Resources, prompts, subscriptions/listen, tasks and multi round-trip (input_required) results are not exercised.
  • JSON Schema checks are a subset (no $ref, format, or conditional keywords).
  • The unknown-tool and parse-error checks follow the spec's recommended codes; some SDKs differ, which shows as a WARN or FAIL you can judge yourself.

Format and license

Zip, 29 KB, v1.0, 15 files. You may use and modify this kit for your own work and for clients you serve, including paid client work. Not affiliated with or endorsed by the MCP project or Anthropic.

FAQ

Does it work with servers in TypeScript, Go or Rust?
Yes. It talks to any server over stdio or HTTP; only the tester itself is Python.
Which MCP versions?
2026-07-28 (stateless, server/discover) and 2025-11-25 (initialize); --era auto picks what the server supports.
Is this the official MCP Inspector?
No. The Inspector is an interactive UI; this is a scriptable test runner for CI. Use both.
How do I get the files?
Pay by card right here on youraitools.co: your download links appear on this page the moment the payment goes through (claim window: 72 hours, up to 5 downloads per 7 days). Need the files re-sent later? Email hello@youraitools.co.
Refunds?
Email hello@youraitools.co within 14 days if it doesn’t work and we can’t fix it.
Can I pay with crypto?
Yes. Pay the same price in USDC or USDT on Base, Ethereum, Arbitrum, Optimism, Polygon or Solana from the "Pay with crypto" button, with no account or KYC. We check the payment on-chain and show your download links as soon as it confirms.

Get MCP Server Test Harness: Conformance + Test Cases for CI

Test any MCP server (stdio or HTTP) against MCP 2026-07-28 and 2025-11-25: conformance checks, YAML test cases, JUnit for CI. Python, no dependencies.

Pairs well with

Related

1 email a week: new x402 + MCP tools and free kits.

Short weekly digest of new x402 + MCP tools and free kits, including the MCP OAuth Checker. No spam, unsubscribe any time.