@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/dist/server.js ADDED
@@ -0,0 +1,329 @@
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 http from "http";
8
+ import fs from "fs";
9
+ import path from "path";
10
+ import { createStdioClient, createHttpClient, createJsonStorage, } from "@yumdee/mcp-studio-core";
11
+ import { diagnoseToolFailure, } from "./diagnostics.js";
12
+ export { diagnoseToolFailure, };
13
+ export class Inspector {
14
+ constructor(config) {
15
+ this.activeClients = new Map();
16
+ this.sseClients = new Set();
17
+ this.port = config.port;
18
+ this.host = config.host || "localhost";
19
+ this.storage = config.storage || createJsonStorage();
20
+ this.staticDir = config.staticDir;
21
+ }
22
+ setCorsHeaders(res) {
23
+ res.setHeader("Access-Control-Allow-Origin", "*");
24
+ res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
25
+ res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
26
+ }
27
+ sendJson(res, status, data) {
28
+ this.setCorsHeaders(res);
29
+ res.writeHead(status, { "Content-Type": "application/json" });
30
+ res.end(JSON.stringify(data));
31
+ }
32
+ broadcastEvent(event, sessionId) {
33
+ const payload = `data: ${JSON.stringify({ sessionId, event })}\n\n`;
34
+ for (const client of this.sseClients) {
35
+ try {
36
+ client.write(payload);
37
+ }
38
+ catch {
39
+ this.sseClients.delete(client);
40
+ }
41
+ }
42
+ }
43
+ async parseBody(req) {
44
+ return new Promise((resolve, reject) => {
45
+ let body = "";
46
+ req.on("data", (chunk) => {
47
+ body += chunk;
48
+ });
49
+ req.on("end", () => {
50
+ try {
51
+ resolve(body ? JSON.parse(body) : {});
52
+ }
53
+ catch (err) {
54
+ reject(new Error("Invalid JSON body"));
55
+ }
56
+ });
57
+ req.on("error", reject);
58
+ });
59
+ }
60
+ async start() {
61
+ return new Promise((resolve) => {
62
+ this.server = http.createServer(async (req, res) => {
63
+ this.setCorsHeaders(res);
64
+ if (req.method === "OPTIONS") {
65
+ res.writeHead(204);
66
+ res.end();
67
+ return;
68
+ }
69
+ const url = new URL(req.url || "/", `http://${this.host}:${this.port}`);
70
+ const pathname = url.pathname;
71
+ try {
72
+ // SSE Live Event Stream
73
+ if (pathname === "/api/events/stream") {
74
+ res.writeHead(200, {
75
+ "Content-Type": "text/event-stream",
76
+ "Cache-Control": "no-cache",
77
+ Connection: "keep-alive",
78
+ });
79
+ res.write(`data: {"type":"connected"}\n\n`);
80
+ this.sseClients.add(res);
81
+ req.on("close", () => {
82
+ this.sseClients.delete(res);
83
+ });
84
+ return;
85
+ }
86
+ // POST /api/servers/connect
87
+ if (pathname === "/api/servers/connect" && req.method === "POST") {
88
+ const body = await this.parseBody(req);
89
+ const { transport, command, args, url: remoteUrl, env } = body;
90
+ let client;
91
+ if (transport === "http" || transport === "sse") {
92
+ client = createHttpClient(remoteUrl);
93
+ }
94
+ else {
95
+ client = createStdioClient(command, args || [], env);
96
+ }
97
+ // Hook into notifications and events
98
+ client.onNotification((method, params) => {
99
+ const session = client.getSession();
100
+ const latestEvent = session.events[session.events.length - 1];
101
+ if (latestEvent) {
102
+ this.broadcastEvent(latestEvent, session.id);
103
+ }
104
+ });
105
+ const serverInfo = await client.connect();
106
+ const session = client.getSession();
107
+ const sessionId = session.id;
108
+ this.activeClients.set(sessionId, client);
109
+ const tools = client.getTools();
110
+ const resources = client.getResources();
111
+ const prompts = client.getPrompts();
112
+ return this.sendJson(res, 200, {
113
+ sessionId,
114
+ serverInfo,
115
+ tools,
116
+ resources,
117
+ prompts,
118
+ session,
119
+ });
120
+ }
121
+ // POST /api/servers/:id/disconnect
122
+ const disconnectMatch = pathname.match(/^\/api\/servers\/([^/]+)\/disconnect$/);
123
+ if (disconnectMatch && req.method === "POST") {
124
+ const sessionId = disconnectMatch[1];
125
+ const client = this.activeClients.get(sessionId);
126
+ if (client) {
127
+ await client.disconnect();
128
+ this.activeClients.delete(sessionId);
129
+ }
130
+ return this.sendJson(res, 200, { success: true });
131
+ }
132
+ // GET /api/servers/:id/tools
133
+ const toolsMatch = pathname.match(/^\/api\/servers\/([^/]+)\/tools$/);
134
+ if (toolsMatch && req.method === "GET") {
135
+ const sessionId = toolsMatch[1];
136
+ const client = this.activeClients.get(sessionId);
137
+ if (!client)
138
+ return this.sendJson(res, 404, { error: "Session not found" });
139
+ return this.sendJson(res, 200, { tools: client.getTools() });
140
+ }
141
+ // POST /api/servers/:id/invoke
142
+ const invokeMatch = pathname.match(/^\/api\/servers\/([^/]+)\/invoke$/);
143
+ if (invokeMatch && req.method === "POST") {
144
+ const sessionId = invokeMatch[1];
145
+ const client = this.activeClients.get(sessionId);
146
+ if (!client)
147
+ return this.sendJson(res, 404, { error: "Session not found" });
148
+ const body = await this.parseBody(req);
149
+ const { toolName, args } = body;
150
+ const startTime = Date.now();
151
+ let result;
152
+ let error;
153
+ try {
154
+ result = await client.call("tools/call", {
155
+ name: toolName,
156
+ arguments: args || {},
157
+ });
158
+ }
159
+ catch (err) {
160
+ error = err.message || String(err);
161
+ }
162
+ const latencyMs = Date.now() - startTime;
163
+ const session = client.getSession();
164
+ const latestEvent = session.events[session.events.length - 1];
165
+ if (latestEvent) {
166
+ this.broadcastEvent(latestEvent, sessionId);
167
+ }
168
+ return this.sendJson(res, 200, {
169
+ success: !error,
170
+ result,
171
+ error,
172
+ latencyMs,
173
+ session,
174
+ });
175
+ }
176
+ // GET /api/servers/:id/session
177
+ const sessionMatch = pathname.match(/^\/api\/servers\/([^/]+)\/session$/);
178
+ if (sessionMatch && req.method === "GET") {
179
+ const sessionId = sessionMatch[1];
180
+ const client = this.activeClients.get(sessionId);
181
+ if (!client)
182
+ return this.sendJson(res, 404, { error: "Session not found" });
183
+ return this.sendJson(res, 200, client.getSession());
184
+ }
185
+ // POST /api/sessions/save
186
+ if (pathname === "/api/sessions/save" && req.method === "POST") {
187
+ const body = await this.parseBody(req);
188
+ const { sessionId } = body;
189
+ const client = this.activeClients.get(sessionId);
190
+ if (!client)
191
+ return this.sendJson(res, 404, { error: "Session not found" });
192
+ const session = client.getSession();
193
+ const savedId = await this.storage.save(session);
194
+ return this.sendJson(res, 200, { success: true, savedId });
195
+ }
196
+ // GET /api/sessions
197
+ if (pathname === "/api/sessions" && req.method === "GET") {
198
+ const sessions = await this.storage.list();
199
+ return this.sendJson(res, 200, { sessions });
200
+ }
201
+ // GET /api/sessions/:id
202
+ const loadMatch = pathname.match(/^\/api\/sessions\/([^/]+)$/);
203
+ if (loadMatch && req.method === "GET") {
204
+ const id = loadMatch[1];
205
+ const session = await this.storage.load(id);
206
+ return this.sendJson(res, 200, session);
207
+ }
208
+ // POST /api/sessions/:id/replay
209
+ const replayMatch = pathname.match(/^\/api\/sessions\/([^/]+)\/replay$/);
210
+ if (replayMatch && req.method === "POST") {
211
+ const id = replayMatch[1];
212
+ const body = await this.parseBody(req);
213
+ const targetSessionId = body.targetSessionId;
214
+ const targetClient = this.activeClients.get(targetSessionId);
215
+ if (!targetClient) {
216
+ return this.sendJson(res, 400, { error: "No active connected server to replay against" });
217
+ }
218
+ const originalSession = await this.storage.load(id);
219
+ const toolCallRequests = originalSession.events.filter((e) => e.type === "request" && (e.method === "tools/call" || e.method?.startsWith("tools/call/")));
220
+ const replayResults = [];
221
+ for (const reqEvent of toolCallRequests) {
222
+ const req = reqEvent;
223
+ const params = req.params || {};
224
+ const toolName = req.method?.startsWith("tools/call/")
225
+ ? req.method.split("/").pop()
226
+ : params.name;
227
+ const args = params.arguments || params;
228
+ const originalResponse = originalSession.events.find((e) => e.type === "response" && e.id === req.id);
229
+ const startMs = Date.now();
230
+ let newResult;
231
+ let newError;
232
+ try {
233
+ newResult = await targetClient.call("tools/call", {
234
+ name: toolName,
235
+ arguments: args,
236
+ });
237
+ }
238
+ catch (err) {
239
+ newError = err.message || String(err);
240
+ }
241
+ const replayedLatencyMs = Date.now() - startMs;
242
+ replayResults.push({
243
+ toolName,
244
+ args,
245
+ originalResponse: originalResponse ? originalResponse.result : null,
246
+ originalLatencyMs: originalResponse ? originalResponse.latencyMs : 0,
247
+ replayedResponse: newResult,
248
+ replayedError: newError,
249
+ replayedLatencyMs,
250
+ matched: JSON.stringify(originalResponse ? originalResponse.result : null) === JSON.stringify(newResult),
251
+ });
252
+ }
253
+ return this.sendJson(res, 200, {
254
+ success: true,
255
+ totalCalls: toolCallRequests.length,
256
+ replays: replayResults,
257
+ });
258
+ }
259
+ // POST /api/diagnose - AI Root Cause Diagnostic & Auto-Fix Copilot
260
+ if (pathname === "/api/diagnose" && req.method === "POST") {
261
+ const body = await this.parseBody(req);
262
+ const diagnostic = diagnoseToolFailure(body);
263
+ return this.sendJson(res, 200, {
264
+ success: true,
265
+ ...diagnostic,
266
+ });
267
+ }
268
+ // Static UI Serving fallback
269
+ if (this.staticDir && fs.existsSync(this.staticDir)) {
270
+ let filePath = path.join(this.staticDir, pathname === "/" ? "index.html" : pathname);
271
+ if (!fs.existsSync(filePath)) {
272
+ filePath = path.join(this.staticDir, "index.html");
273
+ }
274
+ const ext = path.extname(filePath);
275
+ const contentTypes = {
276
+ ".html": "text/html",
277
+ ".js": "application/javascript",
278
+ ".css": "text/css",
279
+ ".json": "application/json",
280
+ ".svg": "image/svg+xml",
281
+ ".png": "image/png",
282
+ };
283
+ const contentType = contentTypes[ext] || "text/plain";
284
+ const content = fs.readFileSync(filePath);
285
+ res.writeHead(200, { "Content-Type": contentType });
286
+ res.end(content);
287
+ return;
288
+ }
289
+ // Health / fallback
290
+ return this.sendJson(res, 200, {
291
+ name: "yumdee-mcp-studio-inspector",
292
+ status: "running",
293
+ version: "0.1.0",
294
+ });
295
+ }
296
+ catch (err) {
297
+ console.error("Inspector API Error:", err);
298
+ return this.sendJson(res, 500, { error: err.message || "Internal Server Error" });
299
+ }
300
+ });
301
+ this.server.listen(this.port, this.host, () => {
302
+ console.log(`⚡ MCP Studio Inspector server running at http://${this.host}:${this.port}`);
303
+ resolve();
304
+ });
305
+ });
306
+ }
307
+ async stop() {
308
+ for (const client of this.activeClients.values()) {
309
+ await client.disconnect().catch(() => { });
310
+ }
311
+ this.activeClients.clear();
312
+ for (const res of this.sseClients) {
313
+ res.end();
314
+ }
315
+ this.sseClients.clear();
316
+ return new Promise((resolve) => {
317
+ if (this.server) {
318
+ this.server.close(() => resolve());
319
+ }
320
+ else {
321
+ resolve();
322
+ }
323
+ });
324
+ }
325
+ }
326
+ export function createInspector(config) {
327
+ return new Inspector(config);
328
+ }
329
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}