@modelcontextprotocol/inspector-client 0.14.3 → 0.16.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/bin/client.js +11 -6
- package/bin/start.js +234 -50
- package/dist/assets/{OAuthCallback-BrCtrNqU.js → OAuthCallback-DMQy4ibj.js} +1 -1
- package/dist/assets/{OAuthDebugCallback-CnQiL6bh.js → OAuthDebugCallback-9JxBAysc.js} +1 -1
- package/dist/assets/{index-C1MLjTGf.css → index-BwWj6LL9.css} +0 -4
- package/dist/assets/{index-DYfnI33L.js → index-DI7JCTeu.js} +854 -342
- package/dist/index.html +3 -3
- package/package.json +6 -4
package/bin/client.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
import open from "open";
|
|
3
4
|
import { join, dirname } from "path";
|
|
4
5
|
import { fileURLToPath } from "url";
|
|
5
6
|
import handler from "serve-handler";
|
|
@@ -39,19 +40,23 @@ const server = http.createServer((request, response) => {
|
|
|
39
40
|
return handler(request, response, handlerOptions);
|
|
40
41
|
});
|
|
41
42
|
|
|
42
|
-
const port = process.env.
|
|
43
|
+
const port = parseInt(process.env.CLIENT_PORT || "6274", 10);
|
|
44
|
+
const host = process.env.HOST || "localhost";
|
|
43
45
|
server.on("listening", () => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
)
|
|
46
|
+
const url = process.env.INSPECTOR_URL || `http://${host}:${port}`;
|
|
47
|
+
console.log(`\n🚀 MCP Inspector is up and running at:\n ${url}\n`);
|
|
48
|
+
if (process.env.MCP_AUTO_OPEN_ENABLED !== "false") {
|
|
49
|
+
console.log(`🌐 Opening browser...`);
|
|
50
|
+
open(url);
|
|
51
|
+
}
|
|
47
52
|
});
|
|
48
53
|
server.on("error", (err) => {
|
|
49
54
|
if (err.message.includes(`EADDRINUSE`)) {
|
|
50
55
|
console.error(
|
|
51
|
-
`❌ MCP Inspector PORT IS IN USE at http
|
|
56
|
+
`❌ MCP Inspector PORT IS IN USE at http://${host}:${port} ❌ `,
|
|
52
57
|
);
|
|
53
58
|
} else {
|
|
54
59
|
throw err;
|
|
55
60
|
}
|
|
56
61
|
});
|
|
57
|
-
server.listen(port);
|
|
62
|
+
server.listen(port, host);
|
package/bin/start.js
CHANGED
|
@@ -2,15 +2,202 @@
|
|
|
2
2
|
|
|
3
3
|
import open from "open";
|
|
4
4
|
import { resolve, dirname } from "path";
|
|
5
|
-
import { spawnPromise } from "spawn-rx";
|
|
5
|
+
import { spawnPromise, spawn } from "spawn-rx";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
|
+
import { randomBytes } from "crypto";
|
|
7
8
|
|
|
8
9
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
const DEFAULT_MCP_PROXY_LISTEN_PORT = "6277";
|
|
9
11
|
|
|
10
12
|
function delay(ms) {
|
|
11
13
|
return new Promise((resolve) => setTimeout(resolve, ms, true));
|
|
12
14
|
}
|
|
13
15
|
|
|
16
|
+
function getClientUrl(port, authDisabled, sessionToken, serverPort) {
|
|
17
|
+
const host = process.env.HOST || "localhost";
|
|
18
|
+
const baseUrl = `http://${host}:${port}`;
|
|
19
|
+
|
|
20
|
+
const params = new URLSearchParams();
|
|
21
|
+
if (serverPort && serverPort !== DEFAULT_MCP_PROXY_LISTEN_PORT) {
|
|
22
|
+
params.set("MCP_PROXY_PORT", serverPort);
|
|
23
|
+
}
|
|
24
|
+
if (!authDisabled) {
|
|
25
|
+
params.set("MCP_PROXY_AUTH_TOKEN", sessionToken);
|
|
26
|
+
}
|
|
27
|
+
return params.size > 0 ? `${baseUrl}/?${params.toString()}` : baseUrl;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function startDevServer(serverOptions) {
|
|
31
|
+
const { SERVER_PORT, CLIENT_PORT, sessionToken, envVars, abort } =
|
|
32
|
+
serverOptions;
|
|
33
|
+
const serverCommand = "npx";
|
|
34
|
+
const serverArgs = ["tsx", "watch", "--clear-screen=false", "src/index.ts"];
|
|
35
|
+
const isWindows = process.platform === "win32";
|
|
36
|
+
|
|
37
|
+
const spawnOptions = {
|
|
38
|
+
cwd: resolve(__dirname, "../..", "server"),
|
|
39
|
+
env: {
|
|
40
|
+
...process.env,
|
|
41
|
+
SERVER_PORT,
|
|
42
|
+
CLIENT_PORT,
|
|
43
|
+
MCP_PROXY_TOKEN: sessionToken,
|
|
44
|
+
MCP_ENV_VARS: JSON.stringify(envVars),
|
|
45
|
+
},
|
|
46
|
+
signal: abort.signal,
|
|
47
|
+
echoOutput: true,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// For Windows, we need to use stdin: 'ignore' to simulate < NUL
|
|
51
|
+
if (isWindows) {
|
|
52
|
+
spawnOptions.stdin = "ignore";
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const server = spawn(serverCommand, serverArgs, spawnOptions);
|
|
56
|
+
|
|
57
|
+
// Give server time to start
|
|
58
|
+
const serverOk = await Promise.race([
|
|
59
|
+
new Promise((resolve) => {
|
|
60
|
+
server.subscribe({
|
|
61
|
+
complete: () => resolve(false),
|
|
62
|
+
error: () => resolve(false),
|
|
63
|
+
next: () => {}, // We're using echoOutput
|
|
64
|
+
});
|
|
65
|
+
}),
|
|
66
|
+
delay(3000).then(() => true),
|
|
67
|
+
]);
|
|
68
|
+
|
|
69
|
+
return { server, serverOk };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function startProdServer(serverOptions) {
|
|
73
|
+
const {
|
|
74
|
+
SERVER_PORT,
|
|
75
|
+
CLIENT_PORT,
|
|
76
|
+
sessionToken,
|
|
77
|
+
envVars,
|
|
78
|
+
abort,
|
|
79
|
+
command,
|
|
80
|
+
mcpServerArgs,
|
|
81
|
+
} = serverOptions;
|
|
82
|
+
const inspectorServerPath = resolve(
|
|
83
|
+
__dirname,
|
|
84
|
+
"../..",
|
|
85
|
+
"server",
|
|
86
|
+
"build",
|
|
87
|
+
"index.js",
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
const server = spawnPromise(
|
|
91
|
+
"node",
|
|
92
|
+
[
|
|
93
|
+
inspectorServerPath,
|
|
94
|
+
...(command ? [`--env`, command] : []),
|
|
95
|
+
...(mcpServerArgs ? [`--args=${mcpServerArgs.join(" ")}`] : []),
|
|
96
|
+
],
|
|
97
|
+
{
|
|
98
|
+
env: {
|
|
99
|
+
...process.env,
|
|
100
|
+
SERVER_PORT,
|
|
101
|
+
CLIENT_PORT,
|
|
102
|
+
MCP_PROXY_TOKEN: sessionToken,
|
|
103
|
+
MCP_ENV_VARS: JSON.stringify(envVars),
|
|
104
|
+
},
|
|
105
|
+
signal: abort.signal,
|
|
106
|
+
echoOutput: true,
|
|
107
|
+
},
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
// Make sure server started before starting client
|
|
111
|
+
const serverOk = await Promise.race([server, delay(2 * 1000)]);
|
|
112
|
+
|
|
113
|
+
return { server, serverOk };
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async function startDevClient(clientOptions) {
|
|
117
|
+
const {
|
|
118
|
+
CLIENT_PORT,
|
|
119
|
+
SERVER_PORT,
|
|
120
|
+
authDisabled,
|
|
121
|
+
sessionToken,
|
|
122
|
+
abort,
|
|
123
|
+
cancelled,
|
|
124
|
+
} = clientOptions;
|
|
125
|
+
const clientCommand = "npx";
|
|
126
|
+
const host = process.env.HOST || "localhost";
|
|
127
|
+
const clientArgs = ["vite", "--port", CLIENT_PORT, "--host", host];
|
|
128
|
+
|
|
129
|
+
const client = spawn(clientCommand, clientArgs, {
|
|
130
|
+
cwd: resolve(__dirname, ".."),
|
|
131
|
+
env: { ...process.env, CLIENT_PORT },
|
|
132
|
+
signal: abort.signal,
|
|
133
|
+
echoOutput: true,
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
const url = getClientUrl(
|
|
137
|
+
CLIENT_PORT,
|
|
138
|
+
authDisabled,
|
|
139
|
+
sessionToken,
|
|
140
|
+
SERVER_PORT,
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
// Give vite time to start before opening or logging the URL
|
|
144
|
+
setTimeout(() => {
|
|
145
|
+
console.log(`\n🚀 MCP Inspector is up and running at:\n ${url}\n`);
|
|
146
|
+
if (process.env.MCP_AUTO_OPEN_ENABLED !== "false") {
|
|
147
|
+
console.log("🌐 Opening browser...");
|
|
148
|
+
open(url);
|
|
149
|
+
}
|
|
150
|
+
}, 3000);
|
|
151
|
+
|
|
152
|
+
await new Promise((resolve) => {
|
|
153
|
+
client.subscribe({
|
|
154
|
+
complete: resolve,
|
|
155
|
+
error: (err) => {
|
|
156
|
+
if (!cancelled || process.env.DEBUG) {
|
|
157
|
+
console.error("Client error:", err);
|
|
158
|
+
}
|
|
159
|
+
resolve(null);
|
|
160
|
+
},
|
|
161
|
+
next: () => {}, // We're using echoOutput
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async function startProdClient(clientOptions) {
|
|
167
|
+
const {
|
|
168
|
+
CLIENT_PORT,
|
|
169
|
+
SERVER_PORT,
|
|
170
|
+
authDisabled,
|
|
171
|
+
sessionToken,
|
|
172
|
+
abort,
|
|
173
|
+
cancelled,
|
|
174
|
+
} = clientOptions;
|
|
175
|
+
const inspectorClientPath = resolve(
|
|
176
|
+
__dirname,
|
|
177
|
+
"../..",
|
|
178
|
+
"client",
|
|
179
|
+
"bin",
|
|
180
|
+
"client.js",
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
const url = getClientUrl(
|
|
184
|
+
CLIENT_PORT,
|
|
185
|
+
authDisabled,
|
|
186
|
+
sessionToken,
|
|
187
|
+
SERVER_PORT,
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
await spawnPromise("node", [inspectorClientPath], {
|
|
191
|
+
env: {
|
|
192
|
+
...process.env,
|
|
193
|
+
CLIENT_PORT,
|
|
194
|
+
INSPECTOR_URL: url,
|
|
195
|
+
},
|
|
196
|
+
signal: abort.signal,
|
|
197
|
+
echoOutput: true,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
14
201
|
async function main() {
|
|
15
202
|
// Parse command line arguments
|
|
16
203
|
const args = process.argv.slice(2);
|
|
@@ -18,6 +205,7 @@ async function main() {
|
|
|
18
205
|
const mcpServerArgs = [];
|
|
19
206
|
let command = null;
|
|
20
207
|
let parsingFlags = true;
|
|
208
|
+
let isDev = false;
|
|
21
209
|
|
|
22
210
|
for (let i = 0; i < args.length; i++) {
|
|
23
211
|
const arg = args[i];
|
|
@@ -27,6 +215,11 @@ async function main() {
|
|
|
27
215
|
continue;
|
|
28
216
|
}
|
|
29
217
|
|
|
218
|
+
if (parsingFlags && arg === "--dev") {
|
|
219
|
+
isDev = true;
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
|
|
30
223
|
if (parsingFlags && arg === "-e" && i + 1 < args.length) {
|
|
31
224
|
const envVar = args[++i];
|
|
32
225
|
const equalsIndex = envVar.indexOf("=");
|
|
@@ -38,34 +231,25 @@ async function main() {
|
|
|
38
231
|
} else {
|
|
39
232
|
envVars[envVar] = "";
|
|
40
233
|
}
|
|
41
|
-
} else if (!command) {
|
|
234
|
+
} else if (!command && !isDev) {
|
|
42
235
|
command = arg;
|
|
43
|
-
} else {
|
|
236
|
+
} else if (!isDev) {
|
|
44
237
|
mcpServerArgs.push(arg);
|
|
45
238
|
}
|
|
46
239
|
}
|
|
47
240
|
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
"../..",
|
|
51
|
-
"server",
|
|
52
|
-
"build",
|
|
53
|
-
"index.js",
|
|
54
|
-
);
|
|
241
|
+
const CLIENT_PORT = process.env.CLIENT_PORT ?? "6274";
|
|
242
|
+
const SERVER_PORT = process.env.SERVER_PORT ?? DEFAULT_MCP_PROXY_LISTEN_PORT;
|
|
55
243
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
"client",
|
|
61
|
-
"bin",
|
|
62
|
-
"client.js",
|
|
244
|
+
console.log(
|
|
245
|
+
isDev
|
|
246
|
+
? "Starting MCP inspector in development mode..."
|
|
247
|
+
: "Starting MCP inspector...",
|
|
63
248
|
);
|
|
64
249
|
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
console.log("Starting MCP inspector...");
|
|
250
|
+
// Generate session token for authentication
|
|
251
|
+
const sessionToken = randomBytes(32).toString("hex");
|
|
252
|
+
const authDisabled = !!process.env.DANGEROUSLY_OMIT_AUTH;
|
|
69
253
|
|
|
70
254
|
const abort = new AbortController();
|
|
71
255
|
|
|
@@ -74,42 +258,42 @@ async function main() {
|
|
|
74
258
|
cancelled = true;
|
|
75
259
|
abort.abort();
|
|
76
260
|
});
|
|
261
|
+
|
|
77
262
|
let server, serverOk;
|
|
263
|
+
|
|
78
264
|
try {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
...process.env,
|
|
89
|
-
PORT: SERVER_PORT,
|
|
90
|
-
MCP_ENV_VARS: JSON.stringify(envVars),
|
|
91
|
-
},
|
|
92
|
-
signal: abort.signal,
|
|
93
|
-
echoOutput: true,
|
|
94
|
-
},
|
|
95
|
-
);
|
|
265
|
+
const serverOptions = {
|
|
266
|
+
SERVER_PORT,
|
|
267
|
+
CLIENT_PORT,
|
|
268
|
+
sessionToken,
|
|
269
|
+
envVars,
|
|
270
|
+
abort,
|
|
271
|
+
command,
|
|
272
|
+
mcpServerArgs,
|
|
273
|
+
};
|
|
96
274
|
|
|
97
|
-
|
|
98
|
-
|
|
275
|
+
const result = isDev
|
|
276
|
+
? await startDevServer(serverOptions)
|
|
277
|
+
: await startProdServer(serverOptions);
|
|
278
|
+
|
|
279
|
+
server = result.server;
|
|
280
|
+
serverOk = result.serverOk;
|
|
99
281
|
} catch (error) {}
|
|
100
282
|
|
|
101
283
|
if (serverOk) {
|
|
102
284
|
try {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
285
|
+
const clientOptions = {
|
|
286
|
+
CLIENT_PORT,
|
|
287
|
+
SERVER_PORT,
|
|
288
|
+
authDisabled,
|
|
289
|
+
sessionToken,
|
|
290
|
+
abort,
|
|
291
|
+
cancelled,
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
await (isDev
|
|
295
|
+
? startDevClient(clientOptions)
|
|
296
|
+
: startProdClient(clientOptions));
|
|
113
297
|
} catch (e) {
|
|
114
298
|
if (!cancelled || process.env.DEBUG) throw e;
|
|
115
299
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { u as useToast, r as reactExports, j as jsxRuntimeExports, S as SESSION_KEYS, I as InspectorOAuthClientProvider, a as auth } from "./index-
|
|
1
|
+
import { u as useToast, r as reactExports, j as jsxRuntimeExports, S as SESSION_KEYS, I as InspectorOAuthClientProvider, a as auth } from "./index-DI7JCTeu.js";
|
|
2
2
|
import { p as parseOAuthCallbackParams, g as generateOAuthErrorDescription } from "./oauthUtils-DTcoXpSP.js";
|
|
3
3
|
const OAuthCallback = ({ onConnect }) => {
|
|
4
4
|
const { toast } = useToast();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as reactExports, S as SESSION_KEYS, j as jsxRuntimeExports } from "./index-
|
|
1
|
+
import { r as reactExports, S as SESSION_KEYS, j as jsxRuntimeExports } from "./index-DI7JCTeu.js";
|
|
2
2
|
import { p as parseOAuthCallbackParams, g as generateOAuthErrorDescription } from "./oauthUtils-DTcoXpSP.js";
|
|
3
3
|
const OAuthDebugCallback = ({ onConnect }) => {
|
|
4
4
|
reactExports.useEffect(() => {
|