Skip to content

Add Streamable HTTP transport for remote deployments#3

Open
ThomsenDrake wants to merge 4 commits into
privy-io:mainfrom
ThomsenDrake:main
Open

Add Streamable HTTP transport for remote deployments#3
ThomsenDrake wants to merge 4 commits into
privy-io:mainfrom
ThomsenDrake:main

Conversation

@ThomsenDrake

@ThomsenDrake ThomsenDrake commented Mar 20, 2026

Copy link
Copy Markdown

Summary

Adds Streamable HTTP transport so the server can be deployed remotely (Railway, Fly.io, etc.) and accessed over the network by any MCP client. All changes serve this goal:

  • Streamable HTTP transport: New startHttpServer() using Express + StreamableHTTPServerTransport with stateful session management. The server exposes a single /mcp endpoint handling POST (JSON-RPC), GET (SSE streaming), and DELETE (session cleanup).
  • Transport auto-detection: When PORT is set or MCP_TRANSPORT=http, the server starts in HTTP mode. Otherwise it uses stdio as before — no breaking changes for existing local users.
  • Optional bearer token auth: When MCP_AUTH_TOKEN is set, all requests require a valid token. On HTTP this uses the standard Authorization header. On stdio it validates an auth field in the JSON-RPC message via a Transform stream that strips the field before it hits the SDK's strict Zod parser. When unset, auth is disabled (the default for local usage).
  • Fix dotenv stdout corruption: dotenv.config({ quiet: true }) — dotenv v17+ logs to stdout by default, which corrupts the MCP stdio protocol. This is a bug that affects the existing server regardless of transport.

Why

The server currently only supports stdio transport, which requires the MCP client to spawn it as a local process. This makes it impossible to deploy remotely or share a single server instance across multiple agents. Streamable HTTP transport is the standard MCP solution for remote servers, and bearer token auth is necessary to secure a network-exposed endpoint.

Client configuration

With a remote deployment, any stdio-based MCP client can connect via mcp-remote:

{
  "mcpServers": {
    "privy": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://your-deployment.example.com/mcp",
        "--header",
        "Authorization:${AUTH_HEADER}"
      ],
      "env": {
        "AUTH_HEADER": "Bearer your_secret_token"
      }
    }
  }
}

Testing

All scenarios verified locally and on a live Railway deployment:

Scenario Transport Result
PORT set, valid bearer token HTTP ✅ Initialize + tools/list
PORT set, invalid token HTTP ✅ 401 Unauthorized
PORT set, no token HTTP ✅ 401 Unauthorized
PORT set, no MCP_AUTH_TOKEN HTTP ✅ No auth enforced
PORT unset, valid auth field stdio ✅ Normal response
PORT unset, invalid auth field stdio -32600 error
PORT unset, no MCP_AUTH_TOKEN stdio ✅ No auth enforced

- Add MCP_AUTH_TOKEN env var for optional bearer token authentication
- When set, validates auth field on all JSON-RPC messages before processing
- When unset, server accepts all messages (default for local usage)
- Silence dotenv stdout output that corrupts MCP stdio protocol
- Update README and .env.example with auth documentation
- Add startHttpServer() with Express + StreamableHTTPServerTransport
- Auto-detect transport mode via PORT env var or MCP_TRANSPORT=http
- Bearer auth on HTTP uses standard Authorization header
- Stateful sessions with per-session server instances
- Stdio transport preserved unchanged for local usage
- Add @types/express dev dependency
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​types/​express@​5.0.61001007185100

View full report

@ThomsenDrake ThomsenDrake changed the title Add optional bearer token auth and fix dotenv stdout corruption Add Streamable HTTP transport for remote deployments Mar 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant