Platform/05MCP Gateway — Upstream/Downstream Architecture

What this is

The Stackbilt MCP Gateway is a Cloudflare Worker that exposes the platform’s product backends as a single MCP-compliant remote server, OAuth-authenticated. It’s the third leg of Stackbilder’s three-consumer fractal: the same backend service bindings power the web UI on stackbilder.com, the Charter CLI, and the gateway. The gateway exists so MCP-native agents (Claude Code, Claude Desktop, custom MCP clients) get a single OAuth endpoint without taking a dependency on the web UI’s session model.

For the full platform architecture this gateway sits in front of, see Stackbilder Platform. For the REST API that the gateway and CLI share, see API Reference. For the ecosystem overview, see Ecosystem.

Endpoint: https://mcp.stackbilt.dev/mcp

Repo: Stackbilt-dev/stackbilt-mcp-gateway

Stack: Cloudflare Worker built on @modelcontextprotocol/sdk and @cloudflare/workers-oauth-provider. Listed on the official MCP registry at registry.modelcontextprotocol.io.

Topology

                          ┌────────────────────────┐
                          │  AI agent / LM       │
                          │  Claude Code,        │
                          │  Claude Desktop,     │
                          │  custom MCP clients  │
                          └──────────┬───────────┘
                                     │ OAuth + MCP (Streamable HTTP / SSE)

                          ┌────────────────────────┐
                          │  mcp.stackbilt.dev   │
                          │  (gateway Worker)    │
                          └──────────┬───────────┘
                                     │ Service Bindings (in-colo, no HTTP)

        ┌──────────────────────────────────────────┐
        │  Backend product Workers (shared by all consumers) │
        │   │                                                 │
        │   ├─ edge-auth         (AUTH_SERVICE)               │
        │   ├─ tarotscript-worker (TAROTSCRIPT, scaffold_*)    │
        │   ├─ img-forge-mcp     (IMG_FORGE,    image_*)      │
        │   ├─ stackbilt-engine  (ENGINE,       arch flows)   │
        │   └─ stackbilt-deployer (DEPLOYER,    CF deploy)    │
        └──────────────────────────────────────────┘

                                     │ Service Bindings (parallel sibling consumers)
        ┌──────────────────────────┐      ┌────────────────────┐
        │  stackbilder.com         │      │  Charter CLI       │
        │  (web UI + REST API)     │      │  (charter blast,   │
        │  human users +           │      │   charter surface) │
        │  ea_* API key callers    │      │  CI / local dev    │
        └──────────────────────────┘      └────────────────────┘

Key invariant: the gateway and stackbilder.com are siblings, not parent/child. Both are CF Workers; both hold parallel service bindings to the same backend product workers; both route through edge-auth for entitlements + quota. A tenant’s Pro tier is consistent across whichever consumer they use.

Service-binding map

Authoritative source: Stackbilt-dev/stackbilt-mcp-gateway/wrangler.toml.

Binding Backend Worker Tool prefix on the gateway What it routes
AUTH_SERVICE edge-auth (entrypoint AuthEntrypoint) (used internally) Tenant resolution, API-key validation, OAuth grant storage in OAUTH_KV, entitlement checks, quota reservation
TAROTSCRIPT tarotscript-worker scaffold_*, agent_* Deterministic project scaffolding, classification, GitHub publishing, CF deployment hand-off, agent consultations
IMG_FORGE img-forge-mcp (not in live registry) AI image generation — use img-forge REST API directly
ENGINE stackbilt-engine (planned) Architecture mode pipeline (PRODUCT → SPRINT)
DEPLOYER stackbilt-deployer (planned) Cloudflare Workers deployment, D1 provisioning, DNS via API

Authentication

Method Header Use case
OAuth 2.1 + PKCE (DCR) Authorization: Bearer <oauth-access-token> Recommended for end-user agent connections (Claude Desktop, Claude Code, MCP Inspector). Clients self-register via Dynamic Client Registration — no pre-issued client_id required.
Static Bearer Authorization: Bearer <STACKBILT_MCP_TOKEN> Server-to-server / CI integrations.

Dynamic Client Registration (DCR)

The gateway exposes a RFC 7591 Dynamic Client Registration endpoint. MCP clients that support DCR (Claude Desktop, Claude Code, MCP Inspector) register automatically on first connect — there is no static client_id or client_secret to configure in advance.

OAuth endpoint Path
Authorization https://mcp.stackbilt.dev/authorize
Token https://mcp.stackbilt.dev/token
Client Registration https://mcp.stackbilt.dev/register

Scopes:

Scope Access
read tools/list, tools/call for read-only tools
generate All mutating tools (scaffold_create, image_generate, etc.)

Connection settings for MCP clients:

Setting Value
Transport Streamable HTTP
MCP endpoint https://mcp.stackbilt.dev/mcp
Auth type Dynamic OAuth Client (DCR)
Client ID / Secret Not applicable — issued dynamically at registration

The gateway intentionally does not accept ea_* API keys on the /mcp path (those are issued from stackbilder.com/settings for the platform’s REST API). The /api/mcp path accepts Bearer API keys for server-to-server use.

Per-client setup

No client_id needed. The gateway uses Dynamic Client Registration (RFC 7591) — clients register automatically on first connect. Paste the URL, authorize in your browser, and you’re done.

Claude Desktop

Config file: ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) · %APPDATA%\Claude\claude_desktop_config.json (Windows)

{
  "mcpServers": {
    "stackbilt": {
      "type": "http",
      "url": "https://mcp.stackbilt.dev/mcp"
    }
  }
}

Restart Claude Desktop after saving. On first use of a Stackbilt tool, a browser window opens for the OAuth flow. After you authorize, credentials are stored and future connections are silent.

Claude Code

claude mcp add --transport http stackbilt https://mcp.stackbilt.dev/mcp

Or add manually to ~/.claude/settings.json:

{
  "mcpServers": {
    "stackbilt": {
      "type": "http",
      "url": "https://mcp.stackbilt.dev/mcp"
    }
  }
}

After adding, run claude mcp list to confirm. The OAuth flow runs inline on first tool call.

Cursor

Global config: ~/.cursor/mcp.json
Project-scoped: .cursor/mcp.json at repo root

{
  "mcpServers": {
    "stackbilt": {
      "type": "http",
      "url": "https://mcp.stackbilt.dev/mcp"
    }
  }
}

Restart Cursor (or reload the window) after saving. Open the MCP panel in settings to confirm the server shows as connected.

Zed

Config file: ~/.config/zed/settings.json

{
  "context_servers": {
    "stackbilt": {
      "transport": {
        "type": "http",
        "url": "https://mcp.stackbilt.dev/mcp"
      }
    }
  }
}

Zed picks up the change on next window open. The server appears in Assistant → Context Servers.

Windsurf

Config file: ~/.codeium/windsurf/mcp_config.json

{
  "mcpServers": {
    "stackbilt": {
      "serverUrl": "https://mcp.stackbilt.dev/mcp"
    }
  }
}

Windsurf defaults to SSE transport for remote URLs. Restart the Windsurf window to activate.

Generic MCP client

For any client that supports Streamable HTTP or SSE:

Field Value
MCP endpoint https://mcp.stackbilt.dev/mcp
Transport Streamable HTTP (POST) or SSE (GET)
Auth OAuth 2.1 + PKCE via DCR (preferred)
Static Bearer (server-to-server) Authorization: Bearer <STACKBILT_MCP_TOKEN> on /api/mcp

For clients without OAuth support, issue a static token at stackbilder.com/settings and call /api/mcp instead of /mcp.

Transports

Transport Endpoint Method Use Case
Streamable HTTP /mcp POST Modern MCP clients, single request/response
SSE Stream /mcp GET Server-pushed events, session-based (requires auth + MCP-Session-Id)
Session teardown /mcp DELETE Terminate a session

Streamable HTTP sessions use the Mcp-Session-Id header. The first initialize POST returns a session ID; include it on subsequent requests; DELETE /mcp with the session ID to terminate. Capability negotiation happens via the standard MCP initialize message over POST — there is no separate unauthenticated info endpoint.

Rate limiting

Per-tenant fixed-window rate limiting via RATELIMIT_KV (60-second window):

Tier Requests / minute
Free 20
Hobby 60
Pro 300
Enterprise 1,000

On limit exhaustion the gateway returns 429 with Retry-After and X-RateLimit-Limit / X-RateLimit-Remaining / X-RateLimit-Reset headers.

Tool catalog

Scaffold tools (TAROTSCRIPT binding)

Tool Description
scaffold_create Generate deployable project files from a description. Response includes files[], nextSteps[], cloudflareManifest: { status, stale, valid_until? }.
scaffold_classify Classify an intention to a Cloudflare stack pattern. Returns pattern, confidence, traits, stack, alternatives.
scaffold_publish Publish generated scaffold to a new GitHub repo with an atomic initial commit.
scaffold_deploy Deploy a published scaffold to Cloudflare Workers via the deployer pipeline.
scaffold_import Import an n8n workflow JSON and transpile it to a deployable Cloudflare Worker.
scaffold_status Poll the status of an async scaffold, publish, or deploy operation by job ID.

Agent tools (TAROTSCRIPT binding)

Tool Description
agent_* C-level agent consultations (CTO, CISO, CFO, CPO, architect). See agent_bootstrap example below. Responses include a chain-verifiable receipt field.

Billing tools (AUTH_SERVICE binding)

Tool Description
billing_status Return current credit balance, quota state, and tier.
billing_purchase_credits Autonomous credit top-up. Charges the tenant’s Stripe payment method on file.

flow_* tools were removed on 2026-06-12 (v0.1.0). visual_* tools are present but gated as internal-only. image_* tools are not in the current live registry — use the img-forge REST API directly for image generation.

For the authoritative live tool list, call tools/list on the gateway or read the gateway repo README (Stackbilt-dev/stackbilt-mcp-gateway). The server.json in that repo is the MCP registry entry.

Scaffold pipeline (end-to-end)

You: "Build a restaurant menu API with D1 storage"


scaffold_create → structured facts + deployable project files


scaffold_publish → GitHub repo with atomic initial commit


git clone → npm install → npx wrangler deploy → live Worker

Zero LLM calls for file generation. ~20ms for structure, ~2s with oracle prose.

Use scaffold_classify before scaffold_create to inspect the stack pattern before committing to a scaffold.

Security model

Every tool in the gateway declares a risk level in route-table.ts:

Risk level Meaning
READ_ONLY No mutations — safe to expose broadly
LOCAL_MUTATION Mutates gateway-managed state only
EXTERNAL_MUTATION Calls an external system (GitHub, Cloudflare, Stripe)

tools/list is filtered by token scopes. tools/call requires the generate scope for any mutating tool. Cost attribution runs before dispatch — quota is reserved via edge-auth and committed or refunded based on outcome. Audit events are emitted to PLATFORM_EVENTS_QUEUE with secret redaction and trace IDs on every tool call.

TarotScript direct MCP surface

In addition to the gateway, the tarotscript-worker itself exposes a peer-to-peer MCP surface at /mcp/tools and /mcp/invoke for callers that hold a direct API key and do not need OAuth.

Tool ID Description
tarotscript.run_grader Grade an artifact against a rubric deck — returns per-dimension findings (TaskFit, Support, Actionability), aggregate score, gap report, and a chain-verifiable receipt.

This surface is additive and orthogonal to the gateway. Use the gateway for end-user agent connections; use the direct surface for CI pipelines and server-to-server callers with a static Bearer key.

Full schema and endpoint reference: TarotScript Runtime Reference.

Example prompts

scaffold_create — Generate a Cloudflare Worker project

Prompt:

scaffold_create: Build a multi-tenant SaaS API with Stripe billing and D1

Response shape:

{
  "files": [
    { "path": "src/index.ts", "role": "scaffold", "content": "..." },
    { "path": "wrangler.toml", "role": "config", "content": "..." },
    { "path": "schema.sql", "role": "config", "content": "..." },
    { "path": ".ai/manifest.adf", "role": "governance", "content": "..." }
  ],
  "nextSteps": [
    "npm install",
    "wrangler d1 create my-saas-api",
    "wrangler dev"
  ],
  "cloudflareManifest": {
    "status": "ready",
    "stale": false
  }
}

files are ready to write to disk. cloudflareManifest.status indicates whether the scaffold is deployable to CF Workers without changes.

scaffold_classify — Classify an intention to a Cloudflare stack pattern

Prompt:

scaffold_classify: real-time notification service with WebSockets and persistent state per connection

Response shape:

{
  "pattern": "durable-object-websocket",
  "confidence": 0.91,
  "traits": ["realtime", "stateful", "websocket", "durable-object"],
  "stack": ["Durable Objects", "WebSocket API"],
  "alternatives": ["workers-kv-cache"]
}

Use this before scaffold_create if you want to inspect the classification before committing to a scaffold.

image_generate — AI image generation (5 quality tiers)

Prompt:

image_generate: A minimalist developer-focused product banner, dark background, cyan accent lines, no text

Response shape:

{
  "url": "https://img-forge.stackbilt.dev/outputs/abc123.png",
  "model": "flux-pro",
  "tier": "standard",
  "width": 1200,
  "height": 630,
  "credits_used": 2
}

Tiers: draft · standard · premium · ultra · ultra_plus. Higher tiers use better models and cost more credits. Check billing_status to see your balance before generating.

agent_bootstrap — C-level agent consultation (CTO, CISO, CFO, CPO)

Prompt:

agent_bootstrap: CTO — should I use D1 or Postgres for a multi-tenant SaaS targeting 10 000 tenants?

Response shape:

{
  "recommendation": "D1",
  "rationale": "At 10k tenants on Cloudflare Workers, D1 per-tenant databases eliminate connection-pool contention and keep latency at the edge. Postgres requires a connection pooler (PgBouncer, Supabase Pooler) and a regional instance, adding ~20–40ms round-trip for edge callers.",
  "risks": [
    "D1 row size limit (2 MB) — plan schema accordingly",
    "No full-text search — add Vectorize or external index if needed"
  ],
  "alternatives_considered": ["Postgres via Hyperdrive", "Turso (LibSQL)"],
  "receipt": "agent:cto:2026-06-21T16:30:00Z:d1-vs-postgres"
}

The receipt field is chain-verifiable via /receipts/:id on the gateway. Use it in PR descriptions or ADRs to link the decision back to the agent consultation.

scaffold_classify (TarotScript direct) — Vocabulary-level intent mapping

Prompt:

scaffold_classify: I want to build something that processes webhook events from Stripe and queues retries

Response shape:

{
  "intent": "event-processor",
  "vocabulary_signal": "webhook, queue, retry",
  "canonical_pattern": "workers-queue-consumer",
  "confidence": 0.87,
  "deck_card": "Queue Consumer — Fire & Forget"
}

This is the TarotScript-native classifier at /mcp/invoke (direct surface, no gateway). Use it when you want the raw deck-level classification before any scaffold output.

Documentation surface

The canonical platform-side reference for the gateway is this page (docs.stackbilder.com/mcp). The gateway repo (Stackbilt-dev/stackbilt-mcp-gateway) also carries docs/api-reference.md, docs/user-guide.md, and docs/architecture.md for developer-facing detail. The server.json in the gateway repo root is the MCP registry entry published at registry.modelcontextprotocol.io.

What was deprecated

This architecture replaces an earlier topology where:

  • The gateway lived behind stackbilt.dev/mcp (the stackbilt.dev domain now 301-redirects to stackbilder.com; stackbilder.com/mcp/info returns 404)
  • A third auth method, Compass JWT, was accepted (Compass was removed as a standalone product per stackbilt-web/CLAUDE.md; its governance logic is being absorbed into stackbilt-engine)
  • A separate Compass Service Adapter (CSA) transport mode existed for routing inside the platform (no longer relevant)
  • Cross-Compass unified-auth via stackbilt.dev/api/auth/token (endpoint dead)

The Stackbilt-dev/edgestack_v2 repo, which previously hosted the canonical mcp.md doc on its way to the docs site, is deprecated for documentation purposes and excluded from docs-manifest.json v3.

Two-consumer fractal in concrete form

The feedback_two_consumer_fractal memory describes the principle: “Every product surface must work for both Human users AND LM agents. UI is one consumer of the API; MCP gateway + Charter CLI are siblings.” The MCP gateway is the concrete instance:

  • Same backend product Workers as stackbilder.com
  • Same AUTH_SERVICE for entitlements
  • Same quota model
  • Different transport (MCP), different auth (OAuth), different consumer (LM agents)

A new feature lands by adding a route on stackbilder.com (the canonical contract); the gateway gains parity by exposing it as an MCP tool that calls the same backend service binding. The web UI is the human surface; the gateway is the agent surface.

Authority

  • Gateway repo: Stackbilt-dev/stackbilt-mcp-gateway
  • Wrangler config (binding map): Stackbilt-dev/stackbilt-mcp-gateway/wrangler.toml
  • Public registry: registry.modelcontextprotocol.io (search: stackbilt)
  • Docs site page: https://docs.stackbilder.com/mcp
  • Canonical platform-side reference: Stackbilt-dev/stackbilt-web/docs/mcp.md
  • Manifest pointing here: Stackbilt-dev/docs/docs-manifest.json v3
  • Two-consumer fractal principle: memory feedback_two_consumer_fractal

When any of these contracts change shape (new service binding, new tool catalog, auth model change, transport addition, gateway URL change), update both the code and this page. Advance lastVerified.