Deploy

Run bitmcp on Node, Vercel, or Cloudflare from one server artifact.

bitmcp build emits dist/server.js, hashed View HTML under dist/ui/, and dist/manifest.json. The server exports a Web-standard fetch handler plus GET, POST, and OPTIONS. Use that file on every platform.

Set deploy in bitmcp.config.ts. Default is "node". Scaffold a target with npx create-bitmcp my-app --deploy vercel or --deploy cloudflare.

Set BITMCP_STATE_KEY in production. Confirmations and ctx.ask mint requestState tokens that must verify on any replica.

Configure http.allowedHosts and http.cors in bitmcp.config.ts for public HTTP.

Node

pnpm build
BITMCP_STATE_KEY=... pnpm start

bitmcp start loads dist/server.js and listens on Streamable HTTP.

Default listen address: http://127.0.0.1:3000/mcp

Override with --port or MCP_PORT, MCP_HOST, and MCP_PATH. GET /health is also served.

Vercel

npx create-bitmcp my-app --deploy vercel

That writes deploy: "vercel" and vercel.json with a rewrite from /mcp to /api/mcp.

  1. Set BITMCP_STATE_KEY in the Vercel project
  2. Set http.allowedHosts to your deployment host
  3. vercel

bitmcp build writes gitignored api/mcp.js that re-exports dist/server.js. vercel runs pnpm build first.

Cloudflare Workers

npx create-bitmcp my-app --deploy cloudflare

That writes deploy: "cloudflare" and wrangler.jsonc with main set to dist/server.js.

  1. Set BITMCP_STATE_KEY as a Worker secret or var
  2. Set http.allowedHosts to your workers.dev or custom domain
  3. wrangler deploy

nodejs_compat is required. Wrangler runs pnpm build and serves dist/server.js directly.

Embed in an existing app

dist/server.js already 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;

Stateless replicas

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

Host and Origin guards

localhost bindings include Host and Origin checks. Production app.fetch only enforces hosts you put in allowedHosts.

Not in v1

OAuth, CIMD, Smithery, and Netlify presets are out of this pass.