From 62463e7fcee4f1d3f96cd352f439582e3ff260cb Mon Sep 17 00:00:00 2001 From: GallaGit Date: Sun, 11 Oct 2026 00:06:46 +0200 Subject: [PATCH 1/3] feat(frontend): add MCP Inspector to Quick Connect --- docs/integrations/claude.md | 4 +++ .../frontend/src/app/mcp-server/[id]/page.tsx | 32 +++++++++++++++++++ packages/frontend/src/lib/inspector-url.ts | 8 +++++ 3 files changed, 44 insertions(+) create mode 100644 packages/frontend/src/lib/inspector-url.ts diff --git a/docs/integrations/claude.md b/docs/integrations/claude.md index dda5792bb..dc40623dd 100644 --- a/docs/integrations/claude.md +++ b/docs/integrations/claude.md @@ -172,6 +172,10 @@ GET https:///.well-known/oauth-protected-resource/mcp/ GET https:///.well-known/oauth-authorization-server ``` +### Test with the MCP Inspector + +The [MCP Inspector](https://github.com/modelcontextprotocol/inspector) shows what this server exposes from the outside: `tools/list`, input schemas, a test call and the raw JSON-RPC messages. Run `npx @modelcontextprotocol/inspector`, then use **Quick Connect → MCP Inspector** on the server page to open it with this server's URL. Sign in with OAuth, or add an `X-API-Key` header in the Inspector's authentication settings. + --- ## Troubleshooting diff --git a/packages/frontend/src/app/mcp-server/[id]/page.tsx b/packages/frontend/src/app/mcp-server/[id]/page.tsx index 14e1d64f3..cf9f798ed 100644 --- a/packages/frontend/src/app/mcp-server/[id]/page.tsx +++ b/packages/frontend/src/app/mcp-server/[id]/page.tsx @@ -12,6 +12,7 @@ import { cn } from '@/lib/utils'; import { ConnectionCheck } from '@/components/connection-check'; import { copyText } from '@/lib/clipboard'; import { CLAUDE_DIRECTORY_URL } from '@/lib/marketing'; +import { inspectorUrl } from '@/lib/inspector-url'; // Opens claude.ai straight on its "Add custom connector" dialog. Connectors // moved from Settings to Customize → Connectors; the old settings URL now only @@ -355,6 +356,7 @@ export default function McpServerDetailPage() { { id: 'muse', name: 'Meta Muse', init: 'Mu', tone: 'info' }, { id: 'gemini', name: 'Gemini CLI', init: 'Ge', tone: 'pink' }, { id: 'windsurf', name: 'Windsurf', init: 'Wi', tone: 'success' }, + { id: 'inspector', name: 'MCP Inspector', init: 'In', tone: 'neutral' }, ]; const codeBlock = (text: string, label: string) => ( @@ -618,6 +620,36 @@ Auth: OAuth`; {codeBlock(windsurfConfig, 'windsurf')} ); + case 'inspector': { + const cmd = `npx @modelcontextprotocol/inspector`; + return ( +
+

+ Run this command in your terminal: +

+
+ {cmd} + +
+

+ Then open the Inspector in your browser: +

+ {linkAction(inspectorUrl(endpointUrl), 'Open in MCP Inspector', true)} +

+ On startup the Inspector prints a URL with MCP_PROXY_AUTH_TOKEN — open that URL, or paste the token when it asks for it. +

+

+ Sign in with OAuth (connect, sign in and approve access) or with an API key in the X-API-Key header from the Inspector's authentication settings. +

+ {endpointRow('modal-inspector-url')} +
+ ); + } default: return null; } diff --git a/packages/frontend/src/lib/inspector-url.ts b/packages/frontend/src/lib/inspector-url.ts new file mode 100644 index 000000000..187f27636 --- /dev/null +++ b/packages/frontend/src/lib/inspector-url.ts @@ -0,0 +1,8 @@ +export const INSPECTOR_BASE_URL = 'http://localhost:6274/'; +/** + * Builds a link that opens the MCP Inspector pointed at this server. + * Only the server URL goes in the link: never API keys or tokens. + */ +export function inspectorUrl(endpointUrl: string): string { + return `${INSPECTOR_BASE_URL}?transport=streamable-http&serverUrl=${encodeURIComponent(endpointUrl)}`; +} From a0d8e16bd59cbaa5d34f988724f795f2cc663987 Mon Sep 17 00:00:00 2001 From: GallaGit Date: Sun, 11 Oct 2026 10:38:13 +0200 Subject: [PATCH 2/3] feat(frontend): pre-fill MCP Inspector v2 via CLI flags and add e2e test --- docs/integrations/claude.md | 2 +- .../frontend/src/app/mcp-server/[id]/page.tsx | 14 ++++++------- packages/frontend/src/lib/inspector-url.ts | 18 +++++++++++------ .../e2e/mcp-server-connect-clients.spec.ts | 20 ++++++++++++++++++- 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/docs/integrations/claude.md b/docs/integrations/claude.md index dc40623dd..ed5cbfd0e 100644 --- a/docs/integrations/claude.md +++ b/docs/integrations/claude.md @@ -174,7 +174,7 @@ GET https:///.well-known/oauth-authorization-server ### Test with the MCP Inspector -The [MCP Inspector](https://github.com/modelcontextprotocol/inspector) shows what this server exposes from the outside: `tools/list`, input schemas, a test call and the raw JSON-RPC messages. Run `npx @modelcontextprotocol/inspector`, then use **Quick Connect → MCP Inspector** on the server page to open it with this server's URL. Sign in with OAuth, or add an `X-API-Key` header in the Inspector's authentication settings. +The [MCP Inspector](https://github.com/modelcontextprotocol/inspector) shows what this server exposes from the outside: `tools/list`, input schemas, a test call and the raw JSON-RPC messages. On the server page, open **Quick Connect → MCP Inspector** and run the command it shows (`npx @modelcontextprotocol/inspector --server-url --transport http`, Node 22.19+); the Inspector opens at http://localhost:6274 already pointed at this server. Sign in with OAuth, or pass an API key with `--header "X-API-Key: "`. Never put a key in a link. --- diff --git a/packages/frontend/src/app/mcp-server/[id]/page.tsx b/packages/frontend/src/app/mcp-server/[id]/page.tsx index cf9f798ed..aa8fe0231 100644 --- a/packages/frontend/src/app/mcp-server/[id]/page.tsx +++ b/packages/frontend/src/app/mcp-server/[id]/page.tsx @@ -12,7 +12,7 @@ import { cn } from '@/lib/utils'; import { ConnectionCheck } from '@/components/connection-check'; import { copyText } from '@/lib/clipboard'; import { CLAUDE_DIRECTORY_URL } from '@/lib/marketing'; -import { inspectorUrl } from '@/lib/inspector-url'; +import { INSPECTOR_URL, inspectorCommand } from '@/lib/inspector-url'; // Opens claude.ai straight on its "Add custom connector" dialog. Connectors // moved from Settings to Customize → Connectors; the old settings URL now only @@ -621,11 +621,11 @@ Auth: OAuth`; ); case 'inspector': { - const cmd = `npx @modelcontextprotocol/inspector`; + const cmd = inspectorCommand(endpointUrl); return (

- Run this command in your terminal: + Run this command in your terminal (Node 22.19 or later). It starts the Inspector already pointed at this server:

{cmd} @@ -637,14 +637,14 @@ Auth: OAuth`;

- Then open the Inspector in your browser: + The Inspector opens in your browser. If it doesn't, open it here:

- {linkAction(inspectorUrl(endpointUrl), 'Open in MCP Inspector', true)} + {linkAction(INSPECTOR_URL, 'Open in MCP Inspector', true)}

- On startup the Inspector prints a URL with MCP_PROXY_AUTH_TOKEN — open that URL, or paste the token when it asks for it. + The Inspector hands its session token (MCP_INSPECTOR_API_TOKEN) to the page it opens, so you don't need to copy it.

- Sign in with OAuth (connect, sign in and approve access) or with an API key in the X-API-Key header from the Inspector's authentication settings. + Sign in with OAuth when the Inspector asks (connect, sign in and approve access), or use an API key: add --header "X-API-Key: <your key>" to the command, or set an X-API-Key header in the server's settings in the Inspector.

{endpointRow('modal-inspector-url')}
diff --git a/packages/frontend/src/lib/inspector-url.ts b/packages/frontend/src/lib/inspector-url.ts index 187f27636..5cd4b9e27 100644 --- a/packages/frontend/src/lib/inspector-url.ts +++ b/packages/frontend/src/lib/inspector-url.ts @@ -1,8 +1,14 @@ -export const INSPECTOR_BASE_URL = 'http://localhost:6274/'; +/** Where `npx @modelcontextprotocol/inspector` serves its web UI (v2 default port). */ +export const INSPECTOR_URL = 'http://localhost:6274/'; + /** - * Builds a link that opens the MCP Inspector pointed at this server. - * Only the server URL goes in the link: never API keys or tokens. + * Command that starts the MCP Inspector already pointed at this server. + * + * Inspector v2 ignores `?serverUrl=` deep links unless they also carry the + * per-launch session token (`autoConnect`), which is secret, so we pre-fill the + * connection through CLI flags instead. Only the server URL goes in here: + * never API keys or tokens. */ -export function inspectorUrl(endpointUrl: string): string { - return `${INSPECTOR_BASE_URL}?transport=streamable-http&serverUrl=${encodeURIComponent(endpointUrl)}`; -} +export function inspectorCommand(endpointUrl: string): string { + return `npx @modelcontextprotocol/inspector --server-url "${endpointUrl}" --transport http`; +} \ No newline at end of file diff --git a/packages/frontend/tests/e2e/mcp-server-connect-clients.spec.ts b/packages/frontend/tests/e2e/mcp-server-connect-clients.spec.ts index bd0ca2fe3..68f05dbc2 100644 --- a/packages/frontend/tests/e2e/mcp-server-connect-clients.spec.ts +++ b/packages/frontend/tests/e2e/mcp-server-connect-clients.spec.ts @@ -96,4 +96,22 @@ test.describe('MCP server Quick Connect', () => { await expect(modal).toContainText('US and Canada'); await expect(modal.getByTestId('claude-directory')).toHaveCount(0); }); -}); + + for (const mode of ['cloud', 'self-hosted'] as const) { + test(`MCP Inspector shows a pre-filled command, a plain link and sign-in steps (${mode})`, async ({ page }) => { + await openServerPage(page, mode); + await openClient(page, 'MCP Inspector'); + + const modal = page.locator('div.fixed').filter({ hasText: 'Connect to MCP Inspector' }); + + // The command points the Inspector at exactly the endpoint shown on the page. + const endpoint = (await modal.locator('code', { hasText: /\/mcp\/s1$/ }).textContent())!.trim(); + const command = modal.locator('code', { hasText: 'npx @modelcontextprotocol/inspector' }); + await expect(command).toHaveText(`npx @modelcontextprotocol/inspector --server-url "${endpoint}" --transport http`); + + // The link opens the local Inspector with no query string, so no credentials can leak. + await expect(modal.getByRole('link', { name: 'Open in MCP Inspector' })).toHaveAttribute('href', 'http://localhost:6274/'); + await expect(modal).toContainText('X-API-Key'); + }); + } +}); \ No newline at end of file From f6fc6e7ee8436d3a627d4c9788c39c2fd8c35b50 Mon Sep 17 00:00:00 2001 From: GallaGit Date: Mon, 12 Oct 2026 15:24:33 +0200 Subject: [PATCH 3/3] docs(frontend): suggest Inspector header field before --header flag; add trailing newlines --- docs/integrations/claude.md | 2 +- packages/frontend/src/app/mcp-server/[id]/page.tsx | 2 +- packages/frontend/src/lib/inspector-url.ts | 2 +- packages/frontend/tests/e2e/mcp-server-connect-clients.spec.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/integrations/claude.md b/docs/integrations/claude.md index ed5cbfd0e..c60bd5fa1 100644 --- a/docs/integrations/claude.md +++ b/docs/integrations/claude.md @@ -174,7 +174,7 @@ GET https:///.well-known/oauth-authorization-server ### Test with the MCP Inspector -The [MCP Inspector](https://github.com/modelcontextprotocol/inspector) shows what this server exposes from the outside: `tools/list`, input schemas, a test call and the raw JSON-RPC messages. On the server page, open **Quick Connect → MCP Inspector** and run the command it shows (`npx @modelcontextprotocol/inspector --server-url --transport http`, Node 22.19+); the Inspector opens at http://localhost:6274 already pointed at this server. Sign in with OAuth, or pass an API key with `--header "X-API-Key: "`. Never put a key in a link. +The [MCP Inspector](https://github.com/modelcontextprotocol/inspector) shows what this server exposes from the outside: `tools/list`, input schemas, a test call and the raw JSON-RPC messages. On the server page, open **Quick Connect → MCP Inspector** and run the command it shows (`npx @modelcontextprotocol/inspector --server-url --transport http`, Node 22.19+); the Inspector opens at http://localhost:6274 already pointed at this server. Sign in with OAuth, or add an `X-API-Key` header in the Inspector's server settings. Passing `--header "X-API-Key: "` also works, but leaves the key in your shell history. Never put a key in a link. --- diff --git a/packages/frontend/src/app/mcp-server/[id]/page.tsx b/packages/frontend/src/app/mcp-server/[id]/page.tsx index aa8fe0231..234485471 100644 --- a/packages/frontend/src/app/mcp-server/[id]/page.tsx +++ b/packages/frontend/src/app/mcp-server/[id]/page.tsx @@ -644,7 +644,7 @@ Auth: OAuth`; The Inspector hands its session token (MCP_INSPECTOR_API_TOKEN) to the page it opens, so you don't need to copy it.

- Sign in with OAuth when the Inspector asks (connect, sign in and approve access), or use an API key: add --header "X-API-Key: <your key>" to the command, or set an X-API-Key header in the server's settings in the Inspector. + Sign in with OAuth when the Inspector asks (connect, sign in and approve access), or use an API key: set an X-API-Key header in the server's settings in the Inspector. You can also add --header "X-API-Key: <your key>" to the command, but the key then stays in your shell history.

{endpointRow('modal-inspector-url')} diff --git a/packages/frontend/src/lib/inspector-url.ts b/packages/frontend/src/lib/inspector-url.ts index 5cd4b9e27..0ce30ff7b 100644 --- a/packages/frontend/src/lib/inspector-url.ts +++ b/packages/frontend/src/lib/inspector-url.ts @@ -11,4 +11,4 @@ export const INSPECTOR_URL = 'http://localhost:6274/'; */ export function inspectorCommand(endpointUrl: string): string { return `npx @modelcontextprotocol/inspector --server-url "${endpointUrl}" --transport http`; -} \ No newline at end of file +} diff --git a/packages/frontend/tests/e2e/mcp-server-connect-clients.spec.ts b/packages/frontend/tests/e2e/mcp-server-connect-clients.spec.ts index 68f05dbc2..c8501e5b0 100644 --- a/packages/frontend/tests/e2e/mcp-server-connect-clients.spec.ts +++ b/packages/frontend/tests/e2e/mcp-server-connect-clients.spec.ts @@ -114,4 +114,4 @@ test.describe('MCP server Quick Connect', () => { await expect(modal).toContainText('X-API-Key'); }); } -}); \ No newline at end of file +});