One process for putting a new capability on the agent, whether it comes from a provider like fal or from a community orchestrator. The stages do not change with the source; only stage 1 does.
This page is the standard — what each stage means and why it exists. For the step-by-step sequence of verb calls, read Register a capability — the admin runbook.
cap_status({ capability: "<name>" })
It audits all six stages and prints the exact next action for each one you have not cleared, naming the file or the verb. Read-only and free, so run it as often as you like while working through the list.
Then work the gaps with the verb for each stage — cap_price (stage 2), cap_route (3), cap_docs (4 + 5), cap_probe (6), and cap_promote for the gate at the end. Everything except cap_probe is read-only and free; cap_probe renders and says so.
A capability that merely runs is not usable. Each stage exists because skipping it produced a specific, expensive failure:
| Stage | What it means | What skipping it caused |
|---|---|---|
| 1 · registered | Something can dispatch to it | Nothing — this one is obvious |
| 2 · priced | Price = a verified upstream cost + 5% | 16 capabilities mispriced by up to 6×, in both directions, for months |
| 3 · discoverable | The agent layer can route to it | A name that resolved to a different model, so users were billed for one thing and served another |
| 4 · skill | A skill file teaching its real contract | Agents guessing at parameters and getting extra_forbidden |
| 5 · playbook + showcase | Proof it works with other capabilities | Capabilities nobody could find a use for |
| 6 · measured | Real probes on the real dispatch path | Timeouts sized from guesses; renders cut off and billed anyway |
NAME_ONLY is a legitimate shipped state, not a half-finished one, and cap_status reports it as such.Community orchestrator — one verb, and the registry write is the wiring:
orch_register({
discovery_url: "https://their-node.example:8935/discovery",
contact_email: "them@example.org"
})
It validates the URL (public host, SSRF-guarded), probes discovery, classifies which advertised capabilities are onboardable, and upserts the provider registry. Capabilities land at registered; orch_update promotes them to live once verified. orch_healthcheck reconciles later — a capability that stops being advertised is marked failing and drops out of routing on its own.
Provider model (fal and friends) — a config change on the provider node plus a code entry. Verify the model id on the provider's own page first: providers rename models, and a wrong id fails at dispatch, not at registration.
A private capability of your own — cap_add. It computes a semantic key and refuses a synonym of an existing capability, so the catalogue does not grow two names for one thing.
Every price is verified upstream cost × 1.05. Record the cost basis — the number, the unit, the date you read it, and the URL you read it from — and let the generator produce the price. Never hand-edit a generated price row.
Three things that have each gone wrong here:
For a community or self-hosted capability the basis is declared rather than read off a price page — so it must carry an expiry date, and the audit fails when it goes stale. "Verified" keeps its meaning that way.
Each one fails differently when it is missing: no output kind ⇒ the result is handled as the wrong media type; no latency prior ⇒ a fabricated ETA; no timeout entry ⇒ the render is cut at the default and billed; no usage contract ⇒ the agent guesses at parameters.
foo-2.5 can quietly steal every request for foo-2. Any version or alias spelling needs an explicit guard placed ahead of prefix matching, and the resolution snapshot updated so the change is reviewable. cap_status checks this: if a name does not resolve to itself, stage 3 is a gap.A skill file is where the capability's real contract lives — especially where it departs from the provider's documentation. The most valuable lines are always the surprising ones: an endpoint that rejects a prompt outright, an option that returns extra assets free, a marketing page that advertises a tier the API schema does not accept.
Read a real response before writing the skill. Every genuinely useful thing in ours was found that way, not from a docs page.
A playbook is a paste-ready brief; a showcase is the rendered proof, with real media and real numbers. The requirement is that it demonstrates the capability in combination — one capability alone rarely answers a brief, and the combination is the thing users cannot work out from a model list.
State the limits next to the output, not below the fold. A showcase that hides what a capability cannot do costs more trust than it earns.
node scripts/smoke-cap.mjs --capability <name> --n 5
Real, billable renders through the production path. It records success rate, p50/p95, the failure class of each miss, and — the reason it exists — quoted cost against actual cost. A gap over 5% there means the price is wrong, not the estimate.
docs/caps/<cap>-smoke-<date>.md), including what you did not measure.Then paste the numbers into the latency prior, the timeout table and the measured-p95 record. cap_status and CI both stay red until you do.
| Verb | Stage | Server | What it does |
|---|---|---|---|
cap_status | all six | agent | Audit one capability; get the next action per open stage |
cap_price | 2 | agent | Is the price derived from a verified basis at the house margin, and how does it move (tiers, add-ons, minimums)? Quote a specific request |
cap_route | 3 | agent | What will actually run for a name or an intent phrase — plus collision and fallback-modality checks |
cap_docs | 4, 5 | agent | Draft the skill + playbook with the derivable facts filled in; returns content, writes nothing |
cap_probe | 6 | agent | Billable. Up to 5 real renders → success rate, p50/p95, failure classes. Needs confirm |
cap_promote | gate | operator | Move into automatic routing — only with all six stages clear and ≥4 successes at ≥80% |
orch_register | 1 | admin | Onboard a community orchestrator and its capabilities |
orch_onboard | 1 | admin | Probe + classify + register in one pipeline |
orch_healthcheck | 1, ongoing | admin | Reconcile registry against live discovery; self-heals routing |
orch_update | 1 | admin | Promote registered → live |
cap_add | 1 | agent | Register a capability, dedup-guarded |
cap_test_report | 1, 6 | agent | Provider-facing readiness + performance verdict |
describe_capability | 3, 4 | agent | What the agent will read: params, price, aliases |
get_perf_report | 6 | admin | Measured latency and success across capabilities |
cap_deprecate / cap_retire | end of life | agent | Steer to a successor; tombstone a name forever |
read-onlycap_status, cap_test_report, describe_capability and the reports change nothing and cost nothing. Only stage 6 spends money, and only through the smoke harness.
one endpointThe “admin” column above is about the role a verb requires, not a separate address. Admin verbs and agent verbs are served by the same MCP endpoint; the admin ones simply refuse a caller without the role. A verb is registered once — registering the same name on both surfaces makes the server throw on construction and every tool on the endpoint fails.
Adding a rigged-3D capability, end to end, took five of the six stages in code and one on the provider node:
1 register → provider node config + capability tables (205 → 207 live)
2 price → cost basis $1.20/call, +5% → $1.26 shipped
composable add-ons: rigging +$0.21, animation +$0.126
3 discoverable→ output kind, latency prior, 700s timeout,
usage contract, input requirement, 6 aliases
4 skill → public/skills/meshy-v7.md
5 playbook → sketch-to-rigged-character + a showcase with real media
6 measured → 4/4 probes: 187s / 199s plain, 395s rigged, 213s multi-view
Two of the most useful facts in that skill are not in any provider document. One option returns walk and run animations free, so a separate paid option was unnecessary. And one endpoint's marketing page advertises a quality tier its API schema rejects — charging for it would have billed users for something that cannot happen. Both came from reading a captured response.
cap_status returns COMPLETE, CI is green, and the capability is deployed. Anything less is NAME_ONLY — shippable, honestly labelled, and not yet in automatic routing.