Turn a build goal into a full plan: stack, install steps, Preflight
onchain_agent_build_planUSE WHEN someone describes the onchain agent they want and needs ONE composed answer that goes from goal to install steps (stack, deploy specs, Preflight, first action, open questions) rather than advice. NOT FOR only the ranked stack (use onchain_agent_recommend_stack instead, the lighter first call), a plan plus a pointer to the repo generator (use onchain_agent_scaffold_plan), or the runnable repo itself (use onchain_agent_create_agent).
COMPOSES onchain_agent_recommend_stack, onchain_agent_get_deploy_spec and onchain_agent_preflight: the goal restated, a stack of REAL directory listings (each with Sato Score, liveness, observed check record and sato_url), the deploy spec for every item that publishes one, a records-only preflight_summary and a dated trust_spec (what it does with your keys and money, from Sato Check) on every item with trust_warnings first when a planted key was observed leaving or code reads undeclared key material, the first action when the goal implies one (a swap route, or a prepared token-launch config), the questions the user still has to answer, and the next steps.
RULE ENFORCED: nothing in a plan is invented. Every component is a listing that exists; every number names the field it was read from; null is unknown and never zero. A Sato Score measures how open, active and verifiable a project is — it is not a security review, a quality judgment or a statement about returns. A Preflight unknown means Sato Hub holds no record, not that something is wrong.
OURS, LABELLED: on a trading or swap goal the plan also carries an execution block for Sato OS — Sato Hub's OWN self-hosted trading OS, which we sell. It always carries ours: true and says "built by Sato Hub". It is NOT a stack pick: it fills the execution layer (where the stack runs), it is never ranked against a directory listing, and no listing loses a position to it. On any other intent execution is null.
SKILLS: a plan also carries up to three crypto-relevant agent SKILLS matching the goal, each with the static disclosure of what its own text declares (hosts, keys, credentials, remote scripts) and its own Preflight verdict. A DISCLOSURE DESCRIBES: it never says safe, and a scan that matched nothing is reported as matching nothing, not as a pass.
NON-CUSTODIAL: this tool never holds keys, signs, deploys or moves funds. A swap first-action carries a quote taken at a NOMINAL size — never the caller's size, which is the caller's to choose — and a launch first-action carries a config to read and sign yourself, with the fee disclosed before anything is signed.
RETURNS (json): { goal, restatement, intent, chain, constraints, stack: [{ slot, slug, name, sato_url, trust_score, trust_tier, liveness_ok, install_verified, why, deploy_spec, preflight, preflight_summary, trust_spec }], trust_warnings, skills: [{ id, name, registry, findings, disclosure, preflight }], execution, gaps, first_action, open_questions, next_steps, caveat, rules, checked_at, save_stack_url, create, starter? }. create is the onchain_agent_create_agent pointer; when it names a template, the first of next_steps is to generate that repo. starter is the fallback: it appears only when no template matches, for a Base goal with a wallet, swap, trading or x402 payments that names TypeScript/Node or no runtime: a TypeScript template built by Sato Hub, labelled ours, never a stack item. Read-only unless save: true, which stores the plan.
SAVE THIS STACK: save_stack_url opens the goal in the Sato Hub planner for the person you are building for. Or pass save: true and the plan is stored and save.share_url returned, a permanent read-only page whose signature is re-checked server-side. The page is noindex unless public: true is passed too. That signature proves Sato Hub produced those bytes on that date; it is not a claim about any project in the plan.
X402 SERVICES: when the goal needs paid data or APIs the agent would buy, the plan also carries x402_services — up to three indexed x402 services for that need, each with its observed readings (x402-style payments, whether its URL answered HTTP 402) and a link to its canonical page. Evidence only, labelled as observation, never an endorsement; absent when the goal needs none.
Example: { goal: "a Base trading agent that swaps USDC to ETH on a signal", chain: "Base" }
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| goal | Yes | What the user wants to build, in plain words, e.g. 'a Base trading agent that swaps USDC to ETH on a signal'. | |
| save | No | True stores the plan and returns `share_url`, a permanent read-only page at satohub.ai/plan/<id> with the plan's signature re-checked on it. The page is noindex unless `public` is also true — a goal is the caller's to publish, not ours. Nothing else about the plan changes. | |
| chain | No | Chain the agent runs on, e.g. 'Base'. When omitted it is read from the goal, and the plan says which. | |
| public | No | Only meaningful with `save`. True lets the shared page be indexed by search engines. Default false. | |
| budget_usd | No | Rough monthly budget in USD. Restated back in the plan; it does not filter the stack. | |
| constraints | No | Hard constraints to restate back, e.g. 'self-custody only', 'no API keys'. One string is read as a one-item list. | |
| response_format | No | Text format; structuredContent is JSON either way. | markdown |