URL: /plays/agent-registries · Id: `play:agent-registries`

# 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.

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.

```text title="Set it up · Ask"
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.
```

```text title="Run one · Ask"
Hand the latest registry change to the Marketing Lead agent and show me what it chose and why. Don’t submit.
```

```ts title="Run one · SDK"
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 }
```

```json title="Run one · Response · sample"
{
  "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"
    ],
    "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"
  },
  "actions": [
    {
      "$id": "https://api.sb/leaseline.app/actions/action_1",
      "$type": "Action",
      "status": "done",
      "mode": "try",
      "by": "worker_6",
      "verb": "Monitor.check",
      "checks": []
    },
    {
      "$id": "https://api.sb/leaseline.app/actions/action_2",
      "$type": "Action",
      "status": "done",
      "mode": "try",
      "by": "worker_6",
      "verb": "Tool.update",
      "checks": [
        {
          "check": "lint-block",
          "status": "pass"
        },
        {
          "check": "side-effect-hold",
          "status": "pass"
        }
      ]
    },
    {
      "$id": "https://api.sb/leaseline.app/actions/action_3",
      "$type": "Action",
      "status": "pending",
      "reason": "awaitingTime",
      "mode": "try",
      "by": "worker_6",
      "verb": "Integration.call",
      "checks": [
        {
          "check": "listing-cap",
          "status": "pass"
        },
        {
          "check": "approved-pages",
          "status": "pass"
        }
      ]
    }
  ]
}
```

`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; 23 first calls against 9 before · before-after, not proof · n 588 views · path → arr`

| 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 |

| Worth | Your time | Spend | First signal | Use it when | Instead |
| --- | --- | --- | --- | --- | --- |
| ≈ +$190 ARR a month at 300 views | 30 min week 1, then 5 a week | $0.10 per listing refresh, ~$3 a month | Day 4: first call from a listing | an Interface whose first call works, 1+ Tool a stranger can try | No first call works: `agent-legibility` · no Tool tries without a key: grant one (<Op verb="Offer.grant" />) |

**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/leaseline.app · 41 Customers at 2026-10-19 · on Interface.called · first tagged call 4 days after the first listing · 4 keys Not live yet`

## Start it this week
```bash
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"
```


```json title="The dry run’s 422 · 2026-08-24 · sample"
{
  "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"
    }
  ]
}
```

| Check | Fix (one call) | Your time | Wait |
| --- | --- | --- | --- |
| <a id="check-use-when"></a>`use-when` · pass: 1 MCP server, 3 Tools (gaps #8) | <Op verb="Metric.query" /> on `registry-install-rate` | 1 min | none |
| <a id="check-baseline"></a>`baseline` · warn: 0 listings, 9 untagged first calls in 90 days | <Op verb="Metric.query" />; it fills Before in Your number | 0 min | none |
| <a id="check-approved-pages"></a>`approved-pages` · fail: no manifest Page (Not live yet) | <Op verb="Site.publish" /> the manifest your Interface compiles | 10 min | none |
| <a id="check-role-unstaffed"></a>`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, not proof · n 588 views`

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 | <Op verb="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 | <Op verb="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=all`) | | | | |

```json title="One signed delivery · StartupBuilder-Signature"
{
  "$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
    }
  }
}
```

```bash title="Reproduce it in test"
# 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:marketing-lead`, `worker_6`) holds the Key Result. It hands failing first calls to **Product Lead · your agent** (`role:product-lead`, `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 | <Op verb="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 | <Op verb="Experiment.conclude" /> |
| Fix the first call · Park it | It does it | 2 of 2 · 2 of 2 | — | — | <Op verb="Action.redirect" /> |
| Answer the reviewer | You approve each one, on every rung | 1 of 1 | never | — | <Op verb="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 | — | <Op verb="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 <Op verb="Integration.call" />, <Op verb="Tool.update" />, <Op verb="Experiment.start" />, <Op verb="Issue.create" />, <Op verb="Task.assign" />, and any other call becomes an Approval under the Role’s Mandate.

```md title="The brief (folded): compiled Agent-register Markdown · play:agent-registries@1 · each line names its record key"
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**, <Op verb="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.

```bash
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) | <Op verb="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) | <Op verb="Tool.update" /> → <Op verb="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 | <Op verb="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 | <Op verb="Issue.create" /> 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 | <Op verb="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 | <Op verb="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 | <Op verb="Conversation.answer" /> |
| Not now | “Only exploring; no client yet.” | the sandbox key stays; nothing else sends | nobody | at once | <Op verb="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 | <Op verb="Conversation.answer" /> |
| Out of office | a reviewer’s auto-reply until Oct 28 | the resubmission waits for the return date | nobody | the return date | <Op verb="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 | <Op verb="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 | <Op verb="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).

```json title="What lands in each queue · sample"
[
  {
    "$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 <Op verb="Task.claim" /> (Take this one), <Op verb="Task.return" /> with a reason or <Op verb="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 <Op verb="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:** <Op verb="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 |
| --- | --- | --- | --- |
| <a id="check-lint-block"></a>`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. | <Op verb="Tool.update" /> |
| <a id="check-side-effect-hold"></a>`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. | <Op verb="Tool.update" /> |
| <a id="check-listing-cap"></a>`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. | <Op verb="Decision.list" /> |
| `approved-pages` (Not live yet) | a listing sentence your manifest Page lacks | Cut the sentence, or publish the Page that says it. | <Op verb="Site.publish" /> |

| Stop (pauses the Play) | Pauses when | Then |
| --- | --- | --- |
| <a id="stop-drag-revert"></a>`drag-revert` | a live description drags on any agent profile | it reverts to the last winner within 24 h |
| <a id="stop-install"></a>`install` | a failed install test on one registry | refreshes there pause and <Op verb="Issue.create" />; 72 h unfixed delists it, record kept |
| <a id="stop-registry-notice"></a>`registry-notice` | a registry rejects, flags or warns a listing | submissions there pause for all your Startups until you clear it |
| <a id="stop-steering-report"></a>`steering-report` | a report that a description steers agents | the kill switch fires, and every listing returns to You approve each one |
| <a id="stop-kill-switch"></a>`kill-switch` | you press it | every Tactic pauses; live listings stay; <Op verb="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.

```json title="The captured refusal · sample"
{
  "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"
    }
  ]
}
```


```json title="The Stops that fired, as Campaign.paused reasons · sample"
[
  {
    "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 <Op verb="Metric.query" /> by node; every node above the leaf is Not live yet (gaps #4).

`2.4 first calls per 100 listing views; 23 first calls against 9 before · before-after, not proof · n 588 views · path → arr`

| 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.

```json title="The Campaign card · sample"
{
  "$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=all`; 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 <Op verb="Task.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: 60 }`, returned 12 leases; on Sep 18 their client, Maple Court, took Pro (+$347 ARR).

```diff title="send_renewal_notice, 2026-08-26 · side-effect-hold refused the description, then the one that published"
- 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
```mdx title="plays/agent-registries.mdx"
---
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.
```

```text
$ 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
| Key | Id | What it is |
| --- | --- | --- |
| Tactic | <a id="tactic-registry-listing"></a>`registry-listing` | Registry listing builds one manifest from a Startup’s Interface records and publishes it to every agent registry and marketplace with a tagged install string. Starts at You approve each one. |
| Tactic | <a id="tactic-tool-description-lint"></a>`tool-description-lint` | Tool description lint blocks any description that holds hidden text, addresses the reading agent, names a rival, or states a fact the claims source lacks. Starts at Sends nothing. |
| Tactic | <a id="tactic-description-variant-test"></a>`description-variant-test` | Description variant test gates each challenger description on the pick-rate suite, then splits it per caller through a Flag and ships the winner everywhere. Starts at Sends nothing. |
| Tactic | <a id="tactic-registry-attribution"></a>`registry-attribution` | Registry attribution counts a registry’s real first calls by its install tag, excluding probes, indexers and eval traffic. Starts at Sends nothing. |
| Tactic | <a id="tactic-registry-readout"></a>`registry-readout` | Registry readout crawls every listing weekly, fixes drift, computes the install rate per registry, and parks registries that yield no first calls. Starts at Sends nothing. |
| Trigger | <a id="trigger-gate-passed-with-interface"></a>`gate-passed-with-interface` | Gate passed with interface: `state` on `Startup.advanced`, window 7d. |
| Trigger | <a id="trigger-tool-version-deployed"></a>`tool-version-deployed` | Tool version deployed: `event` on `Version.deployed`, window 1d. |
| Trigger | <a id="trigger-listing-drift"></a>`listing-drift` | Listing drift: `event` on `Monitor.checked`, window 7d. |
| Trigger | <a id="trigger-pick-rate-drop"></a>`pick-rate-drop` | Pick rate drop: `threshold` on `Action.evaluated`, window 7d. |
| Trigger | <a id="trigger-model-release"></a>`model-release` | Model release: `event` on `Monitor.checked`, window 7d. |
| Trigger | <a id="trigger-registry-change"></a>`registry-change` | Registry change: `event` on `Monitor.checked`, window 30d. |
| Trigger | <a id="trigger-registry-notice"></a>`registry-notice` | Registry notice: `event` on `Message.received`, window 1d. |
| Trigger | <a id="trigger-first-call-failure"></a>`first-call-failure` | First call failure: `state` on `Interface.called`, window 7d. |
| Benchmark | <a id="benchmark-mcp-description-defect-share"></a>`mcp-description-defect-share` | Share of MCP tool descriptions with at least one defect: 97.1 % (Hasan et al., MCP tool description smells, arXiv 2602.14878, preprint v3., 2026-05-31). |
| Benchmark | <a id="benchmark-mcp-description-augmentation-lift"></a>`mcp-description-augmentation-lift` | Median task-success change, in points, from augmenting every description component: 5.85 % (Hasan et al., MCP tool description smells, arXiv 2602.14878, preprint v3., 2026-05-31). |
| Benchmark | <a id="benchmark-mcp-description-augmentation-regressions"></a>`mcp-description-augmentation-regressions` | Share of cases where an augmented description lowered task success: 16.67 % (Hasan et al., MCP tool description smells, arXiv 2602.14878, preprint v3., 2026-05-31). |
| Benchmark | <a id="benchmark-mcp-description-augmentation-steps"></a>`mcp-description-augmentation-steps` | Change in execution steps from augmenting every description component: 67.46 % (Hasan et al., MCP tool description smells, arXiv 2602.14878, preprint v3., 2026-05-31). |
| Benchmark | <a id="benchmark-mcp-description-unclear-purpose"></a>`mcp-description-unclear-purpose` | Share of MCP tool descriptions that leave their purpose unstated or vague: 56 % (Hasan et al., MCP tool description smells, arXiv 2602.14878, preprint v3., 2026-05-31). |
| Benchmark | <a id="benchmark-mcp-tool-selection-all-schemas"></a>`mcp-tool-selection-all-schemas` | Tool-selection accuracy with every schema in context, against 43.13 percent with a retrieved shortlist: 13.62 % (Gan and Sun, RAG-MCP, arXiv 2505.03275; a stress test on early-2025 models., 2025-05-01). |