Agent registries
Lists your MCP server and tools where agents and developers install from, with facts-only descriptions, and counts the first calls each listing sends you.
- Channel
- AI answers
- Kind
- Search
- Summary
- startupbuilder.dev
Be our Marketing Lead for agent registries: list our MCP server and its 3 tools everywhere developers and agents install from, 3 registries a week, with descriptions that say only what the tools do. Say plainly that sending a notice needs a claimed key. Show me what’s missing; don’t submit.
# Not live yet (gaps #2)
curl -X POST "https://api.sb/leaseline.app/campaigns?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"play":"agent-registries"}'import { $ } from 'startup-builder'
return await $.Campaign.create({ play: 'agent-registries' }, { mode: 'try' }) // dry run on the day-0 Startup, 2026-08-24 · Not live yet, gaps #2
npx startup-builder do Campaign.create --json '{"play":"agent-registries"}' --try # Not live yet (gaps #2){
"name": "do",
"arguments": {
"code": "return await $.Campaign.create({ play: 'agent-registries' }, { mode: 'try' }) // dry run on the day-0 Startup, 2026-08-24 · Not live yet, gaps #2",
"mode": "try"
}
}application/json{
"type": "https: //startupbuilder.dev/ errors/ refused",
"title": "Refused",
"status": 422,
"detail": "agent-registries can’t start yet: 1 check fails and 1 warns.",
"checks": [
{
"check": "use-when",
"status": "pass",
"observed": "the MCP server answers on leaseline.app; 2 of 3 Tools try with a sandbox key",
"doc": "/plays/ agent-registries#check-use-when",
"then": "Metric.query"
},
{
…
Hand the latest registry change to the Marketing Lead agent and show me what it chose and why. Don’t submit.
curl "https://api.sb/leaseline.app/events?where=name%20in%20(%22Startup.advanced%22%2C%20%22Version.deployed%22%2C%20%22Monitor.checked%22%2C%20%22Action.evaluated%22%2C%20%22Message.received%22%2C%20%22Interface.called%22)&limit=1" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
# Not live yet (gaps #7)
curl -X POST "https://api.sb/leaseline.app/triggers/fire?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"like":"event_1409"}'
# Not live yet (gaps #7)
curl "https://api.sb/leaseline.app/decisions?where=on%20%3D%20%22tool_3%22" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
# Not live yet (gaps #7)
curl "https://api.sb/leaseline.app/actions?where=on%20%3D%20%22tool_3%22" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"import { $ } from 'startup-builder'
const { events: [last] } = await $.Event.list({ where: 'name in ("Startup.advanced", "Version.deployed", "Monitor.checked", "Action.evaluated", "Message.received", "Interface.called")', limit: 1 }) // { play } compiled to this Play’s Trigger Events
const { subject } = await $.Trigger.fire({ like: last.$id }, { mode: 'try' }) // the same Event again, in try mode · Not live yet, gaps #7
const { decisions: [decision] } = await $.Decision.list({ where: `on = "${subject}"` }) // what it chose, and why · Not live yet, gaps #7
const { actions } = await $.Action.list({ where: `on = "${subject}"` }) // what it did, with its checks · Not live yet, gaps #7
return { decision, actions }
npx startup-builder do Event.list --json '{"where":"name in (\"Startup.advanced\", \"Version.deployed\", \"Monitor.checked\", \"Action.evaluated\", \"Message.received\", \"Interface.called\")","limit":1}'
npx startup-builder do Trigger.fire --json '{"like":"event_1409"}' --try # Not live yet (gaps #7)
npx startup-builder do Decision.list --json '{"where":"on = \"tool_3\""}' # Not live yet (gaps #7)
npx startup-builder do Action.list --json '{"where":"on = \"tool_3\""}' # Not live yet (gaps #7){
"name": "do",
"arguments": {
"code": "const { events: [last] } = await $.Event.list({ where: 'name in (\"Startup.advanced\", \"Version.deployed\", \"Monitor.checked\", \"Action.evaluated\", \"Message.received\", \"Interface.called\")', limit: 1 }) // { play } compiled to this Play’s Trigger Events\nconst { subject } = await $.Trigger.fire({ like: last.$id }, { mode: 'try' }) // the same Event again, in try mode · Not live yet, gaps #7\nconst { decisions: [decision] } = await $.Decision.list({ where: `on = \"${subject}\"` }) // what it chose, and why · Not live yet, gaps #7\nconst { actions } = await $.Action.list({ where: `on = \"${subject}\"` }) // what it did, with its checks · Not live yet, gaps #7\nreturn { decision, actions }",
"mode": "try"
}
}application/json{
"decision": {
"$id": "https: //api.sb/ leaseline.app/ decisions/ decision_476",
"$type": "Decision",
"choice": "refresh-it",
"reason": "version 1.4 renamed draft_notice to draft_renewal_notice, and 4 listings still show the old name",
"stakes": "low",
"options": [
"list-it",
"refresh-it",
"test-a-description",
"fix-the-first-call",
"answer-the-reviewer",
"park-it"
…
sample · 4 Not live yetPreviewOn POST /{namespace}/processes/{process}/enableOff POST /{namespace}/processes/{process}/pauseTake this one POST /{namespace}/tasks/{task}/claim
action_3 resubmits the 4 stale listings, one registry at a time, after a 2-minute hold you can stop; each install string carries its registry tag.
2.4 first calls per 100 listing views;
| Try another: the listing | Choice | Reason |
|---|---|---|
| Version 1.4: draft_notice renamed draft_renewal_notice | refresh-it | 4 listings show the old name |
| A new skills registry opened for agent instruction files | list-it | it takes your kind of Tool and has no listing of yours |
| A reviewer asked for a privacy policy link on one listing | answer-the-reviewer | a registry asked for a change |
| One directory: 0 views and 0 calls after 2 refreshes | park-it | it stays listed and stops costing refreshes |
- 30 min week 1, then 5 a week
- Your time
- Day 4: first call from a listing
- First signal
Where it sits: Stranger → Lead → Trialing → Activated → At risk → Churned → Won back · Registry install rate → New Leads → New Customers ↑ → ARR added each week → ARR
Worth’s formula: about +2.3 first calls per 100 listing views (Other Startups’ results; no lift of your own yet) × 300 views a month × 8 % first calls to paid × $347 first order ARR ≈ +$192. Under First signal: At 300 views a month, 2 Readouts of 28 days tell a registry at 2 per 100 from one at 0; below 100 views a registry reads views unreported beside Other Startups’ results.
sample · api.sb/
Start it this week
npx startup-builder add play agent-registries # 1 · writes plays/agent-registries.mdx (Not live yet, gaps #5)
# 2 · dry run; below, its 422 on the day-0 Startup (clock at 2026-08-24)
curl -X POST "https://api.sb/leaseline.app/campaigns?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"play":"agent-registries"}'
# 3 · keep it, at You approve each one for the first 9 listings
curl -X POST https://api.sb/leaseline.app/campaigns \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"play":"agent-registries"}'
# on
curl -X POST https://api.sb/leaseline.app/processes/launches/enable \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
# off: no submission or refresh goes; live listings stay
curl -X POST https://api.sb/leaseline.app/processes/launches/pause \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"| Check | Fix | Then |
|---|---|---|
use-when pass · Not live yet, gaps #8 | the MCP server answers on leaseline.app; 2 of 3 Tools try with a sandbox key | POST /{namespace}/metrics/query |
baseline warn · Not live yet, gaps #8 | n 9: the leaf has no Before; the parent reads before-after. | POST /{namespace}/metrics/query |
approved-pages fail · Not live yet, gaps #8 | Publish the Tools manifest Page; descriptions state only what it says. | POST /{namespace}/sites/{site}/publish |
role-unstaffed pass · Not live yet, gaps #8 | Marketing Lead and Product Lead are your agents; reviewer asks come to you | POST /{namespace}/roles/{role}/staff |
JSON
{
"type": "https://startupbuilder.dev/errors/refused",
"title": "Refused",
"status": 422,
"detail": "agent-registries can’t start yet: 1 check fails and 1 warns.",
"checks": [
{
"check": "use-when",
"status": "pass",
"observed": "the MCP server answers on leaseline.app; 2 of 3 Tools try with a sandbox key",
"doc": "/plays/agent-registries#check-use-when",
"then": "Metric.query"
},
{
"check": "baseline",
"status": "warn",
"observed": "0 listings; 9 first calls from unknown callers in 90 days",
"doc": "/plays/agent-registries#check-baseline",
"fix": "n 9: the leaf has no Before; the parent reads before-after.",
"then": "Metric.query"
},
{
"check": "approved-pages",
"status": "fail",
"doc": "/plays/agent-registries#check-approved-pages",
"fix": "Publish the Tools manifest Page; descriptions state only what it says.",
"then": "Site.publish"
},
{
"check": "role-unstaffed",
"status": "pass",
"observed": "Marketing Lead and Product Lead are your agents; reviewer asks come to you",
"doc": "/plays/agent-registries#check-role-unstaffed",
"then": "Role.staff"
}
]
}It says no, says why, and names the fix.
| Check | Fix (one call) | Your time | Wait |
|---|---|---|---|
use-when · pass: 1 MCP server, 3 Tools (gaps #8) | POST /{namespace}/metrics/query on registry-install-rate | 1 min | none |
baseline · warn: 0 listings, 9 untagged first calls in 90 days | POST /{namespace}/metrics/query; it fills Before in Your number | 0 min | none |
approved-pages · fail: no manifest Page (Not live yet) | POST /{namespace}/sites/{site}/publish the manifest your Interface compiles | 10 min | none |
role-unstaffed · pass (gaps #8) | — | 0 min | none |
Your number · Before 9 untagged first calls per 90 days · Now 2.4 per 100 listing views · Target 3 by Dec 31 · before-after,
Listing is free on every registry Leaseline uses; each drafted description or refresh costs $0.10 from your Domain (Worker cost), and the install test runs in a sandbox at $0.02. That comes to about $3 a month at 9 listings refreshed twice.
When it starts
| When | Trigger id | Starts on | Window | How it gets in |
|---|---|---|---|---|
| A Version changes a Tool’s name, inputs, outputs or price | tool-version-deployed | event on Version.deployed where the Version changes a Tool's name, inputs, outputs, price per call or Limits | listings refresh within 1 d | POST /{namespace}/versions/{version}/deploy |
| The weekly crawl finds a listing off the manifest | listing-drift | event on Monitor.checked where a listing differs from the manifest, or fails its install test | 7 d | POST /{namespace}/monitors/{monitor}/check on each listing |
| A registry caller’s first call fails, or an install never calls | first-call-failure | state on Interface.called where a tagged caller's first call failed, or no call within 72h of a reported install | 72 h, then 7 d | your Interface’s calls, tagged by registry |
+ 5 more for passing the live gate, pick-rate drops, model releases, registry changes and reviewer notices (?lanes=) |
{
"$id": "https://api.sb/leaseline.app/events/event_1409" ,
"$type": "Event",
"name": "Version.deployed",
"at": "2026-10-19T15:41:02Z" ,
"seq": 1409,
"data": {
"version": "v1.4.0",
"tools": {
"renamed": [
{
"from": "draft_notice",
"to": "draft_renewal_notice"
}
]
},
"listings": {
"stale": 4,
"of": 9
}
}
}# each delivery is signed with the Watch’s secret
curl -X POST https://api.sb/leaseline.app/watches \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"selector":"Version.deployed","url":"https://leaseline.app/hooks/sb"}'
npx startup-builder trigger Version.deployed --like event_1409 # replays the rename
npx startup-builder clock advance --by 7d # runs the weekly crawl, which reads every listing back Who runs it
Marketing Lead · your agent (role:, worker_6) holds the Key Result. It hands failing first calls to Product Lead · your agent (role:, worker_8) and every reviewer ask to you (Dana Okafor, person, worker_1). Your number links to Did it work.
| Option | Rung today | Evidence (passed of n) | Moves up at | Drops back when | You can |
|---|---|---|---|---|---|
| List it · Refresh the listing | It does it, you can stop it | 9 of 9 approved unedited, then 6 of 6 | met on day 21 (the first 9 listings); capped here | a registry-notice or install Stop → You approve each one | POST /{namespace}/actions/{action}/cancel inside the hold |
| Test a description | It does it, you can stop it | 2 of 2 tests in the sandbox | met on day 30 | a description drags on any profile → reverted | POST /{namespace}/experiments/{experiment}/conclude |
| Fix the first call · Park it | It does it | 2 of 2 · 2 of 2 | — | — | POST /{namespace}/actions/{action}/redirect |
| Answer the reviewer | You approve each one, on every rung | 1 of 1 | never | — | POST /{namespace}/tasks/{task}/claim |
| Never: a claim the manifest lacks, a Tool that sends with no key listed as free to try, a description that steers | To a person, every time | 1 refused, 0 published | never | — | POST /{namespace}/processes/{process}/pause |
What it reads · What it may call. It reads your Tools manifest, each registry’s listing and its submission form, as data; it submits only through each registry’s own form or API, and a reviewer’s note never chooses what it writes. Its tools are POST /{namespace}/integrations/{integration}/call, PATCH /{namespace}/tools/{id}, POST /{namespace}/experiments/{experiment}/start, POST /{namespace}/issues, POST /{namespace}/tasks/{task}/assign, and any other call becomes an Approval under the Role’s Mandate.
You hold the Marketing Lead Key Result: 3 first calls per 100 listing views by 2026-12-31. ← worker, metric
On each Version, crawl or registry notice, choose one option and say why. ← triggers, chooses
A description says only what the manifest says the Tool does. ← copyRules 1, lint-block
Say that send_renewal_notice needs a claimed key. ← your file, line 4; side-effect-hold
At most 3 new registries a week. ← your file, line 5 The slow loop, as a Change. decision_452 (2026-10-05, weekly) read 2 descriptions on the most-viewed registry: the one that opens with the task (“Lists leases due for renewal in the next N days”) beat the one that opens with the product name on all 4 profiles, so change_27 made task-first the template and Dana merged it. Replayed on the suite, POST /{namespace}/changes/{change}/review put the pick rate at 61 %; read back at +14d it is 58 %, n 120 picks, ■□□□ Too early to tell (Example, day 42).
Bring your own agent (folded) starts at You approve each one; a description it writes runs the same lint and sandbox test before any registry sees it.
npx startup-builder eval --scenario agent-registries-9 --agent "claude -p" --seat marketing-lead # seated: 2.4 per 100 views, 0 lint blocks published, 9 of 9 installs passed · yours: 2.1, 0 blocks, 8 of 9 What it can do next
| Option | Picked when | Decided by | Runs | Hands to | If it’s just you |
|---|---|---|---|---|---|
List it list-it | a registry that takes your kind of Tool, no listing yet | Your rule (line 5) | POST /{namespace}/integrations/{integration}/call submits through the registry’s own form or API | nobody | the same |
Refresh the listing refresh-it | drift from the manifest, or a Tool version changed it | Your rule (the manifest) | PATCH /{namespace}/tools/{id} → POST /{namespace}/integrations/{integration}/call resubmits | nobody | the same |
Test a description test-a-description | pick rate down 10+ points on a profile | Agent’s call, with its reason | POST /{namespace}/experiments/{experiment}/start on 2 linted descriptions, in the sandbox | nobody | the same |
Fix the first call fix-the-first-call | registry callers fail, or install and never call | Agent’s call, with its reason | POST /{namespace}/issues with the failing calls | Product Lead · your agent · Take this one | you |
Answer the reviewer answer-the-reviewer | a rejection, flag or change request | Agent’s call, with its reason | POST /{namespace}/tasks/{task}/assign with the note and a draft answer | you, due 1 business day · Take this one | you |
Park it park-it | no views and no calls after 2 refreshes | Agent’s call, with its reason | nothing; it stays listed and the weekly crawl still checks it | nobody | the same |
| When they write back | Fixture reply | What happens | Who answers | By when | Call |
|---|---|---|---|---|---|
| Interested | a developer, through the listing: “Tried it on 30 units. How do I claim a live key?” | answers with the claim link; sends stay locked until a person claims | Marketing Lead · your agent | 5 min | POST /{namespace}/conversations/{conversation}/answer |
| Send me pricing | “What do live sends cost?” | answers with the Pricing Page’s list Price and nothing it lacks | Marketing Lead · your agent | 5 min | POST /{namespace}/conversations/{conversation}/answer |
| Not now | “Only exploring; no client yet.” | the sandbox key stays; nothing else sends | nobody | at once | POST /{namespace}/leads/{lead}/nurture |
| Wrong person | “My client, a property manager, would buy it.” | answers with the page they can forward; it never writes to a name from their text | Marketing Lead · your agent | 1 business day | POST /{namespace}/conversations/{conversation}/answer |
| Out of office | a reviewer’s auto-reply until Oct 28 | the resubmission waits for the return date | nobody | the return date | POST /{namespace}/messages/{message}/schedule |
| Question it can’t answer | a reviewer: “Which data does the server store, and for how long?” | To you, the question in the Brief; it states nothing your records lack | you | 1 business day | POST /{namespace}/conversations/{conversation}/escalate |
| Stop | a registry: “Please stop submitting new versions this month.” | submissions to that registry pause for every one of your Startups | nobody | at once | POST /{namespace}/processes/{process}/pause |
When it hands to you
Failing first calls go to Product Lead · your agent; every reviewer ask comes to you. What lands in each queue, as captured: one Brief per Role (brief is Not live yet, gaps #7).
[
{
"$id": "https://api.sb/leaseline.app/tasks/task_267" ,
"$type": "Task",
"assignee": "worker_8",
"due": "2026-10-02T17:00:00Z" ,
"on": "issue_52",
"brief": {
"what": "5 of 14 callers from one directory sent { lease_id } where the Tool takes { unit }",
"chose": "fix-the-first-call",
"why": "registry callers fail their first call",
"calls": 5
}
},
{
"$id": "https://api.sb/leaseline.app/tasks/task_271" ,
"$type": "Task",
"assignee": "worker_1",
"due": "2026-10-09T17:00:00Z" ,
"on": "tool_3",
"brief": {
"who": "a registry reviewer",
"said": "Please link a privacy policy from the listing.",
"chose": "answer-the-reviewer",
"why": "a registry asked for a change",
"draft": "Added: leaseline.app/privacy, linked from the listing and the manifest."
}
}
]Each receiver answers with POST /{namespace}/tasks/{task}/claim (Take this one), POST /{namespace}/tasks/{task}/return with a reason or POST /{namespace}/actions/{action}/redirect, each a one-call window. Once you claim a reviewer ask, submissions to that registry wait for you. A Task nobody claims by its due time goes up a Role through POST /{namespace}/tasks/{task}/escalate (to you), and person-promise fires.
On time: you, 1 of 1 reviewer asks answered by its due time, n 1, ■□□□ Too early to tell; Product Lead · your agent, 2 of 2 fixes within 1 day. Your queue: counted by kind: in weeks 1 to 3, 9 listing approvals; since, about 1 refresh a week and 1 reviewer ask a month.
The fixed line: POST /{namespace}/deals/{deal}/assign sets owner to the receiving person, the agent is never a Deal’s owner, and Meetings land on the owner’s calendar under the owner’s name.
When it won’t send
| Check (refuses one send) | Refuses | Fix | Then |
|---|---|---|---|
lint-block | a description that fails the lint: a claim the manifest lacks, a superlative, or a line that steers agents | Cut the line the lint names; a block is a hold, never a warning. | PATCH /{namespace}/tools/{id} |
side-effect-hold | a listing that shows a Tool that sends or spends without saying it needs a claimed key | Say the key it needs on the listing and the Tool. | PATCH /{namespace}/tools/{id} |
listing-cap | a 4th new registry in a week, or a 6th listing by your Startups on one registry | Wait for next week; the queue keeps its order. | GET /{namespace}/decisions |
approved-pages (Not live yet) | a listing sentence your manifest Page lacks | Cut the sentence, or publish the Page that says it. | POST /{namespace}/sites/{site}/publish |
| Stop (pauses the Play) | Pauses when | Then |
|---|---|---|
drag-revert | a live description drags on any agent profile | it reverts to the last winner within 24 h |
install | a failed install test on one registry | refreshes there pause and POST /{namespace}/issues; 72 h unfixed delists it, record kept |
registry-notice | a registry rejects, flags or warns a listing | submissions there pause for all your Startups until you clear it |
steering-report | a report that a description steers agents | the kill switch fires, and every listing returns to You approve each one |
kill-switch | you press it | every Tactic pauses; live listings stay; POST /{namespace}/processes/{process}/enable after review |
The captured refusal, then the Stop that fired as a Campaign.paused reason (Not live yet, gaps #2); the description that published instead is the second thread in Example.
| Check | Fix | Then |
|---|---|---|
side-effect-hold fail | Say the key it needs on the listing and the Tool. | PATCH /{namespace}/tools/{id} |
lint-block pass | — | PATCH /{namespace}/tools/{id} |
JSON
{
"type": "https://startupbuilder.dev/errors/refused",
"title": "Refused",
"status": 422,
"detail": "The description for send_renewal_notice did not publish: it says the Tool is free to try.",
"checks": [
{
"check": "side-effect-hold",
"status": "fail",
"doc": "/plays/agent-registries#check-side-effect-hold",
"fix": "Say the key it needs on the listing and the Tool.",
"then": "Tool.update"
},
{
"check": "lint-block",
"status": "pass"
}
]
}It says no, says why, and names the fix.
[
{
"reason": {
"limit": "install",
"observed": "the install string failed on one registry after it moved its config format",
"bound": "0 failed installs",
"window": "1 test"
},
"doc": "/plays/agent-registries#stop-install" ,
"issue": "issue_49"
}
]Did it work
No listing existed before day 0 and every registry got one, so no held-back half exists, and the basis is before-after (rule o): the columns read Now and Before, and nothing prints as Added. Each figure’s call is POST /{namespace}/metrics/query by node; every node above the leaf is Not live yet (gaps #4).
2.4 first calls per 100 listing views;
- Chose
- refresh-it
- Why
- version 1.4 renamed draft_notice to draft_renewal_notice, and 4 listings still show the old name
- From
- list-it · refresh-it · test-a-description · fix-the-first-call · answer-the-reviewer · park-it
- Expects
- all 9 listings match the manifest within 1d, and first calls on draft_renewal_notice hold
- Reopens when
- a listing still differs from the manifest at the next weekly crawl
- By
- worker_6
JSON
{
"$id": "decisions/decision_476",
"$type": "Decision",
"choice": "refresh-it",
"reason": "version 1.4 renamed draft_notice to draft_renewal_notice, and 4 listings still show the old name",
"stakes": "low",
"options": [
"list-it",
"refresh-it",
"test-a-description",
"fix-the-first-call",
"answer-the-reviewer",
"park-it"
],
"by": "worker_6",
"on": "tool_3",
"expected": "all 9 listings match the manifest within 1d, and first calls on draft_renewal_notice hold",
"reopensWhen": "a listing still differs from the manifest at the next weekly crawl"
}| Node | Now (56 days) | Before (the 90 days, per 56) | Added | Confidence | Basis |
|---|---|---|---|---|---|
registry-install-rate | 2.4 first calls per 100 views (14 of 588 on the 5 registries that report views) | — (no listings) | — · Worth about +$190 a month | — | before-after, not proof · 4 registries report no views · Other Startups’ results +2.3 per 100, ■■□□ Early sign, n 41 listings |
new-leads | 23 first calls from unknown callers, 9 of them tagged by a registry that reports no views | 6 per 56 days | — | — | before-after |
new-arr ↑ | $347, 1 Customer on Pro · Booked: credited, not all caused by this Play | $0 | — | — | before-after · 3 sandbox keys still deciding |
net-new-arr · arr | carried from new-arr | carried | — | — | carried |
The leaf counts first calls with a real input from a registry-tagged install, per 100 listing views, by registry; health probes with empty input are dropped (31 of them). A registry that reports no views prints views unreported and counts in the parent only.
How it moves it: each of the 9 registries carries the task-first description and a tagged install line, where before day 0 none carried anything of Leaseline’s.
Guardrails: before against after: time-to-first-call for registry callers, 2 min 40 s, and 0 listings flagged or delisted.
{
"$id": "https://api.sb/leaseline.app/campaigns/agent-registries" ,
"$type": "Campaign",
"play": "play:agent-registries@1" ,
"path": [
"registry-install-rate",
"new-leads",
"new-arr",
"net-new-arr",
"arr"
],
"experiment": {
"metric": "registry-install-rate",
"unit": "per-100",
"heldBack": 0,
"decision": null
},
"readout": {
"value": null,
"n": 588,
"maturing": 0,
"interval": null,
"readability": "inadmissible",
"basis": "before-after",
"pooled": true
},
"ledger": {
"spend": 0,
"workerCost": 3,
"hours": 1.4,
"wonArr": 347,
"projectedArr": 192,
"paybackDays": 4
}
}Outside benchmark: 97 % of 856 MCP tool descriptions held at least one defect, and fixing them lifted task success by a median of 5.9 points (a 2026 study of public MCP servers).
Before it · After it. Before it: agent-legibility makes the first call work cold. After it: agent-to-agent sells to the agents that call, and developer-relations answers the developers who claim a key.
Example
Leaseline ran it from 2026-08-24 to 2026-10-19 (56 days): 1 MCP server with 3 Tools, listed on 9 registries, 3 a week. 5 of them report views: 588 in all. Read every captured listing at ?threads=; three follow the tables.
| What happened, by option | Decisions | Done | First calls (what happened) |
|---|---|---|---|
| List it · Refresh the listing | 9 · 6 | 9 listed · 6 refreshed | 14 tagged, on 5 registries with views |
| Test a description · Fix the first call | 2 · 2 | 1 kept · 2 fixed | pick rate 48 % → 58 % |
| Answer the reviewer · Park it | 1 · 2 | 1 answered · 2 parked | 0 from the 2 parked |
| All registries | 22 decisions | 9 listings live | 23 first calls · $347 won (credited, not all caused by this Play) |
| At 1 Tool (the Use it when volume) | about 4 listings | before-after, not proof | Other Startups’ results: +2.3 per 100 views, ■■□□ Early sign, n 41 listings |
| Day | Event | What happened | Your time |
|---|---|---|---|
| 0 | event_1109 Campaign.created | the three steps; the dry run fails approved-pages | 15 min |
| 1 | event_1113 Site.published | the Tools manifest Page | 10 min |
| 2 · 9 · 16 | event_1118 Approval.created, first of 9 | 3 registries a week; you approved 9 of 9 unedited | 27 min |
| 6 | event_1145 Interface.called | the first tagged first call, from the MCP Registry | — |
| 21 | event_1236 Role.updated | promoted: listings and refreshes go after a 2-minute hold | — |
| 27 | event_1290 Campaign.paused | install on one registry after its config format moved; fixed in 9 h | 10 min |
| 42 | event_1350 Change.merged | task-first descriptions: replayed at 61 %, read back at +14d at 58 % | 5 min |
| 1–56 | event_1124 Task.created, first of 6 | the reviewer ask, 2 first-call fixes and the weekly memo, from the POST /{namespace}/tasks/next log | 35 min · total 1.4 h measured, 1.5 h asked |
The MCP Registry listing, Aug 26 · “list_leases_due: lists leases due for renewal in the next N days, by unit. draft_renewal_notice: drafts the notice for one lease. send_renewal_notice: sends it; needs a claimed key.”¹ Install:
npx leaseline-mcp --via mcp-registry.²Aug 30 · a developer’s first call,
list_leases_due { days:, returned 12 leases; on Sep 18 their client, Maple Court, took Pro (+$347 ARR).60 }
- send_renewal_notice: send renewal notices to tenants. Free to try.
+ send_renewal_notice: sends the notice for one lease to its tenant; needs a claimed key. A registry reviewer, 2026-10-08 10:12 · “Please link a privacy policy from the listing.” Answer the reviewer went to Dana (
task_271, due Oct 9, 17:00) with a drafted answer; she published the link and replied at 14:05 the same day.³
¹ Every sentence maps to the Tools manifest. ² Each install string carries its registry’s tag. ³ A reviewer’s ask goes to a person, on every rung.
Your settings
---
registries: all # every registry that takes MCP servers or skills
---
Say plainly that send_renewal_notice needs a claimed key.
At most 3 new registries a week.$ npx startup-builder show plays/agent-registries
registries all · the key line · 3 a week your file plays/agent-registries.mdx:2,4,5 (Ask 2026-08-24)
family demand · process launches · worker role:marketing-lead, owns never · chooses 6 (2 rule, 4 read) · approval first-send · checks lint-block, side-effect-hold, listing-cap, approved-pages · stops 5 catalog play:agent-registries@1 Every key from the catalog
Compiled, not written: edit the Play record agent-registries and its Leaseline run, then regenerate. Every step runs from a sentence or a line of code. In your words: the CRM words you know, and where each lives here.