Malformed and excessive amounts are rejected before anything is issued, and a reservation on its own spends nothing — budget only moves on a commit. What the protocol cannot do is stop an agent from skipping the check entirely, which the project says outright and answers by putting Cycles in the dispatch path.
A budget authority for agent loops. Before a costly step — an LLM call, a tool invocation, an external action — the agent reserves against a scope; afterwards it commits the real usage or releases the hold. Scopes nest from tenant down through workspace, app, workflow, agent and toolset, so a per-customer or per-task cap is enforced by the Cycles runtime rather than by prompt.
- A reservation that locks budget and returns a decision — proceed only on ALLOW, and a reservation_id to finish with later
- A commit that records what was actually used and returns the unspent remainder to the pool, called whether the operation succeeded or failed
- A release for work that was cancelled or skipped, so nothing is left dangling
- A TTL extension that acts as a heartbeat for long jobs, keeping a reservation alive without changing its amount; if the agent dies, the reservation expires and the budget comes back on its own
- A lightweight preflight that answers whether an action would be allowed without locking anything — useful for choosing strategy at the start of a workflow
- Balances per scope showing remaining, reserved, spent, allocated and debt, with child scopes included on request
- Reservations listed by status — ACTIVE, COMMITTED, RELEASED, EXPIRED — and one opened by ID, for finding what is stuck
- Fire-and-forget metering for systems that only want the numbers: record a completed operation directly, applied atomically to every derived scope
- Pressure signalled in the response itself: plain-text hints follow the JSON on a denial, on ALLOW_WITH_CAPS, or when little budget is left, so an agent can downgrade its model or skip optional calls without host support
- Three prompts that use the same data to design a scope hierarchy, generate integration code, and diagnose an overrun
Node.js 20 or newer, run over stdio from npm as @runcycles/mcp-server, or with --transport http for streamable HTTP. Two variables are required in live use: CYCLES_API_KEY and CYCLES_BASE_URL pointing at your Cycles server. CYCLES_MOCK=true explores the tools with no server and no key, prefixing generated IDs with mock_ and enforcing nothing; it is refused under NODE_ENV=production unless CYCLES_ALLOW_MOCK_IN_PRODUCTION is also set. CYCLES_DEFAULT_TENANT and its siblings fill in subject fields an agent omits, and explicit fields win. Every mutating call requires an idempotencyKey — only the caller can hold one stable across a retry. On HTTP, MCP_HTTP_AUTH_TOKEN makes a bearer token mandatory on /mcp while /health stays public.
One command plus a key — npx -y @runcycles/mcp-server, then supply credentials
