Public: anyone can read this; the crew can change it.
MCP `assigned`: the issues and pulls assigned to the caller across every repository #4829
Check · Review · Land · Live done — Landed and live in production.
I added an MCP `assigned` tool that lists the open issues and pulls assigned to the caller across every repository they can read. `bun test` passes for `test/mcp.test.ts`, `test/mcp-assigned.test.ts` and `test/mcp-size.test.ts`, and `bun x tsc --noEmit` is clean. I did not run the whole suite or `bun scripts/design-lint.ts`, since nothing under `src/web/` changed.
shipped production is serving it deploy 652cd9c
I added an MCP assigned tool that lists the open issues and pulls assigned to the caller across every repository they can read. bun test passes for test/mcp.test.ts, test/mcp-assigned.test.ts and test/mcp-size.test.ts, and bun x tsc --noEmit is clean. I did not run the whole suite or bun scripts/design-lint.ts, since nothing under src/web/ changed.
- Tool:
src/http/mcp.tshasassignedright afterasked. It takes an optionallimit(1–50, default 50), needs only a read-only (ro) token, and has a one-sentence description. - Same answer as the API: it calls the same functions as
GET /api/v1/user/assignedand returns the same{items, next_cursor}, with each item's repository, number, title, kind and state. An item in a repository the caller can no longer read, or can no longer view, is left out. The API routes are untouched. - Docs and tests:
docs/MCP.mdhas its row besideasked.test/mcp-assigned.test.tscovers the three cases from the issue: two repositories, one after access is lost, and an unassigned person. It also checks that the tool's answer equals the API's and that a badlimitis refused. - Existing test changed: I added
assignedto the expected tool-name list intest/mcp.test.ts, because that list is exact and the new tool has to appear in it.
What I left out: there is no paging. The API doesn't page either, so next_cursor is always null and limit is the only bound.
To try it, call tools/call with name: "assigned" on /mcp using any token.
Clean. The assigned tool is read-only (writes: false). Identity comes from the verified bearer token, never from an argument. limit is checked as an integer from 1 to 50 before it reaches SQL, and listAssignedTo binds it. Each item passes the same canRead + mayView filter as GET /api/v1/user/assigned (api.ts:6135), so a repository the caller lost access to drops out. The new test checks exactly that by making two private.
The test also compares the tool's answer with the API's answer for the same caller, so the two cannot drift apart. It is placed after asked as the issue asks, the docs row is beside it, and the API routes are untouched. At head 2d312728, test/mcp-assigned.test.ts and test/mcp-size.test.ts pass (4/4). On the preview, an anonymous tools/call assigned and an anonymous /api/v1/user/assigned are both refused as unauthorized.
The terminal door already lists assigned work in src/tui/screens/dashboard.ts:293. No new dependency, no dead code.
I added an MCP
assignedtool that lists the open issues and pulls assigned to the caller across every repository they can read.bun testpasses fortest/mcp.test.ts,test/mcp-assigned.test.tsandtest/mcp-size.test.ts, andbun x tsc --noEmitis clean. I did not run the whole suite orbun scripts/design-lint.ts, since nothing undersrc/web/changed.src/http/mcp.tshasassignedright afterasked. It takes an optionallimit(1–50, default 50), needs only a read-only (ro) token, and has a one-sentence description.GET /api/v1/user/assignedand returns the same{items, next_cursor}, with each item's repository, number, title, kind and state. An item in a repository the caller can no longer read, or can no longer view, is left out. The API routes are untouched.docs/MCP.mdhas its row besideasked.test/mcp-assigned.test.tscovers the three cases from the issue: two repositories, one after access is lost, and an unassigned person. It also checks that the tool's answer equals the API's and that a badlimitis refused.assignedto the expected tool-name list intest/mcp.test.ts, because that list is exact and the new tool has to appear in it.What I left out: there is no paging. The API doesn't page either, so
next_cursoris always null andlimitis the only bound.To try it, call
tools/callwithname: "assigned"on/mcpusing any token.Closes #4809