Deployment
Node and custom
Run your app on Node with pnpm start and verify /health.
When you finish this guide, your app listens on Streamable HTTP at http://127.0.0.1:3000/mcp (or your configured host and port).
Complete the production checklist first.
Build
pnpm buildSet environment variables
Generate a production state key:
export BITMCP_STATE_KEY=$(openssl rand -hex 32)For public HTTP, set http.allowedHosts and http.cors in bitmcp.config.ts. See environment variables.
Start
pnpm startbitmcp start loads dist/server.js and listens on Streamable HTTP. Default address: http://127.0.0.1:3000/mcp.
Override with --port or MCP_PORT, MCP_HOST, and MCP_PATH. Set deploy: "node" in bitmcp.config.ts (this is the default).
Verify
curl http://127.0.0.1:3000/healthExpect { "ok": true }. Connect an MCP client to your /mcp endpoint and call a tool.
Run behind a reverse proxy
Terminate TLS with nginx or Caddy and proxy to your Node process:
location /mcp {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
}Run under a process manager for production:
pm2 start "pnpm start" --name my-mcpEmbed in an existing app
dist/server.js exports GET, POST, OPTIONS, and default.fetch. Point a platform entry at that file, or call app.fetch yourself:
import app from "../dist/server.js";
export const GET = (request: Request) => app.fetch(request);
export const POST = GET;
export const OPTIONS = GET;Operating at scale
Every request builds a fresh MCP server. There is no Mcp-Session-Id.
- Pass handles and ids in tool arguments
- Store job state behind a
HandleStore(KV, Redis, D1) - View HTML is content-addressed. Every replica serves the same hash for the same build
localhost bindings include Host and Origin checks. Production app.fetch only enforces hosts you put in allowedHosts.
Minimal store shape:
type HandleStore<T> = {
get: (id: string) => Promise<T | undefined>;
set: (id: string, value: T) => Promise<void>;
};See Handles for a full walkthrough.
Troubleshooting
- Connection refused — Confirm
pnpm buildsucceeded andpnpm startis running. - Host rejected — Add your public hostname to
http.allowedHosts. - MRTR errors — Set
BITMCP_STATE_KEYbefore starting in production. - CORS errors from browsers — Configure
http.corsinbitmcp.config.ts.
Reference
For programmatic servers and subpath imports, see Package exports.