Skip to content

perf(ai): serve /mcp from its own route graph - #2012

Merged
Makisuo merged 2 commits into
mainfrom
perf/ai-mcp-cold-start
Oct 31, 2026
Merged

Makisuo merged 2 commits into
mainfrom
perf/ai-mcp-cold-start

chore(ai): register the cold-path scripts with knip

bb9a5dd
Select commit
Loading
Failed to load commit list.
Maple Review Bot / Maple / review succeeded Oct 31, 2026 in 36s

Confidence 10/10 · No issues found

🟢 Confidence 10/10 · safe to merge. Both graphs keep the same provides and the new test pins the /mcp vs rest selection in both directions.
no findings · tests covered · risk medium · 1/1 new units observable

Splits maple-ai's route graph so a cold /mcp request no longer loads the chat, security-audit, triage and tool-catalog routes: makeFetch picks runtime/mcp-http-graph for path === "/mcp" and the existing graph for everything else. Safe to merge. It does not fix the open DeviceTokenRejected error from http-graph.js — the auth layers move verbatim, so that path rejects exactly as before.

  • makeFetch builds /mcp from runtime/mcp-http-graph and every other path from runtime/http-graph
  • AiAuthLive moves unchanged to runtime/auth-graph.ts and both graphs provide it
  • rawRoutes leak check moves to runtime/raw-routes.ts, still guarding both graphs
  • Each graph is its own cachedRecoverable, so one failing build leaves the other serving

Production impact

Open errors in the changed files (1)
Issue Service Occurrences File
@maple/backend/auth/device/DeviceTokenRejected maple-api 3 apps/ai/src/runtime/http-graph.ts

After this merges, Maple checks whether they stop.

Production traffic of the changed files (last 7 days)
File Calls/day Busiest operations
apps/ai/scripts/cold-path/build-bundle.mjs 59k maple 59k/day, 83.1% err
apps/ai/scripts/cold-path/graph-probe.ts 58k POST /mcp 28k/day, 0.0% err
POST /mcp 28k/day, 0.0% err
GET /mcp 382/day, 0.0% err
apps/ai/src/runtime/auth-graph.ts 58k POST /mcp 28k/day, 0.0% err
POST /mcp 28k/day, 0.0% err
GET /mcp 382/day, 0.0% err
apps/ai/src/runtime/http-graph.ts 58k POST /mcp 28k/day, 0.0% err
POST /mcp 28k/day, 0.0% err
GET /mcp 382/day, 0.0% err
apps/ai/src/runtime/mcp-http-graph.ts 58k POST /mcp 28k/day, 0.0% err
POST /mcp 28k/day, 0.0% err
GET /mcp 382/day, 0.0% err
apps/ai/src/worker/http.ts 58k POST /mcp 28k/day, 0.0% err
POST /mcp 28k/day, 0.0% err
GET /mcp 382/day, 0.0% err
Ingest cost of new log lines
  • apps/ai/scripts/cold-path/build-bundle.mjs:72: If this logs once per call, about 476 MB/month: the file's operations run 59k times a day.
What was checked
  • AiAuthLive covers every service McpLive declares (mcp/app.ts:224): ApiKeysService, AuthService, Env, ErrorActorsService, McpToolRateLimiter
  • cachedRecoverable is lazy (packages/infra/src/cloudflare/cached-recoverable.ts:11), so neither graph builds at isolate startup
  • api's forwardsToAi also sends /mcp/ prefixes, but 7 days of maple-ai traffic show only exact /mcp (POST 196k, GET 2.6k, DELETE 17)
Observability coverage: 1 of 1 changes observable
Change Kind Observable Evidence
/mcp request handling (POST/GET/DELETE) inbound HTTP yes makeFetch still hands the request to bridgeHandler; WorkerTelemetry({ serviceName: "maple-ai" }) unchanged in worker.ts:129

bb9a5dd · Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.