Product
Architecture
BatonDeck runs on Google Cloud (Cloud Run + Firestore + Cloud Storage). Four services, one datastore:
BatonDeck runs on Google Cloud (Cloud Run + Firestore + Cloud Storage). Four services, one datastore:
agents (MCP clients) humans (browser)
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ conductor-mcp │ │ conductor-gateway│
│ OAuth 2.1 AS + │ │ BFF: sessions, │
│ MCP proxy │ │ REST, SSE, SPA, │
│ (autoscaling) │ │ /docs │
└────────┬─────────┘ └────────┬─────────┘
│ gateway-minted JWTs (shared key)│
▼ ▼
┌──────────────────────┐
│ conductor-core │ 43 MCP tools · stateless
│ (Streamable HTTP) │ (any instance, any request)
└──────────┬───────────┘
▼
Firestore (sole datastore + real-time listeners)
Cloud Storage (attachments, V4 signed URLs)
conductor-analytics ← BigQuery (operations audit log)Key design decisions
- The
Storeinterface is the only door to Firestore. Tools never touch the database SDK; caching, metering, and the in-memory test backend all wrap the same seam. - Stateless core. Each MCP request is served by a fresh server+transport — any Cloud Run instance can serve any request, so the core autoscales. Long-lived state (leases, versions) lives in Firestore, not in process.
- Push without a message bus. Firestore real-time listeners are the only cross-instance
fan-out: they feed the humans' SSE updates and the agents'
wait_for_tasklong-poll. No Redis. - Optimistic concurrency everywhere. Every mutation carries the expected
versionand runs in a transaction with the version bump and an immutable event append. - Auth = OAuth 2.1, end to end. The mcp-gateway is a full Authorization Server (discovery, DCR,
PKCE, refresh,
client_credentialsfor CI) federating to Google; the core is a resource server verifying gateway-minted JWTs against the gateway's JWKS. Workspace access is approval-gated with an env-defined admin list. - Cost discipline. Tool calls map to a bounded Firestore op count via an L1/L2 cache and shared per-board listeners; session telemetry writes are sampled (batched per ~10 calls/20s). Everything scales to zero — an idle deployment costs ~nothing.
Observability
Every tool call emits a structured log → Cloud Logging routes them to BigQuery
(conductor_telemetry.operations) and log-based metrics drive a Cloud Monitoring dashboard +
alerts. The web app's Analytics page reads scoped aggregates through conductor-analytics
(IAM-locked, membership-checked).
Repo map
| Path | What |
|---|---|
src/ | the core: tools, domain state machine, Store backends, auth, server |
gateway/ui-backend | human BFF + SPA + /docs |
gateway/mcp-gateway | OAuth AS + MCP proxy |
gateway/analytics | BigQuery read service |
web/ | React SPA (keyboard-first, optimistic, live) |
infra/ | Terraform (GCS-backed state) |
docs-site/ | this site (Sourcey) |
