@modelcontextprotocol/inspector 1.0.1 → 1.0.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
@@ -213,6 +213,10 @@ If you need to disable authentication (NOT RECOMMENDED), you can set the `DANGER
213
213
  DANGEROUSLY_OMIT_AUTH=true npm start
214
214
  ```
215
215
 
216
+ Only `true`, `1` or `yes` (case-insensitive) disable authentication. Any other value, including `false`, `0` or an empty string, leaves it enabled.
217
+
218
+ While authentication is disabled, the proxy accepts only requests that carry an `Origin` header from an allowed origin (see `ALLOWED_ORIGINS` below), which the Inspector web client sends in its default setup, where it and the proxy run on different ports. Non-browser clients that send no `Origin` header need authentication enabled and the session token.
219
+
216
220
  ---
217
221
 
218
222
  **🚨 WARNING 🚨**
@@ -247,6 +251,18 @@ To prevent DNS rebinding attacks, the MCP Inspector validates the `Origin` heade
247
251
  ALLOWED_ORIGINS=http://localhost:6274,http://localhost:8000 npm start
248
252
  ```
249
253
 
254
+ #### Same-origin API Requests
255
+
256
+ The proxy also serves the MCP Apps sandbox, so app content runs on the proxy's own origin. Because a same-origin request carries no `Origin` header, the proxy additionally rejects any API request whose `Sec-Fetch-Site` header is `same-origin`. The Inspector client always runs on a different port than the proxy, so its requests are never same-origin; non-browser clients (the CLI, curl) send no such header and are unaffected.
257
+
258
+ If you serve the client and the proxy from a single origin, for example behind one reverse proxy that routes by path, the client's own API requests become same-origin and are rejected. In that setup you can disable the check (NOT RECOMMENDED) by setting the `DANGEROUSLY_ALLOW_SAME_ORIGIN_API` environment variable:
259
+
260
+ ```bash
261
+ DANGEROUSLY_ALLOW_SAME_ORIGIN_API=true npm start
262
+ ```
263
+
264
+ Only `true`, `1` or `yes` (case-insensitive) disable the check. Any other value, including `false`, `0` or an empty string, leaves it enabled. While it is disabled, documents served by the proxy, including MCP App content in the sandbox, can call the proxy API, and the proxy prints a warning at startup.
265
+
250
266
  ### Configuration
251
267
 
252
268
  The MCP Inspector supports the following configuration settings. To change them, click on the `Configuration` button in the MCP Inspector UI:
@@ -383,6 +399,8 @@ http://localhost:6274/?MCP_SERVER_REQUEST_TIMEOUT=60000&MCP_REQUEST_TIMEOUT_RESE
383
399
 
384
400
  Note that if both the query param and the corresponding localStorage item are set, the query param will take precedence.
385
401
 
402
+ An `MCP_PROXY_FULL_ADDRESS` supplied this way is kept for that browser tab only (including across the OAuth redirect) and is not saved for later sessions. If it differs from the saved proxy address, the saved proxy session token is not sent to it: include `MCP_PROXY_AUTH_TOKEN` in the same URL, or enter the token in the Configuration panel.
403
+
386
404
  ### From this repository
387
405
 
388
406
  If you're working on the inspector itself:
@@ -9,6 +9,15 @@ import { randomBytes } from "crypto";
9
9
  const __dirname = dirname(fileURLToPath(import.meta.url));
10
10
  const DEFAULT_MCP_PROXY_LISTEN_PORT = "6277";
11
11
 
12
+ // Only an explicit truthy value disables auth; unset, empty, "false", "0" and
13
+ // anything unrecognized leave it enabled. Identical to isAuthDisabledFlag in
14
+ // server/src/request-guards.ts (whose parser lives in server/src/env-flags.ts)
15
+ // so the launcher and the proxy always agree; keep the two in sync.
16
+ function isAuthDisabledFlag(value) {
17
+ if (value === undefined) return false;
18
+ return ["true", "1", "yes"].includes(value.trim().toLowerCase());
19
+ }
20
+
12
21
  function delay(ms) {
13
22
  return new Promise((resolve) => setTimeout(resolve, ms, true));
14
23
  }
@@ -292,7 +301,7 @@ async function main() {
292
301
  // Use provided token from environment or generate a new one
293
302
  const sessionToken =
294
303
  process.env.MCP_PROXY_AUTH_TOKEN || randomBytes(32).toString("hex");
295
- const authDisabled = !!process.env.DANGEROUSLY_OMIT_AUTH;
304
+ const authDisabled = isAuthDisabledFlag(process.env.DANGEROUSLY_OMIT_AUTH);
296
305
 
297
306
  const abort = new AbortController();
298
307
 
@@ -1,4 +1,4 @@
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-CH-qD91V.js";
1
+ import { u as useToast, r as reactExports, c as clearOAuthConnectionSnapshot, j as jsxRuntimeExports, p as parseOAuthCallbackParams, g as generateOAuthErrorDescription, S as SESSION_KEYS, I as InspectorOAuthClientProvider, a as auth } from "./index-C2CDzlVy.js";
2
2
  const OAuthCallback = ({ onConnect }) => {
3
3
  const { toast } = useToast();
4
4
  const hasProcessedRef = reactExports.useRef(false);
@@ -42,9 +42,13 @@ const OAuthCallback = ({ onConnect }) => {
42
42
  description: "Successfully authenticated with OAuth",
43
43
  variant: "default"
44
44
  });
45
- onConnect(serverUrl);
45
+ const refusal = onConnect(serverUrl);
46
+ if (refusal) {
47
+ notifyError(refusal);
48
+ }
46
49
  };
47
50
  handleCallback().finally(() => {
51
+ clearOAuthConnectionSnapshot();
48
52
  window.history.replaceState({}, document.title, "/");
49
53
  });
50
54
  }, [toast, onConnect]);
@@ -1,4 +1,4 @@
1
- import { r as reactExports, S as SESSION_KEYS, p as parseOAuthCallbackParams, j as jsxRuntimeExports, g as generateOAuthErrorDescription } from "./index-CH-qD91V.js";
1
+ import { r as reactExports, S as SESSION_KEYS, p as parseOAuthCallbackParams, j as jsxRuntimeExports, g as generateOAuthErrorDescription } from "./index-C2CDzlVy.js";
2
2
  const OAuthDebugCallback = ({ onConnect }) => {
3
3
  reactExports.useEffect(() => {
4
4
  let isProcessed = false;