Token Cost Optimization
Two cost surfaces are covered here:
- Supabase MCP connector — schema + tool-result bloat (original scope, issue #1413).
- Agent orchestration — context growth and model choice across workers, orchestrators, and scheduled agents (issue #1414).
Part 1 — Supabase MCP
Problem
The claude.ai Supabase MCP connector accounts for ~23% of weekly token usage. Every MCP tool result stays in context for the entire session, bloating subsequent API calls.
Current state (as of 2026-06-27)
All three environments now use disableClaudeAiConnectors: true — the server never starts, so no schema tokens are consumed.
| Environment | Setting | Effect |
|---|---|---|
Local Windows dev (~/.claude/settings.json) | disableClaudeAiConnectors: true | All claude.ai connectors disabled at session start |
vps-i1 claude-runner (/home/claude-runner/.claude/settings.json) | disableClaudeAiConnectors: true | All claude.ai connectors disabled at session start |
bms-4 claude-runner (/home/claude-runner/.claude/settings.json) | disableClaudeAiConnectors: true | All claude.ai connectors disabled at session start |
The
deny: ["mcp__claude_ai_Supabase__*"]entry in localsettings.jsonis kept as defence-in-depth but is effectively redundant — the server never starts, so no tools are callable.
When Supabase MCP IS needed (local dev only)
Enable only for:
- Inspecting live schema not covered by migration files
- Running ad-hoc SQL via MCP tools during debugging
- Using
get_advisors,get_logs, orlist_tables
How to temporarily re-enable (local dev)
Edit ~/.claude/settings.json — set disableClaudeAiConnectors to false (or remove the key):
"disableClaudeAiConnectors": false,Run /compact after any Supabase-heavy work to flush MCP results from context.
Restore when done:
"disableClaudeAiConnectors": true,Note: disabling this key re-enables ALL claude.ai connectors (Gmail, Calendar, Drive, Vercel, etc.), not just Supabase. Re-enable for the minimum time needed, then restore.
Alternatives that avoid MCP cost
| Task | Instead of MCP | Use |
|---|---|---|
| Schema check | list_tables MCP | Read migration files in supabase/migrations/ |
| Table structure | MCP query | Grep for CREATE TABLE in migrations |
| Simple read | execute_sql MCP | Invoke-RestMethod to Supabase REST API |
| Secrets/URL | MCP metadata | sops -d secrets/monitoring.env.sops |
Additional mitigation
- Run
/compactafter any Supabase-heavy work - Isolate one-off Supabase queries to short-lived subagents (their results stay in their context)
Updating VPS agent settings
If you need to change VPS agent settings:
$settings = '{"permissions":{"allow":[],"deny":[]},"disableClaudeAiConnectors":true}'
[System.IO.File]::WriteAllText("$env:TEMP\cr-settings.json", $settings, [System.Text.UTF8Encoding]::new($false))
scp -i C:\Users\konar\.ssh\id_ed25519 "$env:TEMP\cr-settings.json" "root@54.36.123.110:/tmp/cr-settings.json"
ssh -i C:\Users\konar\.ssh\id_ed25519 root@54.36.123.110 "cp /tmp/cr-settings.json /home/claude-runner/.claude/settings.json && chown claude-runner:claude-runner /home/claude-runner/.claude/settings.json"
# Repeat for vps-i1 (217.154.82.162)Part 2 — Agent orchestration (issue #1414)
A 2026-06-25 usage audit identified structural token-burn patterns in how workers, orchestrators, and scheduled agents are built. This part records the rules applied and the rationale.
Rule 1 — /compact at phase boundaries
The largest per-call cost in a long agent session is accumulated context (file reads, diffs, test output,
MCP results) that is no longer needed once a phase completes. Run /compact at natural boundaries so the
rest of the session runs on a lean context. Persisted artifacts (issue comments, plan files on disk, git)
are re-read on demand — they do not need to stay resident.
| Flow | /compact after |
|---|---|
worker-issue.md | Step 2a (codebase/design read), Step 6 (tsc + vitest output) |
issues-review.md | Phase 3 (design catch-up), Phase 9 (plan saved), each Phase 10 PR iteration |
nightly-orchestrator.md | Phase 1 (review agents complete), before Phase 3 (synthesis) |
Rule 2 — Model selection: Haiku for mechanical work, capable model for reasoning
Use model: haiku for sub-agents / phases whose job is mechanical; reserve the default capable model
(Sonnet/Opus) for tasks that write code, generate designs, or reason about architecture.
| Use Haiku for | Use the default capable model for |
|---|---|
| File search / Glob / Grep without synthesis | Writing or editing code |
| Triage / pattern-match on issue titles & bodies | Generating a Code-change-design |
| Health-check / status polling | Reasoning about architecture or trade-offs |
| Heartbeat / bookkeeping REST calls | Resolving merge conflicts |
Applied at:
nightly-devops-triage.md— the triage agent itself runs on Haiku; only the Tier 2 fix workers it spawns use the capable model.new-issue.md— Step 2b codebase exploration; any delegatedgeneral-purpose/Exploresearch sub-agent is spawned withmodel: haiku, escalating only when implementation begins.
Rule 3 — Scope-targeted reads (no full-codebase sweeps)
A blanket read of src/pages + src/components + src/services + src/hooks + public/locales loads
one full-codebase context per worker per wave. Instead:
- If a
## Code-change-designcomment exists, parse itsfiles_to_changelist and read only those. - Otherwise
Grepfor the symbols named in the issue and read only the 2–5 matching files.
The Code-change-design template now carries a files_to_change: field (in both worker-issue.md
Step 2a and issues-review.md Phase 3) precisely so downstream workers can skip discovery.
Rule 4 — Batch bookkeeping calls
Every Supabase MCP result lingers in context for the remainder of the session, so fine-grained bookkeeping bloats every later API call:
worker-issue.mdheartbeats fire at phase boundaries / every ~10 files — not every 3–5 files.nightly-orchestrator.mdpolls review agents every 5 min (not 2 min): ~18 vs ~45 REST calls per run.
Already-resolved / not-applicable audit findings
The 2026-06-25 audit was taken on a snapshot that has since drifted. For traceability:
| Audit finding | Status |
|---|---|
| #4 Hourly triage runs 24×/day at Sonnet | Resolved structurally — hourly-devops-triage was consolidated into nightly-devops-triage (1×/day). Haiku for its mechanical phases (Rule 2) closes the remaining gap. Count-delta early-exit deliberately not added — a once-daily run must always execute SLA + alert phases. |
#5 issues-review.md Phase 0d spawns 5 parallel health-check agents | Not applicable — current issues-review.md Phase 0 has only 0a/0b/0c; no 5-agent Phase 0d exists. |
#2 / Phase 4 Remove runtime Read worker-issue.md; inject instead | Intentionally retained. issues-review.md (Phase 11b) and scripts/spawn-worker.sh deliberately pass a thin prompt that tells the worker to read worker-issue.md at runtime, “to keep the orchestrator thin and ensure all workers stay in sync with worker-issue.md automatically” (documented in issues-review.md). Inlining the full file into each spawn prompt costs the same tokens (the content enters context either way under the current claude -p CLI spawn) and reintroduces drift risk. A true saving would require system-prompt prompt-caching at the spawn layer — tracked as a separate follow-up, not a doc edit. |