Local stdio compatibility reports for MCP server startup and tool discovery.
mcp-smoke starts one local command you provide, sends MCP initialize,
sends notifications/initialized, then calls tools/list. It writes a
Markdown report, a JSON report, and a copyable issue template.
It helps answer a narrow question before you add a server to a client: does this command start, speak JSON-RPC over stdio, initialize as MCP, and return tools?
mcp-smoke is not a sandbox. Run only server commands you trust. It does not
block network access, install packages, manage credentials, or certify server
security.
Commands such as npx, uvx, bunx, pipx, deno, or docker may
download or start other runtimes by their own behavior. mcp-smoke flags
those commands in reports, but it does not prevent them from doing so.
The current scope is stdio only. Fixture-backed local checks cover startup, initialization, tool discovery, pagination, timeouts, protocol errors, and common failure classifications.
Run the checks from the repository root:
python tests.pyThe current release is
v0.1.0.
Bundled reports under examples/report/ were generated from the harmless
local toy server in examples/toy-project/server.py. They demonstrate report
format and behavior; they are not evidence of broad server compatibility or
adoption.
Requirements:
- Python 3.11 or newer.
- No package install step for this version.
Run from the source directory:
python mcp_smoke.py check --helpOn Windows, the wrapper can be used from the same directory:
.\mcp-smoke.cmd check --helppython mcp_smoke.py check --out .\mcp-smoke-out --server-name demo -- python .\server.pyWindows wrapper:
.\mcp-smoke.cmd check --out .\mcp-smoke-out --server-name demo -- python .\server.py{
"schema_version": "mcp-smoke.v0",
"servers": {
"demo": {
"transport": "stdio",
"command": "python",
"args": ["server.py"],
"cwd": ".",
"env": {
"DEMO_MODE": "1"
}
}
}
}Run:
python mcp_smoke.py check --config .\mcp-smoke.json --server demo --out .\mcp-smoke-out- Process starts.
initializereturns a valid JSON-RPC response.notifications/initializedis sent after initialize succeeds.tools/listreturns at least one tool.- Common failures are classified: startup failure, timeout, invalid JSON-RPC, protocol mismatch, no tools, missing auth/config, and unsupported transport.
This version supports stdio only. It does not test HTTP, SSE, WebSocket, gateway behavior, full client behavior, tool calls, OAuth flows, hosted scans, or remote servers.
Each run writes:
mcp-smoke-report.md: human-readable summary.mcp-smoke-report.json: machine-readable result.issue-template.md: copyable issue text.stderr.txt: bounded, redacted stderr.transcript.jsonl: bounded, redacted protocol transcript.
See examples/report/ for a generated demo report from a harmless toy server.
Use GitHub issues for bugs, documentation gaps, and support requests. Include:
- The exact command, with sensitive values removed.
- Bounded, redacted stderr rather than full logs.
- Expected and actual results.
- Operating system and Python version.
- Confirmation that credentials were removed or replaced before sharing.
mcp-smoke returns a non-zero exit code when startup, protocol negotiation, or
tool discovery fails.
| Classification | Meaning |
|---|---|
startup_failure |
Process could not start or exited before initialize. |
timeout |
Initialize or tool discovery did not finish before timeout. |
invalid_json_rpc |
Stdout did not contain a valid JSON-RPC response. |
protocol_mismatch |
Initialize failed or returned an incompatible shape. |
no_tools |
Initialize passed, but tools/list returned no tools. |
auth_config_missing |
Output suggests a missing token, key, proxy, permission, or config. |
unsupported_transport |
Config selected a non-stdio transport. |
Run local checks with harmless toy stdio servers:
python tests.pyGenerate the example report:
.\mcp-smoke.cmd check --out examples\report --server-name demo --cwd examples\toy-project --overwrite -- python server.pyMIT. See LICENSE.