Skip to main content
Glama

spendctl

Fetch a paid sandbox URL

sandbox_pay

Fetches one of the sandbox's paid endpoints (HTTP 402, x402) through the spendctl sidecar, which applies the sandbox agent's budget, allowlist and approval policy, pays with the throwaway wallet if allowed, and returns the response. Use it for every paid call in the sandbox: with dryRun to see the decision without paying, with approvalId to complete a payment that was held and then approved. The endpoints are https://weather.sandbox.spendctl.dev/weather?city= ($0.01) and https://search.sandbox.spendctl.dev/search?q= ($0.02), as listed by sandbox_create and documented at https://spendctl.dev/docs/sandbox/; any other host is refused. Returns a one-line summary (HTTP status, amount paid, decision, receipt id) followed by the response body, or the refusal with its reason, or an approval id when the payment is waiting for a human. Only sandbox hosts exist and no real funds are involved; the request is always a GET and responses are clipped at 20,000 characters. Example: url https://weather.sandbox.spendctl.dev/weather?city=Kyoto

Input Schema

NameRequiredDescriptionDefault
urlYesAbsolute URL of a sandbox endpoint, e.g. https://weather.sandbox.spendctl.dev/weather?city=Kyoto
dryRunNotrue: only report what spendctl would decide; never pay
approvalIdNoThe approval id from an earlier sandbox_pay result, after approve accepted it, to complete that held payment
sandbox_idYesThe sandbox_id returned by sandbox_create (32 hex characters)
idempotencyKeyNoReuse the same key when retrying a call so the sandbox is never charged twice, e.g. "kyoto-1"

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed3 schema fields changed
    • removedInput schema / properties / body
      Removed value: -{
      -  "description": "Request body for POST/PUT/PATCH, up to 16 KB",
      -  "type": "string"
      -}
    • removedInput schema / properties / headers
      Removed value: -{
      -  "additionalProperties": {
      -    "type": "string"
      -  },
      -  "description": "Extra request headers, e.g. {\"accept\": \"application/json\"}",
      -  "propertyNames": {
      -    "type": "string"
      -  },
      -  "type": "object"
      -}
    • removedInput schema / properties / method
      Removed value: -{
      -  "default": "GET",
      -  "description": "HTTP method; both sandbox endpoints answer GET",
      -  "enum": [
      -    "GET",
      -    "POST",
      -    "PUT",
      -    "PATCH",
      -    "DELETE"
      -  ],
      -  "type": "string"
      -}
  2. Changed7 schema fields changed
    • changedInput schema / properties / approvalId / description
      Previous value: -"An approval id that a human approved, to retry the held payment"New value: +"The approval id from an earlier sandbox_pay result, after approve accepted it, to complete that held payment"
    • changedInput schema / properties / body / description
      Previous value: -"Request body (for POST/PUT/PATCH)"New value: +"Request body for POST/PUT/PATCH, up to 16 KB"
    • changedInput schema / properties / dryRun / description
      Previous value: -"Only report what spendctl would do; never pay"New value: +"true: only report what spendctl would decide; never pay"
    • changedInput schema / properties / headers / description
      Previous value: -"Extra request headers"New value: +"Extra request headers, e.g. {\"accept\": \"application/json\"}"
    • changedInput schema / properties / idempotencyKey / description
      Previous value: -"Reuse the same key when retrying so the sandbox is never charged twice"New value: +"Reuse the same key when retrying a call so the sandbox is never charged twice, e.g. \"kyoto-1\""
    • addedInput schema / properties / method / description
      Added value: +"HTTP method; both sandbox endpoints answer GET"
    • changedInput schema / properties / sandbox_id / description
      Previous value: -"The sandbox_id returned by sandbox_create"New value: +"The sandbox_id returned by sandbox_create (32 hex characters)"
  3. First observed

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial context beyond the annotations: payments use a throwaway wallet with no real funds, policy (budget/allowlist/approval) is enforced by the sidecar, requests are always GET, responses are clipped at 20,000 characters, and a result may come back as a refusal or a pending approval id. Annotations only cover safety flags, so this is doing the real work; the only gap is that it doesn't say what the pending-approval path means for the caller's retry/cost beyond the schema's idempotencyKey note, which the description never mentions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and usage directive before detail, and every sentence carries operational information (endpoints, prices, refusal behavior, return shape). It runs long with an inline docs URL and repeated host enumeration, which costs a bit of tightness but not clarity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, and the description compensates fully by describing the return shape: a one-line summary with HTTP status, amount paid, decision and receipt id, followed by the body, or a refusal with reason, or an approval id. Combined with the endpoint list and GET/clipping constraints, an agent has everything needed to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description adds flow-level meaning: dryRun yields a decision without paying, approvalId completes a payment previously held and approved, and the url must match one of two priced sandbox endpoints with example syntax. It omits any mention of idempotencyKey, leaving that entirely to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('fetches one of the sandbox's paid endpoints') and explains the full path: routed through the spendctl sidecar which applies budget, allowlist and approval policy before paying. This is clearly distinguishable from siblings like check_budget, get_policy and approve, which only inspect or authorize rather than fetch.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit directive ('Use it for every paid call in the sandbox') plus the two operating modes: dryRun to see the decision without paying, and approvalId to complete a held-then-approved payment. It also bounds applicability by naming the only two permitted hosts and stating that any other host is refused.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources