Skip to main content

Diagnose MCP client configs, local process startup, and stdio handshakes before tools fail to load.

Project description

mcp-server-doctor

Diagnose the MCP client-to-server boundary: configuration discovery, process launch, and the stdio JSON-RPC handshake that must succeed before tools can load.

mcp-server-doctor is a dependency-free Python CLI for people who configure local Model Context Protocol servers in Claude, Cursor, Copilot, VS Code, or another agent client and then see missing commands, hidden startup failures, or empty tool lists.

It statically checks client configuration and can launch a configured local stdio process to verify initialize, notifications/initialized, and advertised capability listing such as tools/list.

This is not a generic MCP server test client. It focuses on failures that happen before tool invocation: locating client config, resolving the executable and working directory, starting the process, preserving JSON-RPC stdout framing, and completing the stdio handshake.

Why This Exists

MCP adoption is moving quickly across AI coding tools, IDEs, and desktop assistants. The painful part is still local setup:

  • Config files live in different places across clients.
  • npx, uvx, Docker, Python, and absolute-path commands fail differently.
  • A server can show as configured but still expose no tools.
  • Tokens often get pasted into config files during troubleshooting.
  • Server logs accidentally written to stdout can break JSON-RPC.

This tool gives developers and maintainers a fast preflight check for the exact boundary where an MCP client tries to start and discover a local server.

In scope Out of scope
Client config discovery and validation Testing whether individual MCP tools are semantically correct
Command, package, environment, cwd, and shell-wrapper checks Acting as an interactive MCP tool runner
Local process startup and stdio JSON-RPC framing Dynamic testing of remote HTTP or OAuth transports
Initialize and advertised capability listing Security approval for calling a discovered tool

Install

Run without installing:

uvx mcp-server-doctor check .

Or install the isolated CLI:

pipx install mcp-server-doctor

For local development:

python -m pip install -e .

Standard pip installation:

python -m pip install mcp-server-doctor

Quick Start

Check the current repository for MCP config files:

mcp-server-doctor .

Check a specific config file:

mcp-server-doctor check ~/.cursor/mcp.json

Run static checks plus stdio startup probes:

mcp-server-doctor doctor ~/.cursor/mcp.json

Probe one server:

mcp-server-doctor doctor ~/.cursor/mcp.json --server filesystem

Return JSON for CI or editor integrations:

mcp-server-doctor doctor . --format json

Write SARIF for GitHub code scanning:

mcp-server-doctor check . --format sarif --output mcp-server-doctor.sarif

Short alias:

mcp-doctor doctor .

What It Checks

Static checks:

  • Valid JSON
  • Required mcpServers object
  • Local stdio server command, args, env, and cwd types
  • Missing executable on PATH
  • Missing absolute command path
  • Missing or invalid cwd
  • Literal token-like values in env or args
  • Secret-looking env values such as API keys and passwords
  • Shell wrapper usage such as bash -c or powershell -Command
  • Unpinned npx, uvx, or bunx package names
  • Broad Docker volume mounts
  • Remote MCP server configs, reported as static-check only

Dynamic stdio probe:

  • Starts the configured command
  • Sends initialize
  • Sends notifications/initialized
  • Lists tools when available
  • Lists resources and prompts when advertised
  • Detects non-JSON stdout before a protocol response
  • Captures stderr tail on failures without exposing config secrets

Example

Given:

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
    }
  }
}

Run:

mcp-server-doctor check mcp.json

Output:

mcp-server-doctor checked 1 config file(s), 1 server(s)
errors=0 warnings=1 info=0

Configs:
  - mcp.json
    - filesystem (stdio)

Findings:
  [warning] mcp.json#filesystem unpinned-package: npx package is not version-pinned: @modelcontextprotocol/server-filesystem
    hint: Pin package versions for reproducible MCP startup.

Supported Config Locations

When no path is provided, the tool scans the current directory and common user-level locations when present:

  • mcp.json
  • .mcp.json
  • .cursor/mcp.json
  • .vscode/mcp.json
  • .github/copilot/mcp.json
  • Claude Desktop config on Windows, macOS, and Linux

Large generated folders such as .git, node_modules, dist, build, and virtual environments are skipped.

CI

Use the packaged GitHub Action:

name: MCP config check

on:
  pull_request:
  push:
    branches:
      - main

permissions:
  contents: read
  security-events: write

jobs:
  mcp-doctor:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7.0.0
      - uses: Uky0Yang/mcp-server-doctor@v0.2.0
        with:
          path: .
          command: check
          upload-results: "true"
          warnings-as-errors: "true"

Or install the CLI directly:

name: MCP config check

on:
  pull_request:
  push:
    branches:
      - main

jobs:
  mcp-doctor:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7.0.0
      - uses: actions/setup-python@v6.3.0
        with:
          python-version: "3.12"
      - run: python -m pip install mcp-server-doctor
      - run: mcp-server-doctor check . --warnings-as-errors

Use check in CI unless your workflow intentionally installs and starts every configured MCP server.

PyPI Release

This repository is prepared for PyPI Trusted Publishing. Configure a pending publisher on PyPI with:

  • Project: mcp-server-doctor
  • Owner: Uky0Yang
  • Repository: mcp-server-doctor
  • Workflow: release.yml
  • Environment: pypi

Then publish with:

git tag v0.2.0
git push origin v0.2.0

See docs/publishing.md.

Exit Codes

  • 0: no errors
  • 1: static check failed, or warnings failed under --warnings-as-errors
  • 2: static checks passed, but at least one stdio probe failed

Design Principles

  • No model calls
  • No network calls by the doctor itself
  • No runtime dependencies
  • No secret values printed
  • Clear findings that point to a fix
  • Dynamic probing limited to local stdio commands from the provided config

Current Limitations

  • Streamable HTTP and OAuth flows are not dynamically probed yet.
  • The stdio probe uses newline-delimited JSON-RPC, which is what common MCP SDK stdio transports use.
  • The tool does not rewrite configs yet.
  • It cannot know whether an MCP tool is safe to call; it only verifies discovery and startup.

Contributing

See CONTRIBUTING.md. Useful contributions are real-world diagnostics from broken MCP setups, additional client config locations, and tests for server startup edge cases.

License

MIT

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_server_doctor-0.2.0.tar.gz (19.7 kB view details)

Uploaded Source

Built Distribution

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

mcp_server_doctor-0.2.0-py3-none-any.whl (18.0 kB view details)

Uploaded Python 3

File details

Details for the file mcp_server_doctor-0.2.0.tar.gz.

File metadata

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

File hashes

Hashes for mcp_server_doctor-0.2.0.tar.gz
Algorithm Hash digest
SHA256 3c56a076369837a6cd9ac2b97a85fdd8024d2de3058c1b605b83b3a38304a7c2
MD5 2b9840fc7ec6cf93d333d52385ab505f
BLAKE2b-256 51e2a056b88717bb7ad4415b55c4638d09cea8c77424d8757013085c0ef4659d

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_server_doctor-0.2.0.tar.gz:

Publisher: release.yml on Uky0Yang/mcp-server-doctor

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mcp_server_doctor-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for mcp_server_doctor-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c50b585e3d3d781058e76a77c731492a056d3cb85478a22599833a829d69b358
MD5 b76f35170ba3875fb6bba3ce1a935999
BLAKE2b-256 9a8a2171c89c928b049b4b9eeccc99e484b607cefe0dea31f300885a6405cfa4

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_server_doctor-0.2.0-py3-none-any.whl:

Publisher: release.yml on Uky0Yang/mcp-server-doctor

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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