feat: LLM governance — cost tracking, fallback chains, spending limits, rate limiting
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 407
- Forks
- 57
- Avg merge
- 5h 6m
- Merged PRs (30d)
- 880
Description
LLM Governance Features
MCP Mesh captures token counts and has pricing data per model, but lacks cost calculation, fallback routing, spending limits, and rate limiting. These are the top 4 features needed for LiteLLM-like governance over LLM spend — without integrating a separate Python proxy.
Why not integrate LiteLLM directly?
- LiteLLM is a Python proxy server — architectural mismatch with Mesh's Bun/TS stack
- Mesh already has native AI SDK v3 adapters with higher fidelity (reasoning tokens, multi-modal, tool calling loops)
- Adding LiteLLM would mean running a separate Python service, doubling infra complexity
- Building cost tracking + fallback chains gives 80% of LiteLLM's value without the complexity
Feature 1: Cost Calculation & Tracking
Gap: Mesh captures inputTokens/outputTokens AND has per-model pricing data (costs.input/costs.output), but never multiplies them together.
What to build
- Add
cost_usdfield to monitoring records (computed:inputTokens * inputCost + outputTokens * outputCost) - New
computeLlmCost()utility inapps/mesh/src/ai-providers/cost.ts - Emit cost in
monitorLlmCall()andrecordLlmCallMetrics()at bothonFinishandonErrorcallbacks - Add
COST_USDtoMONITORING_LOG_ATTRandMonitoringRow - New counter metric
tool.execution.cost_usd - Cost aggregation query in
monitoring-sql.ts(sum by model/user/time period)
Key files
apps/mesh/src/monitoring/emit-llm-call.tsapps/mesh/src/monitoring/schema.tsapps/mesh/src/monitoring/record-llm-call-metrics.tsapps/mesh/src/api/routes/decopilot/stream-core.ts(~line 701, 757)apps/mesh/src/storage/monitoring-sql.ts
Feature 2: Model Fallback Chains
Gap: If a provider returns an error (rate limit, outage), the request fails. No retry with alternative model.
What to build
withFallback()wrapper inapps/mesh/src/ai-providers/fallback.ts- On 429 or 5xx errors, automatically try next model in chain
- Log fallback events via OTel span events
- Integrate into OpenAI-compat endpoint (
x-fallback-modelsheader or request body extension) - Integrate into decopilot stream (read fallback config from agent/virtual MCP config)
Key files
apps/mesh/src/api/routes/openai-compat.tsapps/mesh/src/api/routes/decopilot/stream-core.ts
Feature 3: Spending Limits & Budget Enforcement
Gap: No way to cap spend per org/user/API key. Depends on Feature 1.
What to build
- New
spending_limitstable (migration062-spending-limits.ts):entity_type(organization / api_key / user),entity_id,limit_usd,period(daily/weekly/monthly)
- Storage operations: CRUD +
getCurrentSpend()+checkBudget() - Budget enforcement middleware (Hono) that checks spend before LLM calls
- Returns 429 with
x-budget-remainingheader when exceeded - Fail-open on DB errors
Key files
apps/mesh/migrations/062-spending-limits.ts(new)apps/mesh/src/storage/spending-limits.ts(new)apps/mesh/src/api/middleware/budget-check.ts(new)apps/mesh/src/api/app.ts
Feature 4: Rate Limiting (RPM/TPM)
Gap: Mesh relies entirely on provider rate limits. No org-level enforcement.
What to build
- In-memory sliding window rate limiter (Map-based, single process)
rate_limitstable alongside spending_limits migrationentity_type,entity_id,rpm_limit,tpm_limit
- Rate limit middleware (Hono) that checks RPM before LLM calls
- Returns 429 with
Retry-Afterandx-ratelimit-*headers - TPM enforcement is post-hoc (record after call, reject next if over)
Key files
apps/mesh/src/api/middleware/rate-limiter.ts(new)apps/mesh/src/api/middleware/rate-limit-check.ts(new)apps/mesh/src/api/app.ts
Implementation Order
Phase 1 (quick wins): Feature 1 — cost calculation
Phase 2 (reliability): Feature 2 — model fallback chains
Phase 3 (governance): Features 3 & 4 — spending limits + rate limiting
Middleware ordering on routes
rate-limit check → budget check → handler
🤖 Generated with Claude Code
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
This is a cross-cutting four-feature effort spanning the monitoring, AI-provider, API route, middleware, storage, migration, and application files listed in the issue. Start with Feature 1 by reading emit-llm-call.ts, schema.ts, record-llm-call-metrics.ts, and monitoring-sql.ts, then follow the stated implementation order. Done means cost tracking, fallback routing, spending limits, and RPM/TPM enforcement are implemented across the named entry points.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- bun, typescript
- Domain
- api, backend, databases, observability
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100