When running the inspector with command-line arguments (e.g.,
`npx @modelcontextprotocol/inspector node build/index.js arg1 arg2`),
the command and arguments were not being properly passed through to
the UI for pre-filling.
Changes:
- cli.ts now passes command and args to start.js
- start.js uses --command for the command and --args for arguments
- Server parses the new --command parameter
- /config endpoint returns correct values for UI pre-filling
This ensures the UI correctly displays the command and arguments
passed on the command line instead of showing old localStorage values.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Simplifies the startup flow by consolidating browser opening
in the client script rather than the start script for prod.
We were duplicating a lot of logging, making it easy for
logs to go out of sync - this is a proposal to consolidate:
- server only logs info about itself
- client only logs info about itself
To reduce the number of places we print connection information
to the user.
- Update client to read MCP_PROXY_PORT from URL parameters
- Update server to include port in displayed URL when non-default
- Update start scripts to pass SERVER_PORT to client
- Use DEFAULT_MCP_PROXY_LISTEN_PORT constant instead of magic numbers
This fixes the issue where the client couldn't connect to the proxy
when SERVER_PORT was set to a non-default value.
Per PR feedback from cliffhall:
- Changed PORT to SERVER_PORT in server/src/index.ts
- Changed PORT to CLIENT_PORT in client/bin/client.js
- Added parseInt() for CLIENT_PORT consistency
- Updated start.js to pass correct env var names
This improves clarity by using specific environment variables for
server and client ports instead of the generic PORT variable.
- Extract duplicated URL generation code into getClientUrl() helper function in start.js
- Replace all 127.0.0.1 references with localhost for consistency across codebase
- Update server to respect HOST environment variable for URL generation
- Remove 127.0.0.1 from default allowed origins in CORS configuration
- Update documentation to use localhost instead of 127.0.0.1
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Unified start.js to handle both dev and production modes with --dev flag
- Generate session token in parent process, pass via MCP_PROXY_TOKEN env var
- Enable browser auto-open even when authentication is enabled by including token in URL
- Auto-reloads now work seamlessly with persistent tokens across hot reloads
- Simplified npm scripts - dev and dev:windows now use the same unified script
- Better developer experience with consistent token handling
The token is generated once per session and remains stable through server/client
reloads, making development smoother while maintaining security.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed proxy authentication to use a custom header (X-MCP-Proxy-Auth) instead of the standard Authorization header. This prevents conflicts when the proxy needs to forward the client's Authorization header to upstream MCP servers.
- Updated client to send proxy auth token in X-MCP-Proxy-Auth header
- Updated server auth middleware to check X-MCP-Proxy-Auth header
- Applies to all transport types (SSE, stdio, streamable-http)
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Auto-open browser only works when DANGEROUSLY_OMIT_AUTH=true
- When auth is enabled (default), users must use the secure URL with token
- Server displays clear message that auto-open is disabled with auth
- Updates documentation to reflect this behavior
This improves UX by preventing the browser from opening without auth token,
forcing users to use the secure pre-filled URL instead.
- Add origin validation middleware to check Origin header
- Default allowed origins respect CLIENT_PORT environment variable
- Support ALLOWED_ORIGINS environment variable for additional origins
- Apply validation to all protected endpoints before auth check
- Return 403 Forbidden with clear message for invalid origins
- Add DNS Rebinding Protection section to README
This completes the security hardening by preventing malicious websites
from making requests to the local proxy server.
- Generate random session token on server startup using crypto.randomBytes
- Add authentication middleware requiring Bearer token for all sensitive endpoints
- Apply auth to /mcp, /stdio, /sse, and /message endpoints
- Display session token in console on startup
- Add DANGEROUSLY_OMIT_AUTH environment variable to disable auth for development
- Update README with authentication documentation
This prevents unauthorized access to the proxy server's ability to execute
local processes and connect to MCP servers.
- Change default binding from 0.0.0.0 (all interfaces) to 127.0.0.1 (localhost only)
- Add HOST environment variable to override binding address when needed
- Update console output to show actual binding address
- Document security change in README with warnings about binding to all interfaces
This prevents remote attackers from accessing the MCP Inspector proxy server,
which has the ability to execute local processes. The proxy should only be
accessible from the local machine unless explicitly configured otherwise.
* In server/src/index.ts
- slight format tweak of the Client <-> Proxy message so that the two messages will line up when displayed
* In server/src/mcpProxy.ts
- add reportedServerSession boolean initialized to false
- in transportToServer.onmessage,
- if reportedServerSession isn't set yet, report the sessionId if present on the transport, and then set reportedServerSession to true
* In server/index.js
- in createTransport()
- stringify query params to put them on one line
- remove logging of transport creation (done in callers)
- in /mcp POST handler
- report POST request if session id is present
- otherwise, report new StreamableHttp connection request
- report creation of server transport
- report creation of client transport
- in /stdio GET handler
- report new STDIO connection request
- report creation of server transport
- report creation of client transport
- report 401 as authentication error without stack
- in stderr data handler
- if it includes "MODULE_NOT_FOUND"
- report "Command not found"
- remove transports
- otherwise send to client as usual
- in /sse GET handler
- report SSE connection request
- report 401 as authentication error without stack
- report 404 as server that may not support SSE
- report error with "ECONNREFUSED" as "Connection refused" without stack
- only create, map, and proxy transports if serverTransport was successfully created
- in /message POST handler
- report received POST message
* In mcpProxy.ts
- in onServerError()
- if error message includes 404 OR error.cause includes ECONNREFUSED, report "Connection refused."
Express converts all header names to lowercase, which prevents custom headers with uppercase characters from being properly passed to the target service. This fix ensures that custom headers preserve their original capitalization when forwarded through the proxy.
* In server/src/index.ts
- add delete handler for /mcp endpoint
- gets the server transport for the sessionId
- calls terminateSession on it
- removes the webapp and server transports for the sessionId from the maps
- returns status 200 to the client.
* In client/src/lib/hooks/useConnection.ts
- import Transport
- add useState for clientTransport, type Transport or null initialized to null
- in connect() function
- move creation of client transport down a ways, just before calling client.connect with it
- immendiately efter calling client.connect, call setClientTransport with the connected transport (has to happen after, so that what's saved has the abort controller, etc. otherwise it doesn't work to save it prior.
- in disconnect() function
- immediately call clientTransport.terminateSession if transportType is "streamable-http"
- setClientTransport to null
* In server/src/index.ts
- add serverTransports map
- remove backingServerTransport var
- in /mcp POST handler, when a new connection is being made
- create a server transport
- map the server transport using the session id from the web app connection
- pass serverTransport to the mcpProxy instead of backingServerTransport
- in /stdio GET handler, when a new connection is being made
- create a server transport
- map the server transport using the session id from the web app connection
- pass serverTransport to the mcpProxy instead of backingServerTransport
- in /sse GET handler, when a new connection is being made
- create a server transport
- map the server transport using the session id from the web app connection
- pass serverTransport to the mcpProxy instead of backingServerTransport
* In index.ts,
- refactor transport webAppTransports to be a map with the session id as key and transport as value.
* Implement /mcp GET and POST endpoints using StreamableHTTPServerTransport and doing the new session in the POST (opposite from SSE) handler.
* In package.json
- update the SDK to 1.10.2
* In useConnection.ts
- import StreamableHTTPClientTransport
- NOTE: while we NEED to do this, it causes useConnection.test.ts to fail with " ReferenceError: TransformStream is not defined"
- in connect method
- instantiate the appropriate transport
* In server/index.js
- add get/post handlers for /mcp
- amend console log on SSE connect, with deprecation message
- add /stdio GET handler and refactored /sse GET handler to not also do stdio. Each transport has its own handler now
- add appropriate headers to streamable-http request
* In /client/src/lib/hooks/useConnection.ts
- in connect function
- create server url properly based on new transport type.