@modelcontextprotocol/inspector 0.16.2 → 0.16.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/README.md +72 -0
- package/cli/build/cli.js +80 -12
- package/cli/build/client/connection.js +5 -0
- package/client/bin/start.js +31 -4
- package/client/dist/assets/{OAuthCallback-CC1cu0Zx.js → OAuthCallback-DyaAiF-O.js} +1 -2
- package/client/dist/assets/{OAuthDebugCallback-_4BLxVDe.js → OAuthDebugCallback-BD-zJllm.js} +1 -2
- package/client/dist/assets/{index-BtsSr_hT.css → index-BWZfLo5E.css} +0 -4
- package/client/dist/assets/{index-DLtnCiTW.js → index-MFoeZZBS.js} +410 -239
- package/client/dist/index.html +2 -2
- package/package.json +12 -12
- package/server/build/index.js +4 -0
- package/client/dist/assets/oauthUtils-DTcoXpSP.js +0 -33
package/README.md
CHANGED
|
@@ -234,6 +234,78 @@ Example server configuration file:
|
|
|
234
234
|
}
|
|
235
235
|
```
|
|
236
236
|
|
|
237
|
+
#### Transport Types in Config Files
|
|
238
|
+
|
|
239
|
+
The inspector automatically detects the transport type from your config file. You can specify different transport types:
|
|
240
|
+
|
|
241
|
+
**STDIO (default):**
|
|
242
|
+
|
|
243
|
+
```json
|
|
244
|
+
{
|
|
245
|
+
"mcpServers": {
|
|
246
|
+
"my-stdio-server": {
|
|
247
|
+
"type": "stdio",
|
|
248
|
+
"command": "npx",
|
|
249
|
+
"args": ["@modelcontextprotocol/server-everything"]
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**SSE (Server-Sent Events):**
|
|
256
|
+
|
|
257
|
+
```json
|
|
258
|
+
{
|
|
259
|
+
"mcpServers": {
|
|
260
|
+
"my-sse-server": {
|
|
261
|
+
"type": "sse",
|
|
262
|
+
"url": "http://localhost:3000/sse"
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
**Streamable HTTP:**
|
|
269
|
+
|
|
270
|
+
```json
|
|
271
|
+
{
|
|
272
|
+
"mcpServers": {
|
|
273
|
+
"my-http-server": {
|
|
274
|
+
"type": "streamable-http",
|
|
275
|
+
"url": "http://localhost:3000/mcp"
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
#### Default Server Selection
|
|
282
|
+
|
|
283
|
+
You can launch the inspector without specifying a server name if your config has:
|
|
284
|
+
|
|
285
|
+
1. **A single server** - automatically selected:
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
# Automatically uses "my-server" if it's the only one
|
|
289
|
+
npx @modelcontextprotocol/inspector --config mcp.json
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
2. **A server named "default-server"** - automatically selected:
|
|
293
|
+
|
|
294
|
+
```json
|
|
295
|
+
{
|
|
296
|
+
"mcpServers": {
|
|
297
|
+
"default-server": {
|
|
298
|
+
"command": "npx",
|
|
299
|
+
"args": ["@modelcontextprotocol/server-everything"]
|
|
300
|
+
},
|
|
301
|
+
"other-server": {
|
|
302
|
+
"command": "node",
|
|
303
|
+
"args": ["other.js"]
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
```
|
|
308
|
+
|
|
237
309
|
> **Tip:** You can easily generate this configuration format using the **Server Entry** and **Servers File** buttons in the Inspector UI, as described in the Servers File Export section above.
|
|
238
310
|
|
|
239
311
|
You can also set the initial `transport` type, `serverUrl`, `serverCommand`, and `serverArgs` via query params, for example:
|
package/cli/build/cli.js
CHANGED
|
@@ -38,6 +38,14 @@ async function runWebClient(args) {
|
|
|
38
38
|
for (const [key, value] of Object.entries(args.envArgs)) {
|
|
39
39
|
startArgs.push("-e", `${key}=${value}`);
|
|
40
40
|
}
|
|
41
|
+
// Pass transport type if specified
|
|
42
|
+
if (args.transport) {
|
|
43
|
+
startArgs.push("--transport", args.transport);
|
|
44
|
+
}
|
|
45
|
+
// Pass server URL if specified
|
|
46
|
+
if (args.serverUrl) {
|
|
47
|
+
startArgs.push("--server-url", args.serverUrl);
|
|
48
|
+
}
|
|
41
49
|
// Pass command and args (using -- to separate them)
|
|
42
50
|
if (args.command) {
|
|
43
51
|
startArgs.push("--", args.command, ...args.args);
|
|
@@ -63,7 +71,17 @@ async function runCli(args) {
|
|
|
63
71
|
abort.abort();
|
|
64
72
|
});
|
|
65
73
|
try {
|
|
66
|
-
|
|
74
|
+
// Build CLI arguments
|
|
75
|
+
const cliArgs = [cliPath];
|
|
76
|
+
// Add transport flag if specified
|
|
77
|
+
if (args.transport && args.transport !== "stdio") {
|
|
78
|
+
// Convert streamable-http back to http for CLI mode
|
|
79
|
+
const cliTransport = args.transport === "streamable-http" ? "http" : args.transport;
|
|
80
|
+
cliArgs.push("--transport", cliTransport);
|
|
81
|
+
}
|
|
82
|
+
// Add command and remaining args
|
|
83
|
+
cliArgs.push(args.command, ...args.args);
|
|
84
|
+
await spawnPromise("node", cliArgs, {
|
|
67
85
|
env: { ...process.env, ...args.envArgs },
|
|
68
86
|
signal: abort.signal,
|
|
69
87
|
echoOutput: true,
|
|
@@ -124,38 +142,88 @@ function parseArgs() {
|
|
|
124
142
|
.option("-e <env>", "environment variables in KEY=VALUE format", parseKeyValuePair, {})
|
|
125
143
|
.option("--config <path>", "config file path")
|
|
126
144
|
.option("--server <n>", "server name from config file")
|
|
127
|
-
.option("--cli", "enable CLI mode")
|
|
145
|
+
.option("--cli", "enable CLI mode")
|
|
146
|
+
.option("--transport <type>", "transport type (stdio, sse, http)")
|
|
147
|
+
.option("--server-url <url>", "server URL for SSE/HTTP transport");
|
|
128
148
|
// Parse only the arguments before --
|
|
129
149
|
program.parse(preArgs);
|
|
130
150
|
const options = program.opts();
|
|
131
151
|
const remainingArgs = program.args;
|
|
132
152
|
// Add back any arguments that came after --
|
|
133
153
|
const finalArgs = [...remainingArgs, ...postArgs];
|
|
134
|
-
// Validate
|
|
135
|
-
if (
|
|
136
|
-
(
|
|
137
|
-
|
|
154
|
+
// Validate config and server options
|
|
155
|
+
if (!options.config && options.server) {
|
|
156
|
+
throw new Error("--server requires --config to be specified");
|
|
157
|
+
}
|
|
158
|
+
// If config is provided without server, try to auto-select
|
|
159
|
+
if (options.config && !options.server) {
|
|
160
|
+
const configContent = fs.readFileSync(path.isAbsolute(options.config)
|
|
161
|
+
? options.config
|
|
162
|
+
: path.resolve(process.cwd(), options.config), "utf8");
|
|
163
|
+
const parsedConfig = JSON.parse(configContent);
|
|
164
|
+
const servers = Object.keys(parsedConfig.mcpServers || {});
|
|
165
|
+
if (servers.length === 1) {
|
|
166
|
+
// Use the only server if there's just one
|
|
167
|
+
options.server = servers[0];
|
|
168
|
+
}
|
|
169
|
+
else if (servers.length === 0) {
|
|
170
|
+
throw new Error("No servers found in config file");
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
// Multiple servers, require explicit selection
|
|
174
|
+
throw new Error(`Multiple servers found in config file. Please specify one with --server.\nAvailable servers: ${servers.join(", ")}`);
|
|
175
|
+
}
|
|
138
176
|
}
|
|
139
177
|
// If config file is specified, load and use the options from the file. We must merge the args
|
|
140
178
|
// from the command line and the file together, or we will miss the method options (--method,
|
|
141
179
|
// etc.)
|
|
142
180
|
if (options.config && options.server) {
|
|
143
181
|
const config = loadConfigFile(options.config, options.server);
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
182
|
+
if (config.type === "stdio") {
|
|
183
|
+
return {
|
|
184
|
+
command: config.command,
|
|
185
|
+
args: [...(config.args || []), ...finalArgs],
|
|
186
|
+
envArgs: { ...(config.env || {}), ...(options.e || {}) },
|
|
187
|
+
cli: options.cli || false,
|
|
188
|
+
transport: "stdio",
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
else if (config.type === "sse" || config.type === "streamable-http") {
|
|
192
|
+
return {
|
|
193
|
+
command: config.url,
|
|
194
|
+
args: finalArgs,
|
|
195
|
+
envArgs: options.e || {},
|
|
196
|
+
cli: options.cli || false,
|
|
197
|
+
transport: config.type,
|
|
198
|
+
serverUrl: config.url,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
// Backwards compatibility: if no type field, assume stdio
|
|
203
|
+
return {
|
|
204
|
+
command: config.command || "",
|
|
205
|
+
args: [...(config.args || []), ...finalArgs],
|
|
206
|
+
envArgs: { ...(config.env || {}), ...(options.e || {}) },
|
|
207
|
+
cli: options.cli || false,
|
|
208
|
+
transport: "stdio",
|
|
209
|
+
};
|
|
210
|
+
}
|
|
150
211
|
}
|
|
151
212
|
// Otherwise use command line arguments
|
|
152
213
|
const command = finalArgs[0] || "";
|
|
153
214
|
const args = finalArgs.slice(1);
|
|
215
|
+
// Map "http" shorthand to "streamable-http"
|
|
216
|
+
let transport = options.transport;
|
|
217
|
+
if (transport === "http") {
|
|
218
|
+
transport = "streamable-http";
|
|
219
|
+
}
|
|
154
220
|
return {
|
|
155
221
|
command,
|
|
156
222
|
args,
|
|
157
223
|
envArgs: options.e || {},
|
|
158
224
|
cli: options.cli || false,
|
|
225
|
+
transport: transport,
|
|
226
|
+
serverUrl: options.serverUrl,
|
|
159
227
|
};
|
|
160
228
|
}
|
|
161
229
|
async function main() {
|
|
@@ -8,6 +8,11 @@ export const validLogLevels = [
|
|
|
8
8
|
export async function connect(client, transport) {
|
|
9
9
|
try {
|
|
10
10
|
await client.connect(transport);
|
|
11
|
+
if (client.getServerCapabilities()?.logging) {
|
|
12
|
+
// default logging level is undefined in the spec, but the user of the
|
|
13
|
+
// inspector most likely wants debug.
|
|
14
|
+
await client.setLoggingLevel("debug");
|
|
15
|
+
}
|
|
11
16
|
}
|
|
12
17
|
catch (error) {
|
|
13
18
|
throw new Error(`Failed to connect to MCP server: ${error instanceof Error ? error.message : String(error)}`);
|
package/client/bin/start.js
CHANGED
|
@@ -28,8 +28,15 @@ function getClientUrl(port, authDisabled, sessionToken, serverPort) {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
async function startDevServer(serverOptions) {
|
|
31
|
-
const {
|
|
32
|
-
|
|
31
|
+
const {
|
|
32
|
+
SERVER_PORT,
|
|
33
|
+
CLIENT_PORT,
|
|
34
|
+
sessionToken,
|
|
35
|
+
envVars,
|
|
36
|
+
abort,
|
|
37
|
+
transport,
|
|
38
|
+
serverUrl,
|
|
39
|
+
} = serverOptions;
|
|
33
40
|
const serverCommand = "npx";
|
|
34
41
|
const serverArgs = ["tsx", "watch", "--clear-screen=false", "src/index.ts"];
|
|
35
42
|
const isWindows = process.platform === "win32";
|
|
@@ -42,6 +49,8 @@ async function startDevServer(serverOptions) {
|
|
|
42
49
|
CLIENT_PORT,
|
|
43
50
|
MCP_PROXY_AUTH_TOKEN: sessionToken,
|
|
44
51
|
MCP_ENV_VARS: JSON.stringify(envVars),
|
|
52
|
+
...(transport ? { MCP_TRANSPORT: transport } : {}),
|
|
53
|
+
...(serverUrl ? { MCP_SERVER_URL: serverUrl } : {}),
|
|
45
54
|
},
|
|
46
55
|
signal: abort.signal,
|
|
47
56
|
echoOutput: true,
|
|
@@ -78,6 +87,8 @@ async function startProdServer(serverOptions) {
|
|
|
78
87
|
abort,
|
|
79
88
|
command,
|
|
80
89
|
mcpServerArgs,
|
|
90
|
+
transport,
|
|
91
|
+
serverUrl,
|
|
81
92
|
} = serverOptions;
|
|
82
93
|
const inspectorServerPath = resolve(
|
|
83
94
|
__dirname,
|
|
@@ -91,10 +102,12 @@ async function startProdServer(serverOptions) {
|
|
|
91
102
|
"node",
|
|
92
103
|
[
|
|
93
104
|
inspectorServerPath,
|
|
94
|
-
...(command ? [`--command
|
|
105
|
+
...(command ? [`--command=${command}`] : []),
|
|
95
106
|
...(mcpServerArgs && mcpServerArgs.length > 0
|
|
96
|
-
? [`--args
|
|
107
|
+
? [`--args=${mcpServerArgs.join(" ")}`]
|
|
97
108
|
: []),
|
|
109
|
+
...(transport ? [`--transport=${transport}`] : []),
|
|
110
|
+
...(serverUrl ? [`--server-url=${serverUrl}`] : []),
|
|
98
111
|
],
|
|
99
112
|
{
|
|
100
113
|
env: {
|
|
@@ -208,6 +221,8 @@ async function main() {
|
|
|
208
221
|
let command = null;
|
|
209
222
|
let parsingFlags = true;
|
|
210
223
|
let isDev = false;
|
|
224
|
+
let transport = null;
|
|
225
|
+
let serverUrl = null;
|
|
211
226
|
|
|
212
227
|
for (let i = 0; i < args.length; i++) {
|
|
213
228
|
const arg = args[i];
|
|
@@ -222,6 +237,16 @@ async function main() {
|
|
|
222
237
|
continue;
|
|
223
238
|
}
|
|
224
239
|
|
|
240
|
+
if (parsingFlags && arg === "--transport" && i + 1 < args.length) {
|
|
241
|
+
transport = args[++i];
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (parsingFlags && arg === "--server-url" && i + 1 < args.length) {
|
|
246
|
+
serverUrl = args[++i];
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
|
|
225
250
|
if (parsingFlags && arg === "-e" && i + 1 < args.length) {
|
|
226
251
|
const envVar = args[++i];
|
|
227
252
|
const equalsIndex = envVar.indexOf("=");
|
|
@@ -273,6 +298,8 @@ async function main() {
|
|
|
273
298
|
abort,
|
|
274
299
|
command,
|
|
275
300
|
mcpServerArgs,
|
|
301
|
+
transport,
|
|
302
|
+
serverUrl,
|
|
276
303
|
};
|
|
277
304
|
|
|
278
305
|
const result = isDev
|
|
@@ -1,5 +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-
|
|
2
|
-
import { p as parseOAuthCallbackParams, g as generateOAuthErrorDescription } from "./oauthUtils-DTcoXpSP.js";
|
|
1
|
+
import { u as useToast, r as reactExports, j as jsxRuntimeExports, p as parseOAuthCallbackParams, g as generateOAuthErrorDescription, S as SESSION_KEYS, I as InspectorOAuthClientProvider, a as auth } from "./index-MFoeZZBS.js";
|
|
3
2
|
const OAuthCallback = ({ onConnect }) => {
|
|
4
3
|
const { toast } = useToast();
|
|
5
4
|
const hasProcessedRef = reactExports.useRef(false);
|
package/client/dist/assets/{OAuthDebugCallback-_4BLxVDe.js → OAuthDebugCallback-BD-zJllm.js}
RENAMED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { r as reactExports, S as SESSION_KEYS, j as jsxRuntimeExports } from "./index-
|
|
2
|
-
import { p as parseOAuthCallbackParams, g as generateOAuthErrorDescription } from "./oauthUtils-DTcoXpSP.js";
|
|
1
|
+
import { r as reactExports, S as SESSION_KEYS, p as parseOAuthCallbackParams, j as jsxRuntimeExports, g as generateOAuthErrorDescription } from "./index-MFoeZZBS.js";
|
|
3
2
|
const OAuthDebugCallback = ({ onConnect }) => {
|
|
4
3
|
reactExports.useEffect(() => {
|
|
5
4
|
let isProcessed = false;
|
|
@@ -56,8 +56,6 @@ pre[class*="language-"] {
|
|
|
56
56
|
-moz-tab-size: 4;
|
|
57
57
|
-o-tab-size: 4;
|
|
58
58
|
tab-size: 4;
|
|
59
|
-
|
|
60
|
-
-webkit-hyphens: none;
|
|
61
59
|
hyphens: none;
|
|
62
60
|
}
|
|
63
61
|
|
|
@@ -1631,9 +1629,7 @@ video {
|
|
|
1631
1629
|
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
|
1632
1630
|
}
|
|
1633
1631
|
.transition {
|
|
1634
|
-
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter;
|
|
1635
1632
|
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
|
|
1636
|
-
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter;
|
|
1637
1633
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
1638
1634
|
transition-duration: 150ms;
|
|
1639
1635
|
}
|