@frankxai/mcp-doctor 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +103 -55
- package/dist/analyzer/tier-optimizer.d.ts.map +1 -1
- package/dist/analyzer/tier-optimizer.js +2 -1
- package/dist/analyzer/tier-optimizer.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/reporter/format.js +1 -1
- package/dist/scanner/health-checker.d.ts +6 -0
- package/dist/scanner/health-checker.d.ts.map +1 -1
- package/dist/scanner/health-checker.js +49 -3
- package/dist/scanner/health-checker.js.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
**Diagnose, optimize, and manage your Claude Code MCP servers.**
|
|
4
4
|
|
|
5
5
|
[](LICENSE)
|
|
6
|
-
[](https://www.npmjs.com/package/mcp-doctor)
|
|
6
|
+
[](https://www.npmjs.com/package/@frankxai/mcp-doctor)
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
@@ -18,13 +18,103 @@ Every broken server adds seconds to your startup. Every misconfigured one wastes
|
|
|
18
18
|
## Quick Start
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
-
npx mcp-doctor audit
|
|
21
|
+
npx @frankxai/mcp-doctor audit
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
That's it. One command scans your entire Claude Code configuration, checks every MCP server across all scopes, and gives you a full health report with actionable fix commands.
|
|
25
25
|
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
### For Humans (CLI)
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# Full health check — spawns each server, tests MCP handshake
|
|
32
|
+
npx @frankxai/mcp-doctor audit
|
|
33
|
+
|
|
34
|
+
# Quick mode — config-only, instant (no spawning)
|
|
35
|
+
npx @frankxai/mcp-doctor audit --quick
|
|
36
|
+
|
|
37
|
+
# Filter to a specific project
|
|
38
|
+
npx @frankxai/mcp-doctor audit --project my-project
|
|
39
|
+
|
|
40
|
+
# Browse curated MCP preset packs
|
|
41
|
+
npx @frankxai/mcp-doctor recommend
|
|
42
|
+
npx @frankxai/mcp-doctor recommend ai-architect
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### For Claude Code (Agent Integration)
|
|
46
|
+
|
|
47
|
+
Add mcp-doctor as a slash command so Claude can self-diagnose MCP issues:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Install globally for any session
|
|
51
|
+
npm install -g @frankxai/mcp-doctor
|
|
52
|
+
|
|
53
|
+
# Run from within a Claude Code session
|
|
54
|
+
mcp-doctor audit --quick
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Or use the programmatic API inside a Claude Code hook or skill:
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import {
|
|
61
|
+
scanAllServers,
|
|
62
|
+
findDuplicates,
|
|
63
|
+
findMisplacedConfigs,
|
|
64
|
+
checkAllServers,
|
|
65
|
+
analyzeTiers,
|
|
66
|
+
redactSecrets,
|
|
67
|
+
} from "@frankxai/mcp-doctor";
|
|
68
|
+
|
|
69
|
+
// Scan and check
|
|
70
|
+
const servers = scanAllServers();
|
|
71
|
+
const health = await checkAllServers(servers, { quick: true });
|
|
72
|
+
const duplicates = findDuplicates(servers);
|
|
73
|
+
const misplaced = findMisplacedConfigs();
|
|
74
|
+
const tiers = analyzeTiers(servers, health);
|
|
75
|
+
|
|
76
|
+
// Safe to log — secrets are redacted
|
|
77
|
+
const message = redactSecrets(someErrorOutput, serverEnv);
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### For Other Coding Agents (Cursor, Windsurf, etc.)
|
|
81
|
+
|
|
82
|
+
MCP Doctor currently reads `~/.claude.json` which is Claude Code's config format. Other agents store MCP configs differently:
|
|
83
|
+
|
|
84
|
+
| Agent | Config Location | Supported |
|
|
85
|
+
|-------|----------------|-----------|
|
|
86
|
+
| Claude Code | `~/.claude.json` | Yes |
|
|
87
|
+
| Claude Desktop | `~/Library/Application Support/Claude/claude_desktop_config.json` | Planned |
|
|
88
|
+
| Cursor | `.cursor/mcp.json` | Planned |
|
|
89
|
+
| Windsurf | `.windsurf/mcp.json` | Planned |
|
|
90
|
+
| VS Code + Copilot | `.vscode/mcp.json` | Planned |
|
|
91
|
+
|
|
92
|
+
The core scanning/health-check logic is agent-agnostic — only `config-reader.ts` needs to know where configs live. PRs adding other agent support are welcome.
|
|
93
|
+
|
|
26
94
|
## What It Does
|
|
27
95
|
|
|
96
|
+
### Misplaced Config Detection
|
|
97
|
+
|
|
98
|
+
The **#1 MCP misconfiguration**: putting `mcpServers` in `settings.json` instead of `.claude.json`. Claude Code silently ignores them. MCP Doctor catches this:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
⚠ MISPLACED MCP CONFIGS (CRITICAL)
|
|
102
|
+
──────────────────────────────────────────────────
|
|
103
|
+
|
|
104
|
+
Claude Code IGNORES mcpServers in settings.json files!
|
|
105
|
+
MCP servers must be in ~/.claude.json (use: claude mcp add)
|
|
106
|
+
|
|
107
|
+
✗ /home/user/.claude/settings.json
|
|
108
|
+
These servers are configured but NEVER loaded:
|
|
109
|
+
- my-server
|
|
110
|
+
- other-server
|
|
111
|
+
|
|
112
|
+
How to fix:
|
|
113
|
+
1. Remove mcpServers from settings.json
|
|
114
|
+
2. Re-add each server with: claude mcp add <name> -e KEY=val -- <command>
|
|
115
|
+
3. Verify with: /mcp in Claude Code
|
|
116
|
+
```
|
|
117
|
+
|
|
28
118
|
### Health Audit
|
|
29
119
|
|
|
30
120
|
Scans `~/.claude.json` across all project scopes and checks:
|
|
@@ -97,7 +187,7 @@ Generates copy-paste-ready commands to clean up your setup:
|
|
|
97
187
|
claude mcp remove replicate
|
|
98
188
|
|
|
99
189
|
# On-demand commands (save for when needed):
|
|
100
|
-
claude mcp add nanobanana -e GEMINI_API_KEY=AIza...
|
|
190
|
+
claude mcp add nanobanana -e GEMINI_API_KEY=AIza... -- uvx nanobanana-mcp-server@latest
|
|
101
191
|
claude mcp add sequential-thinking -- npx -y @modelcontextprotocol/server-sequential-thinking
|
|
102
192
|
```
|
|
103
193
|
|
|
@@ -113,36 +203,6 @@ A single number that tells you how clean your MCP setup is:
|
|
|
113
203
|
8 total servers | 7 healthy | 0 duplicates | 1 should remove
|
|
114
204
|
```
|
|
115
205
|
|
|
116
|
-
## Commands
|
|
117
|
-
|
|
118
|
-
### `audit`
|
|
119
|
-
|
|
120
|
-
Full health check of all MCP servers.
|
|
121
|
-
|
|
122
|
-
```bash
|
|
123
|
-
# Full audit (spawns each server to test connectivity)
|
|
124
|
-
npx mcp-doctor audit
|
|
125
|
-
|
|
126
|
-
# Quick mode (config validation only, no spawning — instant)
|
|
127
|
-
npx mcp-doctor audit --quick
|
|
128
|
-
|
|
129
|
-
# Filter to a specific project
|
|
130
|
-
npx mcp-doctor audit --project my-project
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
### `recommend`
|
|
134
|
-
|
|
135
|
-
Browse curated MCP preset packs for your workflow.
|
|
136
|
-
|
|
137
|
-
```bash
|
|
138
|
-
# List all available presets
|
|
139
|
-
npx mcp-doctor recommend
|
|
140
|
-
|
|
141
|
-
# Get details + install commands for a specific pack
|
|
142
|
-
npx mcp-doctor recommend web-developer
|
|
143
|
-
npx mcp-doctor recommend ai-architect
|
|
144
|
-
```
|
|
145
|
-
|
|
146
206
|
## Preset Packs
|
|
147
207
|
|
|
148
208
|
Pre-configured MCP stacks for common workflows. Each pack specifies which servers to run always-on vs. on-demand.
|
|
@@ -160,28 +220,16 @@ Pre-configured MCP stacks for common workflows. Each pack specifies which server
|
|
|
160
220
|
| `security` | Auditing, pen testing, compliance | 2 | 1 |
|
|
161
221
|
| `minimal` | Just the essentials | 1 | 0 |
|
|
162
222
|
|
|
163
|
-
|
|
223
|
+
## Security
|
|
164
224
|
|
|
165
|
-
|
|
166
|
-
AI Architect
|
|
167
|
-
Building AI systems, agents, and multi-model orchestration
|
|
225
|
+
MCP Doctor reads your `~/.claude.json` which contains API keys and tokens. Here's how we protect them:
|
|
168
226
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
Track architecture decisions, model configs, and system patterns
|
|
174
|
-
● sequential-thinking (always-on)
|
|
175
|
-
Multi-step reasoning for agent design and system architecture
|
|
176
|
-
◐ browser-use (on-demand)
|
|
177
|
-
Visual browser agent for testing AI UIs and design tools like v0.dev
|
|
227
|
+
- **Secret redaction**: All output passes through `redactSecrets()` — known env values and 9 common API key regex patterns are replaced with `[REDACTED:KEY_NAME]`
|
|
228
|
+
- **Safe env inheritance**: Spawned processes only receive safe system vars (`PATH`, `HOME`, etc.) + the server's own declared env — not your full `process.env`
|
|
229
|
+
- **No network access**: MCP Doctor never sends data anywhere. It reads local config and spawns local processes only
|
|
230
|
+
- **Zero dependencies**: No supply chain risk from transitive dependencies
|
|
178
231
|
|
|
179
|
-
|
|
180
|
-
claude mcp add playwright -- npx -y @playwright/mcp
|
|
181
|
-
claude mcp add memory -- npx -y @modelcontextprotocol/server-memory
|
|
182
|
-
claude mcp add sequential-thinking -- npx -y @modelcontextprotocol/server-sequential-thinking
|
|
183
|
-
claude mcp add browser-use -- uvx --from browser-use[cli] browser-use --mcp
|
|
184
|
-
```
|
|
232
|
+
See [SECURITY.md](SECURITY.md) for vulnerability reporting.
|
|
185
233
|
|
|
186
234
|
## How It Works
|
|
187
235
|
|
|
@@ -195,11 +243,10 @@ For each server found, it:
|
|
|
195
243
|
- Validates the configuration structure
|
|
196
244
|
- Checks that required commands exist in PATH
|
|
197
245
|
- Detects placeholder environment variables
|
|
246
|
+
- Scans `settings.json` files for misplaced MCP configs
|
|
198
247
|
- (Full mode) Spawns the process and sends an MCP `initialize` handshake
|
|
199
248
|
- Cross-references against a database of known MCP servers for tier recommendations
|
|
200
249
|
|
|
201
|
-
API keys found in configs are automatically masked in output (`AIza...EgP4`).
|
|
202
|
-
|
|
203
250
|
## MCP Scope Explained
|
|
204
251
|
|
|
205
252
|
If you're confused about where your servers are configured, here's the hierarchy:
|
|
@@ -216,12 +263,13 @@ If you're confused about where your servers are configured, here's the hierarchy
|
|
|
216
263
|
/path/to/project/.mcp.json ← Shared project scope (committed to git)
|
|
217
264
|
```
|
|
218
265
|
|
|
219
|
-
|
|
266
|
+
> **Common mistake**: Putting `mcpServers` in `~/.claude/settings.json` — Claude Code ignores them there. MCP Doctor detects this and tells you how to fix it.
|
|
220
267
|
|
|
221
268
|
## Contributing
|
|
222
269
|
|
|
223
270
|
Contributions welcome. Some ideas:
|
|
224
271
|
|
|
272
|
+
- **Multi-agent support** — Add config readers for Cursor, Windsurf, VS Code Copilot
|
|
225
273
|
- **New preset packs** — Add presets for your workflow in `src/analyzer/presets.ts`
|
|
226
274
|
- **Known server database** — Expand the tier-optimizer's knowledge of common MCP servers
|
|
227
275
|
- **MCP server mode** — Run mcp-doctor as an MCP server itself (meta!)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tier-optimizer.d.ts","sourceRoot":"","sources":["../../src/analyzer/tier-optimizer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAE5D,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,cAAc,CAAC;IACvB,WAAW,EAAE,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC;IACnD,eAAe,EAAE,WAAW,GAAG,WAAW,GAAG,QAAQ,CAAC;IACtD,MAAM,EAAE,MAAM,CAAC;CAChB;AAsBD,wBAAgB,YAAY,CAC1B,OAAO,EAAE,cAAc,EAAE,EACzB,aAAa,EAAE,YAAY,EAAE,GAC5B,kBAAkB,EAAE,CA8EtB;
|
|
1
|
+
{"version":3,"file":"tier-optimizer.d.ts","sourceRoot":"","sources":["../../src/analyzer/tier-optimizer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAE5D,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,cAAc,CAAC;IACvB,WAAW,EAAE,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC;IACnD,eAAe,EAAE,WAAW,GAAG,WAAW,GAAG,QAAQ,CAAC;IACtD,MAAM,EAAE,MAAM,CAAC;CAChB;AAsBD,wBAAgB,YAAY,CAC1B,OAAO,EAAE,cAAc,EAAE,EACzB,aAAa,EAAE,YAAY,EAAE,GAC5B,kBAAkB,EAAE,CA8EtB;AAQD,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,cAAc,EAAE,GACxB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAoBrB"}
|
|
@@ -92,7 +92,8 @@ function analyzeTiers(servers, healthResults) {
|
|
|
92
92
|
function maskSecret(value) {
|
|
93
93
|
if (value.length <= 8)
|
|
94
94
|
return "***";
|
|
95
|
-
|
|
95
|
+
// Show only first 4 chars — enough to identify which key, not enough to exploit
|
|
96
|
+
return value.slice(0, 4) + "...";
|
|
96
97
|
}
|
|
97
98
|
function generateOnDemandCommands(servers) {
|
|
98
99
|
const commands = new Map();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tier-optimizer.js","sourceRoot":"","sources":["../../src/analyzer/tier-optimizer.ts"],"names":[],"mappings":";;AA8BA,oCAiFC;
|
|
1
|
+
{"version":3,"file":"tier-optimizer.js","sourceRoot":"","sources":["../../src/analyzer/tier-optimizer.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { scanAllServers, findDuplicates, findMissingEnvVars, readClaudeConfig, getClaudeConfigPath, } from "./scanner/config-reader.js";
|
|
2
|
-
export { checkServerHealth, checkAllServers, } from "./scanner/health-checker.js";
|
|
1
|
+
export { scanAllServers, findDuplicates, findMissingEnvVars, findMisplacedConfigs, readClaudeConfig, getClaudeConfigPath, } from "./scanner/config-reader.js";
|
|
2
|
+
export { checkServerHealth, checkAllServers, redactSecrets, } from "./scanner/health-checker.js";
|
|
3
3
|
export type { HealthStatus, HealthResult } from "./scanner/health-checker.js";
|
|
4
|
-
export type { McpServerConfig, McpServerEntry, ClaudeConfig } from "./scanner/config-reader.js";
|
|
4
|
+
export type { McpServerConfig, McpServerEntry, ClaudeConfig, MisplacedConfig } from "./scanner/config-reader.js";
|
|
5
5
|
export { analyzeTiers, generateOnDemandCommands } from "./analyzer/tier-optimizer.js";
|
|
6
6
|
export type { TierRecommendation } from "./analyzer/tier-optimizer.js";
|
|
7
7
|
export { listPresets, getPreset, generateInstallCommands, PRESETS } from "./analyzer/presets.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,iBAAiB,EACjB,eAAe,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,aAAa,GACd,MAAM,6BAA6B,CAAC;AAErC,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC9E,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAEjH,OAAO,EAAE,YAAY,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACtF,YAAY,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAEvE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,uBAAuB,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACjG,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PRESETS = exports.generateInstallCommands = exports.getPreset = exports.listPresets = exports.generateOnDemandCommands = exports.analyzeTiers = exports.checkAllServers = exports.checkServerHealth = exports.getClaudeConfigPath = exports.readClaudeConfig = exports.findMissingEnvVars = exports.findDuplicates = exports.scanAllServers = void 0;
|
|
3
|
+
exports.PRESETS = exports.generateInstallCommands = exports.getPreset = exports.listPresets = exports.generateOnDemandCommands = exports.analyzeTiers = exports.redactSecrets = exports.checkAllServers = exports.checkServerHealth = exports.getClaudeConfigPath = exports.readClaudeConfig = exports.findMisplacedConfigs = exports.findMissingEnvVars = exports.findDuplicates = exports.scanAllServers = void 0;
|
|
4
4
|
var config_reader_js_1 = require("./scanner/config-reader.js");
|
|
5
5
|
Object.defineProperty(exports, "scanAllServers", { enumerable: true, get: function () { return config_reader_js_1.scanAllServers; } });
|
|
6
6
|
Object.defineProperty(exports, "findDuplicates", { enumerable: true, get: function () { return config_reader_js_1.findDuplicates; } });
|
|
7
7
|
Object.defineProperty(exports, "findMissingEnvVars", { enumerable: true, get: function () { return config_reader_js_1.findMissingEnvVars; } });
|
|
8
|
+
Object.defineProperty(exports, "findMisplacedConfigs", { enumerable: true, get: function () { return config_reader_js_1.findMisplacedConfigs; } });
|
|
8
9
|
Object.defineProperty(exports, "readClaudeConfig", { enumerable: true, get: function () { return config_reader_js_1.readClaudeConfig; } });
|
|
9
10
|
Object.defineProperty(exports, "getClaudeConfigPath", { enumerable: true, get: function () { return config_reader_js_1.getClaudeConfigPath; } });
|
|
10
11
|
var health_checker_js_1 = require("./scanner/health-checker.js");
|
|
11
12
|
Object.defineProperty(exports, "checkServerHealth", { enumerable: true, get: function () { return health_checker_js_1.checkServerHealth; } });
|
|
12
13
|
Object.defineProperty(exports, "checkAllServers", { enumerable: true, get: function () { return health_checker_js_1.checkAllServers; } });
|
|
14
|
+
Object.defineProperty(exports, "redactSecrets", { enumerable: true, get: function () { return health_checker_js_1.redactSecrets; } });
|
|
13
15
|
var tier_optimizer_js_1 = require("./analyzer/tier-optimizer.js");
|
|
14
16
|
Object.defineProperty(exports, "analyzeTiers", { enumerable: true, get: function () { return tier_optimizer_js_1.analyzeTiers; } });
|
|
15
17
|
Object.defineProperty(exports, "generateOnDemandCommands", { enumerable: true, get: function () { return tier_optimizer_js_1.generateOnDemandCommands; } });
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,+
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,+DAOoC;AANlC,kHAAA,cAAc,OAAA;AACd,kHAAA,cAAc,OAAA;AACd,sHAAA,kBAAkB,OAAA;AAClB,wHAAA,oBAAoB,OAAA;AACpB,oHAAA,gBAAgB,OAAA;AAChB,uHAAA,mBAAmB,OAAA;AAGrB,iEAIqC;AAHnC,sHAAA,iBAAiB,OAAA;AACjB,oHAAA,eAAe,OAAA;AACf,kHAAA,aAAa,OAAA;AAMf,kEAAsF;AAA7E,iHAAA,YAAY,OAAA;AAAE,6HAAA,wBAAwB,OAAA;AAG/C,oDAAiG;AAAxF,yGAAA,WAAW,OAAA;AAAE,uGAAA,SAAS,OAAA;AAAE,qHAAA,uBAAuB,OAAA;AAAE,qGAAA,OAAO,OAAA"}
|
package/dist/reporter/format.js
CHANGED
|
@@ -42,7 +42,7 @@ function formatHeader() {
|
|
|
42
42
|
return [
|
|
43
43
|
"",
|
|
44
44
|
bold(" ╔══════════════════════════════════════╗"),
|
|
45
|
-
bold(" ║ MCP Doctor v0.
|
|
45
|
+
bold(" ║ MCP Doctor v0.3.0 ║"),
|
|
46
46
|
bold(" ║ Diagnose & optimize your MCP setup ║"),
|
|
47
47
|
bold(" ╚══════════════════════════════════════╝"),
|
|
48
48
|
"",
|
|
@@ -6,6 +6,12 @@ export interface HealthResult {
|
|
|
6
6
|
message: string;
|
|
7
7
|
responseTimeMs?: number;
|
|
8
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* Redact any known secret values from a string.
|
|
11
|
+
* Scans for env var values from the server config and replaces them.
|
|
12
|
+
* Also catches common API key patterns as a safety net.
|
|
13
|
+
*/
|
|
14
|
+
export declare function redactSecrets(text: string, serverEnv: Record<string, string>): string;
|
|
9
15
|
export declare function checkServerHealth(server: McpServerEntry, timeoutMs?: number): Promise<HealthResult>;
|
|
10
16
|
export declare function checkAllServers(servers: McpServerEntry[], options?: {
|
|
11
17
|
quick?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health-checker.d.ts","sourceRoot":"","sources":["../../src/scanner/health-checker.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,QAAQ,GACR,SAAS,GACT,iBAAiB,GACjB,aAAa,GACb,WAAW,CAAC;AAEhB,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;
|
|
1
|
+
{"version":3,"file":"health-checker.d.ts","sourceRoot":"","sources":["../../src/scanner/health-checker.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,QAAQ,GACR,SAAS,GACT,iBAAiB,GACjB,aAAa,GACb,WAAW,CAAC;AAEhB,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAiCD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAsBrF;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,cAAc,EACtB,SAAS,GAAE,MAAc,GACxB,OAAO,CAAC,YAAY,CAAC,CAqIvB;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,cAAc,EAAE,EACzB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACpD,OAAO,CAAC,YAAY,EAAE,CAAC,CAoCzB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.redactSecrets = redactSecrets;
|
|
3
4
|
exports.checkServerHealth = checkServerHealth;
|
|
4
5
|
exports.checkAllServers = checkAllServers;
|
|
5
6
|
const child_process_1 = require("child_process");
|
|
@@ -12,6 +13,51 @@ function commandExists(command) {
|
|
|
12
13
|
return false;
|
|
13
14
|
}
|
|
14
15
|
}
|
|
16
|
+
/** Env vars safe to inherit — everything else is stripped */
|
|
17
|
+
const SAFE_ENV_KEYS = new Set([
|
|
18
|
+
"PATH", "HOME", "SHELL", "USER", "LANG", "TERM",
|
|
19
|
+
"NODE_PATH", "NODE_OPTIONS", "NVM_DIR", "NVM_BIN",
|
|
20
|
+
"TMPDIR", "TMP", "TEMP", "XDG_RUNTIME_DIR",
|
|
21
|
+
]);
|
|
22
|
+
/**
|
|
23
|
+
* Build a minimal env for spawned processes.
|
|
24
|
+
* Only passes safe system vars + the server's own env vars.
|
|
25
|
+
* Prevents leaking AWS_SECRET_ACCESS_KEY, GITHUB_TOKEN, etc.
|
|
26
|
+
*/
|
|
27
|
+
function buildSafeEnv(serverEnv) {
|
|
28
|
+
const safe = {};
|
|
29
|
+
for (const key of SAFE_ENV_KEYS) {
|
|
30
|
+
if (process.env[key]) {
|
|
31
|
+
safe[key] = process.env[key];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return { ...safe, ...serverEnv };
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Redact any known secret values from a string.
|
|
38
|
+
* Scans for env var values from the server config and replaces them.
|
|
39
|
+
* Also catches common API key patterns as a safety net.
|
|
40
|
+
*/
|
|
41
|
+
function redactSecrets(text, serverEnv) {
|
|
42
|
+
let result = text;
|
|
43
|
+
// Redact known env var values (exact match replacement)
|
|
44
|
+
for (const [key, value] of Object.entries(serverEnv)) {
|
|
45
|
+
if (value && value.length > 6) {
|
|
46
|
+
result = result.replaceAll(value, `[REDACTED:${key}]`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Safety net: catch common API key patterns even if not in env
|
|
50
|
+
result = result.replace(/AIzaSy[A-Za-z0-9_-]{33}/g, "[REDACTED:GEMINI_KEY]");
|
|
51
|
+
result = result.replace(/sk-ant-api[A-Za-z0-9_-]{20,}/g, "[REDACTED:ANTHROPIC_KEY]");
|
|
52
|
+
result = result.replace(/sk-[A-Za-z0-9]{20,}/g, "[REDACTED:OPENAI_KEY]");
|
|
53
|
+
result = result.replace(/re_[A-Za-z0-9]{20,}/g, "[REDACTED:RESEND_KEY]");
|
|
54
|
+
result = result.replace(/ghp_[A-Za-z0-9]{36,}/g, "[REDACTED:GITHUB_TOKEN]");
|
|
55
|
+
result = result.replace(/gho_[A-Za-z0-9]{36,}/g, "[REDACTED:GITHUB_OAUTH]");
|
|
56
|
+
result = result.replace(/npm_[A-Za-z0-9]{36,}/g, "[REDACTED:NPM_TOKEN]");
|
|
57
|
+
result = result.replace(/xai-[A-Za-z0-9]{20,}/g, "[REDACTED:XAI_KEY]");
|
|
58
|
+
result = result.replace(/eyJ[A-Za-z0-9_-]{50,}\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g, "[REDACTED:JWT]");
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
15
61
|
async function checkServerHealth(server, timeoutMs = 10000) {
|
|
16
62
|
const config = server.config;
|
|
17
63
|
// SSE/HTTP servers — check URL reachability
|
|
@@ -60,7 +106,7 @@ async function checkServerHealth(server, timeoutMs = 10000) {
|
|
|
60
106
|
const startTime = Date.now();
|
|
61
107
|
const args = config.args || [];
|
|
62
108
|
const proc = (0, child_process_1.spawn)(baseCommand, args, {
|
|
63
|
-
env:
|
|
109
|
+
env: buildSafeEnv(env),
|
|
64
110
|
stdio: ["pipe", "pipe", "pipe"],
|
|
65
111
|
});
|
|
66
112
|
let stderr = "";
|
|
@@ -101,7 +147,7 @@ async function checkServerHealth(server, timeoutMs = 10000) {
|
|
|
101
147
|
resolve({
|
|
102
148
|
server,
|
|
103
149
|
status: "broken",
|
|
104
|
-
message: `Exited with code ${code}${stderr ? `: ${stderr.slice(0, 200)}` : ""}`,
|
|
150
|
+
message: `Exited with code ${code}${stderr ? `: ${redactSecrets(stderr.slice(0, 200), env)}` : ""}`,
|
|
105
151
|
responseTimeMs: elapsed,
|
|
106
152
|
});
|
|
107
153
|
}
|
|
@@ -123,7 +169,7 @@ async function checkServerHealth(server, timeoutMs = 10000) {
|
|
|
123
169
|
params: {
|
|
124
170
|
protocolVersion: "2024-11-05",
|
|
125
171
|
capabilities: {},
|
|
126
|
-
clientInfo: { name: "mcp-doctor", version: "0.
|
|
172
|
+
clientInfo: { name: "mcp-doctor", version: "0.3.0" },
|
|
127
173
|
},
|
|
128
174
|
}) + "\n");
|
|
129
175
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health-checker.js","sourceRoot":"","sources":["../../src/scanner/health-checker.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"health-checker.js","sourceRoot":"","sources":["../../src/scanner/health-checker.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.3.1",
|
|
7
7
|
"description": "Diagnose, optimize, and manage your Claude Code MCP servers",
|
|
8
8
|
"main": "dist/index.js",
|
|
9
9
|
"bin": {
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"dev": "tsc --watch",
|
|
15
15
|
"start": "node dist/cli.js",
|
|
16
16
|
"audit": "node dist/cli.js audit",
|
|
17
|
-
"recommend": "node dist/cli.js recommend"
|
|
17
|
+
"recommend": "node dist/cli.js recommend",
|
|
18
|
+
"prepublishOnly": "tsc"
|
|
18
19
|
},
|
|
19
20
|
"keywords": [
|
|
20
21
|
"claude",
|