Skip to main content
Glama

Ask permission to perform a side effect

ratchet_begin_effect

Request a decision before starting any external side effect, using a deterministic idempotency key and cost estimate to block duplicates and enforce spend ceilings.

Instructions

Call this IMMEDIATELY BEFORE performing any side effect that touches the outside world (sending a message, charging a card, creating a resource, writing to someone else's system). Returns a decision you MUST obey. If the response carries budget_warning, a spend ceiling exists but nothing was counted toward it — surface that to the operator rather than ignoring it. If it carries integration_warning, you have been beginning effects without reporting them: call ratchet_report_effect after every action, and tell the operator, because the effects already begun will start being blocked. Decisions:

  • "execute": you hold the lease. Perform the action now, then call ratchet_report_effect. If the response carries vendor_idempotency_key, send that key to the vendor as ITS own idempotency key (the response says where it goes). Where enforced is true the vendor itself will then refuse a duplicate, which protects the action even if some other caller skips this gate entirely.

  • "duplicate": this action ALREADY HAPPENED. Do NOT perform it. Use the returned result as though you had just done the work.

  • "in_flight": another process is doing it right now. Do NOT perform it. Wait retry_after_seconds and ask again.

  • "blocked": an earlier attempt may or may not have taken effect. Do NOT perform it. Tell the user what is unresolved, or verify at the vendor and call ratchet_resolve_effect.

  • "approval_required": a human must approve. Do NOT perform it.

  • "denied": policy or budget refused it. Do NOT perform it. The idempotency_key must be derived deterministically from the work itself so that a retry of the same logical action produces the same key. Never use a random value or the current time.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
run_idNoGroups all effects from one task or run.
vendorNoWhich vendor performs this effect (e.g. "stripe", "square", "adyen"). Shapes vendor_idempotency_key so it satisfies that vendor's rules.
payloadNoThe action's parameters. Only a hash is stored — the raw content never persists. Reusing a key with different parameters is rejected, which catches key collisions.
agent_idNoIdentifier for you, the calling agent.
group_keyNoUse when this action is one step of a multi-step workflow that must succeed or fail as a whole, e.g. "booking:trip_8812". Lets the whole unit be rolled back later.
dimensionsNoWho or what this action is aimed at, most often the destination: {"counterparty":"acct_1234"}. SEND THIS whenever the action targets a specific recipient, account or customer. It is how a per-destination ceiling can exist at all — "no more than $200 to any one counterparty per day" — and only a keyed hash of the value is stored, so Ratchet counts the destination without ever being able to read it. Declaring can only tighten: it never removes a limit. If begin is refused with dimension_required, the operator has made a dimension mandatory for this effect type and you must send it.
effect_typeYesNamespaced kind of side effect, e.g. "email.send", "payment.charge", "github.pr.create". Policy is configured per type.
compensationNoHow to undo THIS step if the workflow has to be rolled back. Declare it now, while you still know what undoing means — it cannot be worked out later. Steps without one are permanent.
lease_secondsNoHow long you expect the action to take. Report before this elapses or the effect becomes indeterminate.
idempotency_keyYesDeterministic identifier for this specific logical action, e.g. "welcome-email:user_123" or "invoice:2026-08:acct_88123". The SAME action retried must produce the SAME key.
compensates_effect_idNoSet when THIS call IS an undo, naming the effect it reverses. Comes from ratchet_unwind_group.
estimated_cost_microsNoWhat this action will cost at the third party, in micro-USD (1000000 = $1). ALWAYS SEND THIS when the action costs money. Spend ceilings are computed from it, and a ceiling with nothing declared against it never fires — the operator would be relying on a limit that cannot trigger. If the response contains budget_warning, that is exactly what has happened: tell the operator. Ratchet does not collect this money; it only counts it. It can also route the action to a human: an operator may set an approval threshold, and an action whose declared cost reaches it comes back approval_required instead of execute — so declaring accurately is what keeps large actions reviewable. Where a threshold is set, omitting this is refused with cost_required rather than allowed.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv0.3.0
    • changedInput schema / properties / estimated_cost_micros / description
      Previous value: -"What this action will cost at the third party, in micro-USD (1000000 = $1). ALWAYS SEND THIS when the action costs money. Spend ceilings are computed from it, and a ceiling with nothing declared against it never fires — the operator would be relying on a limit that cannot trigger. If the response contains budget_warning, that is exactly what has happened: tell the operator. Ratchet does not collect this money; it only counts it."New value: +"What this action will cost at the third party, in micro-USD (1000000 = $1). ALWAYS SEND THIS when the action costs money. Spend ceilings are computed from it, and a ceiling with nothing declared against it never fires — the operator would be relying on a limit that cannot trigger. If the response contains budget_warning, that is exactly what has happened: tell the operator. Ratchet does not collect this money; it only counts it. It can also route the action to a human: an operator may set an approval threshold, and an action whose declared cost reaches it comes back approval_required instead of execute — so declaring accurately is what keeps large actions reviewable. Where a threshold is set, omitting this is refused with cost_required rather than allowed."
  2. Changed1 schema field changedv0.2.1
    • addedInput schema / properties / dimensions
      Added value: +{
      +  "additionalProperties": {
      +    "type": "string"
      +  },
      +  "description": "Who or what this action is aimed at, most often the destination: {\"counterparty\":\"acct_1234\"}. SEND THIS whenever the action targets a specific recipient, account or customer. It is how a per-destination ceiling can exist at all — \"no more than $200 to any one counterparty per day\" — and only a keyed hash of the value is stored, so Ratchet counts the destination without ever being able to read it. Declaring can only tighten: it never removes a limit. If begin is refused with dimension_required, the operator has made a dimension mandatory for this effect type and you must send it.",
      +  "type": "object"
      +}
  3. First observedv0.1.0

TDQS

A4.8/5.0
Behavior5/5

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

There is no output schema and annotations only carry readOnlyHint:false, so the description bears the full behavioral burden — and it is exhaustive. It discloses exactly what happens for each returned decision, that Ratchet does not collect money but only counts it, that only hashes of dimensions are stored, that raw payload content never persists, and how vendor_idempotency_key propagates. No ambiguous side effects are left undisclosed.

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

Conciseness3/5

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

Well-structured with bullets, decision lists, and code blocks, but noticeably verbose — budget_warning is explained twice, the deterministic idempotency-key rule appears twice, and several sentences restate the same guarantees. Every sentence mostly earns its place given the complexity, but trimming redundancy would tighten it without losing meaning.

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?

With no output schema, the description fully defines the return contract — every possible decision value ('execute', 'duplicate', 'in_flight', 'blocked', 'approval_required', 'denied') and its required follow-up. The complex nested objects (payload, compensation, dimensions) and nuanced fields (lease_seconds, group_key, compensates_effect_id) are each explained with concrete examples, leaving no gap an agent needs to guess about.

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

Parameters5/5

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

Schema coverage is 100%, but the description adds substantial meaning beyond it: it tells when parameters are mandatory in practice ('ALWAYS SEND THIS when the action costs money', 'SEND THIS whenever the action targets a specific recipient'), explains the deterministic key requirement, how vendor shapes the key, how dimensions enable per-destination ceilings, and why omitting cost is refused with cost_required. This goes well past the baseline for full schema coverage.

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 an explicit verb ('Ask permission'), a specific resource ('side effect'), and the action's scope ('perform') — 'Ask permission to perform a side effect' unambiguously names what the tool does. It also implicitly separates itself from siblings like ratchet_report_effect (which reports the effect) so an agent can pick the right call.

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 explicit timing — 'Call this IMMEDIATELY BEFORE performing any side effect' — and explicit when-not-to-use behavior for each decision value (duplicate, in_flight, blocked, approval_required, denied). It names the sibling tools to call next (ratchet_report_effect, ratchet_resolve_effect, ratchet_unwind_group), giving clear alternatives rather than leaving them implicit.

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