From a524f17d8074cd720672e3685d114e749b0a9de3 Mon Sep 17 00:00:00 2001 From: KAWAKAMI Moeki Date: Mon, 7 Apr 2025 16:09:46 +0900 Subject: [PATCH 1/6] Implement auto-open feature for browser launch on server start --- README.md | 1 + bin/cli.js | 4 ++ package-lock.json | 134 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + 4 files changed, 140 insertions(+) diff --git a/README.md b/README.md index c43f9432..cb5fd52c 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ The MCP Inspector supports the following configuration settings. To change them | -------------------------- | ----------------------------------------------------------------------------------------- | ------------- | | MCP_SERVER_REQUEST_TIMEOUT | Maximum time in milliseconds to wait for a response from the MCP server before timing out | 10000 | | MCP_PROXY_FULL_ADDRESS | The full URL of the MCP Inspector proxy server (e.g. `http://10.2.1.14:2277`) | `null` | +| MCP_AUTO_OPEN_DISABLED | Disable automatic browser opening when inspector starts | `false` | ### From this repository diff --git a/bin/cli.js b/bin/cli.js index 35edf0e9..21a4bf0e 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -1,5 +1,6 @@ #!/usr/bin/env node +import open from "open"; import { resolve, dirname } from "path"; import { spawnPromise } from "spawn-rx"; import { fileURLToPath } from "url"; @@ -99,6 +100,9 @@ async function main() { if (serverOk) { try { + if (!process.env.MCP_AUTO_OPEN_DISABLED) { + open(`http://localhost:${CLIENT_PORT}`); + } await spawnPromise("node", [inspectorClientPath], { env: { ...process.env, PORT: CLIENT_PORT }, signal: abort.signal, diff --git a/package-lock.json b/package-lock.json index 42fec875..ba5ae44e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "@modelcontextprotocol/inspector-client": "^0.8.1", "@modelcontextprotocol/inspector-server": "^0.8.1", "concurrently": "^9.0.1", + "open": "^10.1.0", "shell-quote": "^1.8.2", "spawn-rx": "^5.1.2", "ts-node": "^10.9.2" @@ -4338,6 +4339,21 @@ "dev": true, "license": "MIT" }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/bytes": { "version": "3.1.2", "license": "MIT", @@ -4786,6 +4802,46 @@ "node": ">=0.10.0" } }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "dev": true, @@ -5995,6 +6051,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "license": "MIT", @@ -6027,6 +6098,24 @@ "node": ">=0.10.0" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-number": { "version": "7.0.0", "license": "MIT", @@ -6054,6 +6143,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isexe": { "version": "2.0.0", "license": "ISC" @@ -7261,6 +7365,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/open": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", + "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optionator": { "version": "0.9.4", "dev": true, @@ -8098,6 +8220,18 @@ "node": ">=16" } }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "funding": [ diff --git a/package.json b/package.json index 453fa71c..f3663f9a 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "@modelcontextprotocol/inspector-client": "^0.8.1", "@modelcontextprotocol/inspector-server": "^0.8.1", "concurrently": "^9.0.1", + "open": "^10.1.0", "shell-quote": "^1.8.2", "spawn-rx": "^5.1.2", "ts-node": "^10.9.2" From d2cb2338a0b69f9f154c43901f75c368051534cd Mon Sep 17 00:00:00 2001 From: KAWAKAMI Moeki Date: Sun, 13 Apr 2025 21:23:39 +0900 Subject: [PATCH 2/6] Fix host name --- bin/cli.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/cli.js b/bin/cli.js index 21a4bf0e..b12564f5 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -101,7 +101,7 @@ async function main() { if (serverOk) { try { if (!process.env.MCP_AUTO_OPEN_DISABLED) { - open(`http://localhost:${CLIENT_PORT}`); + open(`http://127.0.0.1:${CLIENT_PORT}`); } await spawnPromise("node", [inspectorClientPath], { env: { ...process.env, PORT: CLIENT_PORT }, From 52564dd7c5a0ddd3d129566b296659deeb831075 Mon Sep 17 00:00:00 2001 From: KAWAKAMI Moeki Date: Sun, 13 Apr 2025 21:53:42 +0900 Subject: [PATCH 3/6] Add auto open disabled environment option to sidebar --- client/src/components/Sidebar.tsx | 20 +++++++++++--- .../src/components/__tests__/Sidebar.test.tsx | 27 +++++++++++++++++++ client/src/lib/configurationTypes.ts | 5 ++++ client/src/lib/constants.ts | 5 ++++ 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/client/src/components/Sidebar.tsx b/client/src/components/Sidebar.tsx index 2ddb18d7..e7d74f9e 100644 --- a/client/src/components/Sidebar.tsx +++ b/client/src/components/Sidebar.tsx @@ -386,7 +386,6 @@ const Sidebar = ({ /> ) : typeof configItem.value === "boolean" ? ( ) : ( diff --git a/client/src/components/__tests__/Sidebar.test.tsx b/client/src/components/__tests__/Sidebar.test.tsx index 8e72b008..fad066fa 100644 --- a/client/src/components/__tests__/Sidebar.test.tsx +++ b/client/src/components/__tests__/Sidebar.test.tsx @@ -423,6 +423,33 @@ describe("Sidebar Environment Variables", () => { ); }); + it("should update auto browser open disabled", () => { + const setConfig = jest.fn(); + renderSidebar({ config: DEFAULT_INSPECTOR_CONFIG, setConfig }); + + openConfigSection(); + + const autoOpenDisabledInput = screen.getByTestId( + "MCP_AUTO_OPEN_DISABLED-input", + ); + fireEvent.click(autoOpenDisabledInput); + const trueOption = screen.getByTestId( + "MCP_AUTO_OPEN_DISABLED-input-true", + ); + fireEvent.click(trueOption); + + expect(setConfig).toHaveBeenCalledWith( + expect.objectContaining({ + MCP_AUTO_OPEN_DISABLED: { + label: "Auto Browser Open Disabled", + description: + "Disable automatic browser opening when inspector starts", + value: true, + }, + }), + ); + }); + it("should maintain configuration state after multiple updates", () => { const setConfig = jest.fn(); const { rerender } = renderSidebar({ diff --git a/client/src/lib/configurationTypes.ts b/client/src/lib/configurationTypes.ts index 7c74bb71..1b9736fd 100644 --- a/client/src/lib/configurationTypes.ts +++ b/client/src/lib/configurationTypes.ts @@ -33,4 +33,9 @@ export type InspectorConfig = { * The full address of the MCP Proxy Server, in case it is running on a non-default address. Example: http://10.1.1.22:5577 */ MCP_PROXY_FULL_ADDRESS: ConfigItem; + + /** + * Disable automatic browser opening when inspector starts. + */ + MCP_AUTO_OPEN_DISABLED: ConfigItem; }; diff --git a/client/src/lib/constants.ts b/client/src/lib/constants.ts index e7fa14c9..cbfab90c 100644 --- a/client/src/lib/constants.ts +++ b/client/src/lib/constants.ts @@ -43,4 +43,9 @@ export const DEFAULT_INSPECTOR_CONFIG: InspectorConfig = { "Set this if you are running the MCP Inspector Proxy on a non-default address. Example: http://10.1.1.22:5577", value: "", }, + MCP_AUTO_OPEN_DISABLED: { + label: "Auto Browser Open Disabled", + description: "Disable automatic browser opening when inspector starts", + value: false, + }, } as const; From 5bcc1fd77bbbba60e8b7d13b515ededae157046e Mon Sep 17 00:00:00 2001 From: KAWAKAMI Moeki Date: Sun, 13 Apr 2025 21:58:55 +0900 Subject: [PATCH 4/6] Fix condition for auto browser opening --- bin/cli.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/cli.js b/bin/cli.js index b12564f5..cb0db390 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -100,7 +100,7 @@ async function main() { if (serverOk) { try { - if (!process.env.MCP_AUTO_OPEN_DISABLED) { + if (process.env.MCP_AUTO_OPEN_DISABLED !== "true") { open(`http://127.0.0.1:${CLIENT_PORT}`); } await spawnPromise("node", [inspectorClientPath], { From 014acecf777edbc934582be0b1230ce4cb846b70 Mon Sep 17 00:00:00 2001 From: KAWAKAMI Moeki Date: Thu, 17 Apr 2025 18:13:58 +0900 Subject: [PATCH 5/6] Avoid double negative --- README.md | 2 +- client/bin/start.js | 2 +- client/src/components/__tests__/Sidebar.test.tsx | 16 ++++++++-------- client/src/lib/configurationTypes.ts | 2 +- client/src/lib/constants.ts | 8 ++++---- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 221cbd3f..c34673f7 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ The MCP Inspector supports the following configuration settings. To change them, | `MCP_REQUEST_TIMEOUT_RESET_ON_PROGRESS` | Reset timeout on progress notifications | true | | `MCP_REQUEST_MAX_TOTAL_TIMEOUT` | Maximum total timeout for requests sent to the MCP server (ms) (Use with progress notifications) | 60000 | | `MCP_PROXY_FULL_ADDRESS` | Set this if you are running the MCP Inspector Proxy on a non-default address. Example: http://10.1.1.22:5577 | "" | -| `MCP_AUTO_OPEN_DISABLED` | Disable automatic browser opening when inspector starts | false | +| `MCP_AUTO_OPEN_ENABLED` | Enable automatic browser opening when inspector starts | true | The inspector also supports configuration files to store settings for different MCP servers. This is useful when working with multiple servers or complex configurations: diff --git a/client/bin/start.js b/client/bin/start.js index 93d77fa8..8e383b38 100755 --- a/client/bin/start.js +++ b/client/bin/start.js @@ -100,7 +100,7 @@ async function main() { if (serverOk) { try { - if (process.env.MCP_AUTO_OPEN_DISABLED !== "true") { + if (process.env.MCP_AUTO_OPEN_ENABLED !== "false") { open(`http://127.0.0.1:${CLIENT_PORT}`); } await spawnPromise("node", [inspectorClientPath], { diff --git a/client/src/components/__tests__/Sidebar.test.tsx b/client/src/components/__tests__/Sidebar.test.tsx index dffc1393..ed3bbb3b 100644 --- a/client/src/components/__tests__/Sidebar.test.tsx +++ b/client/src/components/__tests__/Sidebar.test.tsx @@ -583,21 +583,21 @@ describe("Sidebar Environment Variables", () => { openConfigSection(); const autoOpenDisabledInput = screen.getByTestId( - "MCP_AUTO_OPEN_DISABLED-input", + "MCP_AUTO_OPEN_ENABLED-input", ); fireEvent.click(autoOpenDisabledInput); - const trueOption = screen.getByTestId( - "MCP_AUTO_OPEN_DISABLED-input-true", + const falseOption = screen.getByTestId( + "MCP_AUTO_OPEN_ENABLED-input-false", ); - fireEvent.click(trueOption); + fireEvent.click(falseOption); expect(setConfig).toHaveBeenCalledWith( expect.objectContaining({ - MCP_AUTO_OPEN_DISABLED: { - label: "Auto Browser Open Disabled", + MCP_AUTO_OPEN_ENABLED: { + label: "Auto Browser Open Enabled", description: - "Disable automatic browser opening when inspector starts", - value: true, + "Enable automatic browser opening when inspector starts", + value: false, }, }), ); diff --git a/client/src/lib/configurationTypes.ts b/client/src/lib/configurationTypes.ts index 1b9736fd..f390e6da 100644 --- a/client/src/lib/configurationTypes.ts +++ b/client/src/lib/configurationTypes.ts @@ -37,5 +37,5 @@ export type InspectorConfig = { /** * Disable automatic browser opening when inspector starts. */ - MCP_AUTO_OPEN_DISABLED: ConfigItem; + MCP_AUTO_OPEN_ENABLED: ConfigItem; }; diff --git a/client/src/lib/constants.ts b/client/src/lib/constants.ts index 210e160c..fc05c069 100644 --- a/client/src/lib/constants.ts +++ b/client/src/lib/constants.ts @@ -52,9 +52,9 @@ export const DEFAULT_INSPECTOR_CONFIG: InspectorConfig = { "Set this if you are running the MCP Inspector Proxy on a non-default address. Example: http://10.1.1.22:5577", value: "", }, - MCP_AUTO_OPEN_DISABLED: { - label: "Auto Browser Open Disabled", - description: "Disable automatic browser opening when inspector starts", - value: false, + MCP_AUTO_OPEN_ENABLED: { + label: "Auto Browser Open Enabled", + description: "Enable automatic browser opening when inspector starts", + value: true, }, } as const; From d82e06fe657a5c8451f98841cebda14da064dd62 Mon Sep 17 00:00:00 2001 From: KAWAKAMI Moeki Date: Fri, 18 Apr 2025 09:28:29 +0900 Subject: [PATCH 6/6] Fix format of README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b568e7cc..6c042c94 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,9 @@ The MCP Inspector supports the following configuration settings. To change them, | `MCP_REQUEST_TIMEOUT_RESET_ON_PROGRESS` | Reset timeout on progress notifications | true | | `MCP_REQUEST_MAX_TOTAL_TIMEOUT` | Maximum total timeout for requests sent to the MCP server (ms) (Use with progress notifications) | 60000 | | `MCP_PROXY_FULL_ADDRESS` | Set this if you are running the MCP Inspector Proxy on a non-default address. Example: http://10.1.1.22:5577 | "" | -| `MCP_AUTO_OPEN_ENABLED` | Enable automatic browser opening when inspector starts | true | +| `MCP_AUTO_OPEN_ENABLED` | Enable automatic browser opening when inspector starts | true | + +These settings can be adjusted in real-time through the UI and will persist across sessions. The inspector also supports configuration files to store settings for different MCP servers. This is useful when working with multiple servers or complex configurations: