Wire an OpenAI mcp_approval_response to a Sume spend cap
When a person approves an mcp_approval_request, reuse the approved dollar amount as max_spend_usd on the Sume call so the approval and the cap match.

Make the human approval and the spend cap the same number. When your app shows an mcp_approval_request for a paid Sume tool, show the dry_run estimate beside it, and have the approver confirm a dollar ceiling. Then use that ceiling as max_spend_usd on the real call so the model cannot spend beyond what the person saw.
OpenAI's MCP guide defines the round trip: the model output has an mcp_approval_request item, and you reply with an mcp_approval_response input item with approve and approval_request_id. Sume's optional spend controls are in tools and gates.
Sequence
| Step | Who | What happens |
|---|---|---|
| 1 | Model | Requests a paid Sume tool; OpenAI returns mcp_approval_request |
| 2 | Your app | Calls the same tool with dry_run=true to get the estimate |
| 3 | Person | Approves a ceiling in dollars |
| 4 | Your app | Sends mcp_approval_response with approve and approval_request_id |
| 5 | Sume | Runs the paid call; max_spend_usd applies only if sent |
The approval reply
The reply is an ordinary input item on the next request. This helper builds it from the request item. Chain it to the previous response so the model continues the same turn.
export function approvalReply(item: { id: string }, approve: boolean) {
return {
type: "mcp_approval_response",
approval_request_id: item.id,
approve,
};
}Gaps to know about
Approval in OpenAI's flow is about whether the call may proceed. It does not by itself set a cap on the Sume side, which is why the second step matters: Sume enforces max_spend_usd only when it is present. If the model controls the arguments, set the cap in your own proxy, or check the arguments in the approval request before you approve.
Sources
Related posts
More in Developers
- require_approval never with tool_names for Sume read tools
Use the object form of require_approval to skip approval only for Sume read tools like account_me, and keep every paid tool on the approval path.
- Restyle burned-in captions without transcribing twice
Pass source_caption_id instead of video_url to re-burn a video under a new Sume caption style. Word timings are reused, so no second speech-to-text runs.
- Resume an Omni batch after a crash with stable idempotency keys
A worker dies halfway through 40 Omni clips. Build Idempotency-Key from the item id so a rerun resubmits safely, and treat 409 and 429 as signals, not failures.
- Retrain a cloned voice without breaking old videos
HeyGen keeps a voice ID when a clone is retrained. On Sume, an avatar is referenced by a stable handle, and each text-to-speech job records its voice and model.
Written by Sume