Docs Join alpha
Model

Home Agent Protocol

How your home agent talks to Sprout. MCP today; the abstraction holds whatever the wire protocol becomes.

Your home agent talks to Sprout over a protocol that exposes everything you can read and write about the family. Today that protocol is MCP (Model Context Protocol). The abstraction is broader than the wire format: any future protocol that gives a home agent the same surface plugs in the same way. The shape of the conversation matters more than the bytes.

This page describes the shape: the session, the two primitives, the metadata Sprout returns alongside results, the error envelope, and the push/pull model. Read it once; from here on, the rest of the docs reference it.

The session

Connect once over OAuth. The handshake binds your agent to a parent account; from then on every call carries a token scoped to that family. The connection persists for the life of the conversation. There is no per-call auth.

On initialize the server returns three things your agent uses immediately:

Progressive context

Sprout doesn't dump the whole SDK on your agent at connect time. The protocol gives your agent three layers of guidance, each loaded on demand, each pointing at the next.

Your home agent initialize 1 The map instructions field, returned once on initialize ~800 tokens injected into your agent's system prompt for the session "before authoring X, read sprout://X/guide" 2 The pointers resources/read sprout://*/authoring-guide deep model loaded on demand, only for the operation about to run tools/call X 3 The next step every tool response carries directional guidance error.code names the fix • response.nextStep names the next call your agent doesn't memorize the protocol; the protocol reminds it next operation, same pattern
  1. The map. On initialize, the instructions field lays out the mental model and the canonical sequences in around 800 tokens. Your agent injects this into its system prompt once at connect and keeps it for the session.
  2. The pointers. When your agent is about to author something consequential (a skill, a canvas, a heartbeat), the instructions tell it to resources/read the matching authoring guide. The deep model loads only for the operation it's running. No upfront ceremony.
  3. The next step. Every tool response carries directional guidance. Errors name the fix (canvas-needs-a-skill, PII_IN_PROMPT, SPEC_HASH_MISMATCH). Success envelopes carry nextStep. Your agent doesn't have to memorize the protocol; the protocol reminds it.

The effect: your agent explores Sprout. It doesn't memorize Sprout. Context arrives just in time, in the right shape, with the next move named.

The rest of this page goes through each layer in turn.

Two primitives, tools and resources

MCP exposes two ways to interact with the server. Both matter.

Tools (tools/call) are actions. task.create, skill.write, gems.adjust, family.query_overview. Your agent picks one, fills the arguments, gets a response. Reads and writes go through the same primitive. The server enforces scopes per tool.

Resources (resources/read) are addressable documents. sprout://skill/authoring-guide, sprout://canvas/sdk, sprout://heartbeat/authoring-guide. Your agent reads them at runtime, before authoring something that needs the deep model. The same documents power these docs you're reading; there is no separate "schema" you have to learn: the resources are the spec.

Shell
# Tool: action
tools/call task.create { name, assignChildIds, runMode, ... }
# Resource: context
resources/read sprout://skill/authoring-guide
# Returns markdown your agent reads before skill.write.

The instructions field

The instructions string ships on every initialize and is meant to land in your LLM's system prompt. It carries:

Token budget: aim under 800 tokens, since clients pay this every request. Sprout's instructions field is treated as a public wire surface and changes go through review: your agent can rely on the shape staying consistent.

Authoring guides as resources

Three resources matter most. Your agent should resources/read them when their domain shows up:

These are the source of truth. The docs here are the human-readable map; the resources are what your agent reads. If a page says one thing and a resource says another, the resource wins.

Dry-run and spec-hash

Write tools with consequential effects (skill.write, canvas.create) support a two-step commit:

  1. Call with dryRun: true. The server validates, runs analyzers, and returns a preview plus a specHash over the canonical input.
  2. Show the preview to the parent. Confirm.
  3. Call again with dryRun: false and the echoed specHash. The server re-hashes the input (excluding dryRun and specHash) and rejects mismatches with SPEC_HASH_MISMATCH.

The point is auditability. Two-step commit means the artifact your agent showed the parent is the artifact that ships. Blind-commit (no prior dry-run) is allowed but discouraged.

Errors and the envelope

Every tool returns either a success envelope or one of four error codes. The classification is directional: your agent reads the code and knows whether to retry, fix the input, or stop.

CodeWhat it meansWhat to do
BAD_INPUTSchema or contract violation. Includes SPEC_HASH_MISMATCH, PII_IN_PROMPT, SAFETY_REJECTED, invariant violations.Fix the input. Retry once the issue is addressed.
PERMISSION_DENIEDThe id you named doesn't belong to this family, or the scope is missing.Stop. Don't retry with the same id. If a scope is missing, reconnect to add it.
DOMAIN_NOT_FOUNDRead tool reports the resource is not visible (covers "missing" AND "cross-family": same code for anti-enumeration).Treat as "not yours." Don't probe further.
INTERNAL_ERRORServer-side fault: downstream timeout, safety provider 5xx, DB blip.Caller did nothing wrong. Retry with backoff.

Misclassifying infra failure as BAD_INPUT would mask ops signal and break retry semantics, so Sprout routes every internal throw through a single re-classification site. You can trust the code.

Idempotency

Write tools accept an Idempotency-Key HTTP header. Same key on retry returns the cached envelope, not a duplicate write. Generate one stable UUID per logical operation; reuse it on retries.

This matters most for task.create, skill.write, heartbeat.create, gems.adjust. A flaky network shouldn't double-deliver a task or double-tip gems.

Cadence caps

Heartbeats are server-capped at 4 fires per 24 hours in the heartbeat's timezone. Anything tighter (e.g. "*/10 * * * *") is rejected at heartbeat.create with a directional error naming the computed fires/day. The cap protects families from runaway-fire mistakes; if you need higher frequency, that's a different surface (not heartbeats).

Pull vs push: where each lives

Today's protocol is mostly pull. Your agent asks; the server responds. Even server-driven work (heartbeats firing, activity accruing) is discovered by polling reads.

Pull (today):

Push (shipping now, leaf-by-leaf):

Realtime (planned, further):

Scopes and sensitivity tiers

Every tool requires one or more OAuth scopes. The parent approves the set at consent time; today it's all-or-nothing, per-scope re-approval is planned.

Scopes are graded by sensitivity:

See the scope table on Plug your agent in for the per-tool mapping.

Further reading

The cast The nouns Plug your agent in How safety works

Was this page helpful?