badgr-mcp-doctor 0.1.0

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 ADDED
@@ -0,0 +1,132 @@
1
+ # badgr-mcp-doctor
2
+
3
+ Diagnose MCP server problems — SSE connectivity, malformed events, tools/list failures, timeouts — in one command.
4
+
5
+ ```bash
6
+ npx badgr-mcp-doctor --url http://localhost:3000/sse
7
+ ```
8
+
9
+ **Free. No signup required.** Runs entirely on your machine.
10
+
11
+ ---
12
+
13
+ ## The problem it solves
14
+
15
+ MCP servers fail silently. Your coding agent stops calling tools but gives no useful error. Is the server down? Is SSE broken? Are events malformed? Did `tools/list` time out? `badgr-mcp-doctor` runs the full diagnostic sequence and tells you exactly what's wrong.
16
+
17
+ ---
18
+
19
+ ## Quick start
20
+
21
+ ```bash
22
+ # Diagnose an MCP server
23
+ npx badgr-mcp-doctor --url http://localhost:3000/sse
24
+
25
+ # Machine-readable JSON (for CI or scripts)
26
+ npx badgr-mcp-doctor --url http://localhost:3000/sse --json
27
+
28
+ # Dry-run a specific tool
29
+ npx badgr-mcp-doctor --url http://localhost:3000/sse --tool my_tool_name
30
+
31
+ # Longer timeout for slow servers
32
+ npx badgr-mcp-doctor --url http://localhost:3000/sse --timeout-ms 20000
33
+
34
+ # Show optional hosted monitoring link
35
+ npx badgr-mcp-doctor connect
36
+ ```
37
+
38
+ ---
39
+
40
+ ## CLI flags
41
+
42
+ | Flag | Description |
43
+ |------|-------------|
44
+ | `--url <url>` | MCP server SSE endpoint, e.g. `http://localhost:3000/sse` |
45
+ | `--timeout-ms <n>` | Connection timeout in milliseconds (default: `10000`) |
46
+ | `--tool <name>` | Optional: dry-run a specific tool by name |
47
+ | `--json` | Output machine-readable JSON |
48
+
49
+ **Commands:**
50
+
51
+ | Command | Description |
52
+ |---------|-------------|
53
+ | `connect` | Show the optional AI Badgr hosted MCP monitoring link |
54
+
55
+ **Exit codes:** `0` = all checks passed or warnings only, `1` = one or more failures, `2` = bad usage
56
+
57
+ ---
58
+
59
+ ## What it checks
60
+
61
+ Each diagnostic runs in sequence and stops early if a hard failure is found:
62
+
63
+ | Step | Check |
64
+ |------|-------|
65
+ | 1 | **HTTP connection** — server responds to the SSE endpoint |
66
+ | 2 | **SSE event parsing** — events arrive and are valid JSON |
67
+ | 3 | **tools/list** — JSON-RPC call returns a list of tool objects |
68
+ | 4 | **Dry-run tool call** — invokes the first tool (or `--tool`) with `{dryRun: true}` |
69
+
70
+ ---
71
+
72
+ ## Example output
73
+
74
+ ```
75
+ badgr-mcp-doctor — http://localhost:3000/sse
76
+
77
+ ✓ HTTP connection: 200 OK
78
+ ✓ SSE events: valid JSON payloads received
79
+ ✗ tools/list: timeout after 10000ms
80
+
81
+ The server connected but tools/list never responded.
82
+ Common causes: server still initializing, blocking startup code, wrong endpoint path.
83
+ ```
84
+
85
+ ```
86
+ badgr-mcp-doctor — http://localhost:3000/sse
87
+
88
+ ✓ HTTP connection: 200 OK
89
+ ✓ SSE events: valid JSON payloads received
90
+ ✓ tools/list: 4 tools found (search, read_file, write_file, run_command)
91
+ ✓ Dry-run tool call: search responded without error
92
+ ```
93
+
94
+ ---
95
+
96
+ ## TypeScript API
97
+
98
+ ```ts
99
+ import { runMcpDoctor } from "badgr-mcp-doctor";
100
+
101
+ const result = await runMcpDoctor({
102
+ url: "http://localhost:3000/sse",
103
+ timeoutMs: 15_000,
104
+ toolName: "my_tool", // optional: dry-run a specific tool
105
+ });
106
+
107
+ for (const check of result.checks) {
108
+ console.log(check.status, check.label, check.detail);
109
+ }
110
+ ```
111
+
112
+ **Types:**
113
+
114
+ ```ts
115
+ interface McpDoctorOptions {
116
+ url: string;
117
+ timeoutMs?: number; // default: 10000
118
+ toolName?: string;
119
+ }
120
+
121
+ interface McpDoctorResult {
122
+ checks: DiagnosticCheck[];
123
+ report: JsonReport;
124
+ }
125
+ ```
126
+
127
+ ---
128
+
129
+ ## Requirements
130
+
131
+ - Node.js 18+
132
+ - An MCP server running and accessible at the given URL
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env node
2
+ import { createLogger, fireTelemetry, formatChecks, parseNumber } from "badgr-shared";
3
+ import { runMcpDoctor } from "./index.js";
4
+ fireTelemetry({ package: "badgr-mcp-doctor", command: process.argv[2] });
5
+ function readArg(name) {
6
+ const index = process.argv.indexOf(name);
7
+ return index >= 0 ? process.argv[index + 1] : undefined;
8
+ }
9
+ const command = process.argv[2];
10
+ if (!command || command === "--help" || command === "-h") {
11
+ console.log(`badgr-mcp-doctor — local MCP server diagnostics
12
+
13
+ Usage:
14
+ npx badgr-mcp-doctor --url <sse-url>
15
+ npx badgr-mcp-doctor --url <sse-url> --json
16
+ npx badgr-mcp-doctor connect
17
+
18
+ Flags:
19
+ --url <url> MCP server SSE endpoint (e.g. http://localhost:3000/sse)
20
+ --timeout-ms <n> Connection timeout in milliseconds (default: 10000)
21
+ --tool <name> Optional tool name for a dry-run call
22
+ --json Output machine-readable JSON
23
+
24
+ Commands:
25
+ connect Show the optional AI Badgr hosted monitoring link
26
+
27
+ Exit codes:
28
+ 0 All checks passed or warnings only
29
+ 1 One or more checks failed
30
+ 2 Bad usage (missing required flag)
31
+
32
+ No signup required. Hosted monitoring is always optional.
33
+
34
+ Environment:
35
+ BADGR_TELEMETRY=0 Disable anonymous usage telemetry`);
36
+ process.exit(0);
37
+ }
38
+ if (command === "connect") {
39
+ console.log("Monitor this MCP server continuously with AI Badgr:");
40
+ console.log("https://aibadgr.com/mcp/connect");
41
+ console.log("");
42
+ console.log("Signup is only required if you enable recurring hosted monitoring.");
43
+ process.exit(0);
44
+ }
45
+ const url = readArg("--url");
46
+ if (!url) {
47
+ console.error("Error: --url is required");
48
+ console.error("Usage: npx badgr-mcp-doctor --url http://localhost:3000/sse [--json]");
49
+ process.exit(2);
50
+ }
51
+ const json = process.argv.includes("--json");
52
+ const result = await runMcpDoctor({ url, timeoutMs: parseNumber(readArg("--timeout-ms")), toolName: readArg("--tool") });
53
+ const logger = createLogger(json);
54
+ if (json) {
55
+ logger.report(result.report);
56
+ }
57
+ else {
58
+ logger.line("badgr-mcp-doctor report");
59
+ logger.line("");
60
+ logger.line(formatChecks(result.checks));
61
+ logger.line("");
62
+ logger.line(`Status: ${result.report.status}`);
63
+ logger.line("");
64
+ logger.line("Optional: monitor this MCP server continuously with AI Badgr:");
65
+ logger.line(" npx badgr-mcp-doctor connect");
66
+ }
67
+ process.exitCode = result.report.status === "failed" ? 1 : 0;
68
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACtF,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,aAAa,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAEzE,SAAS,OAAO,CAAC,IAAY;IAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC1D,CAAC;AAED,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAEhC,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;2DAwB6C,CAAC,CAAC;IAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;IAC1B,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;IACnE,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,oEAAoE,CAAC,CAAC;IAClF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7B,IAAI,CAAC,GAAG,EAAE,CAAC;IACT,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC1C,OAAO,CAAC,KAAK,CAAC,sEAAsE,CAAC,CAAC;IACtF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC7C,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,WAAW,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACzH,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;AAClC,IAAI,IAAI,EAAE,CAAC;IACT,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC;KAAM,CAAC;IACN,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IACvC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChB,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IACzC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChB,MAAM,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/C,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChB,MAAM,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAC;IAC7E,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;AAChD,CAAC;AACD,OAAO,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { type DiagnosticCheck, type JsonReport } from "badgr-shared";
2
+ export interface McpDoctorOptions {
3
+ url: string;
4
+ timeoutMs?: number;
5
+ toolName?: string;
6
+ }
7
+ export interface McpDoctorResult {
8
+ checks: DiagnosticCheck[];
9
+ report: JsonReport;
10
+ }
11
+ export declare function parseSseEvents(chunk: string): DiagnosticCheck[];
12
+ export declare function runMcpDoctor(options: McpDoctorOptions): Promise<McpDoctorResult>;
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0D,KAAK,eAAe,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAE7H,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,MAAM,EAAE,UAAU,CAAC;CACpB;AAOD,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,EAAE,CAgB/D;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAqCtF"}
package/dist/index.js ADDED
@@ -0,0 +1,139 @@
1
+ import { checkToFinding, createReport, reportStatusFromFindings } from "badgr-shared";
2
+ export function parseSseEvents(chunk) {
3
+ const checks = [];
4
+ const events = chunk.split(/\r?\n\r?\n/).filter(Boolean);
5
+ for (const event of events) {
6
+ const dataLines = event.split(/\r?\n/).filter((line) => line.startsWith("data:"));
7
+ if (dataLines.length === 0)
8
+ continue;
9
+ const payload = dataLines.map((line) => line.slice(5).trimStart()).join("\n");
10
+ try {
11
+ JSON.parse(payload);
12
+ checks.push({ name: "sse-parse", status: "pass", message: "SSE event contained valid JSON payload" });
13
+ }
14
+ catch {
15
+ checks.push({ name: "sse-parse", status: "fail", message: "SSE event contained malformed multiline payload", details: { payloadPreview: payload.slice(0, 120) } });
16
+ }
17
+ }
18
+ if (checks.length === 0)
19
+ checks.push({ name: "sse-parse", status: "warn", message: "No SSE data events observed during parsing window" });
20
+ return checks;
21
+ }
22
+ export async function runMcpDoctor(options) {
23
+ const timeoutMs = options.timeoutMs ?? 10_000;
24
+ const checks = [];
25
+ const controller = new AbortController();
26
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
27
+ try {
28
+ const response = await fetch(options.url, { headers: { accept: "text/event-stream, application/json" }, signal: controller.signal });
29
+ checks.push({ name: "connection", status: response.ok ? "pass" : "fail", message: response.ok ? "connection established" : `connection failed with HTTP ${response.status}` });
30
+ const contentType = response.headers.get("content-type") ?? "";
31
+ if (contentType.includes("text/event-stream")) {
32
+ const text = await readSomeText(response, timeoutMs);
33
+ checks.push(...parseSseEvents(text));
34
+ }
35
+ }
36
+ catch (error) {
37
+ checks.push({ name: "connection", status: "fail", message: error instanceof Error && error.name === "AbortError" ? `connection timed out after ${timeoutMs / 1000}s` : `connection failed: ${String(error)}` });
38
+ }
39
+ finally {
40
+ clearTimeout(timer);
41
+ }
42
+ const rpcChecks = await runJsonRpcChecks(options.url, timeoutMs, options.toolName);
43
+ checks.push(...rpcChecks);
44
+ const findings = checks.map((check) => checkToFinding(check, "MCP"));
45
+ const status = reportStatusFromFindings(findings);
46
+ const nextCommand = "npx @aibadgr/mcp-doctor connect";
47
+ const report = createReport({
48
+ tool: "mcp-doctor",
49
+ status,
50
+ summary: status === "failed" ? "MCP server has failing diagnostics" : status === "warning" ? "MCP server has warnings" : "MCP server diagnostics passed",
51
+ findings,
52
+ recommendedActions: buildRecommendedActions(checks),
53
+ nextCommand,
54
+ actionUrl: "https://aibadgr.com/mcp/connect",
55
+ metadata: { url: options.url, timeoutMs },
56
+ });
57
+ return { checks, report };
58
+ }
59
+ async function readSomeText(response, timeoutMs) {
60
+ if (!response.body)
61
+ return await response.text();
62
+ const reader = response.body.getReader();
63
+ const timeout = new Promise((_, reject) => setTimeout(() => reject(new Error("read timeout")), Math.min(timeoutMs, 1500)));
64
+ try {
65
+ const { value } = await Promise.race([reader.read().then((result) => result), timeout.then((value) => ({ value, done: false }))]);
66
+ return Buffer.from(value ?? new Uint8Array()).toString("utf8");
67
+ }
68
+ catch {
69
+ return "";
70
+ }
71
+ finally {
72
+ reader.releaseLock();
73
+ }
74
+ }
75
+ async function runJsonRpcChecks(url, timeoutMs, toolName) {
76
+ const checks = [];
77
+ const endpoint = url.replace(/\/sse\/?$/, "");
78
+ const tools = await callJsonRpc(endpoint, "tools/list", {}, timeoutMs);
79
+ if (tools.timedOut) {
80
+ checks.push({ name: "tools-list", status: "fail", message: `tools/list timed out after ${timeoutMs / 1000}s` });
81
+ return checks;
82
+ }
83
+ if (tools.error) {
84
+ checks.push({ name: "tools-list", status: "warn", message: `tools/list could not be checked over JSON-RPC: ${tools.error}` });
85
+ return checks;
86
+ }
87
+ const result = tools.response?.result;
88
+ const count = Array.isArray(result?.tools) ? result.tools.length : 0;
89
+ checks.push({ name: "tools-list", status: Array.isArray(result?.tools) ? "pass" : "fail", message: Array.isArray(result?.tools) ? `tools/list returned ${count} tools` : "tools/list returned malformed result" });
90
+ const dryRunName = toolName ?? (Array.isArray(result?.tools) && typeof result.tools[0]?.name === "string" ? String(result.tools[0].name) : undefined);
91
+ if (!dryRunName) {
92
+ checks.push({ name: "dry-run-tool", status: "warn", message: "No tool available for dry-run call" });
93
+ return checks;
94
+ }
95
+ const dryRun = await callJsonRpc(endpoint, "tools/call", { name: dryRunName, arguments: { dryRun: true } }, timeoutMs);
96
+ if (dryRun.timedOut)
97
+ checks.push({ name: "dry-run-tool", status: "fail", message: `tool call timed out after ${timeoutMs / 1000}s` });
98
+ else if (dryRun.error)
99
+ checks.push({ name: "dry-run-tool", status: "warn", message: `dry-run tool call returned an error: ${dryRun.error}` });
100
+ else
101
+ checks.push({ name: "dry-run-tool", status: "pass", message: "dry-run tool call returned a result" });
102
+ return checks;
103
+ }
104
+ async function callJsonRpc(url, method, params, timeoutMs) {
105
+ const controller = new AbortController();
106
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
107
+ try {
108
+ const response = await fetch(url, {
109
+ method: "POST",
110
+ headers: { "content-type": "application/json", accept: "application/json" },
111
+ body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params }),
112
+ signal: controller.signal,
113
+ });
114
+ const text = await response.text();
115
+ if (!response.ok)
116
+ return { error: `HTTP ${response.status}` };
117
+ return { response: JSON.parse(text) };
118
+ }
119
+ catch (error) {
120
+ if (error instanceof Error && error.name === "AbortError")
121
+ return { timedOut: true };
122
+ return { error: String(error) };
123
+ }
124
+ finally {
125
+ clearTimeout(timer);
126
+ }
127
+ }
128
+ function buildRecommendedActions(checks) {
129
+ const actions = [];
130
+ if (checks.some((check) => check.name === "sse-parse" && check.status === "fail"))
131
+ actions.push("Fix malformed multiline SSE event payloads");
132
+ if (checks.some((check) => check.message.includes("timed out")))
133
+ actions.push("Add tool-level timeout handling or reduce long-running tool work");
134
+ if (checks.some((check) => check.name === "tools-list" && check.status !== "pass"))
135
+ actions.push("Verify the MCP tools/list JSON-RPC response shape");
136
+ actions.push("Monitor this MCP server continuously with AI Badgr");
137
+ return actions;
138
+ }
139
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "badgr-mcp-doctor",
3
+ "version": "0.1.0",
4
+ "description": "CLI diagnostics for MCP connection, tools/list, timeouts, SSE parsing, and dry-run tool calls.",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": { "badgr-mcp-doctor": "dist/cli.js" },
9
+ "exports": { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" } },
10
+ "files": ["dist", "README.md"],
11
+ "scripts": { "build": "tsc -b", "typecheck": "tsc -b --pretty false", "test": "vitest run" },
12
+ "dependencies": { "badgr-shared": "0.1.1" },
13
+ "engines": { "node": ">=18.0.0" },
14
+ "keywords": ["mcp", "sse", "diagnostics", "tools", "timeout"],
15
+ "license": "MIT"
16
+ }