使用说明
MCP Doctor
Diagnose, optimize, and manage MCP servers across coding agents.
Quick Start
npx @frankxai/mcp-doctor audit
One command scans your Claude Code configuration, checks every MCP server across all scopes, and gives you a health report with fix commands.
Usage
For Humans (CLI)
# Full health check — spawns each server, verifies MCP handshake
npx @frankxai/mcp-doctor audit
# Quick mode — config-only validation (instant, no spawning)
npx @frankxai/mcp-doctor audit --quick
# Filter to a specific project
npx @frankxai/mcp-doctor audit --project my-project
# Browse curated MCP preset packs
npx @frankxai/mcp-doctor recommend
npx @frankxai/mcp-doctor recommend ai-architect
For CI (check any server you build)
check spawns a stdio MCP server, lists its tools and lints them. It needs no config file, so it works in CI on a server you are building.
npx @frankxai/mcp-doctor check -- node dist/server.js
# PASS my-server@1.2.0 — 12 tool(s)
npx @frankxai/mcp-doctor check --json -- node dist/server.js # JSON report, exit 1 on any issue
| Rule | Fails when |
|---|---|
connect |
The server does not start or answer initialize + tools/list within 15 s (its stderr is included) |
name |
A tool name is not ^[a-z][a-z0-9_]{0,63}$ |
duplicate |
Two tools share a name |
description |
A description is missing or under 20 characters |
schema |
inputSchema.type is not "object" |
On Windows, spawn node <script> directly rather than npx <pkg>, because npx resolves to npx.cmd.
Score a server against best practice
check asks "does it work?". score asks "will an agent pick and use it well?". It grades the tool surface on seven criteria drawn from the MCP spec, Anthropic's Writing effective tools for agents, and leading public servers. Each criterion is worth 2 points: all tools pass, half pass, or fewer.
npx @frankxai/mcp-doctor score -- node dist/server.js
npx @frankxai/mcp-doctor score --json --min 80 -- node dist/server.js # CI gate: exit 1 below 80%
npx @frankxai/mcp-doctor score --prefix sis -- node dist/server.js # brand prefix differs from server name
| Criterion | Full marks when |
|---|---|
| Annotations | every tool sets readOnlyHint and openWorldHint; writers also set destructiveHint and idempotentHint |
| Titles | every tool has a human title |
| Service prefix | names start with the service (mcp-doctor → mcp_doctor_…, or --prefix) |
| Descriptions | 80+ characters: when to use it, what it returns, what it costs |
| Bounded inputs | every property is described and bounded (maxLength, enum, maximum, maxItems, anchored bounded pattern); no-input tools set additionalProperties: false |
| Output schema | outputSchema declared, so results can carry structuredContent |
| Paging | list and search tools take a limit with a maximum, or a cursor |
A server with no tools scores 0. Error quality, response size, auth and evals can't be seen from tools/list, so they are printed as a manual checklist. For reference, @modelcontextprotocol/server-filesystem scores 57%, and mcp-doctor serve scores 100%.
As an MCP Server (Universal Agent Access)
mcp-doctor runs as an MCP server so an agent can diagnose its own MCP setup.
# Install globally (recommended — avoids cold-start timeouts)
npm install -g @frankxai/mcp-doctor
# Add to Claude Code
claude mcp add mcp-doctor -- mcp-doctor serve
# Or with explicit path (if 'mcp-doctor' isn't in PATH)
claude mcp add mcp-doctor -- $(which mcp-doctor) serve
For Cursor, Cline, Windsurf — add to their respective config file:
{
"mcpServers": {
"mcp-doctor": {
"command": "mcp-doctor",
"args": ["serve"]
}
}
}
For VS Code (.vscode/mcp.json):
{
"servers": {
"mcp-doctor": {
"type": "stdio",
"command": "mcp-doctor",
"args": ["serve"]
}
}
}
Exposes 4 read-only tools with typed, structured output: mcp_doctor_audit, mcp_doctor_agents, mcp_doctor_misplaced_configs, mcp_doctor_preset_packs. It scores 100% on its own mcp-doctor score bar.
For Claude Code (SessionStart Hook)
Auto-check MCP health on every new session:
// .claude/settings.json → hooks.SessionStart
{
"type": "command",
"command": "bash .claude/hooks/mcp-doctor-check.sh",
"timeout": 8
}
Or use the programmatic API:
import { scanAllServers, findDuplicates, findMisplacedConfigs, checkAllServers, analyzeTiers, redactSecrets } from "@frankxai/mcp-doctor";
const servers = scanAllServers();
const health = await checkAllServers(servers, { quick: true });
const tiers = analyzeTiers(servers, health);
Multi-Agent Support
Detects and reads MCP configs from major coding agents:
npx @frankxai/mcp-doctor agents
| Agent | Config Location | Key | Supported |
|---|---|---|---|
| Claude Code | ~/.claude.json |
mcpServers |
Yes |
| Cursor | ~/.cursor/mcp.json |
mcpServers |
Yes |
| Cline | globalStorage/.../cline_mcp_settings.json |
mcpServers |
Yes |
| Windsurf | ~/.codeium/windsurf/mcp_config.json |
mcpServers |
Yes |
| VS Code | ~/.config/Code/User/mcp.json |
servers |
Yes |
Config differences are normalized automatically (VS Code's servers key, Windsurf's serverUrl field, etc.).
What It Does
Misplaced Config Detection
Claude Code ignores mcpServers in settings.json files; they belong in ~/.claude.json. MCP Doctor detects misplaced configs:
⚠ MISPLACED MCP CONFIGS (CRITICAL)
──────────────────────────────────────────────────
Claude Code IGNORES mcpServers in settings.json files!
MCP servers must be in ~/.claude.json (use: claude mcp add)
✗ /home/user/.claude/settings.json
These servers are configured but NEVER loaded:
- my-server
- other-server
How to fix:
1. Remove mcpServers from settings.json
2. Re-add each server with: claude mcp add <name> -e KEY=val -- <command>
3. Verify with: /mcp in Claude Code
Health Audit
Scans ~/.claude.json across all project scopes and checks:
- Server connectivity (spawns each stdio server and verifies MCP initialize + ping handshake)
- Missing or placeholder environment variables (
YOUR_API_KEY_HERE) - Duplicate registrations across scopes (user, project-local, .mcp.json)
- Command resolution and startup failures during full probes
HEALTH REPORT
──────────────────────────────────────────────────
✓ playwright [user]
✓ memory [project-local]
✓ nanobanana [project-local]
⚠ grok [project-local] XAI_API_KEY not configured
⚠ replicate [project-local] REPLICATE_API_TOKEN not configured
✗ my-server [project-local] Exited before handshake
4 healthy 1 broken 2 missing config 0 skipped
Duplicate Detection
Finds servers registered multiple times across different scopes:
DUPLICATES FOUND
──────────────────────────────────────────────────
⚠ nanobanana registered 4x:
→ project-local (my-project)
→ project-local (other-project)
→ project-local (System32)
→ project-local (system32)
Tip: Duplicates waste startup time. Keep one per scope.
Tier Recommendations
Categorizes servers into always-on, on-demand, or remove:
TIER RECOMMENDATIONS
──────────────────────────────────────────────────
Always-On (load every session)
● playwright — Core utility — useful in nearly every session
● memory — Core utility — useful in nearly every session
On-Demand (add when needed)
◐ nanobanana — Useful but not every session
◐ sequential-thinking — Useful but not every session
◐ lyric-genius — Workflow-specific — add only for relevant sessions
Remove (broken or misconfigured)
✗ grok — Missing environment variable: XAI_API_KEY not configured
Fix Commands
Generates copy-paste-ready commands to clean up your setup:
SUGGESTED FIX COMMANDS
──────────────────────────────────────────────────
# Remove broken/misconfigured servers:
claude mcp remove grok
claude mcp remove replicate
# On-demand commands (save for when needed):
claude mcp add nanobanana -e GEMINI_API_KEY=AIza... -- uvx nanobanana-mcp-server@latest
claude mcp add sequential-thinking -- npx -y @modelcontextprotocol/server-sequential-thinking
Health Score
Seven successful protocol probes out of eight attempted probes score 88/100. Quick mode and setups without runtime probes are unverified:
SCORE
──────────────────────────────────────────────────
MCP Health Score: 88/100
8 total servers | 7 healthy | 0 duplicates | 1 should remove
Preset Packs
Pre-configured MCP stacks for common workflows. Each pack specifies which servers to run always-on vs. on-demand.
| Pack | Description | Always-On | On-Demand |
|---|---|---|---|
web-developer |
Next.js, Vercel, testing | 2 | 1 |
content-creator |
Blogging, images, email | 2 | 1 |
data-engineer |
Databases, APIs, pipelines | 2 | 1 |
music-producer |
AI music, lyrics, audio | 1 | 2 |
ai-architect |
Agents, multi-model systems | 3 | 1 |
agent-os |
Hermes, OpenClaw, DeepAgents, Claude Code, Codex, GitHub, Vercel, browser automation, memory | 4 | 3 |
devops |
CI/CD, infrastructure, containers | 2 | 1 |
mobile-dev |
React Native, Flutter, native | 1 | 2 |
researcher |
Academic, technical writing | 2 | 1 |
security |
Auditing, pen testing, compliance | 2 | 1 |
minimal |
Just the essentials | 1 | 0 |
Security
MCP Doctor reads ~/.claude.json which contains API keys and tokens. Here is how they are protected:
- Secret redaction: Output passes through
redactSecrets()andredactArgSecrets()— known env values, command-line arguments, and API key regex patterns are replaced with[REDACTED:KEY_NAME] - Safe env inheritance: Spawned processes only receive safe system vars (
PATH,HOME, etc.) + the server's own declared env —NODE_OPTIONSandNODE_PATHare not inherited - Execution boundary: Remote servers are skipped. Commands started by full audits can use their own network access.
See SECURITY.md for vulnerability reporting.
How It Works
MCP Doctor reads your Claude Code configuration from ~/.claude.json, which stores MCP server definitions across multiple scopes:
- User scope — Global servers available in all projects
- Project-local scope — Servers specific to a project directory
- .mcp.json — Project-level config files checked into repos
For each server found, it:
- Validates the configuration structure
- (Full mode) Resolves commands through the SDK transport and reports startup failures
- Detects placeholder environment variables
- Scans
settings.jsonfiles for misplaced MCP configs - (Full mode) Spawns the process and performs an MCP
initialize+pinghandshake - Cross-references against a database of known MCP servers for tier recommendations
MCP Scope Explained
The scope hierarchy in Claude Code:
~/.claude.json
├── mcpServers: {} ← User scope (all projects)
└── projects:
├── /path/to/project-a:
│ └── mcpServers: {} ← Project-local scope
└── /path/to/project-b:
└── mcpServers: {} ← Project-local scope
/path/to/project/.mcp.json ← Shared project scope (committed to git)
Contributing
Contributions welcome.
git clone https://github.com/frankxai/mcp-doctor
cd mcp-doctor
pnpm install
pnpm run build
pnpm run audit --quick
License
MIT
Protocol health and configuration checks
The audit --quick command validates configuration and starts no server processes. A valid configuration is unchecked, and its runtime score is unverified. Missing commands and placeholder environment values remain visible configuration findings. Remote servers are also untested by this audit.
Full stdio audits use the installed official MCP SDK to initialize and perform a ping. Only a successful protocol exchange is healthy; a process staying alive or exiting cleanly is insufficient. Resources-only servers do not need to implement tools/list. The reported score is the percentage of attempted stdio probes that succeeded. Duplicates, configuration defects and removal advice are reported separately, and no attempted probes means no numeric score.
Initialization and RPCs share one probe deadline. Shutdown uses the SDK's owned child handle and termination escalation, followed by an exit check, with a separate bounded cleanup allowance. Failed cleanup cannot produce a healthy result. Parent NODE_OPTIONS, NODE_PATH and credentials are not inherited by default; explicit server environment values remain caller-controlled. SDK output buffering is limited to 1 MiB. Diagnostics retain at most 2 KiB of redacted complete stderr lines; oversized lines are omitted.
Full audit runs third-party commands from the selected configuration. Use it when you intend to execute those commands. Suggested CLI commands redact known credentials, so supply credential placeholders privately before using them.
The protocol lifecycle follows the installed SDK's compatibility support. These checks do not certify every transport or modern stateless MCP revision. CI verifies the declared minimum Node version and Node 24 on Windows and Linux, including the audit API, CLI and MCP tools from an actual installed tarball.