@modelcontextprotocol/inspector 0.4.0 → 0.4.1

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.
@@ -1,4 +1,4 @@
1
- import { r as reactExports, j as jsxRuntimeExports, S as SESSION_KEYS, h as handleOAuthCallback } from "./index-DjoEM10P.js";
1
+ import { r as reactExports, j as jsxRuntimeExports, S as SESSION_KEYS, h as handleOAuthCallback } from "./index-DVugRvpa.js";
2
2
  const OAuthCallback = () => {
3
3
  const hasProcessedRef = reactExports.useRef(false);
4
4
  reactExports.useEffect(() => {
@@ -16,8 +16,14 @@ const OAuthCallback = () => {
16
16
  return;
17
17
  }
18
18
  try {
19
- const accessToken = await handleOAuthCallback(serverUrl, code);
20
- sessionStorage.setItem(SESSION_KEYS.ACCESS_TOKEN, accessToken);
19
+ const tokens = await handleOAuthCallback(serverUrl, code);
20
+ sessionStorage.setItem(SESSION_KEYS.ACCESS_TOKEN, tokens.access_token);
21
+ if (tokens.refresh_token) {
22
+ sessionStorage.setItem(
23
+ SESSION_KEYS.REFRESH_TOKEN,
24
+ tokens.refresh_token
25
+ );
26
+ }
21
27
  window.location.href = `/?serverUrl=${encodeURIComponent(serverUrl)}`;
22
28
  } catch (error) {
23
29
  console.error("OAuth callback error:", error);
@@ -11230,16 +11230,32 @@ ZodReadonly.create = (type, params2) => {
11230
11230
  ...processCreateParams(params2)
11231
11231
  });
11232
11232
  };
11233
- function custom(check, params2 = {}, fatal) {
11233
+ function cleanParams(params2, data) {
11234
+ const p2 = typeof params2 === "function" ? params2(data) : typeof params2 === "string" ? { message: params2 } : params2;
11235
+ const p22 = typeof p2 === "string" ? { message: p2 } : p2;
11236
+ return p22;
11237
+ }
11238
+ function custom(check, _params = {}, fatal) {
11234
11239
  if (check)
11235
11240
  return ZodAny.create().superRefine((data, ctx) => {
11236
11241
  var _a, _b;
11237
- if (!check(data)) {
11238
- const p2 = typeof params2 === "function" ? params2(data) : typeof params2 === "string" ? { message: params2 } : params2;
11239
- const _fatal = (_b = (_a = p2.fatal) !== null && _a !== void 0 ? _a : fatal) !== null && _b !== void 0 ? _b : true;
11240
- const p22 = typeof p2 === "string" ? { message: p2 } : p2;
11241
- ctx.addIssue({ code: "custom", ...p22, fatal: _fatal });
11242
+ const r2 = check(data);
11243
+ if (r2 instanceof Promise) {
11244
+ return r2.then((r3) => {
11245
+ var _a2, _b2;
11246
+ if (!r3) {
11247
+ const params2 = cleanParams(_params, data);
11248
+ const _fatal = (_b2 = (_a2 = params2.fatal) !== null && _a2 !== void 0 ? _a2 : fatal) !== null && _b2 !== void 0 ? _b2 : true;
11249
+ ctx.addIssue({ code: "custom", ...params2, fatal: _fatal });
11250
+ }
11251
+ });
11242
11252
  }
11253
+ if (!r2) {
11254
+ const params2 = cleanParams(_params, data);
11255
+ const _fatal = (_b = (_a = params2.fatal) !== null && _a !== void 0 ? _a : fatal) !== null && _b !== void 0 ? _b : true;
11256
+ ctx.addIssue({ code: "custom", ...params2, fatal: _fatal });
11257
+ }
11258
+ return;
11243
11259
  });
11244
11260
  return ZodAny.create();
11245
11261
  }
@@ -13118,27 +13134,39 @@ async function pkceChallenge(length) {
13118
13134
  const SESSION_KEYS = {
13119
13135
  CODE_VERIFIER: "mcp_code_verifier",
13120
13136
  SERVER_URL: "mcp_server_url",
13121
- ACCESS_TOKEN: "mcp_access_token"
13137
+ ACCESS_TOKEN: "mcp_access_token",
13138
+ REFRESH_TOKEN: "mcp_refresh_token"
13122
13139
  };
13140
+ const OAuthMetadataSchema = z.object({
13141
+ authorization_endpoint: z.string(),
13142
+ token_endpoint: z.string()
13143
+ });
13144
+ const OAuthTokensSchema = z.object({
13145
+ access_token: z.string(),
13146
+ refresh_token: z.string().optional(),
13147
+ expires_in: z.number().optional()
13148
+ });
13123
13149
  async function discoverOAuthMetadata(serverUrl) {
13124
13150
  try {
13125
13151
  const url = new URL("/.well-known/oauth-authorization-server", serverUrl);
13126
13152
  const response = await fetch(url.toString());
13127
13153
  if (response.ok) {
13128
13154
  const metadata = await response.json();
13129
- return {
13155
+ const validatedMetadata = OAuthMetadataSchema.parse({
13130
13156
  authorization_endpoint: metadata.authorization_endpoint,
13131
13157
  token_endpoint: metadata.token_endpoint
13132
- };
13158
+ });
13159
+ return validatedMetadata;
13133
13160
  }
13134
13161
  } catch (error) {
13135
13162
  console.warn("OAuth metadata discovery failed:", error);
13136
13163
  }
13137
13164
  const baseUrl = new URL(serverUrl);
13138
- return {
13165
+ const defaultMetadata = {
13139
13166
  authorization_endpoint: new URL("/authorize", baseUrl).toString(),
13140
13167
  token_endpoint: new URL("/token", baseUrl).toString()
13141
13168
  };
13169
+ return OAuthMetadataSchema.parse(defaultMetadata);
13142
13170
  }
13143
13171
  async function startOAuthFlow(serverUrl) {
13144
13172
  const challenge = await pkceChallenge();
@@ -13177,8 +13205,30 @@ async function handleOAuthCallback(serverUrl, code) {
13177
13205
  if (!response.ok) {
13178
13206
  throw new Error("Token exchange failed");
13179
13207
  }
13180
- const data = await response.json();
13181
- return data.access_token;
13208
+ const tokens = await response.json();
13209
+ return OAuthTokensSchema.parse(tokens);
13210
+ }
13211
+ async function refreshAccessToken(serverUrl) {
13212
+ const refreshToken = sessionStorage.getItem(SESSION_KEYS.REFRESH_TOKEN);
13213
+ if (!refreshToken) {
13214
+ throw new Error("No refresh token available");
13215
+ }
13216
+ const metadata = await discoverOAuthMetadata(serverUrl);
13217
+ const response = await fetch(metadata.token_endpoint, {
13218
+ method: "POST",
13219
+ headers: {
13220
+ "Content-Type": "application/json"
13221
+ },
13222
+ body: JSON.stringify({
13223
+ grant_type: "refresh_token",
13224
+ refresh_token: refreshToken
13225
+ })
13226
+ });
13227
+ if (!response.ok) {
13228
+ throw new Error("Token refresh failed");
13229
+ }
13230
+ const tokens = await response.json();
13231
+ return OAuthTokensSchema.parse(tokens);
13182
13232
  }
13183
13233
  const StdErrNotificationSchema = NotificationSchema.extend({
13184
13234
  method: z.literal("notifications/stderr"),
@@ -13257,7 +13307,46 @@ function useConnection({
13257
13307
  throw e;
13258
13308
  }
13259
13309
  };
13260
- const connect = async () => {
13310
+ const initiateOAuthFlow = async () => {
13311
+ sessionStorage.removeItem(SESSION_KEYS.ACCESS_TOKEN);
13312
+ sessionStorage.removeItem(SESSION_KEYS.REFRESH_TOKEN);
13313
+ sessionStorage.setItem(SESSION_KEYS.SERVER_URL, sseUrl);
13314
+ const redirectUrl = await startOAuthFlow(sseUrl);
13315
+ window.location.href = redirectUrl;
13316
+ };
13317
+ const handleTokenRefresh = async () => {
13318
+ try {
13319
+ const tokens = await refreshAccessToken(sseUrl);
13320
+ sessionStorage.setItem(SESSION_KEYS.ACCESS_TOKEN, tokens.access_token);
13321
+ if (tokens.refresh_token) {
13322
+ sessionStorage.setItem(
13323
+ SESSION_KEYS.REFRESH_TOKEN,
13324
+ tokens.refresh_token
13325
+ );
13326
+ }
13327
+ return tokens.access_token;
13328
+ } catch (error) {
13329
+ console.error("Token refresh failed:", error);
13330
+ await initiateOAuthFlow();
13331
+ throw error;
13332
+ }
13333
+ };
13334
+ const handleAuthError = async (error) => {
13335
+ if (error instanceof SseError && error.code === 401) {
13336
+ if (sessionStorage.getItem(SESSION_KEYS.REFRESH_TOKEN)) {
13337
+ try {
13338
+ await handleTokenRefresh();
13339
+ return true;
13340
+ } catch (error2) {
13341
+ console.error("Token refresh failed:", error2);
13342
+ }
13343
+ } else {
13344
+ await initiateOAuthFlow();
13345
+ }
13346
+ }
13347
+ return false;
13348
+ };
13349
+ const connect = async (_e, retryCount = 0) => {
13261
13350
  try {
13262
13351
  const client = new Client(
13263
13352
  {
@@ -13311,10 +13400,11 @@ function useConnection({
13311
13400
  await client.connect(clientTransport);
13312
13401
  } catch (error) {
13313
13402
  console.error("Failed to connect to MCP server:", error);
13403
+ const shouldRetry = await handleAuthError(error);
13404
+ if (shouldRetry) {
13405
+ return connect(void 0, retryCount + 1);
13406
+ }
13314
13407
  if (error instanceof SseError && error.code === 401) {
13315
- sessionStorage.setItem(SESSION_KEYS.SERVER_URL, sseUrl);
13316
- const redirectUrl = await startOAuthFlow(sseUrl);
13317
- window.location.href = redirectUrl;
13318
13408
  return;
13319
13409
  }
13320
13410
  throw error;
@@ -13520,11 +13610,11 @@ var SlotClone = reactExports.forwardRef((props, forwardedRef) => {
13520
13610
  const { children, ...slotProps } = props;
13521
13611
  if (reactExports.isValidElement(children)) {
13522
13612
  const childrenRef = getElementRef$1(children);
13523
- return reactExports.cloneElement(children, {
13524
- ...mergeProps(slotProps, children.props),
13525
- // @ts-ignore
13526
- ref: forwardedRef ? composeRefs(forwardedRef, childrenRef) : childrenRef
13527
- });
13613
+ const props2 = mergeProps(slotProps, children.props);
13614
+ if (children.type !== reactExports.Fragment) {
13615
+ props2.ref = forwardedRef ? composeRefs(forwardedRef, childrenRef) : childrenRef;
13616
+ }
13617
+ return reactExports.cloneElement(children, props2);
13528
13618
  }
13529
13619
  return reactExports.Children.count(children) > 1 ? reactExports.Children.only(null) : null;
13530
13620
  });
@@ -22560,7 +22650,7 @@ const useTheme = () => {
22560
22650
  }, [])
22561
22651
  ];
22562
22652
  };
22563
- const version = "0.4.0";
22653
+ const version = "0.4.1";
22564
22654
  const Sidebar = ({
22565
22655
  connectionStatus,
22566
22656
  transportType,
@@ -23012,7 +23102,7 @@ const PROXY_SERVER_URL = `http://localhost:${PROXY_PORT}`;
23012
23102
  const App = () => {
23013
23103
  if (window.location.pathname === "/oauth/callback") {
23014
23104
  const OAuthCallback = React.lazy(
23015
- () => __vitePreload(() => import("./OAuthCallback-HUNd2OJn.js"), true ? [] : void 0)
23105
+ () => __vitePreload(() => import("./OAuthCallback-DCSQTqKf.js"), true ? [] : void 0)
23016
23106
  );
23017
23107
  return /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: /* @__PURE__ */ jsxRuntimeExports.jsx(OAuthCallback, {}) });
23018
23108
  }
@@ -5,7 +5,7 @@
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-DjoEM10P.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-DVugRvpa.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="/assets/index-eOhPEcGC.css">
10
10
  </head>
11
11
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modelcontextprotocol/inspector",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Model Context Protocol inspector",
5
5
  "license": "MIT",
6
6
  "author": "Anthropic, PBC (https://anthropic.com)",
@@ -33,8 +33,8 @@
33
33
  "publish-all": "npm publish --workspaces --access public && npm publish --access public"
34
34
  },
35
35
  "dependencies": {
36
- "@modelcontextprotocol/inspector-client": "0.3.0",
37
- "@modelcontextprotocol/inspector-server": "0.3.0",
36
+ "@modelcontextprotocol/inspector-client": "0.4.1",
37
+ "@modelcontextprotocol/inspector-server": "0.4.1",
38
38
  "concurrently": "^9.0.1",
39
39
  "shell-quote": "^1.8.2",
40
40
  "spawn-rx": "^5.1.0",
@@ -145,4 +145,15 @@ app.get("/config", (req, res) => {
145
145
  }
146
146
  });
147
147
  const PORT = process.env.PORT || 3000;
148
- app.listen(PORT, () => { });
148
+ try {
149
+ const server = app.listen(PORT);
150
+ server.on("listening", () => {
151
+ const addr = server.address();
152
+ const port = typeof addr === "string" ? addr : addr?.port;
153
+ console.log(`Proxy server listening on port ${port}`);
154
+ });
155
+ }
156
+ catch (error) {
157
+ console.error("Failed to start server:", error);
158
+ process.exit(1);
159
+ }