@modelcontextprotocol/inspector-client 0.14.3 → 0.15.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/start.js +198 -50
- package/dist/assets/{OAuthCallback-BrCtrNqU.js → OAuthCallback-CaW3Hcqw.js} +1 -1
- package/dist/assets/{OAuthDebugCallback-CnQiL6bh.js → OAuthDebugCallback-DiBt_oxh.js} +1 -1
- package/dist/assets/{index-DYfnI33L.js → index-BNqYF5Na.js} +561 -264
- package/dist/index.html +1 -1
- package/package.json +6 -4
package/bin/start.js
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
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));
|
|
9
10
|
|
|
@@ -11,6 +12,157 @@ function delay(ms) {
|
|
|
11
12
|
return new Promise((resolve) => setTimeout(resolve, ms, true));
|
|
12
13
|
}
|
|
13
14
|
|
|
15
|
+
async function startDevServer(serverOptions) {
|
|
16
|
+
const { SERVER_PORT, CLIENT_PORT, sessionToken, envVars, abort } =
|
|
17
|
+
serverOptions;
|
|
18
|
+
const serverCommand = "npx";
|
|
19
|
+
const serverArgs = ["tsx", "watch", "--clear-screen=false", "src/index.ts"];
|
|
20
|
+
const isWindows = process.platform === "win32";
|
|
21
|
+
|
|
22
|
+
const spawnOptions = {
|
|
23
|
+
cwd: resolve(__dirname, "../..", "server"),
|
|
24
|
+
env: {
|
|
25
|
+
...process.env,
|
|
26
|
+
PORT: SERVER_PORT,
|
|
27
|
+
CLIENT_PORT: CLIENT_PORT,
|
|
28
|
+
MCP_PROXY_TOKEN: sessionToken,
|
|
29
|
+
MCP_ENV_VARS: JSON.stringify(envVars),
|
|
30
|
+
},
|
|
31
|
+
signal: abort.signal,
|
|
32
|
+
echoOutput: true,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// For Windows, we need to use stdin: 'ignore' to simulate < NUL
|
|
36
|
+
if (isWindows) {
|
|
37
|
+
spawnOptions.stdin = "ignore";
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const server = spawn(serverCommand, serverArgs, spawnOptions);
|
|
41
|
+
|
|
42
|
+
// Give server time to start
|
|
43
|
+
const serverOk = await Promise.race([
|
|
44
|
+
new Promise((resolve) => {
|
|
45
|
+
server.subscribe({
|
|
46
|
+
complete: () => resolve(false),
|
|
47
|
+
error: () => resolve(false),
|
|
48
|
+
next: () => {}, // We're using echoOutput
|
|
49
|
+
});
|
|
50
|
+
}),
|
|
51
|
+
delay(3000).then(() => true),
|
|
52
|
+
]);
|
|
53
|
+
|
|
54
|
+
return { server, serverOk };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async function startProdServer(serverOptions) {
|
|
58
|
+
const {
|
|
59
|
+
SERVER_PORT,
|
|
60
|
+
CLIENT_PORT,
|
|
61
|
+
sessionToken,
|
|
62
|
+
envVars,
|
|
63
|
+
abort,
|
|
64
|
+
command,
|
|
65
|
+
mcpServerArgs,
|
|
66
|
+
} = serverOptions;
|
|
67
|
+
const inspectorServerPath = resolve(
|
|
68
|
+
__dirname,
|
|
69
|
+
"../..",
|
|
70
|
+
"server",
|
|
71
|
+
"build",
|
|
72
|
+
"index.js",
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
const server = spawnPromise(
|
|
76
|
+
"node",
|
|
77
|
+
[
|
|
78
|
+
inspectorServerPath,
|
|
79
|
+
...(command ? [`--env`, command] : []),
|
|
80
|
+
...(mcpServerArgs ? [`--args=${mcpServerArgs.join(" ")}`] : []),
|
|
81
|
+
],
|
|
82
|
+
{
|
|
83
|
+
env: {
|
|
84
|
+
...process.env,
|
|
85
|
+
PORT: SERVER_PORT,
|
|
86
|
+
CLIENT_PORT: CLIENT_PORT,
|
|
87
|
+
MCP_PROXY_TOKEN: sessionToken,
|
|
88
|
+
MCP_ENV_VARS: JSON.stringify(envVars),
|
|
89
|
+
},
|
|
90
|
+
signal: abort.signal,
|
|
91
|
+
echoOutput: true,
|
|
92
|
+
},
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
// Make sure server started before starting client
|
|
96
|
+
const serverOk = await Promise.race([server, delay(2 * 1000)]);
|
|
97
|
+
|
|
98
|
+
return { server, serverOk };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async function startDevClient(clientOptions) {
|
|
102
|
+
const { CLIENT_PORT, authDisabled, sessionToken, abort, cancelled } =
|
|
103
|
+
clientOptions;
|
|
104
|
+
const clientCommand = "npx";
|
|
105
|
+
const clientArgs = ["vite", "--port", CLIENT_PORT];
|
|
106
|
+
|
|
107
|
+
const client = spawn(clientCommand, clientArgs, {
|
|
108
|
+
cwd: resolve(__dirname, ".."),
|
|
109
|
+
env: { ...process.env, PORT: CLIENT_PORT },
|
|
110
|
+
signal: abort.signal,
|
|
111
|
+
echoOutput: true,
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Auto-open browser after vite starts
|
|
115
|
+
if (process.env.MCP_AUTO_OPEN_ENABLED !== "false") {
|
|
116
|
+
const url = authDisabled
|
|
117
|
+
? `http://127.0.0.1:${CLIENT_PORT}`
|
|
118
|
+
: `http://127.0.0.1:${CLIENT_PORT}/?MCP_PROXY_AUTH_TOKEN=${sessionToken}`;
|
|
119
|
+
|
|
120
|
+
// Give vite time to start before opening browser
|
|
121
|
+
setTimeout(() => {
|
|
122
|
+
open(url);
|
|
123
|
+
console.log(`\n🔗 Opening browser at: ${url}\n`);
|
|
124
|
+
}, 3000);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
await new Promise((resolve) => {
|
|
128
|
+
client.subscribe({
|
|
129
|
+
complete: resolve,
|
|
130
|
+
error: (err) => {
|
|
131
|
+
if (!cancelled || process.env.DEBUG) {
|
|
132
|
+
console.error("Client error:", err);
|
|
133
|
+
}
|
|
134
|
+
resolve(null);
|
|
135
|
+
},
|
|
136
|
+
next: () => {}, // We're using echoOutput
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async function startProdClient(clientOptions) {
|
|
142
|
+
const { CLIENT_PORT, authDisabled, sessionToken, abort } = clientOptions;
|
|
143
|
+
const inspectorClientPath = resolve(
|
|
144
|
+
__dirname,
|
|
145
|
+
"../..",
|
|
146
|
+
"client",
|
|
147
|
+
"bin",
|
|
148
|
+
"client.js",
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
// Auto-open browser with token
|
|
152
|
+
if (process.env.MCP_AUTO_OPEN_ENABLED !== "false") {
|
|
153
|
+
const url = authDisabled
|
|
154
|
+
? `http://127.0.0.1:${CLIENT_PORT}`
|
|
155
|
+
: `http://127.0.0.1:${CLIENT_PORT}/?MCP_PROXY_AUTH_TOKEN=${sessionToken}`;
|
|
156
|
+
open(url);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
await spawnPromise("node", [inspectorClientPath], {
|
|
160
|
+
env: { ...process.env, PORT: CLIENT_PORT },
|
|
161
|
+
signal: abort.signal,
|
|
162
|
+
echoOutput: true,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
14
166
|
async function main() {
|
|
15
167
|
// Parse command line arguments
|
|
16
168
|
const args = process.argv.slice(2);
|
|
@@ -18,6 +170,7 @@ async function main() {
|
|
|
18
170
|
const mcpServerArgs = [];
|
|
19
171
|
let command = null;
|
|
20
172
|
let parsingFlags = true;
|
|
173
|
+
let isDev = false;
|
|
21
174
|
|
|
22
175
|
for (let i = 0; i < args.length; i++) {
|
|
23
176
|
const arg = args[i];
|
|
@@ -27,6 +180,11 @@ async function main() {
|
|
|
27
180
|
continue;
|
|
28
181
|
}
|
|
29
182
|
|
|
183
|
+
if (parsingFlags && arg === "--dev") {
|
|
184
|
+
isDev = true;
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
|
|
30
188
|
if (parsingFlags && arg === "-e" && i + 1 < args.length) {
|
|
31
189
|
const envVar = args[++i];
|
|
32
190
|
const equalsIndex = envVar.indexOf("=");
|
|
@@ -38,34 +196,25 @@ async function main() {
|
|
|
38
196
|
} else {
|
|
39
197
|
envVars[envVar] = "";
|
|
40
198
|
}
|
|
41
|
-
} else if (!command) {
|
|
199
|
+
} else if (!command && !isDev) {
|
|
42
200
|
command = arg;
|
|
43
|
-
} else {
|
|
201
|
+
} else if (!isDev) {
|
|
44
202
|
mcpServerArgs.push(arg);
|
|
45
203
|
}
|
|
46
204
|
}
|
|
47
205
|
|
|
48
|
-
const inspectorServerPath = resolve(
|
|
49
|
-
__dirname,
|
|
50
|
-
"../..",
|
|
51
|
-
"server",
|
|
52
|
-
"build",
|
|
53
|
-
"index.js",
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
// Path to the client entry point
|
|
57
|
-
const inspectorClientPath = resolve(
|
|
58
|
-
__dirname,
|
|
59
|
-
"../..",
|
|
60
|
-
"client",
|
|
61
|
-
"bin",
|
|
62
|
-
"client.js",
|
|
63
|
-
);
|
|
64
|
-
|
|
65
206
|
const CLIENT_PORT = process.env.CLIENT_PORT ?? "6274";
|
|
66
207
|
const SERVER_PORT = process.env.SERVER_PORT ?? "6277";
|
|
67
208
|
|
|
68
|
-
console.log(
|
|
209
|
+
console.log(
|
|
210
|
+
isDev
|
|
211
|
+
? "Starting MCP inspector in development mode..."
|
|
212
|
+
: "Starting MCP inspector...",
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
// Generate session token for authentication
|
|
216
|
+
const sessionToken = randomBytes(32).toString("hex");
|
|
217
|
+
const authDisabled = !!process.env.DANGEROUSLY_OMIT_AUTH;
|
|
69
218
|
|
|
70
219
|
const abort = new AbortController();
|
|
71
220
|
|
|
@@ -74,42 +223,41 @@ async function main() {
|
|
|
74
223
|
cancelled = true;
|
|
75
224
|
abort.abort();
|
|
76
225
|
});
|
|
226
|
+
|
|
77
227
|
let server, serverOk;
|
|
228
|
+
|
|
78
229
|
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
|
-
);
|
|
230
|
+
const serverOptions = {
|
|
231
|
+
SERVER_PORT,
|
|
232
|
+
CLIENT_PORT,
|
|
233
|
+
sessionToken,
|
|
234
|
+
envVars,
|
|
235
|
+
abort,
|
|
236
|
+
command,
|
|
237
|
+
mcpServerArgs,
|
|
238
|
+
};
|
|
96
239
|
|
|
97
|
-
|
|
98
|
-
|
|
240
|
+
const result = isDev
|
|
241
|
+
? await startDevServer(serverOptions)
|
|
242
|
+
: await startProdServer(serverOptions);
|
|
243
|
+
|
|
244
|
+
server = result.server;
|
|
245
|
+
serverOk = result.serverOk;
|
|
99
246
|
} catch (error) {}
|
|
100
247
|
|
|
101
248
|
if (serverOk) {
|
|
102
249
|
try {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
250
|
+
const clientOptions = {
|
|
251
|
+
CLIENT_PORT,
|
|
252
|
+
authDisabled,
|
|
253
|
+
sessionToken,
|
|
254
|
+
abort,
|
|
255
|
+
cancelled,
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
await (isDev
|
|
259
|
+
? startDevClient(clientOptions)
|
|
260
|
+
: startProdClient(clientOptions));
|
|
113
261
|
} catch (e) {
|
|
114
262
|
if (!cancelled || process.env.DEBUG) throw e;
|
|
115
263
|
}
|
|
@@ -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-BNqYF5Na.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-BNqYF5Na.js";
|
|
2
2
|
import { p as parseOAuthCallbackParams, g as generateOAuthErrorDescription } from "./oauthUtils-DTcoXpSP.js";
|
|
3
3
|
const OAuthDebugCallback = ({ onConnect }) => {
|
|
4
4
|
reactExports.useEffect(() => {
|