Skip to content

Auto-inject MCP_INSPECTOR_API_TOKEN so reloads don't 401 without the query string #1378

@cliffhall

Description

@cliffhall

Problem

The dev/prod web backend protects every /api/* route with x-mcp-remote-auth: Bearer <MCP_INSPECTOR_API_TOKEN> (core/mcp/remote/node/server.ts:189-200). The browser only learns the token via ?MCP_INSPECTOR_API_TOKEN=… query string on first page load — clients/web/src/App.tsx:73-93 parses it and persists to sessionStorage.

Failure mode: if the user clears sessionStorage and reloads at the bare URL (no query string), every /api/* request 401s. Same problem if they load via a bookmark or hand-typed URL. No graceful recovery — the UI just fails silently when trying to connect to a server.

Steps to reproduce:

  1. npm run dev, open the URL the banner prints.
  2. DevTools → Application → Session Storage → clear MCP_INSPECTOR_API_TOKEN.
  3. Reload at http://localhost:6274/ (drop the query string).
  4. Click connect on any server → handshake POST to /api/mcp/send returns 401.

Proposed change

The server already knows the token at index.html serve time. Inject it into the page once so the browser doesn't depend on the query string surviving navigation.

Two options worth considering:

  1. HTML template injection (preferred) — the vite-hono-plugin (and the prod server.ts) rewrites index.html on the / route to embed <script>window.__INSPECTOR_API_TOKEN__ = "…"</script>. App.tsx's getAuthToken() reads from window.__INSPECTOR_API_TOKEN__ ahead of the URL/sessionStorage fallback. Same-origin, no cookie semantics to reason about. Token is JS-accessible (same as today via sessionStorage), so no new XSS surface vs. the status quo.

  2. HttpOnly cookie — server sets Set-Cookie: mcp_inspector_token=…; HttpOnly; Path=/; SameSite=Strict on the GET / response. Middleware accepts the token from the cookie OR the existing header. Browser fetches drop the Authorization/x-mcp-remote-auth plumbing (cookies sent automatically with credentials: "same-origin"). Slightly more robust against XSS, but it means changing the auth middleware and removing the header-setting code paths in core/mcp/remote/createRemoteTransport.ts and createRemoteFetch.ts.

Either way, keep the ?MCP_INSPECTOR_API_TOKEN=… query-string path working as a fallback for at least one release — there are scripts and integrations that already paste full URLs around.

Acceptance criteria

  • Reloading at http://localhost:6274/ (no query string, empty sessionStorage) loads the app and successfully calls /api/* without 401.
  • The launcher banner URL still works for users who want to copy/paste it.
  • The chosen path has an integration test exercising the / → first /api/* flow.
  • AGENTS.md or the README mentions the new behavior so the next contributor isn't surprised.

Out of scope

Metadata

Metadata

Assignees

Labels

v2Issues and PRs for v2

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions