Resources · The agent contract
The agent contract
Four entrances. One meaning. An agent that learns SproutPad through MCP already knows it through REST.
Resources · The agent contract
Four entrances. One meaning. An agent that learns SproutPad through MCP already knows it through REST.
SproutPad publishes one set of typed operations. MCP, the REST API, the TypeScript SDK, and the CLI are transports over that set — not four products with four behaviours. The same operation has the same name, the same arguments, the same price, the same retry semantics, the same task lifecycle, and the same receipt no matter which door an agent came through.
This matters because agents are cheap to point at a new surface and expensive to teach. An integration written against MCP keeps working when the same team moves to the SDK.
MCP REST SDK CLI LLMS.TXT
Strict tools, no escape hatch. Each tool publishes its exact typed actions. There is no free-form parameter that quietly accepts anything else, which is what makes the published contract worth reading.
An agent that can open a web link needs nothing else to begin. /llms.txt states the mental model and the entry points; the anonymous operations work without an account, so an agent can price a job before anyone signs up.
Fetch https://sproutpad.ai/llms.txt and follow it to estimate what my project will cost, explain the spending limits, then send me the human review link.
Machine-readable surfaces: llms.txt, openapi.json, .well-known/mcp.json, and .well-known/mcp-tools.json.
An agent authenticates with a scoped, revocable credential. The design assumes the agent is fallible and possibly compromised: nothing depends on the agent behaving well.
Agents do not read dashboards, so every mutating response carries what an agent needs to behave correctly. The field names are normative — an auditor or SDK can check an envelope from any conforming implementation without a per-vendor mapping layer.
{
"data": {
"receipt": {
"action": "launch_service",
"oneTimeUsd": 14.00,
"monthlyDeltaUsd": 5.00,
"resources": [{
"kind": "service",
"provider": "example-compute",
"externalId": "svc_abc"
}]
},
"undo": {
"command": "teardown(proj_abc, dryRun: true)",
"irreversible": false
},
"budgetRemainingUsd": 6.00,
"actions": [{
"kind": "tool",
"tool": "get_status",
"arguments": { "projectId": "proj_abc" },
"reason": "Confirm the live project after launch"
}]
}
}
Blocked responses are just as typed: blockedBy names the gate, message explains it, retryable says whether another attempt can succeed, and a non-empty actions array provides typed recovery or an explicit stop. When relevant, limit/requested carry the numbers. An agent never has to parse prose to find out what happened.
Schema: /spec/envelope.schema.json. Full definition: the open specification.
Why the money is held before it is spent, what an estimate is not, and how headroom is actually computed.
What gets gated, who can decide it, what the approval page must show, and what happens if nobody answers.
Tasks, their four states, why restarts are safe, and how multi-step work compensates when a step fails.