The sato.deploy manifest
One manifest per listing says how to install and run it.
- With a manifest313
- Install reproduced125
- One-click MCP200
64% of 488 listings carry a manifest. Counted from the live directory when this page was built.
The schema
Draft 2020-12, served at /schemas/deploy-spec.json (also at /schemas/deploy-spec/v1.json, beside the other published formats). Put it at the top of your own manifest and your editor will check it as you type:
{
"$schema": "https://satohub.ai/schemas/deploy-spec.json",
"runtime": "Node.js",
"install": ["npm install @example/agent-kit"],
"entry": "npx @example/agent-kit --help",
"requires": ["OPENAI_API_KEY", "RPC_URL"],
"mcp_native": true,
"mcp_invocation": "npx -y @example/agent-kit-mcp",
"deploy_status": "self_reported",
"source_url": "https://github.com/example/agent-kit#readme",
"as_of": "2026-09-10"
}Nothing is required. A manifest with a runtime and an install line is more useful than no manifest, and a field you leave out reads as unknown rather than as false.
The fields
| Field | Type | What it carries |
|---|---|---|
| runtime | string | Language or runtime needed — "Node.js", "Python 3.10+", "Bun". |
| install | string[] | The install command(s), exactly as they should be run. |
| entry | string | The shortest command or snippet that starts it or proves it loaded. |
| requires | string[] | What the operator must supply: env vars, API keys, a wallet, an RPC endpoint. |
| chains | string[] | Chains or networks it operates on. May be finer-grained than the listing's chains. |
| license | string | SPDX id where known — MIT, Apache-2.0. |
| mcp_native | boolean | True if the resource is itself an MCP server. |
| mcp_invocation | string | How to invoke it: a stdio command, or a remote URL. This is what the install buttons read. |
| deploy_clarity | "high" | "medium" | "low" | How clearly the upstream docs spell deployment out. A judgement about the docs, not the code. |
| deploy_status | "verified" | "self_reported" | "failed" | "unknown" | See below. Absent means the same as unknown, and unknown is a value. |
| not_attempted_reason | string | Why we did not try, when deploy_status is "unknown". |
| source_url | string | The README or docs page the spec was read from. We link to source; we never mirror it. |
| as_of | string | YYYY-MM-DD the manifest was last confirmed. |
| verification | object | What the container harness ran, when, and whether both checks passed. |
| install_variants | object[] | Alternative lanes — Node and Python, say. Verification is per lane. |
What deploy_status means
self_reported
Read off the project’s own README or docs and never run. It is a transcription, and a transcription can be stale, wrong, or describe a version that no longer exists. Most manifests are here.
verified
Sato Hub ran the install command and the entry command in an ephemeral container and both passed. The evidence sits in verification: the image, the timestamp, and each check with its result.
It says the documented install resolves and the entry point loads, on that date, in that image. It says nothing about whether the software is safe, correct, audited, maintained, or suitable for what you want to do with it. Those are different questions and we do not answer them with this field.
failed
Sato Hub ran this exact install in a bare container on the date in verification.ran_at, and it did not complete. The rung that failed, the reason, and the literal command we ran are all in verification.checks, so you can reproduce the failure rather than take our word for it.
Read it carefully: this is a measurement of the documented install path, not a verdict on the software. The common cause is a README that has moved on from the code. A container holds no API keys, no wallet and no host package manager, so an install that needs one of those is recorded as unknown instead — we never book our own limits as somebody else’s failure. And we publish it for the same reason we publish everything else: a failure we hide would leave you reading a manifest nobody had tested, with no way to tell.
unknown
We decided not to attempt it, and not_attempted_reason says why — a docker-only install (we will not nest a Docker daemon inside our own sandbox), a client registration rather than an install, a host package manager, or a credential placeholder we cannot fill. Nothing ran, so there is no verification block.
An absent deploy_status is unknown, not a failure. The Sato Score treats a reproduced install as evidence; it never treats a missing one as a mark against a project.
The install_variants invariant
Some projects ship two ways — a Node package and a Python package, say. Those lanes go in install_variants, and one rule holds them together:
When variants are present, the flat install and entry mirror the primary lane (install_variants[0]), and the top-level deploy_status and verification describe that primary lane.
So a consumer that has never heard of variants still reads a correct, complete spec. And because verification is per lane, a lane the harness never ran stays self_reported even when the primary lane is verified — a verified mark never blesses a lane we did not run.
How a project ships one
- 1. Make the README parseable. Most manifests here are seeded automatically from a fenced shell block that contains an install line and a runnable entry line. If your quickstart is prose, or a curl | sh pipe — which we refuse to stage — nothing gets seeded.
- 2. Or publish the manifest yourself, validated against the schema above, and point us at it. A manifest you wrote beats a manifest we inferred.
- 3. Claim your listing to correct the descriptive fields directly. A claim proves you control the project’s domain. It grants no verification status and moves no score — that boundary is deliberate.
- 4. The weekly verifier reproduces what it can in a container and stamps the result. Nothing a project tells us about itself can set verified.
Reading them
- onchain_agent_get_deploy_spec over the MCP server — one call, one manifest.
- /api/export/index.json — every listing carries its deploy_spec. CC-BY-4.0, and the CSV carries the first install line as an install column.
- /api/openapi.json — the same shape, in the machine contract.
Reference
QuestionsWhat people ask about this pageShowHide
Questions about the manifest
- What is the sato.deploy manifest?
- A small JSON object describing how to stand a project up: runtime, install command(s), entry command, what the operator must supply, chains, license, and whether the project is itself an MCP server. Sato Hub publishes one for 313 of 488 live listings (64%), and the schema is at https://satohub.ai/schemas/deploy-spec.json.
- What does deploy_status "verified" mean?
- That Sato Hub ran the documented install command and the entry command in an ephemeral container and both passed, on the date recorded in the verification block. 125 listings carry it. It says the documented install resolves and the entry point loads — nothing about whether the software is correct, maintained or suitable for your use.
- How does an agent install a tool from it?
- Read the manifest over MCP with onchain_agent_get_deploy_spec, or take it off any entry in the free directory export. 200 listings publish an mcp_invocation, which is the exact stdio command or remote URL an MCP client needs, so no README parsing is involved.
- What does a missing field mean?
- Unknown, not false. Nothing in the manifest is required, an absent deploy_status is simply no record of a reproduction, and the Sato Score treats a reproduced install as evidence while never treating a missing one as a mark against a project.
- How does a project ship its own manifest?
- Make the README's quickstart a fenced shell block with an install line and a runnable entry line, or publish a manifest validated against the schema and point us at it. Nothing a project tells us about itself can set verified — only the container harness does that.