DEV Community

matt-dean-git
matt-dean-git

Posted on • Originally published at satgate.io

MCP Budget Enforcement: A Practical Guide to Controlling AI Tool Spend

MCP (Model Context Protocol) is becoming the standard way AI agents interact with tools. But MCP has no built-in concept of cost. A tools/call request to a cheap lookup function and a $2 code execution tool look identical at the protocol level. This guide shows how to add economic governance to any MCP server.

The Problem with Unmetered MCP

When you connect an AI agent to MCP servers, the agent can call any tool it has access to, as many times as it wants. There's no protocol-level mechanism for:

  • Assigning costs to different tool calls
  • Tracking cumulative spend per agent
  • Enforcing a budget ceiling
  • Attributing costs to teams or departments
  • Delegating budget from a parent agent to sub-agents

Most MCP gateways solve the connectivity problem — routing, auth, discovery. But connectivity without cost control is like an open highway with no toll booths.

Step 1: Define Per-Tool Costs

Map tool calls to costs with a cost profile:

mcp:
  costProfile:
    defaultCostCredits: 1
    tools:
      - name: "web_search"
        costCredits: 2
      - name: "code_execute"
        costCredits: 10
      - name: "file_read"
        costCredits: 1
      - name: "database_query"
        costCredits: 5
      - name: "*_premium"
        costCredits: 20  # wildcard matching
Enter fullscreen mode Exit fullscreen mode

Wildcard matching (*_premium) lets you price tool families without listing every variant.

Step 2: Mint Tokens with Budgets

Agents authenticate with capability tokens (macaroons) that carry their budget as a cryptographic caveat:

satgate mint \
  --agent "research-bot" \
  --budget 500 \
  --scope "/mcp/*" \
  --expiry 24h \
  --cost-center "engineering"
Enter fullscreen mode Exit fullscreen mode

The budget is embedded in the token itself. The gateway doesn't need a database lookup to know the ceiling.

Step 3: Agent Sees Its Own Budget

SatGate injects economic metadata into the MCP tools/list response:

{
  "tools": [
    {
      "name": "web_search",
      "description": "Search the web [SatGate: 2 credits per call]",
      "x-satgate": {
        "cost_credits": 2,
        "budget_remaining": 487,
        "calls_affordable": 243
      }
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Smart agents can use this metadata to choose cheaper alternatives when budget is low.

Step 4: Enforce at the Gateway

When an agent makes a tools/call, the MCP proxy:

  • Forwards the request if budget is sufficient (deducts the cost)
  • Returns a budget error if the agent has exceeded its cap

This happens at the proxy layer, before the request reaches your MCP server. Your tools don't need any changes.

Step 5: Delegation Trees

In multi-agent systems, a coordinator can mint sub-tokens from its own token:

# Coordinator has 500 credits
satgate delegate \
  --from <coordinator-token> \
  --to "research-agent" \
  --budget 100 \
  --scope "/mcp/search*"

satgate delegate \
  --from <coordinator-token> \
  --to "code-agent" \
  --budget 200 \
  --scope "/mcp/code*"

# Total across tree: still <= 500
Enter fullscreen mode Exit fullscreen mode

The parent's budget is the ceiling. If you revoke the parent token, the entire tree is instantly invalidated.

Step 6: Monitor and Attribute

Every tool call generates an event with full attribution:

  • Agent identity — which agent made the call
  • Tool name — which tool was invoked
  • Cost — credits charged
  • Budget remaining — after this call
  • Cost center — department/team tag
  • Delegation chain — full path from root to leaf agent

Quick Start

# 1. Install
go install github.com/SatGate-io/satgate@latest

# 2. Configure (mcp-proxy.yaml) and run
satgate -config mcp-proxy.yaml

# 3. Mint a token
curl -X POST http://localhost:9090/admin/mint \
  -d '{"agent":"my-bot","budget_total_credits":100}'

# 4. Connect your agent to localhost:8080/mcp
Enter fullscreen mode Exit fullscreen mode

Try it in the Sandbox — no setup required

GitHub — open source, Apache 2.0

Full documentation

Top comments (0)