Public: anyone can read this; the crew can change it.
Sentinel: shared:01m23vygyffx5hg2f5vm8r74sr:ky51wt3erj was degraded 74 minutes today: trevato/forge: "tools/list stays under 40 KB, with 3 KB of headroom (37,000 bytes)" failed on 3 pulls in the last hour … #5185
Check · Review · Land · Live done — Landed and live in production.
torque/forge:torque/5105-sentinel-shared-01m23vygyffx5hg2f5vm8r74 → main 2 commits fork 1 thread · 1 unresolved
2 files
changed +84
−73
src/http/mcp.ts +71 −71
| @@ -479,7 +479,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 479 | 479 | { |
| 480 | 480 | name: "apps", |
| 481 | 481 | description: |
| 482 | "The apps on this forge you can see: live or not, where served, how each runs itself, what is working.", | |
| 482 | "The apps here you can see: live or not, where served, how each runs, what is working.", | |
| 483 | 483 | inputSchema: { type: "object", properties: {} }, |
| 484 | 484 | writes: false, |
| 485 | 485 | async run(ctx, user) { |
| @@ -510,7 +510,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 510 | 510 | { |
| 511 | 511 | name: "new_app", |
| 512 | 512 | description: |
| 513 | "Make an app from a sentence: a repository, production started, and with `description` the first issue.", | |
| 513 | "Make an app from a sentence: a repository, production started, and with `description` a first issue.", | |
| 514 | 514 | inputSchema: { |
| 515 | 515 | type: "object", |
| 516 | 516 | properties: { |
| @@ -658,7 +658,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 658 | 658 | { |
| 659 | 659 | name: "tell", |
| 660 | 660 | description: |
| 661 | "Tell an app's crew what should change (first line is the title). Without `repo` it is only kept; answers a thought id.", | |
| 661 | "Tell an app's crew what should change (first line is the title). No `repo`: kept, answers a thought id.", | |
| 662 | 662 | inputSchema: { |
| 663 | 663 | type: "object", |
| 664 | 664 | properties: { |
| @@ -737,7 +737,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 737 | 737 | { |
| 738 | 738 | name: "share", |
| 739 | 739 | description: |
| 740 | "Share a feed item. With no `to` it goes to the app's crew and owners, else to its followers; daily budget each.", | |
| 740 | "Share a feed item: no `to` tells the app's crew and owners, else its followers; daily budget each.", | |
| 741 | 741 | inputSchema: { |
| 742 | 742 | type: "object", |
| 743 | 743 | properties: { |
| @@ -764,7 +764,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 764 | 764 | { |
| 765 | 765 | name: "say", |
| 766 | 766 | description: |
| 767 | "Say something on an issue or a pull. A working builder hears it next; otherwise it is feedback for the next run.", | |
| 767 | "Say something on an issue or pull. A working builder hears it next; otherwise the next run does.", | |
| 768 | 768 | inputSchema: { |
| 769 | 769 | type: "object", |
| 770 | 770 | properties: { |
| @@ -796,7 +796,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 796 | 796 | { |
| 797 | 797 | name: "issue", |
| 798 | 798 | description: |
| 799 | "One issue with comments, `blockedBy` and `blocks`. A crew agent sees `untrusted: true` on text by non-writers.", | |
| 799 | "One issue with comments, `blockedBy`, `blocks`; a crew agent sees `untrusted: true` on text by non-writers.", | |
| 800 | 800 | inputSchema: { |
| 801 | 801 | type: "object", |
| 802 | 802 | properties: { |
| @@ -865,7 +865,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 865 | 865 | { |
| 866 | 866 | name: "pull", |
| 867 | 867 | description: |
| 868 | "Read a pull: title, state, head, base, and when open `mergeable`, `conflicts`, `proposal`, `checkStale`, `check`.", | |
| 868 | "Read a pull: title, state, head, base; open: `mergeable`, `conflicts`, `proposal`, `checkStale`, `check`.", | |
| 869 | 869 | inputSchema: { |
| 870 | 870 | type: "object", |
| 871 | 871 | properties: { |
| @@ -908,7 +908,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 908 | 908 | { |
| 909 | 909 | name: "pulls", |
| 910 | 910 | description: |
| 911 | "A repository's pulls, newest first, briefly. `state` open (default) or closed; `limit` 1-50 (default 20).", | |
| 911 | "A repository's pulls, newest first. `state` open (default) or closed; `limit` 1-50 (default 20).", | |
| 912 | 912 | inputSchema: { |
| 913 | 913 | type: "object", |
| 914 | 914 | properties: { |
| @@ -952,7 +952,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 952 | 952 | { |
| 953 | 953 | name: "variant", |
| 954 | 954 | description: |
| 955 | "Like or dislike one pull among its variants; a later vote replaces it. A dislike closes it with `reason`.", | |
| 955 | "Like or dislike one pull among its variants; a later vote replaces it; a dislike closes it (`reason`).", | |
| 956 | 956 | inputSchema: { |
| 957 | 957 | type: "object", |
| 958 | 958 | properties: { |
| @@ -993,7 +993,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 993 | 993 | { |
| 994 | 994 | name: "edit", |
| 995 | 995 | description: |
| 996 | "Give an issue or a pull a new title or body: your own, or anyone's where you write; an agent edits only its own.", | |
| 996 | "Retitle or rewrite an issue or pull: yours, or any where you write; an agent edits only its own.", | |
| 997 | 997 | inputSchema: { |
| 998 | 998 | type: "object", |
| 999 | 999 | properties: { |
| @@ -1037,7 +1037,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 1037 | 1037 | { |
| 1038 | 1038 | name: "close", |
| 1039 | 1039 | description: |
| 1040 | "Close an issue or pull, or reopen it (`state` open); PATCH refusals apply. `reason`: done, dropped, split (`into`).", | |
| 1040 | "Close or reopen (`state` open) an issue or pull. `reason`: done, dropped, split (`into`).", | |
| 1041 | 1041 | inputSchema: { |
| 1042 | 1042 | type: "object", |
| 1043 | 1043 | properties: { |
| @@ -1085,7 +1085,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 1085 | 1085 | { |
| 1086 | 1086 | name: "read_file", |
| 1087 | 1087 | description: |
| 1088 | "Read a file, or list a directory, of a repository at a ref (default branch); over 5 MB answers tooLarge.", | |
| 1088 | "Read a file or list a directory at a ref (default branch); over 5 MB answers tooLarge.", | |
| 1089 | 1089 | inputSchema: { |
| 1090 | 1090 | type: "object", |
| 1091 | 1091 | properties: { |
| @@ -1137,7 +1137,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 1137 | 1137 | { |
| 1138 | 1138 | name: "asks", |
| 1139 | 1139 | description: |
| 1140 | "What waits on you, most consequential first: decision, options, cost of inaction. Your saved filter applies.", | |
| 1140 | "What waits on you, most consequential first: decision, options, cost of inaction; your saved filter applies.", | |
| 1141 | 1141 | inputSchema: { type: "object", properties: { ...CHIP_ARGS } }, |
| 1142 | 1142 | writes: false, |
| 1143 | 1143 | run(ctx, user, args) { |
| @@ -1149,7 +1149,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 1149 | 1149 | { |
| 1150 | 1150 | name: "asks_act", |
| 1151 | 1151 | description: |
| 1152 | "Decide many asks: dismiss, decline, ship (never undone), close (`reason`), mute, replan. `items`: ids from `asks`, or `issue:<id>`.", | |
| 1152 | "Decide asks (`items`: `asks` ids, `issue:<id>`): dismiss, decline, ship (never undone), close (`reason`), mute, replan.", | |
| 1153 | 1153 | inputSchema: { |
| 1154 | 1154 | type: "object", |
| 1155 | 1155 | properties: { |
| @@ -1173,7 +1173,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 1173 | 1173 | { |
| 1174 | 1174 | name: "asks_decide", |
| 1175 | 1175 | description: |
| 1176 | "Let the decider answer a hand-over (`item` is the row's `parked:<id>`). Only a sure set_aside (70%+) clears the card.", | |
| 1176 | "Let the decider answer a hand-over (`item`: `parked:<id>`); only a sure set_aside (70%+) clears it.", | |
| 1177 | 1177 | inputSchema: { |
| 1178 | 1178 | type: "object", |
| 1179 | 1179 | properties: { item: { type: "string", maxLength: 80 } }, |
| @@ -1188,7 +1188,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 1188 | 1188 | { |
| 1189 | 1189 | name: "asks_proposal", |
| 1190 | 1190 | description: |
| 1191 | "Act on a wave proposal (an `asks` row): `approve`, `redirect` (`words`), or `later` (until `again`). Owner only.", | |
| 1191 | "Act on a wave proposal (`asks` row): `approve`, `redirect` (`words`), `later` (`again`). Owner.", | |
| 1192 | 1192 | inputSchema: { |
| 1193 | 1193 | type: "object", |
| 1194 | 1194 | properties: { |
| @@ -1209,7 +1209,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 1209 | 1209 | { |
| 1210 | 1210 | name: "proposal_tokens", |
| 1211 | 1211 | description: |
| 1212 | "Give a child a propose-only credential: `mint` (`child`, `origin`), `list`, `revoke` (`id`). Writers only.", | |
| 1212 | "A child's propose-only credential: `mint` (`child`, `origin`), `list`, `revoke` (`id`). Writers.", | |
| 1213 | 1213 | inputSchema: { |
| 1214 | 1214 | type: "object", |
| 1215 | 1215 | properties: { |
| @@ -1337,7 +1337,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 1337 | 1337 | { |
| 1338 | 1338 | name: "issue_teams", |
| 1339 | 1339 | description: |
| 1340 | "Name crew teams (design, data-science, security, platform) on an issue: at most two; each reviews the closing pull.", | |
| 1340 | "Name up to two crew teams (design, data-science, security, platform) to review an issue's pull.", | |
| 1341 | 1341 | inputSchema: { |
| 1342 | 1342 | type: "object", |
| 1343 | 1343 | properties: { |
| @@ -1410,7 +1410,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 1410 | 1410 | { |
| 1411 | 1411 | name: "now", |
| 1412 | 1412 | description: |
| 1413 | "What the crew is doing now across your apps: who, on what, since when, cost so far; what waits on your review first.", | |
| 1413 | "What the crew is doing across your apps: who, on what, since when, cost; what waits on your review.", | |
| 1414 | 1414 | inputSchema: { type: "object", properties: {} }, |
| 1415 | 1415 | writes: false, |
| 1416 | 1416 | run(ctx, user) { |
| @@ -1533,7 +1533,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 1533 | 1533 | { |
| 1534 | 1534 | name: "audit", |
| 1535 | 1535 | description: |
| 1536 | "Who can do what across every app you can see, from each contract.json: resource × verb answered yes, own or no.", | |
| 1536 | "Who can do what in every app you can see, from each contract.json: resource × verb, yes, own or no.", | |
| 1537 | 1537 | inputSchema: { |
| 1538 | 1538 | type: "object", |
| 1539 | 1539 | properties: { |
| @@ -1581,7 +1581,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 1581 | 1581 | { |
| 1582 | 1582 | name: "model_grant", |
| 1583 | 1583 | description: |
| 1584 | "Give a person's account a capped monthly model grant in dollars (`usdPerMonth` 0 takes it back). Person admins only.", | |
| 1584 | "Give a person a capped monthly model grant (`usdPerMonth`, 0 takes it back). Person admins.", | |
| 1585 | 1585 | inputSchema: { |
| 1586 | 1586 | type: "object", |
| 1587 | 1587 | properties: { |
| @@ -1622,7 +1622,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 1622 | 1622 | { |
| 1623 | 1623 | name: "whoami_can", |
| 1624 | 1624 | description: |
| 1625 | "What you can do here as you: your role and that role's row of the roles table, each ability yes or no.", | |
| 1625 | "What you can do here: your role and its row of the roles table, each ability yes or no.", | |
| 1626 | 1626 | inputSchema: { type: "object", properties: {} }, |
| 1627 | 1627 | writes: false, |
| 1628 | 1628 | run: (ctx, user) => { |
| @@ -1633,7 +1633,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 1633 | 1633 | { |
| 1634 | 1634 | name: "mint_invite", |
| 1635 | 1635 | description: |
| 1636 | "Mint a single-use invite link; it expires in `days` (1–30, default 7) and is shown once. Person admins only.", | |
| 1636 | "Mint a single-use invite link, shown once, expiring in `days` (1–30, default 7). Person admins.", | |
| 1637 | 1637 | inputSchema: { |
| 1638 | 1638 | type: "object", |
| 1639 | 1639 | properties: { |
| @@ -1654,7 +1654,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 1654 | 1654 | { |
| 1655 | 1655 | name: "account_role", |
| 1656 | 1656 | description: |
| 1657 | "Make a person a member, or a guest again, with an optional starter allowance (`usdPerMonth`, promoting only).", | |
| 1657 | "Make a person a member, or a guest again; promoting may give a monthly `usdPerMonth` allowance.", | |
| 1658 | 1658 | inputSchema: { |
| 1659 | 1659 | type: "object", |
| 1660 | 1660 | properties: { |
| @@ -1725,7 +1725,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 1725 | 1725 | { |
| 1726 | 1726 | name: "model_ceiling", |
| 1727 | 1727 | description: |
| 1728 | "Set an account's daily and per-run model spend ceilings in dollars; a run past either does not start.", | |
| 1728 | "Set an account's daily and per-run model spend ceilings in dollars; a run past one does not start.", | |
| 1729 | 1729 | inputSchema: { |
| 1730 | 1730 | type: "object", |
| 1731 | 1731 | properties: { |
| @@ -1789,7 +1789,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 1789 | 1789 | { |
| 1790 | 1790 | name: "outsiders", |
| 1791 | 1791 | description: |
| 1792 | "Whether people who cannot write an app may direct its crew (off by default). Without `on`, says which.", | |
| 1792 | "Whether people who cannot write an app may direct its crew (off by default). No `on` reads it.", | |
| 1793 | 1793 | inputSchema: { |
| 1794 | 1794 | type: "object", |
| 1795 | 1795 | properties: { |
| @@ -1866,7 +1866,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 1866 | 1866 | { |
| 1867 | 1867 | name: "decisions_by", |
| 1868 | 1868 | description: |
| 1869 | "The standing rule for a repository's parked hand-over cards: `me`, `decider`, `decider_tell`. Without `by`, reads it.", | |
| 1869 | "Who decides a repository's parked hand-over cards: `me`, `decider`, `decider_tell`. No `by` reads it.", | |
| 1870 | 1870 | inputSchema: { |
| 1871 | 1871 | type: "object", |
| 1872 | 1872 | properties: { |
| @@ -1905,7 +1905,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 1905 | 1905 | { |
| 1906 | 1906 | name: "archive", |
| 1907 | 1907 | description: |
| 1908 | "Archive a repository or wake it (`archived` true/false); nothing is deleted. Plans first; repository admin token.", | |
| 1908 | "Archive a repository or wake it (`archived` true/false); deletes nothing. Plans first; admin token.", | |
| 1909 | 1909 | inputSchema: { |
| 1910 | 1910 | type: "object", |
| 1911 | 1911 | properties: { |
| @@ -2004,7 +2004,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 2004 | 2004 | { |
| 2005 | 2005 | name: "migrate", |
| 2006 | 2006 | description: |
| 2007 | "Bring a repository in by public `url` (optional `name`, `crew`); git history comes over, nothing reaches back. With `job`, its state.", | |
| 2007 | "Bring a repository in by public `url` (`name`, `crew`), history and all. With `job`, its state.", | |
| 2008 | 2008 | inputSchema: { |
| 2009 | 2009 | type: "object", |
| 2010 | 2010 | properties: { |
| @@ -2085,7 +2085,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 2085 | 2085 | { |
| 2086 | 2086 | name: "branches", |
| 2087 | 2087 | description: |
| 2088 | "List a repository's branches, or with `name` and `action` create (from `from`) or delete one; never the default.", | |
| 2088 | "A repository's branches; `name` and `action` create (from `from`) or delete one, not the default.", | |
| 2089 | 2089 | inputSchema: { |
| 2090 | 2090 | type: "object", |
| 2091 | 2091 | properties: { |
| @@ -2168,7 +2168,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 2168 | 2168 | { |
| 2169 | 2169 | name: "probe", |
| 2170 | 2170 | description: |
| 2171 | "Try every door of a running app as nobody, a user and an admin against its contract.json. Writes nothing.", | |
| 2171 | "Try every door of a running app as nobody, a user and an admin against its contract.json; read-only.", | |
| 2172 | 2172 | inputSchema: { |
| 2173 | 2173 | type: "object", |
| 2174 | 2174 | properties: { repo: REPO_ARG }, |
| @@ -2202,7 +2202,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 2202 | 2202 | { |
| 2203 | 2203 | name: "following", |
| 2204 | 2204 | description: |
| 2205 | "Where a fork stands against what it follows: in step, behind, ahead or diverged, and files needing a decision.", | |
| 2205 | "Where a fork stands against what it follows: in step, behind, ahead, diverged; files to decide.", | |
| 2206 | 2206 | inputSchema: { |
| 2207 | 2207 | type: "object", |
| 2208 | 2208 | properties: { repo: REPO_ARG }, |
| @@ -2375,7 +2375,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 2375 | 2375 | { |
| 2376 | 2376 | name: "forges", |
| 2377 | 2377 | description: |
| 2378 | "The forges you sent from here (an admin's list): name, address, whom for, apps, claimed or not, last activity.", | |
| 2378 | "The forges sent from here (admin): name, address, whom for, apps, claimed or not, last activity.", | |
| 2379 | 2379 | inputSchema: { type: "object", properties: {} }, |
| 2380 | 2380 | writes: false, |
| 2381 | 2381 | async run(ctx, user) { |
| @@ -2394,7 +2394,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 2394 | 2394 | { |
| 2395 | 2395 | name: "claim_link", |
| 2396 | 2396 | description: |
| 2397 | "A new claim link for an unclaimed child forge, only with `reveal: true`; the old one stops. Nothing changes without.", | |
| 2397 | "A new claim link for an unclaimed child forge, only with `reveal: true`; the old one stops at once.", | |
| 2398 | 2398 | inputSchema: { |
| 2399 | 2399 | type: "object", |
| 2400 | 2400 | properties: { |
| @@ -2416,7 +2416,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 2416 | 2416 | { |
| 2417 | 2417 | name: "take_updates", |
| 2418 | 2418 | description: |
| 2419 | "Take the parent forge's updates into a fork: one pull on a spawned forge; otherwise a fast-forward or clean merge.", | |
| 2419 | "Take the parent forge's updates into a fork: a pull on a spawned forge, else a merge.", | |
| 2420 | 2420 | inputSchema: { |
| 2421 | 2421 | type: "object", |
| 2422 | 2422 | properties: { repo: REPO_ARG }, |
| @@ -2468,7 +2468,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 2468 | 2468 | { |
| 2469 | 2469 | name: "sever", |
| 2470 | 2470 | description: |
| 2471 | "Cut a spawned forge's link to the forge its code came from (its `forge` repository's owner only). Deletes nothing.", | |
| 2471 | "Cut a spawned forge's link to its parent (its `forge` repository's owner only). Deletes nothing.", | |
| 2472 | 2472 | inputSchema: { |
| 2473 | 2473 | type: "object", |
| 2474 | 2474 | properties: { repo: REPO_ARG }, |
| @@ -2489,7 +2489,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 2489 | 2489 | { |
| 2490 | 2490 | name: "follow_mode", |
| 2491 | 2491 | description: |
| 2492 | "Choose how a spawned forge follows its parent: `tell-me` or `take-updates` (its `forge` repository's admin only).", | |
| 2492 | "How a spawned forge follows its parent: `tell-me` or `take-updates`. Its `forge` repository's admin.", | |
| 2493 | 2493 | inputSchema: { |
| 2494 | 2494 | type: "object", |
| 2495 | 2495 | properties: { |
| @@ -2553,7 +2553,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 2553 | 2553 | { |
| 2554 | 2554 | name: "propose_to_parent_forge", |
| 2555 | 2555 | description: |
| 2556 | "Offer this forge's landed change to its parent as a pull on `child/<name>/…`; the same tip answers with that pull.", | |
| 2556 | "Offer this forge's landed change to its parent as a pull on `child/<name>/…`; the same tip answers that pull.", | |
| 2557 | 2557 | inputSchema: { |
| 2558 | 2558 | type: "object", |
| 2559 | 2559 | properties: { repo: REPO_ARG }, |
| @@ -2584,7 +2584,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 2584 | 2584 | { |
| 2585 | 2585 | name: "forge_proposals", |
| 2586 | 2586 | description: |
| 2587 | "What this forge proposed to its parent, newest first. `reachable` is false if the parent did not answer.", | |
| 2587 | "What this forge proposed to its parent, newest first; `reachable` false if it did not answer.", | |
| 2588 | 2588 | inputSchema: { |
| 2589 | 2589 | type: "object", |
| 2590 | 2590 | properties: { repo: REPO_ARG }, |
| @@ -2601,7 +2601,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 2601 | 2601 | { |
| 2602 | 2602 | name: "converge", |
| 2603 | 2603 | description: |
| 2604 | "Have a fork's crew merge the parent's updates where both sides changed the same files, as a pull on the fork.", | |
| 2604 | "Have a fork's crew merge the parent's updates where both changed the same files, as a pull.", | |
| 2605 | 2605 | inputSchema: { |
| 2606 | 2606 | type: "object", |
| 2607 | 2607 | properties: { repo: REPO_ARG }, |
| @@ -2628,7 +2628,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 2628 | 2628 | { |
| 2629 | 2629 | name: "family", |
| 2630 | 2630 | description: |
| 2631 | "The forge's family: the forge that sent this one and, for a site admin, those it sent, with state and version.", | |
| 2631 | "The forge that sent this one and, for a site admin, those it sent, with state and version.", | |
| 2632 | 2632 | inputSchema: { type: "object", properties: {} }, |
| 2633 | 2633 | writes: false, |
| 2634 | 2634 | async run(ctx, user) { |
| @@ -2638,7 +2638,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 2638 | 2638 | { |
| 2639 | 2639 | name: "next_steps", |
| 2640 | 2640 | description: |
| 2641 | "On a spawned forge, your first three steps and whether each is done. Empty elsewhere or for anyone but its owner.", | |
| 2641 | "On a spawned forge, its owner's first three steps and whether each is done. Empty elsewhere.", | |
| 2642 | 2642 | inputSchema: { type: "object", properties: {} }, |
| 2643 | 2643 | writes: false, |
| 2644 | 2644 | async run(ctx, user) { |
| @@ -2649,7 +2649,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 2649 | 2649 | { |
| 2650 | 2650 | name: "thought", |
| 2651 | 2651 | description: |
| 2652 | "Where one of your thoughts went: its id (from `tell` without a repo) answers with the placement and reply.", | |
| 2652 | "Where one of your thoughts went: its id (from `tell` without a repo) answers placement and reply.", | |
| 2653 | 2653 | inputSchema: { |
| 2654 | 2654 | type: "object", |
| 2655 | 2655 | properties: { id: { type: "string", maxLength: 64 } }, |
| @@ -2679,7 +2679,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 2679 | 2679 | { |
| 2680 | 2680 | name: "asked", |
| 2681 | 2681 | description: |
| 2682 | "What people asked the crew for, in repositories you can write: by default what has nothing merged yet, oldest first.", | |
| 2682 | "What people asked the crew for where you write: by default nothing merged yet, oldest first.", | |
| 2683 | 2683 | inputSchema: { |
| 2684 | 2684 | type: "object", |
| 2685 | 2685 | properties: { |
| @@ -2733,7 +2733,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 2733 | 2733 | { |
| 2734 | 2734 | name: "app_members", |
| 2735 | 2735 | description: |
| 2736 | "The people a private app names, who may enter it and its previews. Without `members`, the list; with it, plans.", | |
| 2736 | "The people a private app names, who may enter it and its previews. With `members`, plans.", | |
| 2737 | 2737 | inputSchema: { |
| 2738 | 2738 | type: "object", |
| 2739 | 2739 | properties: { |
| @@ -2794,7 +2794,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 2794 | 2794 | { |
| 2795 | 2795 | name: "search", |
| 2796 | 2796 | description: |
| 2797 | "Find issues, pulls, repositories and code you can read, as /search; `kind` narrows, `repo` keeps to one repository.", | |
| 2797 | "Find issues, pulls, repositories and code you can read; `kind` narrows, `repo` keeps to one.", | |
| 2798 | 2798 | inputSchema: { |
| 2799 | 2799 | type: "object", |
| 2800 | 2800 | properties: { |
| @@ -2831,7 +2831,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 2831 | 2831 | { |
| 2832 | 2832 | name: "feed", |
| 2833 | 2833 | description: |
| 2834 | "Your ranked home timeline across visible apps. `cursor` pages. Your saved filter (`feed_chips`) applies.", | |
| 2834 | "Your ranked home timeline across visible apps; `cursor` pages; saved filter (`feed_chips`) applies.", | |
| 2835 | 2835 | inputSchema: { |
| 2836 | 2836 | type: "object", |
| 2837 | 2837 | properties: { |
| @@ -2864,7 +2864,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 2864 | 2864 | { |
| 2865 | 2865 | name: "feed_chips", |
| 2866 | 2866 | description: |
| 2867 | "The feed chips you switched off, left out of `feed` and `asks`. With `kind`, `value` and `hidden` it sets one.", | |
| 2867 | "Feed chips you switched off in `feed` and `asks`. With `kind`, `value` and `hidden`, sets one.", | |
| 2868 | 2868 | inputSchema: { |
| 2869 | 2869 | type: "object", |
| 2870 | 2870 | properties: { |
| @@ -2901,7 +2901,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 2901 | 2901 | { |
| 2902 | 2902 | name: "make_it_yours", |
| 2903 | 2903 | description: |
| 2904 | "Make an app you can see yours: a fork of its code and history, following the original; nothing else is copied.", | |
| 2904 | "Fork an app you can see: its code and history, following the original; nothing else is copied.", | |
| 2905 | 2905 | inputSchema: { |
| 2906 | 2906 | type: "object", |
| 2907 | 2907 | properties: { |
| @@ -3004,7 +3004,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 3004 | 3004 | { |
| 3005 | 3005 | name: "front_page", |
| 3006 | 3006 | description: |
| 3007 | "The front page as a stranger sees it. A site admin also gets the picks and sets them with `pinned`, `hidden`, `weights`.", | |
| 3007 | "The front page as a stranger sees it; a site admin also gets and sets `pinned`, `hidden`, `weights`.", | |
| 3008 | 3008 | inputSchema: { |
| 3009 | 3009 | type: "object", |
| 3010 | 3010 | properties: { |
| @@ -3050,7 +3050,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 3050 | 3050 | { |
| 3051 | 3051 | name: "map", |
| 3052 | 3052 | description: |
| 3053 | "An app's plan: open issues ready or waiting, critical path, every edge, where the crew is, `parkedTwice` issues.", | |
| 3053 | "An app's plan: open issues ready or waiting, critical path, edges, where the crew is, `parkedTwice`.", | |
| 3054 | 3054 | inputSchema: { |
| 3055 | 3055 | type: "object", |
| 3056 | 3056 | properties: { app: APP_ARG }, |
| @@ -3083,7 +3083,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 3083 | 3083 | { |
| 3084 | 3084 | name: "milestones", |
| 3085 | 3085 | description: |
| 3086 | "How far each thing asked for is. With `app`: the plan's top-level limbs with done/total, building and recent merges.", | |
| 3086 | "How far each thing asked for is. With `app`: top-level limbs, done/total, building, recent merges.", | |
| 3087 | 3087 | inputSchema: { |
| 3088 | 3088 | type: "object", |
| 3089 | 3089 | properties: { |
| @@ -3119,7 +3119,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 3119 | 3119 | { |
| 3120 | 3120 | name: "watch", |
| 3121 | 3121 | description: |
| 3122 | "Watch a milestone, or stop (`watch: false`): progress is one feed item; your phone is told once, when it lands.", | |
| 3122 | "Watch a milestone, or stop (`watch: false`): one feed item; your phone is told once when it lands.", | |
| 3123 | 3123 | inputSchema: { |
| 3124 | 3124 | type: "object", |
| 3125 | 3125 | properties: { |
| @@ -3243,7 +3243,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 3243 | 3243 | { |
| 3244 | 3244 | name: "limb", |
| 3245 | 3245 | description: |
| 3246 | "One action on a plan limb: `defer`, `resume` (`pillar`), `close` (`reason`), `raise`/`lower` (`under`), `replan`, `takeback`, `undo`.", | |
| 3246 | "Act on a plan limb: `defer`, `resume`, `close` (`reason`), `raise`, `lower`, `replan`, `takeback`, `undo`.", | |
| 3247 | 3247 | inputSchema: { |
| 3248 | 3248 | type: "object", |
| 3249 | 3249 | properties: { |
| @@ -3325,7 +3325,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 3325 | 3325 | { |
| 3326 | 3326 | name: "returns", |
| 3327 | 3327 | description: |
| 3328 | "What the crew's tokens bought over the last days (1–90, default 7): dollars, runs, changes landed, cost per change.", | |
| 3328 | "What the crew's tokens bought over `days` (1–90, default 7): dollars, runs, landed, cost per change.", | |
| 3329 | 3329 | inputSchema: { |
| 3330 | 3330 | type: "object", |
| 3331 | 3331 | properties: { |
| @@ -3468,7 +3468,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 3468 | 3468 | { |
| 3469 | 3469 | name: "spend", |
| 3470 | 3470 | description: |
| 3471 | "Report what your session spent on work the forge did not run: who, model, tokens or dollars, issue or pull.", | |
| 3471 | "Report what your session spent on work the forge did not run: who, model, tokens or dollars, issue.", | |
| 3472 | 3472 | inputSchema: { |
| 3473 | 3473 | type: "object", |
| 3474 | 3474 | properties: { |
| @@ -3497,7 +3497,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 3497 | 3497 | { |
| 3498 | 3498 | name: "usage", |
| 3499 | 3499 | description: |
| 3500 | "What the crew's runs on an app spent over the last days (1–90, default 7), by agent and issue. Writers only.", | |
| 3500 | "What the crew's runs on an app spent over `days` (1–90, default 7), by agent and issue. Writers.", | |
| 3501 | 3501 | inputSchema: { |
| 3502 | 3502 | type: "object", |
| 3503 | 3503 | properties: { |
| @@ -3528,7 +3528,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 3528 | 3528 | { |
| 3529 | 3529 | name: "labels", |
| 3530 | 3530 | description: |
| 3531 | "Set the labels of an issue or a pull to exactly these (none clears): only the repository's labels; writers only.", | |
| 3531 | "Set an issue's or pull's labels to exactly these (none clears), from the repository's. Writers.", | |
| 3532 | 3532 | inputSchema: { |
| 3533 | 3533 | type: "object", |
| 3534 | 3534 | properties: { |
| @@ -3657,7 +3657,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 3657 | 3657 | { |
| 3658 | 3658 | name: "attach_look", |
| 3659 | 3659 | description: |
| 3660 | "Attach a look to an open pull: PNG or JPEG (max 5 MB, base64 in `image`), `phone` or `desktop`, one line in `says`.", | |
| 3660 | "Attach a PNG or JPEG (base64 `image`, max 5 MB) to an open pull: `phone` or `desktop`, `says`.", | |
| 3661 | 3661 | inputSchema: { |
| 3662 | 3662 | type: "object", |
| 3663 | 3663 | properties: { |
| @@ -3711,7 +3711,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 3711 | 3711 | { |
| 3712 | 3712 | name: "hold", |
| 3713 | 3713 | description: |
| 3714 | "Hold a pull (`why`) or let it go (`release: true`): while held, nothing reviews or lands it. Writers only.", | |
| 3714 | "Hold a pull (`why`) or let it go (`release: true`): while held nothing reviews or lands it. Writers.", | |
| 3715 | 3715 | inputSchema: { |
| 3716 | 3716 | type: "object", |
| 3717 | 3717 | properties: { |
| @@ -3913,7 +3913,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 3913 | 3913 | { |
| 3914 | 3914 | name: "access", |
| 3915 | 3915 | description: |
| 3916 | "What outside agents tried: the redacted log of non-browser requests to public paths, newest first. Forge admin.", | |
| 3916 | "What outside agents tried: redacted log of non-browser requests to public paths, newest first, max 500. Forge admin.", | |
| 3917 | 3917 | inputSchema: { |
| 3918 | 3918 | type: "object", |
| 3919 | 3919 | properties: { |
| @@ -3980,7 +3980,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 3980 | 3980 | { |
| 3981 | 3981 | name: "scorecard", |
| 3982 | 3982 | description: |
| 3983 | "Crew scorecard (forge admin): per agent, all time and 30 days (landed, review rounds, red rate, reverts).", | |
| 3983 | "Crew scorecard (forge admin): per agent, all time and 30 days: landed, rounds, red rate, reverts.", | |
| 3984 | 3984 | inputSchema: { type: "object", properties: {} }, |
| 3985 | 3985 | writes: false, |
| 3986 | 3986 | adminOnly: true, |
| @@ -3992,7 +3992,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 3992 | 3992 | { |
| 3993 | 3993 | name: "flow", |
| 3994 | 3994 | description: |
| 3995 | "The forge's pipeline (forge admin): per stage counts, `oldestWaiting`, `capacity`, the bottleneck, merge `queue`, `reviewing` per reviewer.", | |
| 3995 | "The pipeline (forge admin): per-stage counts, `oldestWaiting`, `capacity`, bottleneck, `queue`, `reviewing` by reviewer.", | |
| 3996 | 3996 | inputSchema: { type: "object", properties: {} }, |
| 3997 | 3997 | writes: false, |
| 3998 | 3998 | run(ctx, user) { |
| @@ -4006,7 +4006,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 4006 | 4006 | { |
| 4007 | 4007 | name: "system", |
| 4008 | 4008 | description: |
| 4009 | "The machine the forge runs on, now: CPU, load, memory, disk, network, processes. Forge admin or telemetry:read.", | |
| 4009 | "The forge's machine now: CPU, load, memory, disk, network, processes. Forge admin or telemetry:read.", | |
| 4010 | 4010 | inputSchema: { type: "object", properties: {} }, |
| 4011 | 4011 | writes: false, |
| 4012 | 4012 | run(ctx, user) { |
| @@ -4020,7 +4020,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 4020 | 4020 | { |
| 4021 | 4021 | name: "contribute", |
| 4022 | 4022 | description: |
| 4023 | "For any arriving agent: what this forge is, its bottleneck, open “help wanted” issues, how to propose.", | |
| 4023 | "For an arriving agent: what this forge is, its bottleneck, “help wanted” issues, how to propose.", | |
| 4024 | 4024 | inputSchema: { type: "object", properties: {} }, |
| 4025 | 4025 | writes: false, |
| 4026 | 4026 | run: (ctx) => good(welcome(ctx.app)), |
| @@ -4028,7 +4028,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 4028 | 4028 | { |
| 4029 | 4029 | name: "limits", |
| 4030 | 4030 | description: |
| 4031 | "Every limit the forge's owner can hit, with value, bounds. With `key` and `value` (\"\" restores default), plans.", | |
| 4031 | "Every limit the forge's owner can hit, value and bounds. `key` and `value` (\"\" restores) plan.", | |
| 4032 | 4032 | inputSchema: { |
| 4033 | 4033 | type: "object", |
| 4034 | 4034 | properties: { |
| @@ -4159,7 +4159,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 4159 | 4159 | { |
| 4160 | 4160 | name: "cloud_accounts", |
| 4161 | 4161 | description: |
| 4162 | "Cloud accounts (forge admin): each attached provider token with use, verification, write permission, today's calls.", | |
| 4162 | "Cloud accounts (forge admin): each provider token's use, verification, write permission, calls today.", | |
| 4163 | 4163 | inputSchema: { type: "object", properties: {} }, |
| 4164 | 4164 | // A read, but marked a write so a `ro` token never lists the accounts; it |
| 4165 | 4165 | // is a forge admin's and the audit rows name every vendor call. |
| @@ -4175,7 +4175,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 4175 | 4175 | { |
| 4176 | 4176 | name: "cloud_account", |
| 4177 | 4177 | description: |
| 4178 | "Change a cloud account (admin-scope token). `verb`: attach, verify, rotate, rename, remove, allow_writes, audit.", | |
| 4178 | "Change a cloud account (admin token): `verb` attach, verify, rotate, rename, remove, allow_writes, audit.", | |
| 4179 | 4179 | inputSchema: { |
| 4180 | 4180 | type: "object", |
| 4181 | 4181 | properties: { |
| @@ -4230,7 +4230,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 4230 | 4230 | { |
| 4231 | 4231 | name: "quotas", |
| 4232 | 4232 | description: |
| 4233 | "Per-account repository and app quotas (number or null; not enforced yet). With `key`, `value` (\"\" clears), plans.", | |
| 4233 | "Per-account repository and app quotas (number or null; not enforced yet). With `key` and `value` (\"\" clears), plans.", | |
| 4234 | 4234 | inputSchema: { |
| 4235 | 4235 | type: "object", |
| 4236 | 4236 | properties: { |
| @@ -4268,7 +4268,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 4268 | 4268 | { |
| 4269 | 4269 | name: "signup", |
| 4270 | 4270 | description: |
| 4271 | "Who may sign up: open (default); invite lets in only a person with an open invite link; closed refuses every new account. With `mode`, plans.", | |
| 4271 | "Sign-ups: open (default); invite lets in only a person with an open invite link; closed refuses every new account.", | |
| 4272 | 4272 | inputSchema: { |
| 4273 | 4273 | type: "object", |
| 4274 | 4274 | properties: { |
| @@ -4364,7 +4364,7 @@ const TOOLS: readonly Tool[] = [ | ||
| 4364 | 4364 | { |
| 4365 | 4365 | name: "board_write", |
| 4366 | 4366 | description: |
| 4367 | "Write a whole board under a slug (made or replaced): {title, range, refresh, panels: [{title, chart, query, w, h}]}.", | |
| 4367 | "Write a whole board under a slug: {title, range, refresh, panels: [{title, chart, query, w, h}]}.", | |
| 4368 | 4368 | inputSchema: { |
| 4369 | 4369 | type: "object", |
| 4370 | 4370 | properties: { |
test/mcp-size.test.ts +13 −2
| @@ -20,7 +20,12 @@ import { serve, type Servers } from "../src/http/server.ts"; | ||
| 20 | 20 | |
| 21 | 21 | const CEILING = 40_000; |
| 22 | 22 | // Headroom: a new tool should fit without another round of cuts. |
| 23 | const HEADROOM_CEILING = 37_500; | |
| 23 | // #4990 raised it to 37,500 to fit `threads`; the tool descriptions were cut | |
| 24 | // instead (#5105), so it is 37,000 again: raising it is how the lane went red. | |
| 25 | const HEADROOM_CEILING = 37_000; | |
| 26 | // One sentence a tool: past this, a description is a paragraph and belongs in | |
| 27 | // docs/MCP.md, which keeps the detail. | |
| 28 | const DESCRIPTION_CEILING = 120; | |
| 24 | 29 | |
| 25 | 30 | let dataDir: string; |
| 26 | 31 | let app: App; |
| @@ -50,7 +55,7 @@ afterAll(async () => { | ||
| 50 | 55 | await rm(dataDir, { recursive: true, force: true }); |
| 51 | 56 | }); |
| 52 | 57 | |
| 53 | test("tools/list stays under 40 KB, with 3 KB of headroom (37,500 bytes)", async () => { | |
| 58 | test("tools/list stays under 40 KB, with 3 KB of headroom (37,000 bytes)", async () => { | |
| 54 | 59 | const res = await fetch(`${servers.url}/mcp`, { |
| 55 | 60 | method: "POST", |
| 56 | 61 | headers: { |
| @@ -85,4 +90,10 @@ test("tools/list stays under 40 KB, with 3 KB of headroom (37,500 bytes)", async | ||
| 85 | 90 | bytes, |
| 86 | 91 | `tools/list is ${bytes} bytes, ${bytes - HEADROOM_CEILING} over the ${HEADROOM_CEILING} headroom (${CEILING - bytes} left under the ceiling); the five longest descriptions: ${longest.join(", ")}`, |
| 87 | 92 | ).toBeLessThanOrEqual(HEADROOM_CEILING); |
| 93 | expect( | |
| 94 | tools | |
| 95 | .filter((t) => Buffer.byteLength(t.description) > DESCRIPTION_CEILING) | |
| 96 | .map((t) => `${t.name} (${Buffer.byteLength(t.description)} bytes)`), | |
| 97 | `tool descriptions over ${DESCRIPTION_CEILING} bytes`, | |
| 98 | ).toEqual([]); | |
| 88 | 99 | }); |
new above
offline
Low: the description no longer says that
signupwithmodeonly plans unlessdryRun: falseis sent. The schema'sdryRun: "false to apply"still tells an agent, so this does not block. If a later pull has bytes to spare, "…every new account;modeplans." fits under 120.