title: "TICKET_049: Build & Deploy Bus MCP Server (Relay A)"
type: ticket
subtype: execution
purpose: "Build the STRUXIO Bus MCP Server from BLUEPRINT_Bus_MCP_Server_v1.md and deploy to Hetzner. This is the central nervous system for multi-brain communication."
Build and deploy the STRUXIO Bus MCP Server — a remote Streamable HTTP MCP relay that connects all Claude surfaces (B0-B5, CLI, Hetzner agents). Deploy to Hetzner with Postgres, Caddy TLS, and bearer token auth.
BLUEPRINT_Bus_MCP_Server_v1.md (Section 3: tools, Section 4: schema, Section 6: deployment)https://bus.struxio.ai/mcpmkdir -p /opt/struxio/bus && cd /opt/struxio/bus
npm init -y
npm install fastmcp fastify @fastify/cors pg ulid zod dotenv
npm install -D typescript @types/node @types/pg tsx
npx tsc --init --target ES2022 --module NodeNext --moduleResolution NodeNext --outDir dist --rootDir src --strict true
Per BLUEPRINT Section 6.1 (see blueprint for full tree).
src/store/migrations/001_initial.sql — SQL schema from BLUEPRINT Section 4.
src/store/postgres.ts — Connection pool, parameterized queries: insertEvent, pollEvents, ackCursor, upsertSession, insertAuditLog.
src/auth/tokens.ts — validateBearerToken(): SHA256 hash, lookup in api_tokens.
src/mcp/tools/bus.ts — 5 tools from BLUEPRINT 3.1-3.5: send_message, poll, ack, presence_heartbeat, status.
src/mcp/tools/paperclip.ts — 8 tools from BLUEPRINT 3.6-3.13: REST client wrappers. Credentials SERVER-SIDE ONLY.
src/mcp/mcpServer.ts — Register all tools with FastMCP. Server name: "struxio-bus".
src/server.ts — Fastify on BUS_PORT (8088). Mount FastMCP at /mcp. Mount /hooks/event, /healthz, /readyz. CORS. Auth middleware. Run migrations on startup.
src/hooks/ingest.ts — POST /hooks/event for Claude Code hook package.
Copy from BLUEPRINT Sections 6.3, 6.4. See blueprint for exact content.
Generates bearer tokens for each principal, inserts SHA256 hashes into DB, outputs raw tokens once.
npm run build
docker run -d --name bus-pg -e POSTGRES_PASSWORD=test -e POSTGRES_DB=bus -p 5433:5432 postgres:15
export BUS_DATABASE_URL=postgresql://postgres:test@localhost:5433/bus
node dist/server.js
curl http://localhost:8088/healthz
cd /opt/struxio/bus
git init
cat > .gitignore << 'GITIGNORE'
node_modules/
dist/
.env
*.log
GITIGNORE
git add -A
git commit -m "feat: TICKET_049 — Bus MCP Server scaffold"
git remote add origin git@github.com:STRUXIO/struxio-bus.git
git push -u origin main
# On Hetzner — clone the repo that Mac CLI just pushed:
cd /opt/struxio
git clone git@github.com:STRUXIO/struxio-bus.git bus
cd bus
# For subsequent updates after Mac pushes:
# git pull origin main
cd /opt/struxio/bus
cp .env.example .env
# Generate strong passwords:
openssl rand -base64 32 # POSTGRES_PASSWORD
openssl rand -base64 32 # BUS_PAPERCLIP_TOKEN
# Edit .env with generated values
cd /opt/struxio/bus
docker compose up -d --build
docker compose logs -f bus
docker compose exec bus node -e "require('./dist/store/postgres').runMigrations()"
docker compose exec bus node scripts/bootstrap_tokens.js
# Save the output tokens securely!
curl https://bus.struxio.ai/healthz
curl https://bus.struxio.ai/readyz
curl -X POST https://bus.struxio.ai/mcp # expect 401
curl -X POST https://bus.struxio.ai/mcp \
-H "Authorization: Bearer <B0_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"bus.status","arguments":{}},"id":1}'
curl https://bus.struxio.ai/healthz returns 200curl https://bus.struxio.ai/readyz returns 200bus.send_message returns event_id + seqbus.poll returns the sent messagebus.ack persists cursorbus.presence_heartbeat registers sessionbus.status returns online actors + pending countsdocker compose down
# Existing services unaffected (separate Docker network)
STRUXIO.ai // Confidential & Proprietary // © 2026