@modelcontextprotocol/inspector 0.16.2 → 0.16.3

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 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
- await spawnPromise("node", [cliPath, args.command, ...args.args], {
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 that config and server are provided together
135
- if ((options.config && !options.server) ||
136
- (!options.config && options.server)) {
137
- throw new Error("Both --config and --server must be provided together. If you specify one, you must specify the other.");
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
- return {
145
- command: config.command,
146
- args: [...(config.args || []), ...finalArgs],
147
- envArgs: { ...(config.env || {}), ...(options.e || {}) },
148
- cli: options.cli || false,
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)}`);
@@ -28,8 +28,15 @@ function getClientUrl(port, authDisabled, sessionToken, serverPort) {
28
28
  }
29
29
 
30
30
  async function startDevServer(serverOptions) {
31
- const { SERVER_PORT, CLIENT_PORT, sessionToken, envVars, abort } =
32
- serverOptions;
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`, command] : []),
105
+ ...(command ? [`--command=${command}`] : []),
95
106
  ...(mcpServerArgs && mcpServerArgs.length > 0
96
- ? [`--args`, mcpServerArgs.join(" ")]
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,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-DLtnCiTW.js";
1
+ import { u as useToast, r as reactExports, j as jsxRuntimeExports, S as SESSION_KEYS, I as InspectorOAuthClientProvider, a as auth } from "./index-CHDvjhl9.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-DLtnCiTW.js";
1
+ import { r as reactExports, S as SESSION_KEYS, j as jsxRuntimeExports } from "./index-CHDvjhl9.js";
2
2
  import { p as parseOAuthCallbackParams, g as generateOAuthErrorDescription } from "./oauthUtils-DTcoXpSP.js";
3
3
  const OAuthDebugCallback = ({ onConnect }) => {
4
4
  reactExports.useEffect(() => {
@@ -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
  }
@@ -1,4 +1,4 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/OAuthCallback-CC1cu0Zx.js","assets/oauthUtils-DTcoXpSP.js","assets/OAuthDebugCallback-_4BLxVDe.js"])))=>i.map(i=>d[i]);
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/OAuthCallback-DCwiUoWl.js","assets/oauthUtils-DTcoXpSP.js","assets/OAuthDebugCallback-BNuktUej.js"])))=>i.map(i=>d[i]);
2
2
  function _mergeNamespaces(n, m2) {
3
3
  for (var i = 0; i < m2.length; i++) {
4
4
  const e = m2[i];
@@ -16403,10 +16403,10 @@ class DebugInspectorOAuthClientProvider extends InspectorOAuthClientProvider {
16403
16403
  );
16404
16404
  }
16405
16405
  }
16406
- let crypto;
16407
- crypto = globalThis.crypto;
16406
+ let crypto$1;
16407
+ crypto$1 = globalThis.crypto;
16408
16408
  async function getRandomValues(size2) {
16409
- return (await crypto).getRandomValues(new Uint8Array(size2));
16409
+ return (await crypto$1).getRandomValues(new Uint8Array(size2));
16410
16410
  }
16411
16411
  async function random(size2) {
16412
16412
  const mask = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~";
@@ -16422,7 +16422,7 @@ async function generateVerifier(length) {
16422
16422
  return await random(length);
16423
16423
  }
16424
16424
  async function generateChallenge(code_verifier) {
16425
- const buffer = await (await crypto).subtle.digest("SHA-256", new TextEncoder().encode(code_verifier));
16425
+ const buffer = await (await crypto$1).subtle.digest("SHA-256", new TextEncoder().encode(code_verifier));
16426
16426
  return btoa(String.fromCharCode(...new Uint8Array(buffer))).replace(/\//g, "_").replace(/\+/g, "-").replace(/=/g, "");
16427
16427
  }
16428
16428
  async function pkceChallenge(length) {
@@ -16866,7 +16866,7 @@ async function discoverAuthorizationServerMetadata(authorizationServerUrl, { fet
16866
16866
  for (const { url: endpointUrl, type: type2 } of urlsToTry) {
16867
16867
  const response = await fetchWithCorsRetry(endpointUrl, headers, fetchFn);
16868
16868
  if (!response) {
16869
- throw new Error(`CORS error trying to load ${type2 === "oauth" ? "OAuth" : "OpenID provider"} metadata from ${endpointUrl}`);
16869
+ continue;
16870
16870
  }
16871
16871
  if (!response.ok) {
16872
16872
  if (response.status >= 400 && response.status < 500) {
@@ -17095,6 +17095,12 @@ const oauthTransitions = {
17095
17095
  if (metadata.scopes_supported) {
17096
17096
  scope = metadata.scopes_supported.join(" ");
17097
17097
  }
17098
+ const array = new Uint8Array(32);
17099
+ crypto.getRandomValues(array);
17100
+ const state = Array.from(
17101
+ array,
17102
+ (byte) => byte.toString(16).padStart(2, "0")
17103
+ ).join("");
17098
17104
  const { authorizationUrl, codeVerifier } = await startAuthorization(
17099
17105
  context.serverUrl,
17100
17106
  {
@@ -17102,6 +17108,7 @@ const oauthTransitions = {
17102
17108
  clientInformation,
17103
17109
  redirectUrl: context.provider.redirectUrl,
17104
17110
  scope,
17111
+ state,
17105
17112
  resource: context.state.resource ?? void 0
17106
17113
  }
17107
17114
  );
@@ -23404,10 +23411,11 @@ class Protocol {
23404
23411
  Promise.resolve().then(() => handler(notification)).catch((error) => this._onerror(new Error(`Uncaught error in notification handler: ${error}`)));
23405
23412
  }
23406
23413
  _onrequest(request, extra) {
23407
- var _a, _b, _c, _d;
23414
+ var _a, _b;
23408
23415
  const handler = (_a = this._requestHandlers.get(request.method)) !== null && _a !== void 0 ? _a : this.fallbackRequestHandler;
23416
+ const capturedTransport = this._transport;
23409
23417
  if (handler === void 0) {
23410
- (_b = this._transport) === null || _b === void 0 ? void 0 : _b.send({
23418
+ capturedTransport === null || capturedTransport === void 0 ? void 0 : capturedTransport.send({
23411
23419
  jsonrpc: "2.0",
23412
23420
  id: request.id,
23413
23421
  error: {
@@ -23421,8 +23429,8 @@ class Protocol {
23421
23429
  this._requestHandlerAbortControllers.set(request.id, abortController);
23422
23430
  const fullExtra = {
23423
23431
  signal: abortController.signal,
23424
- sessionId: (_c = this._transport) === null || _c === void 0 ? void 0 : _c.sessionId,
23425
- _meta: (_d = request.params) === null || _d === void 0 ? void 0 : _d._meta,
23432
+ sessionId: capturedTransport === null || capturedTransport === void 0 ? void 0 : capturedTransport.sessionId,
23433
+ _meta: (_b = request.params) === null || _b === void 0 ? void 0 : _b._meta,
23426
23434
  sendNotification: (notification) => this.notification(notification, { relatedRequestId: request.id }),
23427
23435
  sendRequest: (r2, resultSchema, options) => this.request(r2, resultSchema, { ...options, relatedRequestId: request.id }),
23428
23436
  authInfo: extra === null || extra === void 0 ? void 0 : extra.authInfo,
@@ -23430,26 +23438,25 @@ class Protocol {
23430
23438
  requestInfo: extra === null || extra === void 0 ? void 0 : extra.requestInfo
23431
23439
  };
23432
23440
  Promise.resolve().then(() => handler(request, fullExtra)).then((result) => {
23433
- var _a2;
23434
23441
  if (abortController.signal.aborted) {
23435
23442
  return;
23436
23443
  }
23437
- return (_a2 = this._transport) === null || _a2 === void 0 ? void 0 : _a2.send({
23444
+ return capturedTransport === null || capturedTransport === void 0 ? void 0 : capturedTransport.send({
23438
23445
  result,
23439
23446
  jsonrpc: "2.0",
23440
23447
  id: request.id
23441
23448
  });
23442
23449
  }, (error) => {
23443
- var _a2, _b2;
23450
+ var _a2;
23444
23451
  if (abortController.signal.aborted) {
23445
23452
  return;
23446
23453
  }
23447
- return (_a2 = this._transport) === null || _a2 === void 0 ? void 0 : _a2.send({
23454
+ return capturedTransport === null || capturedTransport === void 0 ? void 0 : capturedTransport.send({
23448
23455
  jsonrpc: "2.0",
23449
23456
  id: request.id,
23450
23457
  error: {
23451
23458
  code: Number.isSafeInteger(error["code"]) ? error["code"] : ErrorCode.InternalError,
23452
- message: (_b2 = error.message) !== null && _b2 !== void 0 ? _b2 : "Internal error"
23459
+ message: (_a2 = error.message) !== null && _a2 !== void 0 ? _a2 : "Internal error"
23453
23460
  }
23454
23461
  });
23455
23462
  }).catch((error) => this._onerror(new Error(`Failed to send response: ${error}`))).finally(() => {
@@ -24779,7 +24786,7 @@ const StdErrNotificationSchema = NotificationSchema.extend({
24779
24786
  ClientNotificationSchema.or(
24780
24787
  StdErrNotificationSchema
24781
24788
  ).or(ServerNotificationSchema).or(NotificationSchema);
24782
- const version$1 = "0.16.2";
24789
+ const version$1 = "0.16.3";
24783
24790
  const packageJson = {
24784
24791
  version: version$1
24785
24792
  };
@@ -24914,7 +24921,8 @@ function useConnection({
24914
24921
  onStdErrNotification,
24915
24922
  onPendingRequest,
24916
24923
  onElicitationRequest,
24917
- getRoots
24924
+ getRoots,
24925
+ defaultLoggingLevel
24918
24926
  }) {
24919
24927
  const [connectionStatus, setConnectionStatus] = reactExports.useState("disconnected");
24920
24928
  const { toast: toast2 } = useToast();
@@ -24992,7 +25000,7 @@ function useConnection({
24992
25000
  throw e;
24993
25001
  }
24994
25002
  };
24995
- const handleCompletion = async (ref2, argName, value, signal) => {
25003
+ const handleCompletion = async (ref2, argName, value, context, signal) => {
24996
25004
  if (!mcpClient || !completionsSupported) {
24997
25005
  return [];
24998
25006
  }
@@ -25006,6 +25014,11 @@ function useConnection({
25006
25014
  ref: ref2
25007
25015
  }
25008
25016
  };
25017
+ if (context) {
25018
+ request["params"]["context"] = {
25019
+ arguments: context
25020
+ };
25021
+ }
25009
25022
  try {
25010
25023
  const response = await makeRequest(request, CompleteResultSchema, {
25011
25024
  signal,
@@ -25268,6 +25281,9 @@ function useConnection({
25268
25281
  return { roots: getRoots() };
25269
25282
  });
25270
25283
  }
25284
+ if ((capabilities == null ? void 0 : capabilities.logging) && defaultLoggingLevel) {
25285
+ await client2.setLoggingLevel(defaultLoggingLevel);
25286
+ }
25271
25287
  if (onElicitationRequest) {
25272
25288
  client2.setRequestHandler(ElicitRequestSchema, async (request) => {
25273
25289
  return new Promise((resolve) => {
@@ -29552,7 +29568,7 @@ const flip$2 = function(options) {
29552
29568
  const ignoreCrossAxisOverflow = checkCrossAxis === "alignment" ? initialSideAxis !== getSideAxis(nextPlacement) : false;
29553
29569
  if (!ignoreCrossAxisOverflow || // We leave the current main axis only if every placement on that axis
29554
29570
  // overflows the main axis.
29555
- overflowsData.every((d) => d.overflows[0] > 0 && getSideAxis(d.placement) === initialSideAxis)) {
29571
+ overflowsData.every((d) => getSideAxis(d.placement) === initialSideAxis ? d.overflows[0] > 0 : true)) {
29556
29572
  return {
29557
29573
  data: {
29558
29574
  index: nextIndex,
@@ -31767,7 +31783,7 @@ function useCompletionState(handleCompletion, completionsSupported = true, debou
31767
31783
  }, [cleanup]);
31768
31784
  const requestCompletions = reactExports.useMemo(() => {
31769
31785
  return debounce(
31770
- async (ref2, argName, value) => {
31786
+ async (ref2, argName, value, context) => {
31771
31787
  if (!completionsSupported) {
31772
31788
  return;
31773
31789
  }
@@ -31779,10 +31795,14 @@ function useCompletionState(handleCompletion, completionsSupported = true, debou
31779
31795
  loading: { ...prev.loading, [argName]: true }
31780
31796
  }));
31781
31797
  try {
31798
+ if (context !== void 0) {
31799
+ delete context[argName];
31800
+ }
31782
31801
  const values = await handleCompletion(
31783
31802
  ref2,
31784
31803
  argName,
31785
31804
  value,
31805
+ context,
31786
31806
  abortController.signal
31787
31807
  );
31788
31808
  if (!abortController.signal.aborted) {
@@ -31793,6 +31813,7 @@ function useCompletionState(handleCompletion, completionsSupported = true, debou
31793
31813
  }));
31794
31814
  }
31795
31815
  } catch {
31816
+ console.error("completion failed");
31796
31817
  if (!abortController.signal.aborted) {
31797
31818
  setState((prev) => ({
31798
31819
  ...prev,
@@ -31848,7 +31869,8 @@ const PromptsTab = ({
31848
31869
  name: selectedPrompt.name
31849
31870
  },
31850
31871
  argName,
31851
- value
31872
+ value,
31873
+ promptArgs
31852
31874
  );
31853
31875
  }
31854
31876
  };
@@ -32174,7 +32196,8 @@ const ResourcesTab = ({
32174
32196
  uri: selectedTemplate.uriTemplate
32175
32197
  },
32176
32198
  key,
32177
- value
32199
+ value,
32200
+ templateValues
32178
32201
  );
32179
32202
  }
32180
32203
  };
@@ -36263,7 +36286,7 @@ const useTheme = () => {
36263
36286
  [theme, setThemeWithSideEffect]
36264
36287
  );
36265
36288
  };
36266
- const version = "0.16.2";
36289
+ const version = "0.16.3";
36267
36290
  var [createTooltipContext, createTooltipScope] = createContextScope("Tooltip", [
36268
36291
  createPopperScope
36269
36292
  ]);
@@ -37917,6 +37940,10 @@ const ToolResults = ({
37917
37940
  )
37918
37941
  ] })
37919
37942
  ] }),
37943
+ structuredResult._meta && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4", children: [
37944
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h5", { className: "font-semibold mb-2 text-sm", children: "Meta:" }),
37945
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-gray-50 dark:bg-gray-900 p-3 rounded-lg", children: /* @__PURE__ */ jsxRuntimeExports.jsx(JsonView, { data: structuredResult._meta }) })
37946
+ ] }),
37920
37947
  !structuredResult.structuredContent && validationResult && !validationResult.isValid && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-red-100 dark:bg-red-900 text-red-800 dark:text-red-200 p-2 rounded text-sm", children: [
37921
37948
  "✗ Validation Error: ",
37922
37949
  validationResult.error
@@ -37980,6 +38007,7 @@ const ToolResults = ({
37980
38007
  }
37981
38008
  return null;
37982
38009
  };
38010
+ const hasMeta = (tool) => typeof tool._meta !== "undefined";
37983
38011
  const ToolsTab = ({
37984
38012
  tools,
37985
38013
  listTools,
@@ -37995,6 +38023,7 @@ const ToolsTab = ({
37995
38023
  const [params, setParams] = reactExports.useState({});
37996
38024
  const [isToolRunning, setIsToolRunning] = reactExports.useState(false);
37997
38025
  const [isOutputSchemaExpanded, setIsOutputSchemaExpanded] = reactExports.useState(false);
38026
+ const [isMetaExpanded, setIsMetaExpanded] = reactExports.useState(false);
37998
38027
  reactExports.useEffect(() => {
37999
38028
  const params2 = Object.entries(
38000
38029
  (selectedTool == null ? void 0 : selectedTool.inputSchema.properties) ?? []
@@ -38166,6 +38195,34 @@ const ToolsTab = ({
38166
38195
  }
38167
38196
  )
38168
38197
  ] }),
38198
+ selectedTool && hasMeta(selectedTool) && selectedTool._meta && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-gray-50 dark:bg-gray-900 p-3 rounded-lg", children: [
38199
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-2", children: [
38200
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-sm font-semibold", children: "Meta:" }),
38201
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
38202
+ Button,
38203
+ {
38204
+ size: "sm",
38205
+ variant: "ghost",
38206
+ onClick: () => setIsMetaExpanded(!isMetaExpanded),
38207
+ className: "h-6 px-2",
38208
+ children: isMetaExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
38209
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronUp, { className: "h-3 w-3 mr-1" }),
38210
+ "Collapse"
38211
+ ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
38212
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "h-3 w-3 mr-1" }),
38213
+ "Expand"
38214
+ ] })
38215
+ }
38216
+ )
38217
+ ] }),
38218
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
38219
+ "div",
38220
+ {
38221
+ className: `transition-all ${isMetaExpanded ? "" : "max-h-[8rem] overflow-y-auto"}`,
38222
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(JsonView, { data: selectedTool._meta })
38223
+ }
38224
+ )
38225
+ ] }),
38169
38226
  /* @__PURE__ */ jsxRuntimeExports.jsx(
38170
38227
  Button,
38171
38228
  {
@@ -38471,7 +38528,8 @@ const App = () => {
38471
38528
  setActiveTab("elicitations");
38472
38529
  window.location.hash = "elicitations";
38473
38530
  },
38474
- getRoots: () => rootsRef.current
38531
+ getRoots: () => rootsRef.current,
38532
+ defaultLoggingLevel: logLevel
38475
38533
  });
38476
38534
  reactExports.useEffect(() => {
38477
38535
  if (serverCapabilities) {
@@ -38624,6 +38682,14 @@ const App = () => {
38624
38682
  if (data2.defaultArgs) {
38625
38683
  setArgs(data2.defaultArgs);
38626
38684
  }
38685
+ if (data2.defaultTransport) {
38686
+ setTransportType(
38687
+ data2.defaultTransport
38688
+ );
38689
+ }
38690
+ if (data2.defaultServerUrl) {
38691
+ setSseUrl(data2.defaultServerUrl);
38692
+ }
38627
38693
  }).catch(
38628
38694
  (error) => console.error("Error fetching default environment:", error)
38629
38695
  );
@@ -38632,10 +38698,17 @@ const App = () => {
38632
38698
  rootsRef.current = roots;
38633
38699
  }, [roots]);
38634
38700
  reactExports.useEffect(() => {
38635
- if (!window.location.hash) {
38636
- window.location.hash = "resources";
38701
+ if (mcpClient && !window.location.hash) {
38702
+ const defaultTab = (serverCapabilities == null ? void 0 : serverCapabilities.resources) ? "resources" : (serverCapabilities == null ? void 0 : serverCapabilities.prompts) ? "prompts" : (serverCapabilities == null ? void 0 : serverCapabilities.tools) ? "tools" : "ping";
38703
+ window.location.hash = defaultTab;
38704
+ } else if (!mcpClient && window.location.hash) {
38705
+ window.history.replaceState(
38706
+ null,
38707
+ "",
38708
+ window.location.pathname + window.location.search
38709
+ );
38637
38710
  }
38638
- }, []);
38711
+ }, [mcpClient, serverCapabilities]);
38639
38712
  reactExports.useEffect(() => {
38640
38713
  const handleHashChange = () => {
38641
38714
  const hash = window.location.hash.slice(1);
@@ -38879,13 +38952,13 @@ const App = () => {
38879
38952
  ) });
38880
38953
  if (window.location.pathname === "/oauth/callback") {
38881
38954
  const OAuthCallback = React.lazy(
38882
- () => __vitePreload(() => import("./OAuthCallback-CC1cu0Zx.js"), true ? __vite__mapDeps([0,1]) : void 0)
38955
+ () => __vitePreload(() => import("./OAuthCallback-DCwiUoWl.js"), true ? __vite__mapDeps([0,1]) : void 0)
38883
38956
  );
38884
38957
  return /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: /* @__PURE__ */ jsxRuntimeExports.jsx(OAuthCallback, { onConnect: onOAuthConnect }) });
38885
38958
  }
38886
38959
  if (window.location.pathname === "/oauth/callback/debug") {
38887
38960
  const OAuthDebugCallback = React.lazy(
38888
- () => __vitePreload(() => import("./OAuthDebugCallback-_4BLxVDe.js"), true ? __vite__mapDeps([2,1]) : void 0)
38961
+ () => __vitePreload(() => import("./OAuthDebugCallback-BNuktUej.js"), true ? __vite__mapDeps([2,1]) : void 0)
38889
38962
  );
38890
38963
  return /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: /* @__PURE__ */ jsxRuntimeExports.jsx(OAuthDebugCallback, { onConnect: onOAuthDebugConnect }) });
38891
38964
  }
@@ -5,8 +5,8 @@
5
5
  <link rel="icon" type="image/svg+xml" href="/mcp.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>MCP Inspector</title>
8
- <script type="module" crossorigin src="/assets/index-DLtnCiTW.js"></script>
9
- <link rel="stylesheet" crossorigin href="/assets/index-BtsSr_hT.css">
8
+ <script type="module" crossorigin src="/assets/index-CHDvjhl9.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-BWZfLo5E.css">
10
10
  </head>
11
11
  <body>
12
12
  <div id="root" class="w-full"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modelcontextprotocol/inspector",
3
- "version": "0.16.2",
3
+ "version": "0.16.3",
4
4
  "description": "Model Context Protocol inspector",
5
5
  "license": "MIT",
6
6
  "author": "Anthropic, PBC (https://anthropic.com)",
@@ -47,24 +47,24 @@
47
47
  "check-version": "node scripts/check-version-consistency.js"
48
48
  },
49
49
  "dependencies": {
50
- "@modelcontextprotocol/inspector-cli": "^0.16.2",
51
- "@modelcontextprotocol/inspector-client": "^0.16.2",
52
- "@modelcontextprotocol/inspector-server": "^0.16.2",
50
+ "@modelcontextprotocol/inspector-cli": "^0.16.3",
51
+ "@modelcontextprotocol/inspector-client": "^0.16.3",
52
+ "@modelcontextprotocol/inspector-server": "^0.16.3",
53
53
  "@modelcontextprotocol/sdk": "^1.17.0",
54
- "concurrently": "^9.0.1",
55
- "open": "^10.1.0",
56
- "shell-quote": "^1.8.2",
54
+ "concurrently": "^9.2.0",
55
+ "open": "^10.2.0",
56
+ "shell-quote": "^1.8.3",
57
57
  "spawn-rx": "^5.1.2",
58
58
  "ts-node": "^10.9.2",
59
- "zod": "^3.23.8"
59
+ "zod": "^3.25.76"
60
60
  },
61
61
  "devDependencies": {
62
- "@playwright/test": "^1.52.0",
62
+ "@playwright/test": "^1.54.1",
63
63
  "@types/jest": "^29.5.14",
64
- "@types/node": "^22.7.5",
64
+ "@types/node": "^22.17.0",
65
65
  "@types/shell-quote": "^1.7.5",
66
66
  "jest-fixed-jsdom": "^0.0.9",
67
- "prettier": "3.3.3",
67
+ "prettier": "^3.6.2",
68
68
  "rimraf": "^6.0.1",
69
69
  "typescript": "^5.4.2"
70
70
  },
@@ -28,6 +28,8 @@ const { values } = parseArgs({
28
28
  env: { type: "string", default: "" },
29
29
  args: { type: "string", default: "" },
30
30
  command: { type: "string", default: "" },
31
+ transport: { type: "string", default: "" },
32
+ "server-url": { type: "string", default: "" },
31
33
  },
32
34
  });
33
35
  // Function to get HTTP headers.
@@ -399,6 +401,8 @@ app.get("/config", originValidationMiddleware, authMiddleware, (req, res) => {
399
401
  defaultEnvironment,
400
402
  defaultCommand: values.command,
401
403
  defaultArgs: values.args,
404
+ defaultTransport: values.transport,
405
+ defaultServerUrl: values["server-url"],
402
406
  });
403
407
  }
404
408
  catch (error) {