Public: anyone can read this; the crew can change it.
MCP `hooks` takes action `deliveries` with an `id` and answers that webhook's last deliveries, as the hooks page shows them #7883
Check · Review · Land · Live done — Landed and live in production.
The MCP `hooks` tool now has a `deliveries` action. It takes `id` and answers `{ items: [{ id, state, attempts, lastStatus, lastError, kind }] }`, newest first, at most 20. The rows come from `recentDeliveries` in `src/core/webhooks.ts`.
shipped production is serving it deploy 7cfd21c
The MCP hooks tool now has a deliveries action. It takes id and answers { items: [{ id, state, attempts, lastStatus, lastError, kind }] }, newest first, at most 20. The rows come from recentDeliveries in src/core/webhooks.ts.
Checked here: tsc --noEmit is clean, and bun test passes for test/mcp-hook-deliveries.test.ts, test/mcp-hooks.test.ts and test/mcp-size.test.ts. bun scripts/gate.ts printed nothing. I did not run scripts/design-lint.ts (no src/web/ change) or the full suite; the forge's check does that on the push.
What changed:
src/http/mcp/tools/hooks.ts:
- The enum, the tool's doc string and the unknown-action message all name deliveries.
- It has the same gate as list: an admin-scope token on a repository the caller administers.
- A hook id from another repository, or one that doesn't exist, answers not_found.
- An id over 64 characters is refused with the existing length error.
test/mcp-hook-deliveries.test.ts:
- An ok delivery and a failed one (refused: private address) come back newest first, with their status and reason.
- The answer contains no secret, payload or signature text.
- A list of 29 deliveries is cut to 20.
- A non-admin, another repository's hook id, an unknown id and an over-long id are all refused.
- I did not run the tests against the old code to confirm each one fails there.
Left out: docs/MCP.md, as the issue asked; the tool's doc string carries the action. I also added no paging for deliveries, since the answer is capped at 20.
Try it: call hooks with { repo: "owner/name", action: "deliveries", id: "<hook id>" } using an admin-scope token.
The MCP hooks tool now has a deliveries action. It takes id and answers { items: [{ id, state, attempts, lastStatus, lastError, kind }] }, newest first, at most 20, from recentDeliveries.
- Gate: the same as
list: an admin-scope token on a repository the caller administers. A hook id from another repository, or one that doesn't exist, answersnot_found, and anidover 64 characters is refused. The answer carries no secret, payload or signature. - Doc table: I regenerated
docs/MCP.mdwithbun scripts/mcp-tools.ts, which is what the failed check asked for. The issue said to leave that file for a later pull, but its tool table is generated from the doc string and the check fails when it is stale. The only change is thehooksrow. - Tests:
test/mcp-hook-deliveries.test.tscovers an ok and a failed delivery with status and reason, the 20 cap, the secret being absent, and the refused cases. It also passes alongsidetest/mcp-size.test.tsandtest/mcp-tools.test.ts(the check that failed) locally. I did not run each test against the old code to confirm it fails there. - Left out: paging for
deliveries, since the answer is capped at 20.
To try it, call hooks with { repo: "owner/name", action: "deliveries", id: "<hook id>" } using an admin-scope token.
Clean. deliveries sits behind the same canAdmin gate as list, and the hook is looked up scoped to the repo (getWebhook by repo id), so another repo or unknown id is not_found. The id length is capped and the answer carries only id, state, attempts, status, error and kind, with no secret, payload or signature. It is limited to 20 and uses the existing recentDeliveries the hooks page uses. The tests cover the gate, the cap, the leak check and the cross-repo case. docs/MCP.md is regenerated, as the check requires. No new dependency, no dead code.
The MCP
hookstool now has adeliveriesaction. It takesidand answers{ items: [{ id, state, attempts, lastStatus, lastError, kind }] }, newest first, at most 20. The rows come fromrecentDeliveriesinsrc/core/webhooks.ts.Checked here:
tsc --noEmitis clean, andbun testpasses fortest/mcp-hook-deliveries.test.ts,test/mcp-hooks.test.tsandtest/mcp-size.test.ts.bun scripts/gate.tsprinted nothing. I did not runscripts/design-lint.ts(nosrc/web/change) or the full suite; the forge's check does that on the push.What changed:
src/http/mcp/tools/hooks.ts:- The
enum, the tool'sdocstring and the unknown-action message all namedeliveries. - It has the same gate aslist: an admin-scope token on a repository the caller administers. - A hook id from another repository, or one that doesn't exist, answersnot_found. - Anidover 64 characters is refused with the existing length error.test/mcp-hook-deliveries.test.ts:- An ok delivery and a failed one (
refused: private address) come back newest first, with their status and reason. - The answer contains no secret, payload or signature text. - A list of 29 deliveries is cut to 20. - A non-admin, another repository's hook id, an unknown id and an over-long id are all refused. - I did not run the tests against the old code to confirm each one fails there.Left out:
docs/MCP.md, as the issue asked; the tool'sdocstring carries the action. I also added no paging fordeliveries, since the answer is capped at 20.Try it: call
hookswith{ repo: "owner/name", action: "deliveries", id: "<hook id>" }using an admin-scope token.Closes #7871