@modelcontextprotocol/inspector-client 0.15.0 → 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 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.PORT || 6274;
43
+ const port = parseInt(process.env.CLIENT_PORT || "6274", 10);
44
+ const host = process.env.HOST || "localhost";
43
45
  server.on("listening", () => {
44
- console.log(
45
- `🔍 MCP Inspector is up and running at http://127.0.0.1:${port} 🚀`,
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://127.0.0.1:${port} ❌ `,
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
@@ -7,11 +7,26 @@ import { fileURLToPath } from "url";
7
7
  import { randomBytes } from "crypto";
8
8
 
9
9
  const __dirname = dirname(fileURLToPath(import.meta.url));
10
+ const DEFAULT_MCP_PROXY_LISTEN_PORT = "6277";
10
11
 
11
12
  function delay(ms) {
12
13
  return new Promise((resolve) => setTimeout(resolve, ms, true));
13
14
  }
14
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
+
15
30
  async function startDevServer(serverOptions) {
16
31
  const { SERVER_PORT, CLIENT_PORT, sessionToken, envVars, abort } =
17
32
  serverOptions;
@@ -23,8 +38,8 @@ async function startDevServer(serverOptions) {
23
38
  cwd: resolve(__dirname, "../..", "server"),
24
39
  env: {
25
40
  ...process.env,
26
- PORT: SERVER_PORT,
27
- CLIENT_PORT: CLIENT_PORT,
41
+ SERVER_PORT,
42
+ CLIENT_PORT,
28
43
  MCP_PROXY_TOKEN: sessionToken,
29
44
  MCP_ENV_VARS: JSON.stringify(envVars),
30
45
  },
@@ -82,8 +97,8 @@ async function startProdServer(serverOptions) {
82
97
  {
83
98
  env: {
84
99
  ...process.env,
85
- PORT: SERVER_PORT,
86
- CLIENT_PORT: CLIENT_PORT,
100
+ SERVER_PORT,
101
+ CLIENT_PORT,
87
102
  MCP_PROXY_TOKEN: sessionToken,
88
103
  MCP_ENV_VARS: JSON.stringify(envVars),
89
104
  },
@@ -99,30 +114,40 @@ async function startProdServer(serverOptions) {
99
114
  }
100
115
 
101
116
  async function startDevClient(clientOptions) {
102
- const { CLIENT_PORT, authDisabled, sessionToken, abort, cancelled } =
103
- clientOptions;
117
+ const {
118
+ CLIENT_PORT,
119
+ SERVER_PORT,
120
+ authDisabled,
121
+ sessionToken,
122
+ abort,
123
+ cancelled,
124
+ } = clientOptions;
104
125
  const clientCommand = "npx";
105
- const clientArgs = ["vite", "--port", CLIENT_PORT];
126
+ const host = process.env.HOST || "localhost";
127
+ const clientArgs = ["vite", "--port", CLIENT_PORT, "--host", host];
106
128
 
107
129
  const client = spawn(clientCommand, clientArgs, {
108
130
  cwd: resolve(__dirname, ".."),
109
- env: { ...process.env, PORT: CLIENT_PORT },
131
+ env: { ...process.env, CLIENT_PORT },
110
132
  signal: abort.signal,
111
133
  echoOutput: true,
112
134
  });
113
135
 
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}`;
136
+ const url = getClientUrl(
137
+ CLIENT_PORT,
138
+ authDisabled,
139
+ sessionToken,
140
+ SERVER_PORT,
141
+ );
119
142
 
120
- // Give vite time to start before opening browser
121
- setTimeout(() => {
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...");
122
148
  open(url);
123
- console.log(`\n🔗 Opening browser at: ${url}\n`);
124
- }, 3000);
125
- }
149
+ }
150
+ }, 3000);
126
151
 
127
152
  await new Promise((resolve) => {
128
153
  client.subscribe({
@@ -139,7 +164,14 @@ async function startDevClient(clientOptions) {
139
164
  }
140
165
 
141
166
  async function startProdClient(clientOptions) {
142
- const { CLIENT_PORT, authDisabled, sessionToken, abort } = clientOptions;
167
+ const {
168
+ CLIENT_PORT,
169
+ SERVER_PORT,
170
+ authDisabled,
171
+ sessionToken,
172
+ abort,
173
+ cancelled,
174
+ } = clientOptions;
143
175
  const inspectorClientPath = resolve(
144
176
  __dirname,
145
177
  "../..",
@@ -148,16 +180,19 @@ async function startProdClient(clientOptions) {
148
180
  "client.js",
149
181
  );
150
182
 
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
- }
183
+ const url = getClientUrl(
184
+ CLIENT_PORT,
185
+ authDisabled,
186
+ sessionToken,
187
+ SERVER_PORT,
188
+ );
158
189
 
159
190
  await spawnPromise("node", [inspectorClientPath], {
160
- env: { ...process.env, PORT: CLIENT_PORT },
191
+ env: {
192
+ ...process.env,
193
+ CLIENT_PORT,
194
+ INSPECTOR_URL: url,
195
+ },
161
196
  signal: abort.signal,
162
197
  echoOutput: true,
163
198
  });
@@ -204,7 +239,7 @@ async function main() {
204
239
  }
205
240
 
206
241
  const CLIENT_PORT = process.env.CLIENT_PORT ?? "6274";
207
- const SERVER_PORT = process.env.SERVER_PORT ?? "6277";
242
+ const SERVER_PORT = process.env.SERVER_PORT ?? DEFAULT_MCP_PROXY_LISTEN_PORT;
208
243
 
209
244
  console.log(
210
245
  isDev
@@ -249,6 +284,7 @@ async function main() {
249
284
  try {
250
285
  const clientOptions = {
251
286
  CLIENT_PORT,
287
+ SERVER_PORT,
252
288
  authDisabled,
253
289
  sessionToken,
254
290
  abort,
@@ -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-BNqYF5Na.js";
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-BNqYF5Na.js";
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(() => {
@@ -1,7 +1,3 @@
1
- #root {
2
- margin: 0 auto;
3
- }
4
-
5
1
  .logo {
6
2
  height: 6em;
7
3
  padding: 1.5em;
@@ -1,4 +1,4 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/OAuthCallback-CaW3Hcqw.js","assets/oauthUtils-DTcoXpSP.js","assets/OAuthDebugCallback-DiBt_oxh.js"])))=>i.map(i=>d[i]);
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/OAuthCallback-DMQy4ibj.js","assets/oauthUtils-DTcoXpSP.js","assets/OAuthDebugCallback-9JxBAysc.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];
@@ -11612,8 +11612,9 @@ class ZodError extends Error {
11612
11612
  const formErrors = [];
11613
11613
  for (const sub of this.issues) {
11614
11614
  if (sub.path.length > 0) {
11615
- fieldErrors[sub.path[0]] = fieldErrors[sub.path[0]] || [];
11616
- fieldErrors[sub.path[0]].push(mapper(sub));
11615
+ const firstEl = sub.path[0];
11616
+ fieldErrors[firstEl] = fieldErrors[firstEl] || [];
11617
+ fieldErrors[firstEl].push(mapper(sub));
11617
11618
  } else {
11618
11619
  formErrors.push(mapper(sub));
11619
11620
  }
@@ -11689,6 +11690,8 @@ const errorMap = (issue, _ctx) => {
11689
11690
  message = `String must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `over`} ${issue.minimum} character(s)`;
11690
11691
  else if (issue.type === "number")
11691
11692
  message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;
11693
+ else if (issue.type === "bigint")
11694
+ message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;
11692
11695
  else if (issue.type === "date")
11693
11696
  message = `Date must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${new Date(Number(issue.minimum))}`;
11694
11697
  else
@@ -12241,6 +12244,8 @@ function isValidJWT(jwt, alg) {
12241
12244
  return false;
12242
12245
  try {
12243
12246
  const [header] = jwt.split(".");
12247
+ if (!header)
12248
+ return false;
12244
12249
  const base64 = header.replace(/-/g, "+").replace(/_/g, "/").padEnd(header.length + (4 - header.length % 4) % 4, "=");
12245
12250
  const decoded = JSON.parse(atob(base64));
12246
12251
  if (typeof decoded !== "object" || decoded === null)
@@ -15913,7 +15918,7 @@ const ElicitResultSchema = ResultSchema.extend({
15913
15918
  /**
15914
15919
  * The user's response action.
15915
15920
  */
15916
- action: enumType(["accept", "reject", "cancel"]),
15921
+ action: enumType(["accept", "decline", "cancel"]),
15917
15922
  /**
15918
15923
  * The collected user input content (only present if action is "accept").
15919
15924
  */
@@ -16505,7 +16510,11 @@ async function fetchWithCorsRetry(url, headers) {
16505
16510
  return await fetch(url, { headers });
16506
16511
  } catch (error) {
16507
16512
  if (error instanceof TypeError) {
16508
- return await fetch(url);
16513
+ if (headers) {
16514
+ return fetchWithCorsRetry(url);
16515
+ } else {
16516
+ return void 0;
16517
+ }
16509
16518
  }
16510
16519
  throw error;
16511
16520
  }
@@ -16524,7 +16533,7 @@ async function tryMetadataDiscovery(url, protocolVersion) {
16524
16533
  return await fetchWithCorsRetry(url, headers);
16525
16534
  }
16526
16535
  function shouldAttemptFallback(response, pathname) {
16527
- return response.status === 404 && pathname !== "/";
16536
+ return !response || response.status === 404 && pathname !== "/";
16528
16537
  }
16529
16538
  async function discoverOAuthMetadata(authorizationServerUrl, opts) {
16530
16539
  var _a;
@@ -16534,16 +16543,10 @@ async function discoverOAuthMetadata(authorizationServerUrl, opts) {
16534
16543
  const pathAwareUrl = new URL(wellKnownPath, issuer);
16535
16544
  let response = await tryMetadataDiscovery(pathAwareUrl, protocolVersion);
16536
16545
  if (shouldAttemptFallback(response, issuer.pathname)) {
16537
- try {
16538
- const rootUrl = new URL("/.well-known/oauth-authorization-server", issuer);
16539
- response = await tryMetadataDiscovery(rootUrl, protocolVersion);
16540
- if (response.status === 404) {
16541
- return void 0;
16542
- }
16543
- } catch (_b) {
16544
- return void 0;
16545
- }
16546
- } else if (response.status === 404) {
16546
+ const rootUrl = new URL("/.well-known/oauth-authorization-server", issuer);
16547
+ response = await tryMetadataDiscovery(rootUrl, protocolVersion);
16548
+ }
16549
+ if (!response || response.status === 404) {
16547
16550
  return void 0;
16548
16551
  }
16549
16552
  if (!response.ok) {
@@ -22908,38 +22911,44 @@ function validateToolOutput(toolName, structuredContent) {
22908
22911
  function hasOutputSchema(toolName) {
22909
22912
  return toolOutputValidators.has(toolName);
22910
22913
  }
22911
- function generateDefaultValue(schema) {
22912
- if ("default" in schema) {
22914
+ function generateDefaultValue(schema, propertyName, parentSchema) {
22915
+ if ("default" in schema && schema.default !== void 0) {
22913
22916
  return schema.default;
22914
22917
  }
22915
- if (!schema.required) {
22916
- if (schema.type === "array") return [];
22917
- if (schema.type === "object") return {};
22918
- return void 0;
22919
- }
22918
+ const isRequired = propertyName && parentSchema ? isPropertyRequired(propertyName, parentSchema) : false;
22920
22919
  switch (schema.type) {
22921
22920
  case "string":
22922
- return "";
22921
+ return isRequired ? "" : void 0;
22923
22922
  case "number":
22924
22923
  case "integer":
22925
- return 0;
22924
+ return isRequired ? 0 : void 0;
22926
22925
  case "boolean":
22927
- return false;
22926
+ return isRequired ? false : void 0;
22928
22927
  case "array":
22929
22928
  return [];
22930
22929
  case "object": {
22931
22930
  if (!schema.properties) return {};
22932
22931
  const obj = {};
22933
- Object.entries(schema.properties).filter(([, prop]) => prop.required).forEach(([key, prop]) => {
22934
- const value = generateDefaultValue(prop);
22935
- obj[key] = value;
22932
+ Object.entries(schema.properties).forEach(([key, prop]) => {
22933
+ if (isPropertyRequired(key, schema)) {
22934
+ const value = generateDefaultValue(prop, key, schema);
22935
+ if (value !== void 0) {
22936
+ obj[key] = value;
22937
+ }
22938
+ }
22936
22939
  });
22937
22940
  return obj;
22938
22941
  }
22939
- default:
22942
+ case "null":
22940
22943
  return null;
22944
+ default:
22945
+ return void 0;
22941
22946
  }
22942
22947
  }
22948
+ function isPropertyRequired(propertyName, schema) {
22949
+ var _a;
22950
+ return ((_a = schema.required) == null ? void 0 : _a.includes(propertyName)) ?? false;
22951
+ }
22943
22952
  const DEFAULT_REQUEST_TIMEOUT_MSEC = 6e4;
22944
22953
  class Protocol {
22945
22954
  constructor(_options) {
@@ -23900,6 +23909,7 @@ class SSEClientTransport {
23900
23909
  this._eventSourceInit = opts === null || opts === void 0 ? void 0 : opts.eventSourceInit;
23901
23910
  this._requestInit = opts === null || opts === void 0 ? void 0 : opts.requestInit;
23902
23911
  this._authProvider = opts === null || opts === void 0 ? void 0 : opts.authProvider;
23912
+ this._fetch = opts === null || opts === void 0 ? void 0 : opts.fetch;
23903
23913
  }
23904
23914
  async _authThenStart() {
23905
23915
  var _a;
@@ -23935,8 +23945,8 @@ class SSEClientTransport {
23935
23945
  return headers;
23936
23946
  }
23937
23947
  _startOrAuth() {
23938
- var _a;
23939
- const fetchImpl = ((_a = this === null || this === void 0 ? void 0 : this._eventSourceInit) === null || _a === void 0 ? void 0 : _a.fetch) || fetch;
23948
+ var _a, _b, _c;
23949
+ const fetchImpl = (_c = (_b = (_a = this === null || this === void 0 ? void 0 : this._eventSourceInit) === null || _a === void 0 ? void 0 : _a.fetch) !== null && _b !== void 0 ? _b : this._fetch) !== null && _c !== void 0 ? _c : fetch;
23940
23950
  return new Promise((resolve, reject) => {
23941
23951
  this._eventSource = new EventSource(this._url.href, {
23942
23952
  ...this._eventSourceInit,
@@ -23985,7 +23995,7 @@ class SSEClientTransport {
23985
23995
  resolve();
23986
23996
  });
23987
23997
  this._eventSource.onmessage = (event) => {
23988
- var _a2, _b;
23998
+ var _a2, _b2;
23989
23999
  const messageEvent = event;
23990
24000
  let message;
23991
24001
  try {
@@ -23994,7 +24004,7 @@ class SSEClientTransport {
23994
24004
  (_a2 = this.onerror) === null || _a2 === void 0 ? void 0 : _a2.call(this, error);
23995
24005
  return;
23996
24006
  }
23997
- (_b = this.onmessage) === null || _b === void 0 ? void 0 : _b.call(this, message);
24007
+ (_b2 = this.onmessage) === null || _b2 === void 0 ? void 0 : _b2.call(this, message);
23998
24008
  };
23999
24009
  });
24000
24010
  }
@@ -24023,7 +24033,7 @@ class SSEClientTransport {
24023
24033
  (_c = this.onclose) === null || _c === void 0 ? void 0 : _c.call(this);
24024
24034
  }
24025
24035
  async send(message) {
24026
- var _a, _b;
24036
+ var _a, _b, _c;
24027
24037
  if (!this._endpoint) {
24028
24038
  throw new Error("Not connected");
24029
24039
  }
@@ -24038,7 +24048,7 @@ class SSEClientTransport {
24038
24048
  body: JSON.stringify(message),
24039
24049
  signal: (_a = this._abortController) === null || _a === void 0 ? void 0 : _a.signal
24040
24050
  };
24041
- const response = await fetch(this._endpoint, init);
24051
+ const response = await ((_b = this._fetch) !== null && _b !== void 0 ? _b : fetch)(this._endpoint, init);
24042
24052
  if (!response.ok) {
24043
24053
  if (response.status === 401 && this._authProvider) {
24044
24054
  this._resourceMetadataUrl = extractResourceMetadataUrl(response);
@@ -24052,7 +24062,7 @@ class SSEClientTransport {
24052
24062
  throw new Error(`Error POSTing to endpoint (HTTP ${response.status}): ${text}`);
24053
24063
  }
24054
24064
  } catch (error) {
24055
- (_b = this.onerror) === null || _b === void 0 ? void 0 : _b.call(this, error);
24065
+ (_c = this.onerror) === null || _c === void 0 ? void 0 : _c.call(this, error);
24056
24066
  throw error;
24057
24067
  }
24058
24068
  }
@@ -24101,6 +24111,7 @@ class StreamableHTTPClientTransport {
24101
24111
  this._resourceMetadataUrl = void 0;
24102
24112
  this._requestInit = opts === null || opts === void 0 ? void 0 : opts.requestInit;
24103
24113
  this._authProvider = opts === null || opts === void 0 ? void 0 : opts.authProvider;
24114
+ this._fetch = opts === null || opts === void 0 ? void 0 : opts.fetch;
24104
24115
  this._sessionId = opts === null || opts === void 0 ? void 0 : opts.sessionId;
24105
24116
  this._reconnectionOptions = (_a = opts === null || opts === void 0 ? void 0 : opts.reconnectionOptions) !== null && _a !== void 0 ? _a : DEFAULT_STREAMABLE_HTTP_RECONNECTION_OPTIONS;
24106
24117
  }
@@ -24136,10 +24147,14 @@ class StreamableHTTPClientTransport {
24136
24147
  if (this._protocolVersion) {
24137
24148
  headers["mcp-protocol-version"] = this._protocolVersion;
24138
24149
  }
24139
- return new Headers({ ...headers, ...(_a = this._requestInit) === null || _a === void 0 ? void 0 : _a.headers });
24150
+ const extraHeaders = this._normalizeHeaders((_a = this._requestInit) === null || _a === void 0 ? void 0 : _a.headers);
24151
+ return new Headers({
24152
+ ...headers,
24153
+ ...extraHeaders
24154
+ });
24140
24155
  }
24141
24156
  async _startOrAuthSse(options) {
24142
- var _a, _b;
24157
+ var _a, _b, _c;
24143
24158
  const { resumptionToken } = options;
24144
24159
  try {
24145
24160
  const headers = await this._commonHeaders();
@@ -24147,10 +24162,10 @@ class StreamableHTTPClientTransport {
24147
24162
  if (resumptionToken) {
24148
24163
  headers.set("last-event-id", resumptionToken);
24149
24164
  }
24150
- const response = await fetch(this._url, {
24165
+ const response = await ((_a = this._fetch) !== null && _a !== void 0 ? _a : fetch)(this._url, {
24151
24166
  method: "GET",
24152
24167
  headers,
24153
- signal: (_a = this._abortController) === null || _a === void 0 ? void 0 : _a.signal
24168
+ signal: (_b = this._abortController) === null || _b === void 0 ? void 0 : _b.signal
24154
24169
  });
24155
24170
  if (!response.ok) {
24156
24171
  if (response.status === 401 && this._authProvider) {
@@ -24163,7 +24178,7 @@ class StreamableHTTPClientTransport {
24163
24178
  }
24164
24179
  this._handleSseStream(response.body, options);
24165
24180
  } catch (error) {
24166
- (_b = this.onerror) === null || _b === void 0 ? void 0 : _b.call(this, error);
24181
+ (_c = this.onerror) === null || _c === void 0 ? void 0 : _c.call(this, error);
24167
24182
  throw error;
24168
24183
  }
24169
24184
  }
@@ -24179,6 +24194,17 @@ class StreamableHTTPClientTransport {
24179
24194
  const maxDelay = this._reconnectionOptions.maxReconnectionDelay;
24180
24195
  return Math.min(initialDelay * Math.pow(growFactor, attempt), maxDelay);
24181
24196
  }
24197
+ _normalizeHeaders(headers) {
24198
+ if (!headers)
24199
+ return {};
24200
+ if (headers instanceof Headers) {
24201
+ return Object.fromEntries(headers.entries());
24202
+ }
24203
+ if (Array.isArray(headers)) {
24204
+ return Object.fromEntries(headers);
24205
+ }
24206
+ return { ...headers };
24207
+ }
24182
24208
  /**
24183
24209
  * Schedule a reconnection attempt with exponential backoff
24184
24210
  *
@@ -24275,7 +24301,7 @@ class StreamableHTTPClientTransport {
24275
24301
  (_b = this.onclose) === null || _b === void 0 ? void 0 : _b.call(this);
24276
24302
  }
24277
24303
  async send(message, options) {
24278
- var _a, _b, _c;
24304
+ var _a, _b, _c, _d;
24279
24305
  try {
24280
24306
  const { resumptionToken, onresumptiontoken } = options || {};
24281
24307
  if (resumptionToken) {
@@ -24295,7 +24321,7 @@ class StreamableHTTPClientTransport {
24295
24321
  body: JSON.stringify(message),
24296
24322
  signal: (_a = this._abortController) === null || _a === void 0 ? void 0 : _a.signal
24297
24323
  };
24298
- const response = await fetch(this._url, init);
24324
+ const response = await ((_b = this._fetch) !== null && _b !== void 0 ? _b : fetch)(this._url, init);
24299
24325
  const sessionId = response.headers.get("mcp-session-id");
24300
24326
  if (sessionId) {
24301
24327
  this._sessionId = sessionId;
@@ -24331,14 +24357,14 @@ class StreamableHTTPClientTransport {
24331
24357
  const data2 = await response.json();
24332
24358
  const responseMessages = Array.isArray(data2) ? data2.map((msg) => JSONRPCMessageSchema.parse(msg)) : [JSONRPCMessageSchema.parse(data2)];
24333
24359
  for (const msg of responseMessages) {
24334
- (_b = this.onmessage) === null || _b === void 0 ? void 0 : _b.call(this, msg);
24360
+ (_c = this.onmessage) === null || _c === void 0 ? void 0 : _c.call(this, msg);
24335
24361
  }
24336
24362
  } else {
24337
24363
  throw new StreamableHTTPError(-1, `Unexpected content type: ${contentType}`);
24338
24364
  }
24339
24365
  }
24340
24366
  } catch (error) {
24341
- (_c = this.onerror) === null || _c === void 0 ? void 0 : _c.call(this, error);
24367
+ (_d = this.onerror) === null || _d === void 0 ? void 0 : _d.call(this, error);
24342
24368
  throw error;
24343
24369
  }
24344
24370
  }
@@ -24357,7 +24383,7 @@ class StreamableHTTPClientTransport {
24357
24383
  * the server does not allow clients to terminate sessions.
24358
24384
  */
24359
24385
  async terminateSession() {
24360
- var _a, _b;
24386
+ var _a, _b, _c;
24361
24387
  if (!this._sessionId) {
24362
24388
  return;
24363
24389
  }
@@ -24369,13 +24395,13 @@ class StreamableHTTPClientTransport {
24369
24395
  headers,
24370
24396
  signal: (_a = this._abortController) === null || _a === void 0 ? void 0 : _a.signal
24371
24397
  };
24372
- const response = await fetch(this._url, init);
24398
+ const response = await ((_b = this._fetch) !== null && _b !== void 0 ? _b : fetch)(this._url, init);
24373
24399
  if (!response.ok && response.status !== 405) {
24374
24400
  throw new StreamableHTTPError(response.status, `Failed to terminate session: ${response.statusText}`);
24375
24401
  }
24376
24402
  this._sessionId = void 0;
24377
24403
  } catch (error) {
24378
- (_b = this.onerror) === null || _b === void 0 ? void 0 : _b.call(this, error);
24404
+ (_c = this.onerror) === null || _c === void 0 ? void 0 : _c.call(this, error);
24379
24405
  throw error;
24380
24406
  }
24381
24407
  }
@@ -24395,16 +24421,26 @@ const StdErrNotificationSchema = NotificationSchema.extend({
24395
24421
  ClientNotificationSchema.or(
24396
24422
  StdErrNotificationSchema
24397
24423
  ).or(ServerNotificationSchema).or(NotificationSchema);
24398
- const version$1 = "0.15.0";
24424
+ const version$1 = "0.16.0";
24399
24425
  const packageJson = {
24400
24426
  version: version$1
24401
24427
  };
24428
+ const getSearchParam = (key) => {
24429
+ try {
24430
+ const url = new URL(window.location.href);
24431
+ return url.searchParams.get(key);
24432
+ } catch {
24433
+ return null;
24434
+ }
24435
+ };
24402
24436
  const getMCPProxyAddress = (config) => {
24403
- const proxyFullAddress = config.MCP_PROXY_FULL_ADDRESS.value;
24437
+ let proxyFullAddress = config.MCP_PROXY_FULL_ADDRESS.value;
24404
24438
  if (proxyFullAddress) {
24439
+ proxyFullAddress = proxyFullAddress.replace(/\/+$/, "");
24405
24440
  return proxyFullAddress;
24406
24441
  }
24407
- return `${window.location.protocol}//${window.location.hostname}:${DEFAULT_MCP_PROXY_LISTEN_PORT}`;
24442
+ const proxyPort = getSearchParam("MCP_PROXY_PORT") || DEFAULT_MCP_PROXY_LISTEN_PORT;
24443
+ return `${window.location.protocol}//${window.location.hostname}:${proxyPort}`;
24408
24444
  };
24409
24445
  const getMCPServerRequestTimeout = (config) => {
24410
24446
  return config.MCP_SERVER_REQUEST_TIMEOUT.value;
@@ -24421,14 +24457,6 @@ const getMCPProxyAuthToken = (config) => {
24421
24457
  header: "X-MCP-Proxy-Auth"
24422
24458
  };
24423
24459
  };
24424
- const getSearchParam = (key) => {
24425
- try {
24426
- const url = new URL(window.location.href);
24427
- return url.searchParams.get(key);
24428
- } catch {
24429
- return null;
24430
- }
24431
- };
24432
24460
  const getInitialTransportType = () => {
24433
24461
  const param = getSearchParam("transport");
24434
24462
  if (param === "stdio" || param === "sse" || param === "streamable-http") {
@@ -26864,7 +26892,9 @@ const HistoryAndNotifications = ({
26864
26892
  "div",
26865
26893
  {
26866
26894
  className: "flex justify-between items-center cursor-pointer",
26867
- onClick: () => toggleNotificationExpansion(index2),
26895
+ onClick: () => toggleNotificationExpansion(
26896
+ serverNotifications.length - 1 - index2
26897
+ ),
26868
26898
  children: [
26869
26899
  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono", children: [
26870
26900
  serverNotifications.length - index2,
@@ -26872,11 +26902,11 @@ const HistoryAndNotifications = ({
26872
26902
  " ",
26873
26903
  notification.method
26874
26904
  ] }),
26875
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: expandedNotifications[index2] ? "▼" : "▶" })
26905
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: expandedNotifications[serverNotifications.length - 1 - index2] ? "▼" : "▶" })
26876
26906
  ]
26877
26907
  }
26878
26908
  ),
26879
- expandedNotifications[index2] && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2", children: [
26909
+ expandedNotifications[serverNotifications.length - 1 - index2] && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2", children: [
26880
26910
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex justify-between items-center mb-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-purple-600", children: "Details:" }) }),
26881
26911
  /* @__PURE__ */ jsxRuntimeExports.jsx(
26882
26912
  JsonView,
@@ -31455,9 +31485,9 @@ const PromptsTab = ({
31455
31485
  setSelectedPrompt(prompt);
31456
31486
  setPromptArgs({});
31457
31487
  },
31458
- renderItem: (prompt) => /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
31488
+ renderItem: (prompt) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-start", children: [
31459
31489
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1", children: prompt.name }),
31460
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm text-gray-500", children: prompt.description })
31490
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm text-gray-500 text-left", children: prompt.description })
31461
31491
  ] }),
31462
31492
  title: "Prompts",
31463
31493
  buttonText: nextCursor ? "List More Prompts" : "List Prompts",
@@ -33916,10 +33946,37 @@ const JsonEditor = ({
33916
33946
  const isSimpleObject = (schema) => {
33917
33947
  const supportedTypes = ["string", "number", "integer", "boolean", "null"];
33918
33948
  if (supportedTypes.includes(schema.type)) return true;
33919
- if (schema.type !== "object") return false;
33920
- return Object.values(schema.properties ?? {}).every(
33921
- (prop) => supportedTypes.includes(prop.type)
33922
- );
33949
+ if (schema.type === "object") {
33950
+ return Object.values(schema.properties ?? {}).every(
33951
+ (prop) => supportedTypes.includes(prop.type)
33952
+ );
33953
+ }
33954
+ if (schema.type === "array") {
33955
+ return !!schema.items && isSimpleObject(schema.items);
33956
+ }
33957
+ return false;
33958
+ };
33959
+ const getArrayItemDefault = (schema) => {
33960
+ if ("default" in schema && schema.default !== void 0) {
33961
+ return schema.default;
33962
+ }
33963
+ switch (schema.type) {
33964
+ case "string":
33965
+ return "";
33966
+ case "number":
33967
+ case "integer":
33968
+ return 0;
33969
+ case "boolean":
33970
+ return false;
33971
+ case "array":
33972
+ return [];
33973
+ case "object":
33974
+ return {};
33975
+ case "null":
33976
+ return null;
33977
+ default:
33978
+ return null;
33979
+ }
33923
33980
  };
33924
33981
  const DynamicJsonForm = ({
33925
33982
  schema,
@@ -33930,6 +33987,8 @@ const DynamicJsonForm = ({
33930
33987
  const isOnlyJSON = !isSimpleObject(schema);
33931
33988
  const [isJsonMode, setIsJsonMode] = reactExports.useState(isOnlyJSON);
33932
33989
  const [jsonError, setJsonError] = reactExports.useState();
33990
+ const [copiedJson, setCopiedJson] = reactExports.useState(false);
33991
+ const { toast: toast2 } = useToast();
33933
33992
  const [rawJsonValue, setRawJsonValue] = reactExports.useState(
33934
33993
  JSON.stringify(value ?? generateDefaultValue(schema), null, 2)
33935
33994
  );
@@ -33987,13 +34046,14 @@ const DynamicJsonForm = ({
33987
34046
  setJsonError(err instanceof Error ? err.message : "Invalid JSON");
33988
34047
  }
33989
34048
  };
33990
- const renderFormFields = (propSchema, currentValue, path = [], depth = 0) => {
34049
+ const renderFormFields = (propSchema, currentValue, path = [], depth = 0, parentSchema, propertyName) => {
34050
+ var _a, _b, _c;
33991
34051
  if (depth >= maxDepth && (propSchema.type === "object" || propSchema.type === "array")) {
33992
34052
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
33993
34053
  JsonEditor,
33994
34054
  {
33995
34055
  value: JSON.stringify(
33996
- currentValue ?? generateDefaultValue(propSchema),
34056
+ currentValue ?? generateDefaultValue(propSchema, propertyName, parentSchema),
33997
34057
  null,
33998
34058
  2
33999
34059
  ),
@@ -34010,6 +34070,7 @@ const DynamicJsonForm = ({
34010
34070
  }
34011
34071
  );
34012
34072
  }
34073
+ const isRequired = ((_a = parentSchema == null ? void 0 : parentSchema.required) == null ? void 0 : _a.includes(propertyName || "")) ?? false;
34013
34074
  switch (propSchema.type) {
34014
34075
  case "string":
34015
34076
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -34019,14 +34080,10 @@ const DynamicJsonForm = ({
34019
34080
  value: currentValue ?? "",
34020
34081
  onChange: (e) => {
34021
34082
  const val = e.target.value;
34022
- if (!val && !propSchema.required) {
34023
- handleFieldChange(path, void 0);
34024
- } else {
34025
- handleFieldChange(path, val);
34026
- }
34083
+ handleFieldChange(path, val);
34027
34084
  },
34028
34085
  placeholder: propSchema.description,
34029
- required: propSchema.required
34086
+ required: isRequired
34030
34087
  }
34031
34088
  );
34032
34089
  case "number":
@@ -34037,7 +34094,7 @@ const DynamicJsonForm = ({
34037
34094
  value: (currentValue == null ? void 0 : currentValue.toString()) ?? "",
34038
34095
  onChange: (e) => {
34039
34096
  const val = e.target.value;
34040
- if (!val && !propSchema.required) {
34097
+ if (!val && !isRequired) {
34041
34098
  handleFieldChange(path, void 0);
34042
34099
  } else {
34043
34100
  const num = Number(val);
@@ -34047,7 +34104,7 @@ const DynamicJsonForm = ({
34047
34104
  }
34048
34105
  },
34049
34106
  placeholder: propSchema.description,
34050
- required: propSchema.required
34107
+ required: isRequired
34051
34108
  }
34052
34109
  );
34053
34110
  case "integer":
@@ -34059,7 +34116,7 @@ const DynamicJsonForm = ({
34059
34116
  value: (currentValue == null ? void 0 : currentValue.toString()) ?? "",
34060
34117
  onChange: (e) => {
34061
34118
  const val = e.target.value;
34062
- if (!val && !propSchema.required) {
34119
+ if (!val && !isRequired) {
34063
34120
  handleFieldChange(path, void 0);
34064
34121
  } else {
34065
34122
  const num = Number(val);
@@ -34069,7 +34126,7 @@ const DynamicJsonForm = ({
34069
34126
  }
34070
34127
  },
34071
34128
  placeholder: propSchema.description,
34072
- required: propSchema.required
34129
+ required: isRequired
34073
34130
  }
34074
34131
  );
34075
34132
  case "boolean":
@@ -34080,9 +34137,116 @@ const DynamicJsonForm = ({
34080
34137
  checked: currentValue ?? false,
34081
34138
  onChange: (e) => handleFieldChange(path, e.target.checked),
34082
34139
  className: "w-4 h-4",
34083
- required: propSchema.required
34140
+ required: isRequired
34141
+ }
34142
+ );
34143
+ case "object":
34144
+ if (!propSchema.properties) {
34145
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
34146
+ JsonEditor,
34147
+ {
34148
+ value: JSON.stringify(currentValue ?? {}, null, 2),
34149
+ onChange: (newValue) => {
34150
+ try {
34151
+ const parsed = JSON.parse(newValue);
34152
+ handleFieldChange(path, parsed);
34153
+ setJsonError(void 0);
34154
+ } catch (err) {
34155
+ setJsonError(
34156
+ err instanceof Error ? err.message : "Invalid JSON"
34157
+ );
34158
+ }
34159
+ },
34160
+ error: jsonError
34161
+ }
34162
+ );
34163
+ }
34164
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2 border rounded p-3", children: Object.entries(propSchema.properties).map(([key, subSchema]) => {
34165
+ var _a2;
34166
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
34167
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm font-medium mb-1", children: [
34168
+ key,
34169
+ ((_a2 = propSchema.required) == null ? void 0 : _a2.includes(key)) && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500 ml-1", children: "*" })
34170
+ ] }),
34171
+ renderFormFields(
34172
+ subSchema,
34173
+ currentValue == null ? void 0 : currentValue[key],
34174
+ [...path, key],
34175
+ depth + 1,
34176
+ propSchema,
34177
+ key
34178
+ )
34179
+ ] }, key);
34180
+ }) });
34181
+ case "array": {
34182
+ const arrayValue = Array.isArray(currentValue) ? currentValue : [];
34183
+ if (!propSchema.items) return null;
34184
+ if (isSimpleObject(propSchema.items)) {
34185
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
34186
+ propSchema.description && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600", children: propSchema.description }),
34187
+ ((_b = propSchema.items) == null ? void 0 : _b.description) && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-gray-500", children: [
34188
+ "Items: ",
34189
+ propSchema.items.description
34190
+ ] }),
34191
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
34192
+ arrayValue.map((item, index2) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
34193
+ renderFormFields(
34194
+ propSchema.items,
34195
+ item,
34196
+ [...path, index2.toString()],
34197
+ depth + 1
34198
+ ),
34199
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
34200
+ Button,
34201
+ {
34202
+ variant: "outline",
34203
+ size: "sm",
34204
+ onClick: () => {
34205
+ const newArray = [...arrayValue];
34206
+ newArray.splice(index2, 1);
34207
+ handleFieldChange(path, newArray);
34208
+ },
34209
+ children: "Remove"
34210
+ }
34211
+ )
34212
+ ] }, index2)),
34213
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
34214
+ Button,
34215
+ {
34216
+ variant: "outline",
34217
+ size: "sm",
34218
+ onClick: () => {
34219
+ const defaultValue = getArrayItemDefault(
34220
+ propSchema.items
34221
+ );
34222
+ handleFieldChange(path, [...arrayValue, defaultValue]);
34223
+ },
34224
+ title: ((_c = propSchema.items) == null ? void 0 : _c.description) ? `Add new ${propSchema.items.description}` : "Add new item",
34225
+ children: "Add Item"
34226
+ }
34227
+ )
34228
+ ] })
34229
+ ] });
34230
+ }
34231
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
34232
+ JsonEditor,
34233
+ {
34234
+ value: JSON.stringify(currentValue ?? [], null, 2),
34235
+ onChange: (newValue) => {
34236
+ try {
34237
+ const parsed = JSON.parse(newValue);
34238
+ handleFieldChange(path, parsed);
34239
+ setJsonError(void 0);
34240
+ } catch (err) {
34241
+ setJsonError(
34242
+ err instanceof Error ? err.message : "Invalid JSON"
34243
+ );
34244
+ }
34245
+ },
34246
+ error: jsonError
34084
34247
  }
34085
34248
  );
34249
+ }
34086
34250
  default:
34087
34251
  return null;
34088
34252
  }
@@ -34106,18 +34270,57 @@ const DynamicJsonForm = ({
34106
34270
  setIsJsonMode(true);
34107
34271
  }
34108
34272
  }, [shouldUseJsonMode, isJsonMode]);
34273
+ const handleCopyJson = reactExports.useCallback(() => {
34274
+ const copyToClipboard = async () => {
34275
+ try {
34276
+ await navigator.clipboard.writeText(
34277
+ JSON.stringify(value, null, 2) ?? "[]"
34278
+ );
34279
+ setCopiedJson(true);
34280
+ toast2({
34281
+ title: "JSON copied",
34282
+ description: "The JSON data has been successfully copied to your clipboard."
34283
+ });
34284
+ setTimeout(() => {
34285
+ setCopiedJson(false);
34286
+ }, 2e3);
34287
+ } catch (error) {
34288
+ toast2({
34289
+ title: "Error",
34290
+ description: `Failed to copy JSON: ${error instanceof Error ? error.message : String(error)}`,
34291
+ variant: "destructive"
34292
+ });
34293
+ }
34294
+ };
34295
+ copyToClipboard();
34296
+ }, [toast2, value]);
34109
34297
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
34110
34298
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-end space-x-2", children: [
34111
- isJsonMode && /* @__PURE__ */ jsxRuntimeExports.jsx(
34112
- Button,
34113
- {
34114
- type: "button",
34115
- variant: "outline",
34116
- size: "sm",
34117
- onClick: formatJson,
34118
- children: "Format JSON"
34119
- }
34120
- ),
34299
+ isJsonMode && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
34300
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
34301
+ Button,
34302
+ {
34303
+ type: "button",
34304
+ variant: "outline",
34305
+ size: "sm",
34306
+ onClick: handleCopyJson,
34307
+ children: [
34308
+ copiedJson ? /* @__PURE__ */ jsxRuntimeExports.jsx(CheckCheck, { className: "h-4 w-4 mr-2" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "h-4 w-4 mr-2" }),
34309
+ "Copy JSON"
34310
+ ]
34311
+ }
34312
+ ),
34313
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
34314
+ Button,
34315
+ {
34316
+ type: "button",
34317
+ variant: "outline",
34318
+ size: "sm",
34319
+ onClick: formatJson,
34320
+ children: "Format JSON"
34321
+ }
34322
+ )
34323
+ ] }),
34121
34324
  !isOnlyJSON && /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", size: "sm", onClick: handleSwitchToFormMode, children: isJsonMode ? "Switch to Form" : "Switch to JSON" })
34122
34325
  ] }),
34123
34326
  isJsonMode ? /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -35595,7 +35798,7 @@ const useTheme = () => {
35595
35798
  [theme, setThemeWithSideEffect]
35596
35799
  );
35597
35800
  };
35598
- const version = "0.15.0";
35801
+ const version = "0.16.0";
35599
35802
  var [createTooltipContext, createTooltipScope] = createContextScope("Tooltip", [
35600
35803
  createPopperScope
35601
35804
  ]);
@@ -37204,7 +37407,11 @@ const ToolsTab = ({
37204
37407
  (selectedTool == null ? void 0 : selectedTool.inputSchema.properties) ?? []
37205
37408
  ).map(([key, value]) => [
37206
37409
  key,
37207
- generateDefaultValue(value)
37410
+ generateDefaultValue(
37411
+ value,
37412
+ key,
37413
+ selectedTool == null ? void 0 : selectedTool.inputSchema
37414
+ )
37208
37415
  ]);
37209
37416
  setParams(Object.fromEntries(params2));
37210
37417
  }, [selectedTool]);
@@ -37235,13 +37442,18 @@ const ToolsTab = ({
37235
37442
  Object.entries(selectedTool.inputSchema.properties ?? []).map(
37236
37443
  ([key, value]) => {
37237
37444
  const prop = value;
37445
+ const inputSchema = selectedTool.inputSchema;
37446
+ const required2 = isPropertyRequired(key, inputSchema);
37238
37447
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
37239
- /* @__PURE__ */ jsxRuntimeExports.jsx(
37448
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
37240
37449
  Label$1,
37241
37450
  {
37242
37451
  htmlFor: key,
37243
37452
  className: "block text-sm font-medium text-gray-700 dark:text-gray-300",
37244
- children: key
37453
+ children: [
37454
+ key,
37455
+ required2 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500 ml-1", children: "*" })
37456
+ ]
37245
37457
  }
37246
37458
  ),
37247
37459
  prop.type === "boolean" ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center space-x-2 mt-2", children: [
@@ -37303,10 +37515,13 @@ const ToolsTab = ({
37303
37515
  name: key,
37304
37516
  placeholder: prop.description,
37305
37517
  value: params[key] ?? "",
37306
- onChange: (e) => setParams({
37307
- ...params,
37308
- [key]: Number(e.target.value)
37309
- }),
37518
+ onChange: (e) => {
37519
+ const value2 = e.target.value;
37520
+ setParams({
37521
+ ...params,
37522
+ [key]: value2 === "" ? "" : Number(value2)
37523
+ });
37524
+ },
37310
37525
  className: "mt-1"
37311
37526
  }
37312
37527
  ) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -37816,13 +38031,13 @@ const App = () => {
37816
38031
  ) });
37817
38032
  if (window.location.pathname === "/oauth/callback") {
37818
38033
  const OAuthCallback = React.lazy(
37819
- () => __vitePreload(() => import("./OAuthCallback-CaW3Hcqw.js"), true ? __vite__mapDeps([0,1]) : void 0)
38034
+ () => __vitePreload(() => import("./OAuthCallback-DMQy4ibj.js"), true ? __vite__mapDeps([0,1]) : void 0)
37820
38035
  );
37821
38036
  return /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: /* @__PURE__ */ jsxRuntimeExports.jsx(OAuthCallback, { onConnect: onOAuthConnect }) });
37822
38037
  }
37823
38038
  if (window.location.pathname === "/oauth/callback/debug") {
37824
38039
  const OAuthDebugCallback = React.lazy(
37825
- () => __vitePreload(() => import("./OAuthDebugCallback-DiBt_oxh.js"), true ? __vite__mapDeps([2,1]) : void 0)
38040
+ () => __vitePreload(() => import("./OAuthDebugCallback-9JxBAysc.js"), true ? __vite__mapDeps([2,1]) : void 0)
37826
38041
  );
37827
38042
  return /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: /* @__PURE__ */ jsxRuntimeExports.jsx(OAuthDebugCallback, { onConnect: onOAuthDebugConnect }) });
37828
38043
  }
package/dist/index.html CHANGED
@@ -5,10 +5,10 @@
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-BNqYF5Na.js"></script>
9
- <link rel="stylesheet" crossorigin href="/assets/index-C1MLjTGf.css">
8
+ <script type="module" crossorigin src="/assets/index-DI7JCTeu.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-BwWj6LL9.css">
10
10
  </head>
11
11
  <body>
12
- <div id="root"></div>
12
+ <div id="root" class="w-full"></div>
13
13
  </body>
14
14
  </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modelcontextprotocol/inspector-client",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "description": "Client-side application for the Model Context Protocol inspector",
5
5
  "license": "MIT",
6
6
  "author": "Anthropic, PBC (https://anthropic.com)",