Skip to main content

Zero LLM, zero network, zero API keys - a CI-gate harness for stdio MCPs.

Project description

mcp-stdio-test

PyPI version Python versions CI License: MIT Downloads

Zero LLM, zero network, zero API keys - a CI-gate harness for stdio MCPs.

mcp-stdio-test spawns an MCP server over stdio, runs the JSON-RPC initialize handshake, and lets you assert on tools/list or call any tool - all with CI-friendly exit codes. It is the thing you wire into .github/workflows/ci.yml so a missing tool or a broken signature turns the pipeline red without anyone reading the output.

If you want a scored quality report, use mcp-doctor. If you want rule-based lint, use mcp-lint. If you want agent-driven end-to-end evaluation with cost tracking, use mcp-tester. If you want to click through your server, use MCP Inspector. mcp-stdio-test is the harness.

Install

pip install mcp-stdio-test
# or
pipx install mcp-stdio-test
# or (no install)
uvx mcp-stdio-test --help

Zero runtime dependencies. Python 3.10+.

60-second quickstart

# 1. Confirm the tool works on your machine.
mcp-stdio-test doctor

# 2. Point it at any stdio MCP server script.
mcp-stdio-test path/to/server.py --list-tools

# 3. Gate CI on the tool inventory.
mcp-stdio-test path/to/server.py --list-tools --expect-count 5 --expect-tool search

A non-zero exit code means something regressed. No log-scraping required.

CLI reference

Flag Purpose
<server> Path to the MCP server script to spawn.
--pyexe PATH Python interpreter to run the server with (default: sys.executable).
--list-tools Print the tool inventory returned by tools/list.
--call TOOL Invoke a single tool by name.
--args JSON JSON-encoded arguments for --call (default: {}).
--expect-count N Assert tools/list returns exactly N tools. Exit 4 on mismatch.
--expect-tool NAME Assert a tool with NAME is registered. Repeatable. Exit 4 on miss.
--timeout SECONDS Wall-clock deadline (default 30). Kills hung servers.
--json Emit machine-readable JSON instead of text.
doctor Self-check: Python version, optional mcp SDK, stdio handshake.

Exit codes

Code Meaning
0 OK
1 initialize / handshake failed
2 tools/list failed
3 tools/call failed
4 assertion failed (--expect-count / --expect-tool mismatch)
5 usage error (bad flags, missing server path)

Examples

Fresh-MCP smoke test

mcp-stdio-test my_mcp/server.py --list-tools

Regression gate when adding a tool

# Before the change: 4 tools.
# After the change: assert 5.
mcp-stdio-test my_mcp/server.py --list-tools --expect-count 5

CI integration (GitHub Actions)

- run: pip install mcp-stdio-test
- run: mcp-stdio-test my_mcp/server.py --list-tools --expect-count 5 --expect-tool search

Pre-commit hook

repos:
  - repo: https://github.com/dtchen07/mcp-stdio-test
    rev: v0.1.0
    hooks:
      - id: mcp-stdio-test

Comparison with neighbors

Tool Primary job Transport LLM Exit-code CI Tool-count / tool-name assertions
mcp-stdio-test (this) Per-repo declarative CI gates stdio no yes (0/1/2/3/4 tiered) yes (first-class, user-authored)
mcp-lint (LuxshanLux) 23 deterministic lint rules, scored stdio + SSE no yes (0/1/2) no
mcp-tester (saqadri, "MCP-Eval") Pytest-style agent evaluation + cost stdio yes JSON + pytest no
mcp-doctor (destilabs) Diagnostic + agent-friendliness scorer stdio + HTTP partial (generate-dataset only) scored report no
mcp-probe (conikeec) Rust TUI debugger + compliance suite stdio / SSE / HTTP no --fail-fast pass/fail built-in suite, not user-authored
MCP Inspector (official) Interactive debugger + --cli stdio / SSE / HTTP no JSON (no assertions) no

Two distinctions that hold up on direct comparison: none of the five ship per-repo, user-authored tool-count / tool-name assertions, and only two publish numbered CI exit codes at all (mcp-lint's 0/1/2, mcp-probe's pass/fail) — neither tiered by handshake vs tool-count vs usage like the 0/1/2/3/4 ladder here.

Compatibility

This release Tested against
0.1.0 MCP protocol 2024-11-05; mcp SDK >=1.2,<2 for optional user fixtures

Support matrix: Python 3.10, 3.11, 3.12, 3.13 on Linux, macOS, Windows.

Non-goals

  • Not a framework. Do not wrap your server in it.
  • Not a pytest plugin. Use subprocess from pytest if you want; no plugin glue.
  • No HTTP / SSE / streaming transport - stdio only.
  • No LLM-in-the-loop evaluation.
  • No multi-MCP orchestration.

The why

The long-form rationale, evidence from 6 weeks of real usage, and a walkthrough from empty repo to green CI is in the launch blog post: https://dtchen07.github.io/2026/04/harness-first-mcp/

Maintenance

This is a personal tool released as-is. Issue response target: 7 days, best-effort; no SLA on fixes. PRs are merged if they ship with tests and stay within scope; feature requests outside the non-goals will be declined politely. See RELEASE.md for the release runbook and the launch blog post for kill-criteria.

A field-data-backed 0.2.0 is targeted ~8 weeks after 0.1.0 ships.

Verify the supply chain

Every release is published via PyPI Trusted Publishing and ships with PEP 740 build provenance. Verify from your shell:

pip download mcp-stdio-test
gh attestation verify mcp_stdio_test-*.whl --owner dtchen07

License and citation

Code: MIT. Citation metadata in CITATION.cff. Contributing guide: CHANGELOG.md plus the PR template.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcp_stdio_test-0.1.0.tar.gz (13.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_stdio_test-0.1.0-py3-none-any.whl (12.3 kB view details)

Uploaded Python 3

File details

Details for the file mcp_stdio_test-0.1.0.tar.gz.

File metadata

  • Download URL: mcp_stdio_test-0.1.0.tar.gz
  • Upload date:
  • Size: 13.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mcp_stdio_test-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6f0b5fc3bbef2e61d2e15623a8c66cf82d03db08e262362fb337d345b226b25b
MD5 f1bc03bf1a03381bd241a712b3b62eca
BLAKE2b-256 3d8542fd5f4f9a817e0a5ea84fc684decf823b54ceda2266143416541f40a83c

See more details on using hashes here.

File details

Details for the file mcp_stdio_test-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: mcp_stdio_test-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 12.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mcp_stdio_test-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6fccf74f6b4a535e2447b0bb9412f126e83698969e2f0f130bfaa74427943754
MD5 742b10810c341ff5cd4745e0c57118a9
BLAKE2b-256 3e8fd8f049cb85aad0a199670f2d9a20fd29c601fe2a0e8684b7afa7ae51bd91

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page