Skip to content

Add HTTPS/TLS support for the Inspector web listener #2446

Description

@steventamm

Which client?

Web

The problem

I need to run the Inspector web UI over HTTPS for local integration testing
with services that require secure origins and TLS-protected callback/discovery
URLs.

Today Inspector's web listener runs only over HTTP. Using a browser exception
or trusting a certificate in the browser does not solve this: Inspector's Node
backend also needs to communicate with HTTPS MCP and OAuth endpoints. A
reverse proxy is possible, but adds another process, separate host/port
configuration, and origin/CORS complexity to every local run.

This blocks repeatable local testing whenever HTTPS is required.

Solution you have in mind (optional)

Add optional TLS support to the Inspector web listener, enabled only when both
PEM paths are supplied:

  • INSPECTOR_TLS_KEY_PATH
  • INSPECTOR_TLS_CERT_PATH

It should work consistently for both the production web listener (npm run web / mcp-inspector --web) and Vite development (npm run web:dev and cd clients/web && npm run dev).

When enabled, Inspector should:

  • serve the UI over HTTPS;
  • print an https:// URL in its launch banner;
  • derive default ALLOWED_ORIGINS using HTTPS;
  • fail clearly at startup when only one of the two TLS variables is set, or
    when a certificate file cannot be read.

Please add a docs/tls.md guide and link it from the README and
docs/environment-variables.md. The guide should include a trusted local
mkcert workflow:

mkcert -install
mkcert localhost 127.0.0.1 ::1

export INSPECTOR_TLS_KEY_PATH="$PWD/localhost+2-key.pem"
export INSPECTOR_TLS_CERT_PATH="$PWD/localhost+2.pem"

npm install
npm run build
npm run web

It should also show verification with:

curl --cacert "$(mkcert -CAROOT)/rootCA.pem" https://localhost:6274/

Document custom local hostnames, explicit HTTPS ALLOWED_ORIGINS,
NODE_EXTRA_CA_CERTS for outbound connections to private-CA MCP/OAuth
servers, and why NODE_TLS_REJECT_UNAUTHORIZED=0 should not be used.

This repo enforces a per-file ≥90% coverage gate on lines, statements,
functions, and branches (npm run coverage), so please make sure the
implementation includes direct tests for the TLS config surface, not just the
docs guide — for example:

  • Both env vars unset: TLS config resolves to undefined, listener stays
    plain HTTP.
  • Only one of the two set: startup fails with a clear error naming both
    variables.
  • Both set to valid PEM files: the key/cert are read and used to configure the
    listener.
  • A configured path that cannot be read: startup fails with an error naming
    the unreadable path, not a raw ENOENT/stack trace.
  • Default ALLOWED_ORIGINS derivation uses https:// (loopback,
    all-interfaces, and explicit-host cases) when TLS is enabled, http://
    otherwise.
  • Launch banner prints https:// when TLS is enabled and http:// otherwise,
    including the EADDRINUSE error path.
  • The Vite dev server picks up the same TLS pair for its server.https
    option.

Alternatives or workarounds you have tried

I considered terminating TLS in a local reverse proxy and using browser
certificate exceptions. A reverse proxy works around the missing listener
support, but adds configuration and process-management overhead and makes
local setup less reproducible. Browser trust alone is insufficient because the
Inspector Node process performs outbound MCP and OAuth requests of its own.

For local certificates, mkcert provides a trusted development CA and is
preferable to disabling TLS verification process-wide with
NODE_TLS_REJECT_UNAUTHORIZED=0.

Already built it locally?

Yes, I prototyped this locally. Exact prompt used:

Implement optional TLS for the Inspector web UI. Add INSPECTOR_TLS_KEY_PATH and INSPECTOR_TLS_CERT_PATH, require both or neither, read PEM key/certificate files at startup, and use them for both the production Hono listener and the Vite development listener. Preserve HTTP behavior when unset. Make the launch banner and default ALLOWED_ORIGINS use https when TLS is active. Ensure Vite's API middleware works correctly over TLS/HTTP2 as well as plain HTTP dev mode. Add tests that clear this repo's ≥90% per-file coverage gate on lines, statements, functions, and branches: TLS pair resolution (both set, only one set, neither set), reading key/cert files (success and an unreadable-path failure), HTTPS origin derivation for loopback / all-interfaces / explicit hosts, and banner output (including the EADDRINUSE path). Add docs/tls.md, link it from README.md and docs/environment-variables.md, and include mkcert setup, a curl --cacert verification step, custom-hostname guidance, NODE_EXTRA_CA_CERTS for private outbound CAs, and a warning against NODE_TLS_REJECT_UNAUTHORIZED=0. Do not add TLS to the sandbox or app-origin listeners.

Before you submit

  • I searched existing issues and this is not a duplicate.
  • This is a request for the Inspector itself, not for the MCP specification or an SDK.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature requestv2Issues and PRs for v2

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions