@mcpjam/inspector 0.2.3 → 0.2.4
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/client/bin/start.js +28 -4
- package/client/dist/assets/{OAuthCallback-CfsBsNUt.js → OAuthCallback-DkLMDxkx.js} +1 -1
- package/client/dist/assets/{OAuthDebugCallback-DuorYCq_.js → OAuthDebugCallback-DaNmVTKt.js} +1 -1
- package/client/dist/assets/{index-CHsLKjnG.js → index-CLxTHffA.js} +1469 -279
- package/client/dist/assets/{index-C5Ywrn22.css → index-ebsMqCvj.css} +31 -0
- package/client/dist/index.html +2 -2
- package/package.json +1 -1
- package/server/build/index.js +25 -35
|
@@ -1282,12 +1282,18 @@ video {
|
|
|
1282
1282
|
.max-h-\[300px\] {
|
|
1283
1283
|
max-height: 300px;
|
|
1284
1284
|
}
|
|
1285
|
+
.max-h-\[90vh\] {
|
|
1286
|
+
max-height: 90vh;
|
|
1287
|
+
}
|
|
1285
1288
|
.max-h-screen {
|
|
1286
1289
|
max-height: 100vh;
|
|
1287
1290
|
}
|
|
1288
1291
|
.min-h-0 {
|
|
1289
1292
|
min-height: 0px;
|
|
1290
1293
|
}
|
|
1294
|
+
.min-h-\[200px\] {
|
|
1295
|
+
min-height: 200px;
|
|
1296
|
+
}
|
|
1291
1297
|
.min-h-\[48px\] {
|
|
1292
1298
|
min-height: 48px;
|
|
1293
1299
|
}
|
|
@@ -1379,6 +1385,9 @@ video {
|
|
|
1379
1385
|
.max-w-4xl {
|
|
1380
1386
|
max-width: 56rem;
|
|
1381
1387
|
}
|
|
1388
|
+
.max-w-6xl {
|
|
1389
|
+
max-width: 72rem;
|
|
1390
|
+
}
|
|
1382
1391
|
.max-w-\[75\%\] {
|
|
1383
1392
|
max-width: 75%;
|
|
1384
1393
|
}
|
|
@@ -1689,6 +1698,9 @@ video {
|
|
|
1689
1698
|
.border-border\/50 {
|
|
1690
1699
|
border-color: hsl(var(--border) / 0.5);
|
|
1691
1700
|
}
|
|
1701
|
+
.border-current {
|
|
1702
|
+
border-color: currentColor;
|
|
1703
|
+
}
|
|
1692
1704
|
.border-destructive {
|
|
1693
1705
|
border-color: hsl(var(--destructive));
|
|
1694
1706
|
}
|
|
@@ -1720,6 +1732,9 @@ video {
|
|
|
1720
1732
|
.border-primary {
|
|
1721
1733
|
border-color: hsl(var(--primary));
|
|
1722
1734
|
}
|
|
1735
|
+
.border-primary\/20 {
|
|
1736
|
+
border-color: hsl(var(--primary) / 0.2);
|
|
1737
|
+
}
|
|
1723
1738
|
.border-red-200 {
|
|
1724
1739
|
--tw-border-opacity: 1;
|
|
1725
1740
|
border-color: rgb(254 202 202 / var(--tw-border-opacity, 1));
|
|
@@ -1809,6 +1824,10 @@ video {
|
|
|
1809
1824
|
.bg-green-50\/80 {
|
|
1810
1825
|
background-color: rgb(240 253 244 / 0.8);
|
|
1811
1826
|
}
|
|
1827
|
+
.bg-green-500 {
|
|
1828
|
+
--tw-bg-opacity: 1;
|
|
1829
|
+
background-color: rgb(34 197 94 / var(--tw-bg-opacity, 1));
|
|
1830
|
+
}
|
|
1812
1831
|
.bg-muted {
|
|
1813
1832
|
background-color: hsl(var(--muted));
|
|
1814
1833
|
}
|
|
@@ -1905,6 +1924,11 @@ video {
|
|
|
1905
1924
|
--tw-gradient-to: rgb(37 99 235 / 0) var(--tw-gradient-to-position);
|
|
1906
1925
|
--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
|
|
1907
1926
|
}
|
|
1927
|
+
.from-card\/80 {
|
|
1928
|
+
--tw-gradient-from: hsl(var(--card) / 0.8) var(--tw-gradient-from-position);
|
|
1929
|
+
--tw-gradient-to: hsl(var(--card) / 0) var(--tw-gradient-to-position);
|
|
1930
|
+
--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
|
|
1931
|
+
}
|
|
1908
1932
|
.from-card\/95 {
|
|
1909
1933
|
--tw-gradient-from: hsl(var(--card) / 0.95) var(--tw-gradient-from-position);
|
|
1910
1934
|
--tw-gradient-to: hsl(var(--card) / 0) var(--tw-gradient-to-position);
|
|
@@ -1986,6 +2010,9 @@ video {
|
|
|
1986
2010
|
.to-blue-700 {
|
|
1987
2011
|
--tw-gradient-to: #1d4ed8 var(--tw-gradient-to-position);
|
|
1988
2012
|
}
|
|
2013
|
+
.to-card\/60 {
|
|
2014
|
+
--tw-gradient-to: hsl(var(--card) / 0.6) var(--tw-gradient-to-position);
|
|
2015
|
+
}
|
|
1989
2016
|
.to-card\/95 {
|
|
1990
2017
|
--tw-gradient-to: hsl(var(--card) / 0.95) var(--tw-gradient-to-position);
|
|
1991
2018
|
}
|
|
@@ -2709,6 +2736,10 @@ h1 {
|
|
|
2709
2736
|
background-color: hsl(var(--muted));
|
|
2710
2737
|
}
|
|
2711
2738
|
|
|
2739
|
+
.hover\:bg-muted-foreground\/10:hover {
|
|
2740
|
+
background-color: hsl(var(--muted-foreground) / 0.1);
|
|
2741
|
+
}
|
|
2742
|
+
|
|
2712
2743
|
.hover\:bg-muted\/30:hover {
|
|
2713
2744
|
background-color: hsl(var(--muted) / 0.3);
|
|
2714
2745
|
}
|
package/client/dist/index.html
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/mcp_jam.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>MCPJam Inspector</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-CLxTHffA.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-ebsMqCvj.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<div id="root"></div>
|
package/package.json
CHANGED
package/server/build/index.js
CHANGED
|
@@ -38,7 +38,6 @@ app.use((req, res, next) => {
|
|
|
38
38
|
const webAppTransports = new Map(); // Transports by sessionId
|
|
39
39
|
const createTransport = async (req) => {
|
|
40
40
|
const query = req.query;
|
|
41
|
-
console.log("Query parameters:", query);
|
|
42
41
|
const transportType = query.transportType;
|
|
43
42
|
if (transportType === "stdio") {
|
|
44
43
|
const command = query.command;
|
|
@@ -46,7 +45,7 @@ const createTransport = async (req) => {
|
|
|
46
45
|
const queryEnv = query.env ? JSON.parse(query.env) : {};
|
|
47
46
|
const env = { ...process.env, ...defaultEnvironment, ...queryEnv };
|
|
48
47
|
const { cmd, args } = findActualExecutable(command, origArgs);
|
|
49
|
-
console.log(
|
|
48
|
+
console.log(`🚀 Stdio transport: command=${cmd}, args=${args}`);
|
|
50
49
|
const transport = new StdioClientTransport({
|
|
51
50
|
command: cmd,
|
|
52
51
|
args,
|
|
@@ -54,7 +53,6 @@ const createTransport = async (req) => {
|
|
|
54
53
|
stderr: "pipe",
|
|
55
54
|
});
|
|
56
55
|
await transport.start();
|
|
57
|
-
console.log("Spawned stdio transport");
|
|
58
56
|
return transport;
|
|
59
57
|
}
|
|
60
58
|
else if (transportType === "sse") {
|
|
@@ -69,7 +67,6 @@ const createTransport = async (req) => {
|
|
|
69
67
|
const value = req.headers[key];
|
|
70
68
|
headers[key] = Array.isArray(value) ? value[value.length - 1] : value;
|
|
71
69
|
}
|
|
72
|
-
console.log(`SSE transport: url=${url}, headers=${Object.keys(headers)}`);
|
|
73
70
|
const transport = new SSEClientTransport(new URL(url), {
|
|
74
71
|
eventSourceInit: {
|
|
75
72
|
fetch: (url, init) => fetch(url, { ...init, headers }),
|
|
@@ -79,7 +76,6 @@ const createTransport = async (req) => {
|
|
|
79
76
|
},
|
|
80
77
|
});
|
|
81
78
|
await transport.start();
|
|
82
|
-
console.log("Connected to SSE transport");
|
|
83
79
|
return transport;
|
|
84
80
|
}
|
|
85
81
|
else if (transportType === "streamable-http") {
|
|
@@ -99,18 +95,17 @@ const createTransport = async (req) => {
|
|
|
99
95
|
},
|
|
100
96
|
});
|
|
101
97
|
await transport.start();
|
|
102
|
-
console.log("Connected to Streamable HTTP transport");
|
|
103
98
|
return transport;
|
|
104
99
|
}
|
|
105
100
|
else {
|
|
106
|
-
console.error(
|
|
101
|
+
console.error(`❌ Invalid transport type: ${transportType}`);
|
|
107
102
|
throw new Error("Invalid transport type specified");
|
|
108
103
|
}
|
|
109
104
|
};
|
|
110
105
|
let backingServerTransport;
|
|
111
106
|
app.get("/mcp", async (req, res) => {
|
|
112
107
|
const sessionId = req.headers["mcp-session-id"];
|
|
113
|
-
console.log(
|
|
108
|
+
console.log(`📥 Received GET message for sessionId ${sessionId}`);
|
|
114
109
|
try {
|
|
115
110
|
const transport = webAppTransports.get(sessionId);
|
|
116
111
|
if (!transport) {
|
|
@@ -122,34 +117,34 @@ app.get("/mcp", async (req, res) => {
|
|
|
122
117
|
}
|
|
123
118
|
}
|
|
124
119
|
catch (error) {
|
|
125
|
-
console.error("Error in /mcp route:", error);
|
|
120
|
+
console.error("❌ Error in /mcp route:", error);
|
|
126
121
|
res.status(500).json(error);
|
|
127
122
|
}
|
|
128
123
|
});
|
|
129
124
|
app.post("/mcp", async (req, res) => {
|
|
130
125
|
const sessionId = req.headers["mcp-session-id"];
|
|
131
|
-
console.log(
|
|
126
|
+
console.log(`📥 Received POST message for sessionId ${sessionId}`);
|
|
132
127
|
if (!sessionId) {
|
|
133
128
|
try {
|
|
134
|
-
console.log("New streamable-http connection");
|
|
129
|
+
console.log("🔄 New streamable-http connection");
|
|
135
130
|
try {
|
|
136
131
|
await backingServerTransport?.close();
|
|
137
132
|
backingServerTransport = await createTransport(req);
|
|
138
133
|
}
|
|
139
134
|
catch (error) {
|
|
140
135
|
if (error instanceof SseError && error.code === 401) {
|
|
141
|
-
console.error("Received 401 Unauthorized from MCP server:", error.message);
|
|
136
|
+
console.error("🔒 Received 401 Unauthorized from MCP server:", error.message);
|
|
142
137
|
res.status(401).json(error);
|
|
143
138
|
return;
|
|
144
139
|
}
|
|
145
140
|
throw error;
|
|
146
141
|
}
|
|
147
|
-
console.log("Connected MCP client to backing server transport");
|
|
142
|
+
console.log("✨ Connected MCP client to backing server transport");
|
|
148
143
|
const webAppTransport = new StreamableHTTPServerTransport({
|
|
149
144
|
sessionIdGenerator: randomUUID,
|
|
150
145
|
onsessioninitialized: (sessionId) => {
|
|
151
146
|
webAppTransports.set(sessionId, webAppTransport);
|
|
152
|
-
console.log("Created streamable web app transport " + sessionId);
|
|
147
|
+
console.log("✨ Created streamable web app transport " + sessionId);
|
|
153
148
|
},
|
|
154
149
|
});
|
|
155
150
|
await webAppTransport.start();
|
|
@@ -160,7 +155,7 @@ app.post("/mcp", async (req, res) => {
|
|
|
160
155
|
await webAppTransport.handleRequest(req, res, req.body);
|
|
161
156
|
}
|
|
162
157
|
catch (error) {
|
|
163
|
-
console.error("Error in /mcp POST route:", error);
|
|
158
|
+
console.error("❌ Error in /mcp POST route:", error);
|
|
164
159
|
res.status(500).json(error);
|
|
165
160
|
}
|
|
166
161
|
}
|
|
@@ -175,30 +170,28 @@ app.post("/mcp", async (req, res) => {
|
|
|
175
170
|
}
|
|
176
171
|
}
|
|
177
172
|
catch (error) {
|
|
178
|
-
console.error("Error in /mcp route:", error);
|
|
173
|
+
console.error("❌ Error in /mcp route:", error);
|
|
179
174
|
res.status(500).json(error);
|
|
180
175
|
}
|
|
181
176
|
}
|
|
182
177
|
});
|
|
183
178
|
app.get("/stdio", async (req, res) => {
|
|
184
179
|
try {
|
|
185
|
-
console.log("New connection");
|
|
180
|
+
console.log("🔄 New connection");
|
|
186
181
|
try {
|
|
187
182
|
await backingServerTransport?.close();
|
|
188
183
|
backingServerTransport = await createTransport(req);
|
|
189
184
|
}
|
|
190
185
|
catch (error) {
|
|
191
186
|
if (error instanceof SseError && error.code === 401) {
|
|
192
|
-
console.error("Received 401 Unauthorized from MCP server:", error.message);
|
|
187
|
+
console.error("🔒 Received 401 Unauthorized from MCP server:", error.message);
|
|
193
188
|
res.status(401).json(error);
|
|
194
189
|
return;
|
|
195
190
|
}
|
|
196
191
|
throw error;
|
|
197
192
|
}
|
|
198
|
-
console.log("Connected MCP client to backing server transport");
|
|
199
193
|
const webAppTransport = new SSEServerTransport("/message", res);
|
|
200
194
|
webAppTransports.set(webAppTransport.sessionId, webAppTransport);
|
|
201
|
-
console.log("Created web app transport");
|
|
202
195
|
await webAppTransport.start();
|
|
203
196
|
backingServerTransport.stderr.on("data", (chunk) => {
|
|
204
197
|
webAppTransport.send({
|
|
@@ -213,48 +206,43 @@ app.get("/stdio", async (req, res) => {
|
|
|
213
206
|
transportToClient: webAppTransport,
|
|
214
207
|
transportToServer: backingServerTransport,
|
|
215
208
|
});
|
|
216
|
-
console.log("Set up MCP proxy");
|
|
217
209
|
}
|
|
218
210
|
catch (error) {
|
|
219
|
-
console.error("Error in /stdio route:", error);
|
|
211
|
+
console.error("❌ Error in /stdio route:", error);
|
|
220
212
|
res.status(500).json(error);
|
|
221
213
|
}
|
|
222
214
|
});
|
|
223
215
|
app.get("/sse", async (req, res) => {
|
|
224
216
|
try {
|
|
225
|
-
console.log("New SSE connection. NOTE: The sse transport is deprecated and has been replaced by streamable-http");
|
|
226
217
|
try {
|
|
227
218
|
await backingServerTransport?.close();
|
|
228
219
|
backingServerTransport = await createTransport(req);
|
|
229
220
|
}
|
|
230
221
|
catch (error) {
|
|
231
222
|
if (error instanceof SseError && error.code === 401) {
|
|
232
|
-
console.error("Received 401 Unauthorized from MCP server:", error.message);
|
|
223
|
+
console.error("🔒 Received 401 Unauthorized from MCP server:", error.message);
|
|
233
224
|
res.status(401).json(error);
|
|
234
225
|
return;
|
|
235
226
|
}
|
|
236
227
|
throw error;
|
|
237
228
|
}
|
|
238
|
-
console.log("Connected MCP client to backing server transport");
|
|
239
229
|
const webAppTransport = new SSEServerTransport("/message", res);
|
|
240
230
|
webAppTransports.set(webAppTransport.sessionId, webAppTransport);
|
|
241
|
-
console.log("Created web app transport");
|
|
242
231
|
await webAppTransport.start();
|
|
243
232
|
mcpProxy({
|
|
244
233
|
transportToClient: webAppTransport,
|
|
245
234
|
transportToServer: backingServerTransport,
|
|
246
235
|
});
|
|
247
|
-
console.log("Set up MCP proxy");
|
|
248
236
|
}
|
|
249
237
|
catch (error) {
|
|
250
|
-
console.error("Error in /sse route:", error);
|
|
238
|
+
console.error("❌ Error in /sse route:", error);
|
|
251
239
|
res.status(500).json(error);
|
|
252
240
|
}
|
|
253
241
|
});
|
|
254
242
|
app.post("/message", async (req, res) => {
|
|
255
243
|
try {
|
|
256
244
|
const sessionId = req.query.sessionId;
|
|
257
|
-
console.log(
|
|
245
|
+
console.log(`📥 Received message for sessionId ${sessionId}`);
|
|
258
246
|
const transport = webAppTransports.get(sessionId);
|
|
259
247
|
if (!transport) {
|
|
260
248
|
res.status(404).end("Session not found");
|
|
@@ -263,7 +251,7 @@ app.post("/message", async (req, res) => {
|
|
|
263
251
|
await transport.handlePostMessage(req, res);
|
|
264
252
|
}
|
|
265
253
|
catch (error) {
|
|
266
|
-
console.error("Error in /message route:", error);
|
|
254
|
+
console.error("❌ Error in /message route:", error);
|
|
267
255
|
res.status(500).json(error);
|
|
268
256
|
}
|
|
269
257
|
});
|
|
@@ -281,7 +269,7 @@ app.get("/config", (req, res) => {
|
|
|
281
269
|
});
|
|
282
270
|
}
|
|
283
271
|
catch (error) {
|
|
284
|
-
console.error("Error in /config route:", error);
|
|
272
|
+
console.error("❌ Error in /config route:", error);
|
|
285
273
|
res.status(500).json(error);
|
|
286
274
|
}
|
|
287
275
|
});
|
|
@@ -295,10 +283,12 @@ const findAvailablePort = async (startPort) => {
|
|
|
295
283
|
resolve(port);
|
|
296
284
|
});
|
|
297
285
|
});
|
|
298
|
-
server.on(
|
|
299
|
-
if (err.code ===
|
|
286
|
+
server.on("error", (err) => {
|
|
287
|
+
if (err.code === "EADDRINUSE") {
|
|
300
288
|
// Port is in use, try the next one
|
|
301
|
-
findAvailablePort(startPort + 1)
|
|
289
|
+
findAvailablePort(startPort + 1)
|
|
290
|
+
.then(resolve)
|
|
291
|
+
.catch(reject);
|
|
302
292
|
}
|
|
303
293
|
else {
|
|
304
294
|
reject(err);
|
|
@@ -316,7 +306,7 @@ const startServer = async () => {
|
|
|
316
306
|
if (availablePort !== Number(PORT)) {
|
|
317
307
|
console.log(`⚠️ Port ${PORT} was in use, using available port ${availablePort} instead`);
|
|
318
308
|
}
|
|
319
|
-
console.log(`⚙️ Proxy server listening on port ${availablePort}`);
|
|
309
|
+
console.log(`\x1b[32m%s\x1b[0m`, `⚙️ Proxy server listening on port ${availablePort}`);
|
|
320
310
|
});
|
|
321
311
|
server.on("error", (err) => {
|
|
322
312
|
console.error(`❌ Server error: ${err.message}`);
|