diff --git a/README.md b/README.md index 94efe83c..1a5bffff 100644 --- a/README.md +++ b/README.md @@ -168,13 +168,13 @@ DANGEROUSLY_OMIT_AUTH=true npm start #### Local-only Binding -By default, the MCP Inspector proxy server binds only to `127.0.0.1` (localhost) to prevent network access. This ensures the server is not accessible from other devices on the network. If you need to bind to all interfaces for development purposes, you can override this with the `HOST` environment variable: +By default, both the MCP Inspector proxy server and client bind only to `127.0.0.1` (localhost) to prevent network access. This ensures they are not accessible from other devices on the network. If you need to bind to all interfaces for development purposes, you can override this with the `HOST` environment variable: ```bash HOST=0.0.0.0 npm start ``` -**Warning:** Only bind to all interfaces in trusted network environments, as this exposes the proxy server's ability to execute local processes. +**Warning:** Only bind to all interfaces in trusted network environments, as this exposes the proxy server's ability to execute local processes and both services to network access. #### DNS Rebinding Protection diff --git a/client/bin/client.js b/client/bin/client.js index 7179e19e..45fc2421 100755 --- a/client/bin/client.js +++ b/client/bin/client.js @@ -40,18 +40,19 @@ const server = http.createServer((request, response) => { }); const port = process.env.PORT || 6274; +const host = process.env.HOST || "127.0.0.1"; server.on("listening", () => { console.log( - `🔍 MCP Inspector is up and running at http://127.0.0.1:${port} 🚀`, + `🔍 MCP Inspector is up and running at http://${host}:${port} 🚀`, ); }); server.on("error", (err) => { if (err.message.includes(`EADDRINUSE`)) { console.error( - `❌ MCP Inspector PORT IS IN USE at http://127.0.0.1:${port} ❌ `, + `❌ MCP Inspector PORT IS IN USE at http://${host}:${port} ❌ `, ); } else { throw err; } }); -server.listen(port); +server.listen(port, host); diff --git a/client/bin/start.js b/client/bin/start.js index ad75078a..54b125e9 100755 --- a/client/bin/start.js +++ b/client/bin/start.js @@ -102,7 +102,8 @@ async function startDevClient(clientOptions) { const { CLIENT_PORT, authDisabled, sessionToken, abort, cancelled } = clientOptions; const clientCommand = "npx"; - const clientArgs = ["vite", "--port", CLIENT_PORT]; + const host = process.env.HOST || "127.0.0.1"; + const clientArgs = ["vite", "--port", CLIENT_PORT, "--host", host]; const client = spawn(clientCommand, clientArgs, { cwd: resolve(__dirname, ".."), @@ -113,9 +114,10 @@ async function startDevClient(clientOptions) { // Auto-open browser after vite starts if (process.env.MCP_AUTO_OPEN_ENABLED !== "false") { + const clientHost = process.env.HOST || "127.0.0.1"; const url = authDisabled - ? `http://127.0.0.1:${CLIENT_PORT}` - : `http://127.0.0.1:${CLIENT_PORT}/?MCP_PROXY_AUTH_TOKEN=${sessionToken}`; + ? `http://${clientHost}:${CLIENT_PORT}` + : `http://${clientHost}:${CLIENT_PORT}/?MCP_PROXY_AUTH_TOKEN=${sessionToken}`; // Give vite time to start before opening browser setTimeout(() => { @@ -139,7 +141,8 @@ async function startDevClient(clientOptions) { } async function startProdClient(clientOptions) { - const { CLIENT_PORT, authDisabled, sessionToken, abort } = clientOptions; + const { CLIENT_PORT, authDisabled, sessionToken, abort, cancelled } = + clientOptions; const inspectorClientPath = resolve( __dirname, "../..", @@ -148,11 +151,12 @@ async function startProdClient(clientOptions) { "client.js", ); - // Auto-open browser with token - if (process.env.MCP_AUTO_OPEN_ENABLED !== "false") { + // Only auto-open browser if not cancelled + if (process.env.MCP_AUTO_OPEN_ENABLED !== "false" && !cancelled) { + const clientHost = process.env.HOST || "127.0.0.1"; const url = authDisabled - ? `http://127.0.0.1:${CLIENT_PORT}` - : `http://127.0.0.1:${CLIENT_PORT}/?MCP_PROXY_AUTH_TOKEN=${sessionToken}`; + ? `http://${clientHost}:${CLIENT_PORT}` + : `http://${clientHost}:${CLIENT_PORT}/?MCP_PROXY_AUTH_TOKEN=${sessionToken}`; open(url); }