Deployment

This page covers the two main deployment topics for the MCP server: configuring HTTPS (required in production) and setting the correct public URL when the server runs behind a reverse proxy. Both topics must be addressed before clients can connect reliably in a non-local environment.

For a full list of the configuration keys referenced on this page, see Configuration reference.

HTTPS and local development

OAuth 2.1 requires HTTPS in production. The MCP server enforces this at startup and refuses to run with a plain HTTP public URL outside of development mode.

Production HTTPS

For production deployments, configure SSL in the Neptune DXP - Open Edition configuration:

{
  "enableSSL": true,
  "sslPort": 8443,
  "sslKey": "/path/to/key.pem",
  "sslCert": "/path/to/cert.pem"
}

After SSL is enabled, the MCP server uses https:// in all metadata documents and OAuth challenges.

Local development

For local development, you can run the MCP server over plain HTTP. The behavior depends on the hostname:

  • http://localhost and http://127.0.0.1 always work, regardless of NODE_ENV.

  • For other hostnames — for example, http://mcp-dev.internal — set NODE_ENV=development and start the process with MCP_DANGEROUSLY_ALLOW_INSECURE_ISSUER_URL=1.

    Never set MCP_DANGEROUSLY_ALLOW_INSECURE_ISSUER_URL=1 in a production environment. The flag disables the protection that prevents OAuth metadata from advertising insecure URLs.

Client behavior with plain HTTP varies:

  • Claude Code generally accepts HTTP for local servers.

  • Claude Desktop may require HTTPS. Configure SSL in Neptune DXP - Open Edition if needed.

Reverse proxy deployments

When Neptune DXP - Open Edition sits behind a reverse proxy, for example, nginx, an AWS Application Load Balancer, Cloudflare, or a Kubernetes ingress controller, the URL that clients use is not the URL that the server binds to. Without explicit configuration, the MCP server builds its OAuth metadata from the bind URL and advertises endpoints that clients cannot reach.

Configure the public URL

To make the MCP server advertise the correct public URL, set the mcpPublicUrl configuration key (or the equivalent environment variable PLANET9_MCP_PUBLIC_URL) to the URL clients will use:

{
  "port": 8080,
  "ip": "127.0.0.1",
  "mcpPublicUrl": "https://mcp.planet9.com"
}

Supply scheme and host only. Do not include a path or a trailing slash. The value is used for:

  • The authorization-server issuer URL and resource server URL.

  • The advertised .well-known metadata documents.

  • The WWW-Authenticate challenge issued when the client is unauthenticated.

Leave mcpPublicUrl empty in single-host or local-development setups. The bind URL is then used as a fallback.

Applying configuration changes

Neptune DXP - Open Edition hydrates its runtime configuration from a database table on each worker startup, then writes the result back to the configuration file. Editing mcpPublicUrl in the configuration file and restarting the server does not persist the change on its own — the database value wins.

To push a configuration-file edit through to the database, start the server once with the --overwrite flag:

# binary installation
planet9 --overwrite

# from source or in development
npm run start:dev -- --overwrite

The process clears the settings row, re-synchronizes from the configuration file, and exits. Start the server normally afterward. The same applies to any configuration key that is loaded from this table — mcpPublicUrl is one common example.

Changing mcpPublicUrl after clients have authenticated invalidates every existing session. Tokens are bound to the original public URL. The server refuses tokens whose audience does not match the new value. Connected clients must repeat the authorization flow. Schedule URL changes during a maintenance window if you have many active clients.