@k08200/mcp-probe 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 k08200
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,144 @@
1
+ # mcp-probe
2
+
3
+ [![CI](https://github.com/k08200/mcp-probe/actions/workflows/ci.yml/badge.svg)](https://github.com/k08200/mcp-probe/actions/workflows/ci.yml)
4
+ [![npm](https://img.shields.io/npm/v/mcp-probe)](https://www.npmjs.com/package/mcp-probe)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
6
+ [![Node.js](https://img.shields.io/node/v/mcp-probe)](package.json)
7
+
8
+ **Quality checker for MCP servers.** Validates protocol handshake, tool discovery, and response latency in one command.
9
+
10
+ The `npm audit` for the [MCP](https://modelcontextprotocol.io) ecosystem — because [awesome-mcp-servers](https://github.com/punkpeye/awesome-mcp-servers) lists 200+ servers and there was no way to know if they actually worked.
11
+
12
+ ```bash
13
+ npx @k08200/mcp-probe @modelcontextprotocol/server-memory
14
+ ```
15
+
16
+ ```
17
+ mcp-probe @modelcontextprotocol/server-memory
18
+ ────────────────────────────────────────────────────
19
+ ✓ Target resolution
20
+ npx --yes @modelcontextprotocol/server-memory
21
+ ✓ MCP protocol handshake 1392ms
22
+ memory-server v0.6.3
23
+ ✓ Tools discovery 33ms
24
+ Found 9 tools
25
+ ✓ Tool schema validation
26
+ All tool schemas are valid
27
+ ────────────────────────────────────────────────────
28
+ Server memory-server v0.6.3
29
+ Caps tools
30
+
31
+ Tools
32
+ ▸ create_entities Create multiple new entities in the knowledge graph
33
+ ▸ create_relations Create multiple new relations between entities
34
+ ▸ add_observations Add new observations to existing entities
35
+ ▸ delete_entities Delete entities and their associated relations
36
+ ▸ read_graph Read the entire knowledge graph
37
+ ▸ search_nodes Search for nodes in the knowledge graph
38
+ ▸ ...and 3 more
39
+
40
+ ✓ PASS 1455ms total
41
+ ```
42
+
43
+ ---
44
+
45
+ ## Install
46
+
47
+ ```bash
48
+ # No install needed
49
+ npx @k08200/mcp-probe <target>
50
+
51
+ # Or install globally
52
+ npm install -g @k08200/mcp-probe
53
+ ```
54
+
55
+ ## Usage
56
+
57
+ ```bash
58
+ # Check an npm package
59
+ mcp-probe @modelcontextprotocol/server-memory
60
+
61
+ # Check a server that requires arguments (e.g. directories to serve)
62
+ mcp-probe @modelcontextprotocol/server-filesystem /tmp /Users/me/projects
63
+
64
+ # Check a local server file
65
+ mcp-probe ./my-server.js
66
+
67
+ # JSON output for CI / scripting
68
+ mcp-probe @scope/server --output json
69
+
70
+ # Custom timeout (default: 10000ms)
71
+ mcp-probe @scope/server --timeout 30000
72
+ ```
73
+
74
+ ## What it checks
75
+
76
+ | Check | Description |
77
+ |-------|-------------|
78
+ | **Target resolution** | Can the package be located and spawned? |
79
+ | **MCP protocol handshake** | Does the server respond to `initialize`? Measures connect latency. |
80
+ | **Tools discovery** | Does `tools/list` return results? Measures list latency. |
81
+ | **Tool schema validation** | Are all tool schemas well-formed? |
82
+
83
+ ## Exit codes
84
+
85
+ | Code | Meaning |
86
+ |------|---------|
87
+ | `0` | All checks passed (or warnings only) |
88
+ | `1` | One or more checks failed |
89
+
90
+ ## CI integration
91
+
92
+ ```yaml
93
+ # .github/workflows/mcp-probe.yml
94
+ - name: Validate MCP server
95
+ run: npx @k08200/mcp-probe @your-org/your-mcp-server
96
+ timeout-minutes: 2
97
+ ```
98
+
99
+ ## JSON output
100
+
101
+ ```bash
102
+ mcp-probe @modelcontextprotocol/server-memory --output json
103
+ ```
104
+
105
+ ```json
106
+ {
107
+ "target": "@modelcontextprotocol/server-memory",
108
+ "timestamp": "2026-05-17T12:00:00.000Z",
109
+ "overallStatus": "pass",
110
+ "checks": [
111
+ { "name": "Target resolution", "status": "pass", "message": "npx --yes @modelcontextprotocol/server-memory" },
112
+ { "name": "MCP protocol handshake", "status": "pass", "message": "memory-server v0.6.3", "latencyMs": 1392 },
113
+ { "name": "Tools discovery", "status": "pass", "message": "Found 9 tools", "latencyMs": 33 },
114
+ { "name": "Tool schema validation", "status": "pass", "message": "All tool schemas are valid" }
115
+ ],
116
+ "serverInfo": { "name": "memory-server", "version": "0.6.3", "capabilities": ["tools"] },
117
+ "tools": [{ "name": "create_entities", "description": "Create multiple new entities in the knowledge graph" }],
118
+ "totalLatencyMs": 1455
119
+ }
120
+ ```
121
+
122
+ ## Status values
123
+
124
+ | Status | Icon | Meaning |
125
+ |--------|------|---------|
126
+ | `pass` | ✓ | Check succeeded |
127
+ | `warn` | ⚠ | Non-fatal issue (e.g. no tools registered) |
128
+ | `fail` | ✗ | Check failed — exits with code 1 |
129
+
130
+ ## Roadmap
131
+
132
+ - [ ] `resources/list` and `prompts/list` checks
133
+ - [ ] HTTP/SSE transport support
134
+ - [ ] Batch checking from a file (`mcp-probe --list servers.txt`)
135
+ - [ ] Badge generation (`mcp-probe --badge > badge.json`)
136
+ - [ ] Weekly quality report for awesome-mcp-servers
137
+
138
+ ## Contributing
139
+
140
+ Issues and PRs are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md).
141
+
142
+ ## License
143
+
144
+ [MIT](LICENSE)
@@ -0,0 +1,13 @@
1
+ import type { CheckReport } from './types.js';
2
+ type CheckOptions = {
3
+ target: string;
4
+ serverArgs?: string[];
5
+ timeoutMs: number;
6
+ };
7
+ export declare function resolveTarget(target: string): {
8
+ command: string;
9
+ args: string[];
10
+ };
11
+ export declare function checkMcpServer(options: CheckOptions): Promise<CheckReport>;
12
+ export {};
13
+ //# sourceMappingURL=checker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checker.d.ts","sourceRoot":"","sources":["../src/checker.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAa,WAAW,EAAe,MAAM,YAAY,CAAC;AAEtE,KAAK,YAAY,GAAG;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAKjF;AAQD,wBAAsB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CA4FhF"}
@@ -0,0 +1,100 @@
1
+ import { probeMcpServer } from './protocols/mcp-client.js';
2
+ export function resolveTarget(target) {
3
+ if (target.startsWith('.') || target.startsWith('/')) {
4
+ return { command: 'node', args: [target] };
5
+ }
6
+ return { command: 'npx', args: ['--yes', target] };
7
+ }
8
+ function deriveOverallStatus(checks) {
9
+ if (checks.some((c) => c.status === 'fail'))
10
+ return 'fail';
11
+ if (checks.some((c) => c.status === 'warn'))
12
+ return 'warn';
13
+ return 'pass';
14
+ }
15
+ export async function checkMcpServer(options) {
16
+ const startTime = Date.now();
17
+ const checks = [];
18
+ const resolved = resolveTarget(options.target);
19
+ const args = [...resolved.args, ...(options.serverArgs ?? [])];
20
+ const { command } = resolved;
21
+ checks.push({
22
+ name: 'Target resolution',
23
+ status: 'pass',
24
+ message: `${command} ${args.join(' ')}`,
25
+ });
26
+ try {
27
+ const probe = await probeMcpServer({ command, args, timeoutMs: options.timeoutMs });
28
+ checks.push({
29
+ name: 'MCP protocol handshake',
30
+ status: 'pass',
31
+ message: `${probe.serverInfo.name} v${probe.serverInfo.version}`,
32
+ latencyMs: probe.connectLatencyMs,
33
+ });
34
+ const toolsStatus = probe.tools.length > 0 ? 'pass' : 'warn';
35
+ checks.push({
36
+ name: 'Tools discovery',
37
+ status: toolsStatus,
38
+ message: probe.tools.length > 0
39
+ ? `Found ${probe.tools.length} tool${probe.tools.length !== 1 ? 's' : ''}`
40
+ : 'No tools registered — server may be resources/prompts-only',
41
+ latencyMs: probe.toolsLatencyMs,
42
+ });
43
+ const toolsMissingName = probe.tools.filter((t) => !t.name);
44
+ if (probe.tools.length > 0) {
45
+ checks.push({
46
+ name: 'Tool schema validation',
47
+ status: toolsMissingName.length > 0 ? 'warn' : 'pass',
48
+ message: toolsMissingName.length > 0
49
+ ? `${toolsMissingName.length} tool(s) missing required name field`
50
+ : 'All tool schemas are valid',
51
+ });
52
+ }
53
+ if (probe.resources.length > 0 || probe.resourcesLatencyMs !== undefined) {
54
+ checks.push({
55
+ name: 'Resources discovery',
56
+ status: 'pass',
57
+ message: `Found ${probe.resources.length} resource${probe.resources.length !== 1 ? 's' : ''}`,
58
+ latencyMs: probe.resourcesLatencyMs,
59
+ });
60
+ }
61
+ if (probe.prompts.length > 0 || probe.promptsLatencyMs !== undefined) {
62
+ checks.push({
63
+ name: 'Prompts discovery',
64
+ status: 'pass',
65
+ message: `Found ${probe.prompts.length} prompt${probe.prompts.length !== 1 ? 's' : ''}`,
66
+ latencyMs: probe.promptsLatencyMs,
67
+ });
68
+ }
69
+ return {
70
+ target: options.target,
71
+ timestamp: new Date().toISOString(),
72
+ overallStatus: deriveOverallStatus(checks),
73
+ checks,
74
+ serverInfo: probe.serverInfo,
75
+ tools: probe.tools,
76
+ resources: probe.resources,
77
+ prompts: probe.prompts,
78
+ totalLatencyMs: Date.now() - startTime,
79
+ };
80
+ }
81
+ catch (error) {
82
+ const message = error instanceof Error ? error.message : String(error);
83
+ checks.push({
84
+ name: 'MCP protocol handshake',
85
+ status: 'fail',
86
+ message,
87
+ });
88
+ return {
89
+ target: options.target,
90
+ timestamp: new Date().toISOString(),
91
+ overallStatus: 'fail',
92
+ checks,
93
+ tools: [],
94
+ resources: [],
95
+ prompts: [],
96
+ totalLatencyMs: Date.now() - startTime,
97
+ };
98
+ }
99
+ }
100
+ //# sourceMappingURL=checker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checker.js","sourceRoot":"","sources":["../src/checker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAS3D,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC;IAC7C,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC;AACrD,CAAC;AAED,SAAS,mBAAmB,CAAC,MAAmB;IAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAC3D,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAC3D,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAqB;IACxD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC;IAC/D,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC;IAE7B,MAAM,CAAC,IAAI,CAAC;QACV,IAAI,EAAE,mBAAmB;QACzB,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,GAAG,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;KACxC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;QAEpF,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,wBAAwB;YAC9B,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,IAAI,KAAK,KAAK,CAAC,UAAU,CAAC,OAAO,EAAE;YAChE,SAAS,EAAE,KAAK,CAAC,gBAAgB;SAClC,CAAC,CAAC;QAEH,MAAM,WAAW,GAAgB,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;QAC1E,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,iBAAiB;YACvB,MAAM,EAAE,WAAW;YACnB,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;gBAC7B,CAAC,CAAC,SAAS,KAAK,CAAC,KAAK,CAAC,MAAM,QAAQ,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gBAC1E,CAAC,CAAC,4DAA4D;YAChE,SAAS,EAAE,KAAK,CAAC,cAAc;SAChC,CAAC,CAAC;QAEH,MAAM,gBAAgB,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC5D,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,wBAAwB;gBAC9B,MAAM,EAAE,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;gBACrD,OAAO,EAAE,gBAAgB,CAAC,MAAM,GAAG,CAAC;oBAClC,CAAC,CAAC,GAAG,gBAAgB,CAAC,MAAM,sCAAsC;oBAClE,CAAC,CAAC,4BAA4B;aACjC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,kBAAkB,KAAK,SAAS,EAAE,CAAC;YACzE,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,qBAAqB;gBAC3B,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,SAAS,KAAK,CAAC,SAAS,CAAC,MAAM,YAAY,KAAK,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gBAC7F,SAAS,EAAE,KAAK,CAAC,kBAAkB;aACpC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;YACrE,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,mBAAmB;gBACzB,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,SAAS,KAAK,CAAC,OAAO,CAAC,MAAM,UAAU,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gBACvF,SAAS,EAAE,KAAK,CAAC,gBAAgB;aAClC,CAAC,CAAC;QACL,CAAC;QAED,OAAO;YACL,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,aAAa,EAAE,mBAAmB,CAAC,MAAM,CAAC;YAC1C,MAAM;YACN,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,cAAc,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;SACvC,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,wBAAwB;YAC9B,MAAM,EAAE,MAAM;YACd,OAAO;SACR,CAAC,CAAC;QAEH,OAAO;YACL,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,aAAa,EAAE,MAAM;YACrB,MAAM;YACN,KAAK,EAAE,EAAE;YACT,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,EAAE;YACX,cAAc,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;SACvC,CAAC;IACJ,CAAC;AACH,CAAC"}
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,38 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import ora from 'ora';
4
+ import { checkMcpServer } from './checker.js';
5
+ import { renderTerminal } from './reporters/terminal.js';
6
+ import { renderJson } from './reporters/json-reporter.js';
7
+ const program = new Command();
8
+ program
9
+ .name('mcp-probe')
10
+ .description('Quality checker for MCP servers')
11
+ .version('0.1.0')
12
+ .argument('<target>', 'npm package, npx-style command, or local file path')
13
+ .argument('[server-args...]', 'extra arguments passed directly to the MCP server')
14
+ .option('-o, --output <format>', 'output format: terminal | json', 'terminal')
15
+ .option('-t, --timeout <ms>', 'connection timeout in ms', '10000')
16
+ .action(async (target, serverArgs, opts) => {
17
+ const timeoutMs = parseInt(opts.timeout, 10);
18
+ if (opts.output === 'json') {
19
+ const report = await checkMcpServer({ target, serverArgs, timeoutMs });
20
+ renderJson(report);
21
+ process.exit(report.overallStatus === 'fail' ? 1 : 0);
22
+ return;
23
+ }
24
+ const spinner = ora(`Checking ${target}`).start();
25
+ try {
26
+ const report = await checkMcpServer({ target, serverArgs, timeoutMs });
27
+ spinner.stop();
28
+ renderTerminal(report);
29
+ process.exit(report.overallStatus === 'fail' ? 1 : 0);
30
+ }
31
+ catch (err) {
32
+ spinner.fail('Unexpected error');
33
+ console.error(err instanceof Error ? err.message : String(err));
34
+ process.exit(1);
35
+ }
36
+ });
37
+ program.parse();
38
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE1D,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,iCAAiC,CAAC;KAC9C,OAAO,CAAC,OAAO,CAAC;KAChB,QAAQ,CAAC,UAAU,EAAE,oDAAoD,CAAC;KAC1E,QAAQ,CAAC,kBAAkB,EAAE,mDAAmD,CAAC;KACjF,MAAM,CAAC,uBAAuB,EAAE,gCAAgC,EAAE,UAAU,CAAC;KAC7E,MAAM,CAAC,oBAAoB,EAAE,0BAA0B,EAAE,OAAO,CAAC;KACjE,MAAM,CAAC,KAAK,EACX,MAAc,EACd,UAAoB,EACpB,IAAyC,EACzC,EAAE;IACF,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAE7C,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;QACvE,UAAU,CAAC,MAAM,CAAC,CAAC;QACnB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtD,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;IAClD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;QACvE,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,cAAc,CAAC,MAAM,CAAC,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACjC,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ProbeOptions, ProbeResult } from '../types.js';
2
+ export declare function probeMcpServer(options: ProbeOptions): Promise<ProbeResult>;
3
+ //# sourceMappingURL=mcp-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-client.d.ts","sourceRoot":"","sources":["../../src/protocols/mcp-client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAoB7D,wBAAsB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAiFhF"}
@@ -0,0 +1,87 @@
1
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
+ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
3
+ function firstMeaningfulLine(text) {
4
+ const lines = text.split('\n').map((l) => l.trim()).filter(Boolean);
5
+ // 1. "Error: ..." lines are most informative
6
+ const errorColonLine = lines.find((l) => /^Error:/.test(l));
7
+ if (errorColonLine)
8
+ return errorColonLine;
9
+ // 2. Skip stack frames, node internals, carets, and bare code fragments
10
+ const skip = /^at |^node:|^\^$|^const |^throw |^Require stack/;
11
+ const meaningful = lines.find((l) => !skip.test(l) && l.length > 3);
12
+ return meaningful ?? lines[0] ?? text;
13
+ }
14
+ function withTimeout(promise, ms, label) {
15
+ const timeout = new Promise((_, reject) => setTimeout(() => reject(new Error(`${label} timed out after ${ms}ms`)), ms));
16
+ return Promise.race([promise, timeout]);
17
+ }
18
+ export async function probeMcpServer(options) {
19
+ const transport = new StdioClientTransport({
20
+ command: options.command,
21
+ args: options.args,
22
+ env: { ...process.env },
23
+ stderr: 'pipe',
24
+ });
25
+ // Collect stderr so we can surface crash reasons in error messages
26
+ const stderrChunks = [];
27
+ transport.stderr?.on('data', (chunk) => stderrChunks.push(chunk));
28
+ const client = new Client({ name: 'mcp-probe', version: '0.1.0' }, { capabilities: { roots: { listChanged: false } } });
29
+ const connectStart = Date.now();
30
+ try {
31
+ await withTimeout(client.connect(transport), options.timeoutMs, 'Connection');
32
+ }
33
+ catch (err) {
34
+ const stderrText = Buffer.concat(stderrChunks).toString('utf8').trim();
35
+ const reason = stderrText
36
+ ? firstMeaningfulLine(stderrText)
37
+ : err instanceof Error ? err.message : String(err);
38
+ throw new Error(reason);
39
+ }
40
+ const connectLatencyMs = Date.now() - connectStart;
41
+ const rawServerInfo = client.getServerVersion();
42
+ const rawCaps = client.getServerCapabilities();
43
+ const capabilities = Object.keys(rawCaps ?? {});
44
+ const toolsStart = Date.now();
45
+ const toolsResult = await withTimeout(client.listTools(), options.timeoutMs, 'tools/list');
46
+ const toolsLatencyMs = Date.now() - toolsStart;
47
+ let resourcesLatencyMs;
48
+ let promptsLatencyMs;
49
+ const resourcesList = [];
50
+ const promptsList = [];
51
+ if (rawCaps?.resources) {
52
+ const t = Date.now();
53
+ const result = await withTimeout(client.listResources(), options.timeoutMs, 'resources/list');
54
+ resourcesLatencyMs = Date.now() - t;
55
+ for (const r of result.resources) {
56
+ resourcesList.push({ uri: r.uri, name: r.name, description: r.description });
57
+ }
58
+ }
59
+ if (rawCaps?.prompts) {
60
+ const t = Date.now();
61
+ const result = await withTimeout(client.listPrompts(), options.timeoutMs, 'prompts/list');
62
+ promptsLatencyMs = Date.now() - t;
63
+ for (const p of result.prompts) {
64
+ promptsList.push({ name: p.name, description: p.description });
65
+ }
66
+ }
67
+ await client.close();
68
+ return {
69
+ serverInfo: {
70
+ name: rawServerInfo?.name ?? 'unknown',
71
+ version: rawServerInfo?.version ?? 'unknown',
72
+ capabilities,
73
+ },
74
+ tools: toolsResult.tools.map((t) => ({
75
+ name: t.name,
76
+ description: t.description,
77
+ inputSchema: t.inputSchema,
78
+ })),
79
+ resources: resourcesList,
80
+ prompts: promptsList,
81
+ connectLatencyMs,
82
+ toolsLatencyMs,
83
+ resourcesLatencyMs,
84
+ promptsLatencyMs,
85
+ };
86
+ }
87
+ //# sourceMappingURL=mcp-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-client.js","sourceRoot":"","sources":["../../src/protocols/mcp-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { CheckReport } from '../types.js';
2
+ export declare function renderJson(report: CheckReport): void;
3
+ //# sourceMappingURL=json-reporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-reporter.d.ts","sourceRoot":"","sources":["../../src/reporters/json-reporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAEpD"}
@@ -0,0 +1,4 @@
1
+ export function renderJson(report) {
2
+ process.stdout.write(JSON.stringify(report, null, 2) + '\n');
3
+ }
4
+ //# sourceMappingURL=json-reporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-reporter.js","sourceRoot":"","sources":["../../src/reporters/json-reporter.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,UAAU,CAAC,MAAmB;IAC5C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AAC/D,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { CheckReport } from '../types.js';
2
+ export declare function renderTerminal(report: CheckReport): void;
3
+ //# sourceMappingURL=terminal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/reporters/terminal.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAe,MAAM,aAAa,CAAC;AAgB5D,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAyDxD"}
@@ -0,0 +1,64 @@
1
+ import chalk from 'chalk';
2
+ const ICONS = {
3
+ pass: chalk.green('✓'),
4
+ fail: chalk.red('✗'),
5
+ warn: chalk.yellow('⚠'),
6
+ };
7
+ const COLORS = {
8
+ pass: chalk.green,
9
+ fail: chalk.red,
10
+ warn: chalk.yellow,
11
+ };
12
+ const DIVIDER = chalk.dim('─'.repeat(52));
13
+ export function renderTerminal(report) {
14
+ console.log('');
15
+ console.log(chalk.bold.white('mcp-probe') + ' ' + chalk.dim(report.target));
16
+ console.log(DIVIDER);
17
+ for (const check of report.checks) {
18
+ const latency = check.latencyMs !== undefined
19
+ ? chalk.dim(` ${check.latencyMs}ms`)
20
+ : '';
21
+ console.log(` ${ICONS[check.status]} ${chalk.bold(check.name)}${latency}`);
22
+ console.log(` ${chalk.dim(check.message)}`);
23
+ }
24
+ console.log(DIVIDER);
25
+ if (report.serverInfo) {
26
+ const { name, version, capabilities } = report.serverInfo;
27
+ console.log(chalk.dim(` Server ${name} v${version}`));
28
+ if (capabilities.length > 0) {
29
+ console.log(chalk.dim(` Caps ${capabilities.join(', ')}`));
30
+ }
31
+ }
32
+ if (report.tools.length > 0) {
33
+ console.log('');
34
+ console.log(chalk.bold(' Tools'));
35
+ for (const tool of report.tools) {
36
+ const desc = tool.description ? chalk.dim(` ${tool.description}`) : '';
37
+ console.log(` ${chalk.cyan('▸')} ${chalk.bold(tool.name)}${desc}`);
38
+ }
39
+ }
40
+ if (report.resources.length > 0) {
41
+ console.log('');
42
+ console.log(chalk.bold(' Resources'));
43
+ for (const res of report.resources) {
44
+ const label = res.name ?? res.uri;
45
+ const desc = res.description ? chalk.dim(` ${res.description}`) : '';
46
+ console.log(` ${chalk.magenta('▸')} ${chalk.bold(label)}${desc}`);
47
+ }
48
+ }
49
+ if (report.prompts.length > 0) {
50
+ console.log('');
51
+ console.log(chalk.bold(' Prompts'));
52
+ for (const prompt of report.prompts) {
53
+ const desc = prompt.description ? chalk.dim(` ${prompt.description}`) : '';
54
+ console.log(` ${chalk.yellow('▸')} ${chalk.bold(prompt.name)}${desc}`);
55
+ }
56
+ }
57
+ console.log('');
58
+ const status = report.overallStatus;
59
+ const label = COLORS[status](chalk.bold(status.toUpperCase()));
60
+ const total = chalk.dim(` ${report.totalLatencyMs}ms total`);
61
+ console.log(` ${ICONS[status]} ${label}${total}`);
62
+ console.log('');
63
+ }
64
+ //# sourceMappingURL=terminal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal.js","sourceRoot":"","sources":["../../src/reporters/terminal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ export type CheckStatus = 'pass' | 'fail' | 'warn';
2
+ export type CheckItem = {
3
+ name: string;
4
+ status: CheckStatus;
5
+ message: string;
6
+ latencyMs?: number;
7
+ };
8
+ export type ToolInfo = {
9
+ name: string;
10
+ description?: string;
11
+ inputSchema?: unknown;
12
+ };
13
+ export type ServerInfo = {
14
+ name: string;
15
+ version: string;
16
+ capabilities: string[];
17
+ };
18
+ export type CheckReport = {
19
+ target: string;
20
+ timestamp: string;
21
+ overallStatus: CheckStatus;
22
+ checks: CheckItem[];
23
+ serverInfo?: ServerInfo;
24
+ tools: ToolInfo[];
25
+ resources: ResourceInfo[];
26
+ prompts: PromptInfo[];
27
+ totalLatencyMs: number;
28
+ };
29
+ export type ResourceInfo = {
30
+ uri: string;
31
+ name?: string;
32
+ description?: string;
33
+ };
34
+ export type PromptInfo = {
35
+ name: string;
36
+ description?: string;
37
+ };
38
+ export type ProbeResult = {
39
+ serverInfo: ServerInfo;
40
+ tools: ToolInfo[];
41
+ resources: ResourceInfo[];
42
+ prompts: PromptInfo[];
43
+ connectLatencyMs: number;
44
+ toolsLatencyMs: number;
45
+ resourcesLatencyMs?: number;
46
+ promptsLatencyMs?: number;
47
+ };
48
+ export type ProbeOptions = {
49
+ command: string;
50
+ args: string[];
51
+ timeoutMs: number;
52
+ };
53
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEnD,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,WAAW,CAAC;IAC3B,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@k08200/mcp-probe",
3
+ "version": "0.1.0",
4
+ "description": "Quality checker for MCP servers — validates protocol handshake, tool discovery, and response latency",
5
+ "type": "module",
6
+ "bin": {
7
+ "mcp-probe": "dist/cli.js"
8
+ },
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsc",
14
+ "dev": "tsx src/cli.ts",
15
+ "test": "vitest run",
16
+ "test:watch": "vitest",
17
+ "test:coverage": "vitest run --coverage",
18
+ "typecheck": "tsc --noEmit",
19
+ "prepublishOnly": "npm run build"
20
+ },
21
+ "keywords": [
22
+ "mcp",
23
+ "model-context-protocol",
24
+ "ai",
25
+ "llm",
26
+ "cli",
27
+ "testing",
28
+ "validation",
29
+ "inspector",
30
+ "checker"
31
+ ],
32
+ "author": "k08200",
33
+ "license": "MIT",
34
+ "homepage": "https://github.com/k08200/mcp-probe#readme",
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "git+https://github.com/k08200/mcp-probe.git"
38
+ },
39
+ "bugs": {
40
+ "url": "https://github.com/k08200/mcp-probe/issues"
41
+ },
42
+ "dependencies": {
43
+ "@modelcontextprotocol/sdk": "^1.0.0",
44
+ "chalk": "^5.3.0",
45
+ "commander": "^12.1.0",
46
+ "ora": "^8.1.0"
47
+ },
48
+ "devDependencies": {
49
+ "@types/node": "^22.0.0",
50
+ "@vitest/coverage-v8": "^2.0.0",
51
+ "tsx": "^4.19.0",
52
+ "typescript": "^5.6.0",
53
+ "vitest": "^2.0.0"
54
+ },
55
+ "engines": {
56
+ "node": ">=18.0.0"
57
+ }
58
+ }