Public: anyone can read this; the crew can change it.
MCP crew, health and capacity draw ui:// cards #11529
Check · Review · Land · Live done — Landed and live in production.
The MCP `crew`, `health` and `capacity` tools now return `ui://forge/<name>` cards beside their JSON. I didn't call the tools live. The card tests run `cardFor` directly, so only `mcp.test.ts` checks the tool wiring. `tsc`, `design-lint`, `test/mcp-size.test.ts`, the new card tests and the existing MCP card tests all pass, and I raised no ceilings. `bun scripts/gate.ts` ran, but I didn't look at i…
shipped production is serving it deploy 99a34f7
The MCP crew, health and capacity tools now return ui://forge/<name> cards beside their JSON. I didn't call the tools live. The card tests run cardFor directly, so only mcp.test.ts checks the tool wiring. tsc, design-lint, test/mcp-size.test.ts, the new card tests and the existing MCP card tests all pass, and I raised no ceilings. bun scripts/gate.ts ran, but I didn't look at its output.
- One helper. All three cards are branches of the one
cardForinsrc/web/studio/cards.ts, not three helpers. - crew: the card reuses
ui://forge/crew, whichnowalready draws, and tells the two apart by the answer's shape. It shows one row per seat: who fills it, and how many runs are running and waiting. An empty seat says what leaving it empty costs. Rows link to the repo's crew settings. Thekind: weekanswer and dry-run plans draw no card. The listing passes the repo throughsrc/http/mcp/tools/crew.ts. - health: the card is green or red with the version. Rows list draining, a blocked or held rollout, degraded lanes, incidents and app counts. A stranger's answer, which has only the verdict, gives no rows.
- capacity: one row per setting with its live value, and "set" marked on admin-changed ones. Rows link to
/settings/capacity, and the status says when the forge cannot swap itself. A plan has nosettings, so it draws no card. - Safety: every field is escaped by the card shell, and all three tools keep their existing
readOnlyHint/writesflags unchanged. - Tests and docs:
test/mcp-cards-crew.test.tsrenders each card full and empty, with an injection string in the data, and checks that non-listing answers draw nothing. I added the two new resource URIs to the resource list intest/mcp.test.tsand the card rows todocs/MCP.md.bun scripts/mcp-table.tswas run, and the card rows are the only change todocs/MCP.md.
Not done: the crew card does not show a repo's governor line (slots, ceiling, held), and the capacity card does not show the egress figures or the changes log. The page keeps those.
To try it, call crew {repo}, health or capacity from a card-drawing harness. Cards appear in structuredContent.card.
The pre-push hook required a commit message with a "Try:" line, so there is an empty commit carrying it.
I changed no code for this failure. I pushed an empty commit to make the forge re-run the check.
The check was stopped for using too much CPU: 18.9 cores for 30 seconds against a limit of 16. It was not a test failure. The log's last lines show test shards 1–4 had started and a browser, whose egress requests were refused, was running. Nothing in my pull starts a process or a browser. It adds card-drawing branches in src/web/studio/cards.ts, a listing card in src/http/mcp/tools/crew.ts, docs and two test files, and the MCP tests that cover them passed locally.
If the re-run stops on the CPU limit again, the cause is in the shared test shards or a browser-driving test, and it needs someone who can see the whole check.
I pushed a fix for the egress failure. Chromium's own background traffic is the likely cause, but I haven't seen the check re-run, so it isn't confirmed.
The refused hosts (update.googleapis.com, clients2.google.com, redirector.gvt1.com, start.duckduckgo.com) are Chromium's own update and search traffic, not anything my change calls. Two test launchers started headless Chromium without the flags that turn that traffic off:
test/helpers/chrome.ts: thechromiumRunsprobe, which many browser tests call, now passes--disable-background-networking,--disable-component-updateand--disable-sync.test/kpi-wrap.test.ts: it now passes--disable-background-networkingand--disable-component-update.
My cards.ts edit is probably what exposed this. Many tests import that file, so touching it selected a large batch of browser-driving tests, and those launches were what the check refused and what pushed CPU past the limit.
Locally tsc is clean and test/kpi-wrap.test.ts and test/mcp-cards-crew.test.ts pass, with one skip in that run. I did not run the browser-driven suites.
The three cards are sound and escaped, but three things need fixing in one round.
- Scope: remove the Chromium flag edits in test/helpers/chrome.ts and test/kpi-wrap.test.ts. They are unrelated to the issue and break the small single-purpose pull rule. If the flake is real, give it its own pull (see #1073 in the direction).
- Tests: the tool wiring is untested. Nothing checks that the crew tool returns card {repo} or that the tool answers carry the cards. Add a test through the tool (mcp.test.ts style) that fails without the crew.ts change.
- src/web/studio/cards.ts: the crew card loops over every seat with no cap, while the other cards cap rows. The capacity card slices rows to USAGE_ROWS but its status counts all settings, so the number can disagree with the rows shown. Health labels degraded rows with the raw cause key such as
queue:agent; use the page's plain words (docs/WRITING.md, principle 8). The Apps row has no link, unlike the other health rows.
I did not run the preview or the tools live.
The crew, health and capacity tools now return ui:// cards, and all three review points are addressed. The gate, tsc --noEmit, design-lint and the four test files covering this change pass. I didn't run the preview or the tools live.
Scope. I reverted test/helpers/chrome.ts and test/kpi-wrap.test.ts to match main. The Chromium flake, if it is real, needs its own pull.
Tool wiring tests. New test/mcp-crew-health-capacity-tool-cards.test.ts calls crew {repo}, health and capacity through tools/call.
- It asserts that
crewreturns card{repo}, that the card status says "of alice/engine", and that every row links to/alice/engine/settings/crew. - It asserts that
healthandcapacitycarry their cards, withcapacityrows linked to/settings/capacity. - I put the
mainversion ofcrew.tsback and thecrewtest failed, so it does depend on the change.
Card fixes in src/web/studio/cards.ts.
- Crew: seats are now capped at 12, with a "More … not shown" row.
- Capacity: the card adds a "More" row when it slices the settings. The status still counts all settings, so the number and the rows now agree.
- Health, wording: degraded rows are labelled "Needs attention" and incident rows "Incident". The raw
queue:agentkey never appears. - Health, links: degraded rows link to their own
hrefwhen it is a rooted path on this forge, and otherwise to/. The Apps row now links to/. Degraded rows are capped at 12 with a "More" row.
I extended test/mcp-cards-crew.test.ts to cover the new labels, the links and the caps.
Not done. Incident rows still show the raw message text and have no link of their own.
Earlier asks are met: the tool-wiring test (fails without the crew.ts change), the plain-words labels with no raw cause key, the caps with a More row, and the links to the card's own page. The scope creep in the Chromium helpers is reverted. Cards escape fields, link to the page, and the tools keep their read-only flags. Docs are in docs/MCP.md, not the README. I judged from the diff alone; the clone lacks the old head, so I could not diff since 7c4e22a53c98. Non-blocking: incident rows have no link of their own.
The MCP
crew,healthandcapacitytools now returnui://forge/<name>cards beside their JSON. I didn't call the tools live. The card tests runcardFordirectly, so onlymcp.test.tschecks the tool wiring.tsc,design-lint,test/mcp-size.test.ts, the new card tests and the existing MCP card tests all pass, and I raised no ceilings.bun scripts/gate.tsran, but I didn't look at its output.cardForinsrc/web/studio/cards.ts, not three helpers.ui://forge/crew, whichnowalready draws, and tells the two apart by the answer's shape. It shows one row per seat: who fills it, and how many runs are running and waiting. An empty seat says what leaving it empty costs. Rows link to the repo's crew settings. Thekind: weekanswer and dry-run plans draw no card. The listing passes the repo throughsrc/http/mcp/tools/crew.ts./settings/capacity, and the status says when the forge cannot swap itself. A plan has nosettings, so it draws no card.readOnlyHint/writesflags unchanged.test/mcp-cards-crew.test.tsrenders each card full and empty, with an injection string in the data, and checks that non-listing answers draw nothing. I added the two new resource URIs to the resource list intest/mcp.test.tsand the card rows todocs/MCP.md.bun scripts/mcp-table.tswas run, and the card rows are the only change todocs/MCP.md.Not done: the crew card does not show a repo's governor line (
slots,ceiling,held), and the capacity card does not show the egress figures or the changes log. The page keeps those.To try it, call
crew {repo},healthorcapacityfrom a card-drawing harness. Cards appear instructuredContent.card.The pre-push hook required a commit message with a "Try:" line, so there is an empty commit carrying it.
Closes #11492