Resources · The agent contract

The agent contract

Four entrances. One meaning. An agent that learns SproutPad through MCP already knows it through REST.

One contract, four doors

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.

Start from one URL

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.

agent promptcopy/paste
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.

What a key can actually do

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.

Scope
One project, and only the limits set on it.
Cannot do
Approve its own gated actions, read another tenant's tasks, or reach your registrar, hosting, or payment-account logins.
Never sees
Card details. Stripe holds the instrument; SproutPad holds permission to charge inside an approved flow.
Revocation
Immediate, and it does not disturb the underlying provider accounts.

Governance the agent can read

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.

POST /v1/… · mutating successapplication/json
{
  "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.

Keep reading