The Claude Code run had a $25 limit. It made one call to logs.summarize_fleet, received a successful response, and stopped.
The invoice arrived later: $286.40.
The MCP server had expanded the request across 42 services. Each service triggered retrieval, a hosted model summary, and a paid log scan. Claude Code’s counter still looked reassuring:
tool calls: 1
estimated cost: $0.22
actual cost: $286.40
run budget: $25.00
Nothing looped in Claude Code. No subagent broke its local allowance. The spend happened beyond the boundary where the budget was enforced.
Permission to call one method had become permission to buy an unknown amount of downstream work.
All systems, identifiers, prices, and records below are fictional examples.
Count economic effects, not tool calls
A tool-call cap is useful when an agent gets stuck in a retry loop. It cannot price a method whose workload grows with services, repositories, documents, tenants, or rows.
The first problem in this run was the estimate. Claude Code priced the visible request, while the MCP server knew the downstream scope. The server should quote that work before admission:
proposed_effect:
method: logs.summarize_fleet
scope:
services: 42
time_window_minutes: 60
billable_units:
log_scan_gb: 318
retrieval_queries: 42
hosted_model_calls: 42
quoted_cost_usd: 23.80
quote_expires_at: 2026-09-14T08:31:00Z
The quote is not a prediction tucked into a trace. It is part of the admission decision. The caller can reduce the scope, accept the quote, or stop before any paid worker starts.
Method names are poor cost boundaries. logs.summarize_fleet sounds like one read. Its economic effect depends on how much fleet work the server creates.
This is the cost version of an MCP blast-radius problem. As I wrote in Claude Code had no deploy permission. Its MCP tool deployed anyway, the agent-visible method does not reveal every effect behind it.
Put the spending ceiling inside the capability
A boolean permission answers whether the agent may call the method. It does not say how much work that method may purchase.
Carry a cost capability with the request:
cost_capability:
capability_id: cost-example-914
run_id: run-example-914
currency: USD
hard_limit: 25.00
available: 25.00
allowed_units:
- log_scan_gb
- retrieval_query
- hosted_model_call
max_delegation_depth: 2
expires_at: 2026-09-14T08:35:00Z
unknown_outcome_policy: retain_reservation
The MCP server must present that capability when it creates downstream work. Every worker spends from the same run allowance. A worker that cannot reserve enough money must refuse the job.
Do not copy available: 25.00 into 42 child requests. That creates 42 apparent budgets and a possible $1,050 commitment. Delegate slices of the original allowance instead. Child reservations cannot add up to more than their parent.
The currency and allowed unit classes matter too. A worker should not quietly add a paid dependency that was absent from the quote. Currency conversion should happen before admission, using a recorded rate and a conservative buffer, not after the bill lands.
You can download the blank MCP cost-capability YAML template and adapt the fields to your gateway and billing system.
Reserve before the server fans out
Forty-two workers cannot each read the same remaining balance, decide there is enough, and update it later. The owner of the run budget needs one atomic reservation operation.
quoted work $23.80
safety hold $1.20
atomic reservation $25.00
remaining after reservation $0.00
The MCP server can divide that reservation into child holds. It cannot mint fresh money. If two requests race for the last $4, one wins and the other stops before dispatch.
I used the same parent-owned ledger pattern for parallel Claude Code subagents. The difference here is location. The ledger must remain authoritative after the request leaves Claude Code. An in-process counter cannot govern work hidden inside an MCP server.
The reservation should bind at least these fields:
reservation:
reservation_id: reserve-example-44
parent_reservation_id: null
run_id: run-example-914
operation_id: op-example-914
quote_digest: sha256:example-quote
amount_usd: 25.00
status: held
Binding the quote digest prevents a server from reserving against a cheap scope and dispatching an expensive one. Binding the operation ID keeps a recovery attempt attached to the existing financial commitment.
Stop when the quote no longer covers the work
Fleet size can change between quote and dispatch. A scan may discover more data than expected. A provider may charge for an attempted batch even when it returns an error.
Use a narrow variance rule:
variance_policy:
quote_digest: sha256:example-quote
permitted_increase_usd: 0.50
on_excess: stop_before_dispatch
partial_results: return_with_receipt
A $23.80 quote plus fifty cents of permitted variance is not an open-ended approval. Once the reservation cannot cover the next worker, the server should stop and return the completed subset.
This is where partial results help. Forty completed summaries and two blocked ones are better than an invisible overrun, provided the response states exactly what is missing. The caller can request a new quote for the remaining services instead of letting the server improvise.
Atomic admission also needs current state. If the quote, target set, or balance changed before dispatch, reject the stale decision. The failure is similar to approving one state while an MCP write changes another.
A timeout leaves an unknown financial outcome
A timeout does not prove that paid work was cancelled. The provider may have accepted the job before the response disappeared.
Keep the reservation while the outcome is unknown:
unknown_commitment:
operation_id: op-example-914
reserved_usd: 7.40
dispatch_status: confirmed
provider_result: unknown
retry_allowed: false
reconciliation_deadline: 2026-09-14T09:05:00Z
A retry must reuse the operation identity. Creating a new ID can buy the same scan twice. This is why a timed-out MCP write should be treated as an unknown outcome, even when the effect is financial rather than a data change.
Rollback will not refund consumed model tokens, scans, or external API calls. Recovery means stopping further dispatch, preserving useful partial output, and reconciling every outstanding hold. Release money only when the provider confirms that it did not accept the work or reports the final charge.
Require a transitive cost receipt
The MCP response should account for the work purchased behind the method:
cost_receipt:
run_id: run-example-914
capability_id: cost-example-914
quoted_usd: 23.80
reserved_usd: 25.00
actual_usd: 22.64
released_usd: 2.36
downstream:
log_scan_gb: 301
retrieval_queries: 40
hosted_model_calls: 40
blocked_workers: 2
unknown_commitments: 0
complete: true
For a billable tool, success: true without this receipt is incomplete. A useful review packet shows the quote, reservation, actual charge, released amount, blocked work, and unresolved commitments.
The receipt should come from the budget owner, not from a model summarising its own run. Join it to the tool trace with the run ID, capability ID, operation ID, and quote digest. The reviewer can then test whether the observed charge belongs to the approved request.
If any worker can spend outside the capability, mark the receipt incomplete. unknown_commitments: 0 is a claim that needs evidence from every allowed downstream path.
Test the boundary that receives the bill
An agent-side test that counts one MCP call will pass the broken design. Put the harder evals around the server, reservation ledger, and paid workers:
- The MCP server omits the cost capability when delegating. The worker must refuse the job.
- Forty-two workers reserve at once. Their committed total must stay under the parent hold.
- The quote expires before dispatch. No worker may start.
- Actual units exceed the permitted variance. The server must return partial output and stop.
- A provider times out after accepting a job. The reservation must remain held and a blind retry must fail.
- A retry arrives with a new operation ID. Reconciliation must flag possible duplicate spend.
- A child adds an undeclared paid API. Admission must fail.
- The server reports success with one unknown commitment. The final receipt must remain incomplete.
The eval passes when total committed spend stays inside the hard limit and every allowed financial path appears in the receipt. A polished summary cannot rescue a run that violated its budget.
Put cost evidence beside permission evidence
The final review needs two verdicts. Was the method authorised? Did its complete economic effect stay within the authorised ceiling?
review:
method_authorised: true
target_scope_authorised: true
cost_capability_valid_at_dispatch: true
total_committed_usd: 22.64
hard_limit_usd: 25.00
undeclared_paid_dependencies: 0
unresolved_commitments: 0
reviewer_decision: accept
tool_calls: 1 answers neither question well. The useful record follows the money through every delegation and shows where work was blocked.
My operating rule is simple: if an MCP method can fan out, the run budget must cross the boundary with it. Reserve before dispatch. Make every downstream worker spend from the same capability. Do not report success until the cost receipt accounts for every commitment.
Claude Code: Building Production Agents That Actually Scale covers MCP effects, permission boundaries, retries, cost loops, rollback, evals, and review evidence for coding agents that reach real systems.