@yumdee/mcp-studio-inspector 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 +23 -0
- package/README.md +74 -0
- package/dist/__tests__/diagnose.test.d.ts +2 -0
- package/dist/__tests__/diagnose.test.d.ts.map +1 -0
- package/dist/__tests__/diagnose.test.js +102 -0
- package/dist/__tests__/diagnose.test.js.map +1 -0
- package/dist/__tests__/inspector.test.d.ts +2 -0
- package/dist/__tests__/inspector.test.d.ts.map +1 -0
- package/dist/__tests__/inspector.test.js +65 -0
- package/dist/__tests__/inspector.test.js.map +1 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +50 -0
- package/dist/cli.js.map +1 -0
- package/dist/diagnostics.d.ts +23 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +114 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +33 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +329 -0
- package/dist/server.js.map +1 -0
- package/dist/ui/assets/index-oTA5OCCv.js +41 -0
- package/dist/ui/index.html +15 -0
- package/dist/ui.d.ts +6 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +16 -0
- package/dist/ui.js.map +1 -0
- package/package.json +58 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# License
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2024 yumdee-Mcp-studio Contributors
|
|
6
|
+
|
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
in the Software without restriction, including without limitation the rights
|
|
10
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
furnished to do so, subject to the following conditions:
|
|
13
|
+
|
|
14
|
+
The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
copies or substantial portions of the Software.
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# @yumdee/mcp-studio-inspector
|
|
2
|
+
|
|
3
|
+
> 🔍 **Open-source Web UI Debugger, Session Replayer, and AI Diagnostic Copilot for the Model Context Protocol (MCP)**
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@yumdee/mcp-studio-inspector)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
|
|
9
|
+
Inspect, test, and debug any MCP server (Stdio, SSE, HTTP) with zero configuration. Includes dynamic schema-driven form runners, live latency timelines, regression replays, and an **AI Root-Cause Diagnostic Copilot**.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## ⚡ Quickstart (Zero Install)
|
|
14
|
+
|
|
15
|
+
Run directly in any terminal:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx @yumdee/mcp-studio-inspector
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Or specify a custom port:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npx @yumdee/mcp-studio-inspector --port 4000
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Then open **`http://localhost:3000`** in your browser!
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## ✨ Features
|
|
32
|
+
|
|
33
|
+
- **🌐 Multi-Transport Support**: Connect instantly via `stdio` subprocesses or `http`/`sse` endpoints.
|
|
34
|
+
- **⚡ 1-Click Internet Presets**: Preloaded test buttons for official MCP servers:
|
|
35
|
+
- `@modelcontextprotocol/server-everything`
|
|
36
|
+
- `@modelcontextprotocol/server-filesystem`
|
|
37
|
+
- `@modelcontextprotocol/server-memory`
|
|
38
|
+
- **🩺 AI Root-Cause Diagnostic Copilot**: Automatically diagnoses failed tool invocations, classifies boundary errors, and provides one-click **"Apply to Runner"** parameter auto-fixes.
|
|
39
|
+
- **📜 Live SSE Timeline**: Real-time server-sent event feed with round-trip latency metrics and JSON inspector.
|
|
40
|
+
- **🔁 Session Recording & Regression Replay**: Record testing workflows and diff outputs against past runs.
|
|
41
|
+
- **🎨 Warm Minimalist Design System**: Editorial aesthetic built with Fraunces serif and Plus Jakarta Sans typography, featuring dynamic light and dark theme switching.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 💻 CLI Usage
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# Start inspector with default settings (port 3000)
|
|
49
|
+
npx @yumdee/mcp-studio-inspector
|
|
50
|
+
|
|
51
|
+
# Start on custom port
|
|
52
|
+
npx @yumdee/mcp-studio-inspector --port 8080
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 📦 Programmatic Usage
|
|
58
|
+
|
|
59
|
+
You can also mount the Inspector server or React UI programmatically in your own Node.js or Vite projects:
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import { createInspector } from "@yumdee/mcp-studio-inspector";
|
|
63
|
+
|
|
64
|
+
const inspector = createInspector({ port: 3000 });
|
|
65
|
+
await inspector.start();
|
|
66
|
+
console.log("Inspector running on port 3000");
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 📄 License
|
|
72
|
+
|
|
73
|
+
MIT © [Mahesh Singh](https://github.com/maheshsingh20) & YumDee Community
|
|
74
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnose.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/diagnose.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { describe, it, expect, afterAll, beforeAll } from "vitest";
|
|
2
|
+
import { diagnoseToolFailure, createInspector } from "../server.js";
|
|
3
|
+
describe("AI Diagnostic Engine", () => {
|
|
4
|
+
const calcSchema = {
|
|
5
|
+
type: "object",
|
|
6
|
+
properties: {
|
|
7
|
+
operation: {
|
|
8
|
+
type: "string",
|
|
9
|
+
enum: ["add", "subtract", "multiply", "divide"],
|
|
10
|
+
description: "Arithmetic operation",
|
|
11
|
+
},
|
|
12
|
+
a: { type: "number", description: "First operand" },
|
|
13
|
+
b: { type: "number", description: "Second operand" },
|
|
14
|
+
},
|
|
15
|
+
required: ["operation", "a", "b"],
|
|
16
|
+
};
|
|
17
|
+
it("diagnoses missing required arguments and provides corrected payload", () => {
|
|
18
|
+
const result = diagnoseToolFailure({
|
|
19
|
+
toolName: "calculate",
|
|
20
|
+
schema: calcSchema,
|
|
21
|
+
arguments: { operation: "add", a: 15 },
|
|
22
|
+
error: "Invalid parameters: missing b",
|
|
23
|
+
});
|
|
24
|
+
expect(result.category).toBe("MISSING_REQUIRED_ARGUMENT");
|
|
25
|
+
expect(result.rootCause).toContain("requires parameter(s)");
|
|
26
|
+
expect(result.suggestedFix).toContain("b");
|
|
27
|
+
expect(result.correctedArgs).toBeDefined();
|
|
28
|
+
expect(result.correctedArgs.b).toBe(5);
|
|
29
|
+
expect(result.confidence).toBeGreaterThanOrEqual(0.95);
|
|
30
|
+
});
|
|
31
|
+
it("diagnoses arithmetic boundary errors (division by zero)", () => {
|
|
32
|
+
const result = diagnoseToolFailure({
|
|
33
|
+
toolName: "calculate",
|
|
34
|
+
schema: calcSchema,
|
|
35
|
+
arguments: { operation: "divide", a: 100, b: 0 },
|
|
36
|
+
error: "Division by zero is undefined",
|
|
37
|
+
});
|
|
38
|
+
expect(result.category).toBe("ARITHMETIC_BOUNDARY");
|
|
39
|
+
expect(result.rootCause).toContain("division by zero");
|
|
40
|
+
expect(result.suggestedFix).toContain("non-zero");
|
|
41
|
+
expect(result.correctedArgs.b).toBe(2);
|
|
42
|
+
expect(result.confidence).toBeGreaterThanOrEqual(0.98);
|
|
43
|
+
});
|
|
44
|
+
it("diagnoses type mismatches (string instead of number)", () => {
|
|
45
|
+
const result = diagnoseToolFailure({
|
|
46
|
+
toolName: "calculate",
|
|
47
|
+
schema: calcSchema,
|
|
48
|
+
arguments: { operation: "add", a: "42", b: 10 },
|
|
49
|
+
error: "Expected number for a, received string",
|
|
50
|
+
});
|
|
51
|
+
expect(result.category).toBe("TYPE_MISMATCH");
|
|
52
|
+
expect(result.rootCause).toContain("expects a numeric literal");
|
|
53
|
+
expect(result.correctedArgs.a).toBe(42);
|
|
54
|
+
expect(result.confidence).toBeGreaterThanOrEqual(0.95);
|
|
55
|
+
});
|
|
56
|
+
it("diagnoses invalid enum choices", () => {
|
|
57
|
+
const result = diagnoseToolFailure({
|
|
58
|
+
toolName: "calculate",
|
|
59
|
+
schema: calcSchema,
|
|
60
|
+
arguments: { operation: "modulo", a: 10, b: 3 },
|
|
61
|
+
error: "Unsupported operation modulo",
|
|
62
|
+
});
|
|
63
|
+
expect(result.category).toBe("INVALID_ENUM");
|
|
64
|
+
expect(result.rootCause).toContain("is not allowed");
|
|
65
|
+
expect(result.suggestedFix).toContain("add");
|
|
66
|
+
expect(result.correctedArgs.operation).toBe("add");
|
|
67
|
+
expect(result.confidence).toBeGreaterThanOrEqual(0.95);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
describe("Inspector /api/diagnose endpoint", () => {
|
|
71
|
+
let inspector;
|
|
72
|
+
const testPort = 3199;
|
|
73
|
+
beforeAll(async () => {
|
|
74
|
+
inspector = createInspector({ port: testPort, host: "localhost" });
|
|
75
|
+
await inspector.start();
|
|
76
|
+
});
|
|
77
|
+
afterAll(async () => {
|
|
78
|
+
await inspector.stop();
|
|
79
|
+
});
|
|
80
|
+
it("handles POST /api/diagnose via HTTP", async () => {
|
|
81
|
+
const res = await fetch(`http://localhost:${testPort}/api/diagnose`, {
|
|
82
|
+
method: "POST",
|
|
83
|
+
headers: { "Content-Type": "application/json" },
|
|
84
|
+
body: JSON.stringify({
|
|
85
|
+
toolName: "calculate",
|
|
86
|
+
schema: {
|
|
87
|
+
type: "object",
|
|
88
|
+
properties: { a: { type: "number" }, b: { type: "number" } },
|
|
89
|
+
required: ["a", "b"],
|
|
90
|
+
},
|
|
91
|
+
arguments: { a: 10 },
|
|
92
|
+
error: "Missing required argument 'b'",
|
|
93
|
+
}),
|
|
94
|
+
});
|
|
95
|
+
expect(res.status).toBe(200);
|
|
96
|
+
const data = await res.json();
|
|
97
|
+
expect(data.success).toBe(true);
|
|
98
|
+
expect(data.category).toBe("MISSING_REQUIRED_ARGUMENT");
|
|
99
|
+
expect(data.correctedArgs.b).toBeDefined();
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
//# sourceMappingURL=diagnose.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnose.test.js","sourceRoot":"","sources":["../../src/__tests__/diagnose.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspector.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/inspector.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { describe, it, expect, beforeAll, afterAll } from "vitest";
|
|
2
|
+
import { createInspector } from "../server.js";
|
|
3
|
+
import { InMemoryStorage } from "@yumdee/mcp-studio-core";
|
|
4
|
+
import * as path from "path";
|
|
5
|
+
describe("Inspector Server API", () => {
|
|
6
|
+
let inspector;
|
|
7
|
+
const port = 3899;
|
|
8
|
+
const baseUrl = `http://localhost:${port}`;
|
|
9
|
+
const serverPath = path.resolve(__dirname, "../../../../examples/math-server/dist/index.js");
|
|
10
|
+
beforeAll(async () => {
|
|
11
|
+
inspector = createInspector({
|
|
12
|
+
port,
|
|
13
|
+
storage: new InMemoryStorage(),
|
|
14
|
+
});
|
|
15
|
+
await inspector.start();
|
|
16
|
+
});
|
|
17
|
+
afterAll(async () => {
|
|
18
|
+
await inspector.stop();
|
|
19
|
+
});
|
|
20
|
+
it("should respond to health check", async () => {
|
|
21
|
+
const res = await fetch(baseUrl);
|
|
22
|
+
const data = await res.json();
|
|
23
|
+
expect(data.status).toBe("running");
|
|
24
|
+
});
|
|
25
|
+
it("should connect to math-server and return tools", async () => {
|
|
26
|
+
const connectRes = await fetch(`${baseUrl}/api/servers/connect`, {
|
|
27
|
+
method: "POST",
|
|
28
|
+
headers: { "Content-Type": "application/json" },
|
|
29
|
+
body: JSON.stringify({
|
|
30
|
+
transport: "stdio",
|
|
31
|
+
command: "node",
|
|
32
|
+
args: [serverPath],
|
|
33
|
+
}),
|
|
34
|
+
});
|
|
35
|
+
const connectData = await connectRes.json();
|
|
36
|
+
expect(connectRes.status).toBe(200);
|
|
37
|
+
expect(connectData.serverInfo.name).toBe("math-server");
|
|
38
|
+
expect(connectData.tools.length).toBeGreaterThan(0);
|
|
39
|
+
const sessionId = connectData.sessionId;
|
|
40
|
+
// Test invoking a tool
|
|
41
|
+
const invokeRes = await fetch(`${baseUrl}/api/servers/${sessionId}/invoke`, {
|
|
42
|
+
method: "POST",
|
|
43
|
+
headers: { "Content-Type": "application/json" },
|
|
44
|
+
body: JSON.stringify({
|
|
45
|
+
toolName: "multiply",
|
|
46
|
+
args: { a: 6, b: 7 },
|
|
47
|
+
}),
|
|
48
|
+
});
|
|
49
|
+
const invokeData = await invokeRes.json();
|
|
50
|
+
expect(invokeData.success).toBe(true);
|
|
51
|
+
expect(invokeData.result.content[0].text).toContain("42");
|
|
52
|
+
expect(invokeData.latencyMs).toBeGreaterThanOrEqual(0);
|
|
53
|
+
// Test save session
|
|
54
|
+
const saveRes = await fetch(`${baseUrl}/api/sessions/save`, {
|
|
55
|
+
method: "POST",
|
|
56
|
+
headers: { "Content-Type": "application/json" },
|
|
57
|
+
body: JSON.stringify({ sessionId }),
|
|
58
|
+
});
|
|
59
|
+
const saveData = await saveRes.json();
|
|
60
|
+
expect(saveData.success).toBe(true);
|
|
61
|
+
// Disconnect
|
|
62
|
+
await fetch(`${baseUrl}/api/servers/${sessionId}/disconnect`, { method: "POST" });
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
//# sourceMappingURL=inspector.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspector.test.js","sourceRoot":"","sources":["../../src/__tests__/inspector.test.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* MCP Studio Inspector CLI
|
|
4
|
+
*
|
|
5
|
+
* Entry point: npx mcp-studio-inspect
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* mcp-studio-inspect # Start inspector at localhost:3000
|
|
9
|
+
* mcp-studio-inspect --port 4000 # Start at custom port
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;;GAQG"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* MCP Studio Inspector CLI
|
|
4
|
+
*
|
|
5
|
+
* Entry point: npx mcp-studio-inspect
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* mcp-studio-inspect # Start inspector at localhost:3000
|
|
9
|
+
* mcp-studio-inspect --port 4000 # Start at custom port
|
|
10
|
+
*/
|
|
11
|
+
import * as path from "path";
|
|
12
|
+
import { fileURLToPath } from "url";
|
|
13
|
+
import { createInspector } from "./server.js";
|
|
14
|
+
async function main() {
|
|
15
|
+
const args = process.argv.slice(2);
|
|
16
|
+
let port = 3000;
|
|
17
|
+
const portFlagIdx = args.indexOf("--port");
|
|
18
|
+
if (portFlagIdx !== -1 && args[portFlagIdx + 1]) {
|
|
19
|
+
port = parseInt(args[portFlagIdx + 1], 10) || 3000;
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
const eqMatch = args.find((a) => a.startsWith("--port="));
|
|
23
|
+
if (eqMatch) {
|
|
24
|
+
port = parseInt(eqMatch.split("=")[1], 10) || 3000;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
let staticDir;
|
|
28
|
+
try {
|
|
29
|
+
const currentDir = path.dirname(fileURLToPath(import.meta.url));
|
|
30
|
+
staticDir = path.resolve(currentDir, "../dist/ui");
|
|
31
|
+
}
|
|
32
|
+
catch { }
|
|
33
|
+
const inspector = createInspector({ port, staticDir });
|
|
34
|
+
try {
|
|
35
|
+
await inspector.start();
|
|
36
|
+
console.log(`\n🔍 MCP Studio Inspector running at http://localhost:${port}`);
|
|
37
|
+
console.log(" Open in your browser to debug and replay MCP servers.\n");
|
|
38
|
+
process.on("SIGINT", async () => {
|
|
39
|
+
console.log("\n✋ Shutting down inspector server...");
|
|
40
|
+
await inspector.stop();
|
|
41
|
+
process.exit(0);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
console.error("Failed to start inspector:", err);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
main();
|
|
50
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;;GAQG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,IAAI,GAAG,IAAI,CAAC;IAEhB,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC3C,IAAI,WAAW,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,EAAE,CAAC;QAChD,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC;IACrD,CAAC;SAAM,CAAC;QACN,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;QAC1D,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC;QACrD,CAAC;IACH,CAAC;IAED,IAAI,SAA6B,CAAC;IAClC,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAChE,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAEV,MAAM,SAAS,GAAG,eAAe,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;IAEvD,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,yDAAyD,IAAI,EAAE,CAAC,CAAC;QAC7E,OAAO,CAAC,GAAG,CAAC,4DAA4D,CAAC,CAAC;QAE1E,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;YAC9B,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;YACrD,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;YACvB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,GAAG,CAAC,CAAC;QACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @yumdee/mcp-studio-inspector - AI Diagnostic Engine
|
|
3
|
+
*
|
|
4
|
+
* Automated Root-Cause Analysis (RCA) and patch synthesis for failed MCP tool executions.
|
|
5
|
+
* Classifies runtime errors, schema boundary violations, and missing parameters.
|
|
6
|
+
*/
|
|
7
|
+
export type DiagnosticCategory = "MISSING_REQUIRED_ARGUMENT" | "TYPE_MISMATCH" | "ARITHMETIC_BOUNDARY" | "INVALID_ENUM" | "INVALID_JSON" | "SERVER_RUNTIME_ERROR";
|
|
8
|
+
export interface DiagnosticRequest {
|
|
9
|
+
toolName?: string;
|
|
10
|
+
schema?: any;
|
|
11
|
+
arguments?: any;
|
|
12
|
+
error?: string;
|
|
13
|
+
logs?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface DiagnosticResult {
|
|
16
|
+
rootCause: string;
|
|
17
|
+
category: DiagnosticCategory;
|
|
18
|
+
suggestedFix: string;
|
|
19
|
+
correctedArgs?: any;
|
|
20
|
+
confidence: number;
|
|
21
|
+
}
|
|
22
|
+
export declare function diagnoseToolFailure(req: DiagnosticRequest): DiagnosticResult;
|
|
23
|
+
//# sourceMappingURL=diagnostics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,kBAAkB,GAC1B,2BAA2B,GAC3B,eAAe,GACf,qBAAqB,GACrB,cAAc,GACd,cAAc,GACd,sBAAsB,CAAC;AAE3B,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,SAAS,CAAC,EAAE,GAAG,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,GAAG,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,iBAAiB,GAAG,gBAAgB,CAiH5E"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @yumdee/mcp-studio-inspector - AI Diagnostic Engine
|
|
3
|
+
*
|
|
4
|
+
* Automated Root-Cause Analysis (RCA) and patch synthesis for failed MCP tool executions.
|
|
5
|
+
* Classifies runtime errors, schema boundary violations, and missing parameters.
|
|
6
|
+
*/
|
|
7
|
+
export function diagnoseToolFailure(req) {
|
|
8
|
+
const { toolName, schema, error = "" } = req;
|
|
9
|
+
const args = typeof req.arguments === "object" && req.arguments !== null ? { ...req.arguments } : {};
|
|
10
|
+
const errorLower = error.toLowerCase();
|
|
11
|
+
// 1. Check for Arithmetic / Mathematical Boundary Violations (e.g. division by zero)
|
|
12
|
+
if (errorLower.includes("divide by zero") ||
|
|
13
|
+
errorLower.includes("division by zero") ||
|
|
14
|
+
(args.operation === "divide" && (args.b === 0 || args.b === "0"))) {
|
|
15
|
+
return {
|
|
16
|
+
category: "ARITHMETIC_BOUNDARY",
|
|
17
|
+
rootCause: "Attempted division by zero, which is mathematically undefined and caused the calculator to reject the call.",
|
|
18
|
+
suggestedFix: "Change the denominator parameter 'b' to a non-zero numeric value (e.g. 1 or 2).",
|
|
19
|
+
correctedArgs: { ...args, b: 2 },
|
|
20
|
+
confidence: 0.99,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
// 2. Check Schema Required Fields
|
|
24
|
+
if (schema && typeof schema === "object") {
|
|
25
|
+
const required = Array.isArray(schema.required) ? schema.required : [];
|
|
26
|
+
const missing = required.filter((key) => args[key] === undefined || args[key] === null || args[key] === "");
|
|
27
|
+
if (missing.length > 0) {
|
|
28
|
+
const firstMissing = missing[0];
|
|
29
|
+
const prop = schema.properties?.[firstMissing] || {};
|
|
30
|
+
const expectedType = prop.type || "string";
|
|
31
|
+
let sampleVal = "example";
|
|
32
|
+
if (expectedType === "number" || expectedType === "integer")
|
|
33
|
+
sampleVal = 10;
|
|
34
|
+
else if (expectedType === "boolean")
|
|
35
|
+
sampleVal = true;
|
|
36
|
+
else if (expectedType === "array")
|
|
37
|
+
sampleVal = [];
|
|
38
|
+
else if (expectedType === "object")
|
|
39
|
+
sampleVal = {};
|
|
40
|
+
const corrected = { ...args };
|
|
41
|
+
for (const m of missing) {
|
|
42
|
+
const mType = schema.properties?.[m]?.type || "string";
|
|
43
|
+
corrected[m] = mType === "number" ? 5 : mType === "boolean" ? true : "example";
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
category: "MISSING_REQUIRED_ARGUMENT",
|
|
47
|
+
rootCause: `The tool '${toolName || "invoked"}' requires parameter(s) [${missing.join(", ")}], but '${firstMissing}' was omitted from the payload.`,
|
|
48
|
+
suggestedFix: `Add '${firstMissing}' (${expectedType}) to the arguments payload.`,
|
|
49
|
+
correctedArgs: corrected,
|
|
50
|
+
confidence: 0.98,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
// 3. Check for Type Mismatches
|
|
54
|
+
if (schema.properties && typeof schema.properties === "object") {
|
|
55
|
+
for (const [key, prop] of Object.entries(schema.properties)) {
|
|
56
|
+
if (args[key] !== undefined && prop?.type) {
|
|
57
|
+
const val = args[key];
|
|
58
|
+
if (prop.type === "number" && typeof val === "string") {
|
|
59
|
+
const parsed = Number(val);
|
|
60
|
+
if (!isNaN(parsed)) {
|
|
61
|
+
return {
|
|
62
|
+
category: "TYPE_MISMATCH",
|
|
63
|
+
rootCause: `Parameter '${key}' was provided as a string ("${val}"), but the schema expects a numeric literal.`,
|
|
64
|
+
suggestedFix: `Convert '${key}' to a raw number without quotation marks.`,
|
|
65
|
+
correctedArgs: { ...args, [key]: parsed },
|
|
66
|
+
confidence: 0.96,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else if (prop.type === "string" && typeof val === "number") {
|
|
71
|
+
return {
|
|
72
|
+
category: "TYPE_MISMATCH",
|
|
73
|
+
rootCause: `Parameter '${key}' was provided as a number (${val}), but the schema expects a string.`,
|
|
74
|
+
suggestedFix: `Enclose '${key}' in double quotation marks as a string literal.`,
|
|
75
|
+
correctedArgs: { ...args, [key]: String(val) },
|
|
76
|
+
confidence: 0.95,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
// 4. Check for Enum Violations
|
|
80
|
+
if (Array.isArray(prop.enum) && prop.enum.length > 0) {
|
|
81
|
+
if (!prop.enum.includes(val)) {
|
|
82
|
+
return {
|
|
83
|
+
category: "INVALID_ENUM",
|
|
84
|
+
rootCause: `Parameter '${key}' value "${val}" is not allowed. Valid options are: [${prop.enum.join(", ")}].`,
|
|
85
|
+
suggestedFix: `Change '${key}' to one of the accepted enum choices: ${prop.enum.join(", ")}.`,
|
|
86
|
+
correctedArgs: { ...args, [key]: prop.enum[0] },
|
|
87
|
+
confidence: 0.97,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// 5. Check for JSON syntax or parsing failure
|
|
96
|
+
if (errorLower.includes("json") || errorLower.includes("syntax") || errorLower.includes("parse")) {
|
|
97
|
+
return {
|
|
98
|
+
category: "INVALID_JSON",
|
|
99
|
+
rootCause: "The arguments payload contains malformed JSON syntax.",
|
|
100
|
+
suggestedFix: "Verify that all keys and strings are enclosed in double quotes and commas are properly positioned.",
|
|
101
|
+
correctedArgs: args,
|
|
102
|
+
confidence: 0.92,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
// 6. Generic Server Runtime Error
|
|
106
|
+
return {
|
|
107
|
+
category: "SERVER_RUNTIME_ERROR",
|
|
108
|
+
rootCause: error || `Tool '${toolName || "unknown"}' failed execution with an unhandled exception.`,
|
|
109
|
+
suggestedFix: "Inspect the server standard error (stderr) logs and confirm underlying services or database connections are active.",
|
|
110
|
+
correctedArgs: args,
|
|
111
|
+
confidence: 0.82,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=diagnostics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @yumdee/mcp-studio-inspector
|
|
3
|
+
*
|
|
4
|
+
* Web UI debugger for MCP servers with session recording and replay.
|
|
5
|
+
*
|
|
6
|
+
* Exports:
|
|
7
|
+
* - Inspector class - main server
|
|
8
|
+
* - createInspector() - factory function
|
|
9
|
+
* - InspectorConfig - configuration interface
|
|
10
|
+
*/
|
|
11
|
+
export { Inspector, createInspector, type InspectorConfig } from "./server.js";
|
|
12
|
+
export { InspectorUI, type InspectorUIProps } from "./ui.js";
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAC/E,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @yumdee/mcp-studio-inspector
|
|
3
|
+
*
|
|
4
|
+
* Web UI debugger for MCP servers with session recording and replay.
|
|
5
|
+
*
|
|
6
|
+
* Exports:
|
|
7
|
+
* - Inspector class - main server
|
|
8
|
+
* - createInspector() - factory function
|
|
9
|
+
* - InspectorConfig - configuration interface
|
|
10
|
+
*/
|
|
11
|
+
export { Inspector, createInspector } from "./server.js";
|
|
12
|
+
export { InspectorUI } from "./ui.js";
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,SAAS,EAAE,eAAe,EAAwB,MAAM,aAAa,CAAC;AAC/E,OAAO,EAAE,WAAW,EAAyB,MAAM,SAAS,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Studio Inspector - Web UI & API Server
|
|
3
|
+
*
|
|
4
|
+
* Runs a local HTTP server with REST APIs and SSE streaming for live server inspection,
|
|
5
|
+
* tool invocation, session recording, and session replay.
|
|
6
|
+
*/
|
|
7
|
+
import { SessionStorage } from "@yumdee/mcp-studio-core";
|
|
8
|
+
import { diagnoseToolFailure, DiagnosticRequest, DiagnosticResult, DiagnosticCategory } from "./diagnostics.js";
|
|
9
|
+
export { diagnoseToolFailure, DiagnosticRequest, DiagnosticResult, DiagnosticCategory, };
|
|
10
|
+
export interface InspectorConfig {
|
|
11
|
+
port: number;
|
|
12
|
+
host?: string;
|
|
13
|
+
storage?: SessionStorage;
|
|
14
|
+
staticDir?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare class Inspector {
|
|
17
|
+
private port;
|
|
18
|
+
private host;
|
|
19
|
+
private storage;
|
|
20
|
+
private staticDir?;
|
|
21
|
+
private server?;
|
|
22
|
+
private activeClients;
|
|
23
|
+
private sseClients;
|
|
24
|
+
constructor(config: InspectorConfig);
|
|
25
|
+
private setCorsHeaders;
|
|
26
|
+
private sendJson;
|
|
27
|
+
private broadcastEvent;
|
|
28
|
+
private parseBody;
|
|
29
|
+
start(): Promise<void>;
|
|
30
|
+
stop(): Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
export declare function createInspector(config: InspectorConfig): Inspector;
|
|
33
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EAEL,cAAc,EAMf,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,GACnB,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAC,CAAc;IAC7B,OAAO,CAAC,aAAa,CAAqC;IAC1D,OAAO,CAAC,UAAU,CAAuC;gBAE7C,MAAM,EAAE,eAAe;IAOnC,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,cAAc;YAWR,SAAS;IAiBjB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAuRtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAmB5B;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,CAElE"}
|