Give the MCP tools the same reach the page and the terminal have, so a Claude session can finish a piece of work on a board instead of only adding and moving cards.
What it is like today.src/mcp.ts offers four tools — list_boards, list_cards, add_card, move_card (five once #52 lands list_columns). A person on the page, or in the terminal (src/keys.ts: a/e/d for cards, c/r/D for columns, u for undo), can also rename a card, delete one, add a column, rename a column and undo. So the third seat at the board can put cards on it and shuffle them, and cannot correct a typo it made, clear a card it finished, or set up the column it needs. AGENTS.md asks this of the terminal in so many words — "what a person can do on the web page they should be able to do here too" — and the agent seat is the one the direction names.
What done looks like
[ ] Three more tools in src/mcp.ts, each built exactly like the ones there now: edit_card (board_id, card_id, title), delete_card (board_id, card_id), add_column (board_id, name).
[ ] Each validates at the boundary with the same BOARD_ID / ENTITY_ID shapes and the same trimmed, length-capped title (200) and column name (60) the routes use, and returns the error shape #52 settles on — one that names the way out rather than only what was wrong.
[ ] Each publishes its bus event (card.edited, card.deleted, column.added) with by set from the caller's identity and client: null, so an agent's change appears on every open page within a second, like a person's does.
[ ] The board's caps are respected and said: add_column past MAX_COLUMNS_PER_BOARD fails with the number in the message, same as the page.
[ ] tools/list describes each new tool in one sentence a model can act on, including that a card id comes from list_cards and a column id from list_columns.
[ ] Tests over HTTP in src/server.test.ts (where the MCP tests already live): each tool called through POST /mcp changes the board, a watcher on GET /b/:id/events sees the matching frame within a second, and a bad id is refused without touching the database.
[ ] Deliberately not in scope, and said in the pull: undo (board-wide and destructive — an agent reversing a person's last change is a decision for its own issue), deleting a column (cascades every card in it; see #50 and #54), and anything that changes ownership.
[ ] bun test passes; the README's Agents bullet lists the full tool set instead of four names.
Files I expect to change:src/mcp.ts, src/server.test.ts, README.md.
Risks. Every tool added is another unauthenticated write path onto a board whose id is its access control — none of these grants more than the link already does, but each one must validate exactly as the route does, and delete_card is the first destructive thing an agent can do (it stays undoable from the page, which is the mitigation). Keep the tool list small enough that a model picks the right one; if it starts reading like an API, stop. Waits for #52, which reshapes the error text and adds the tool that hands out column ids — building on it avoids two runs rewriting the same block.
Who fits:scout to build it, reviewed by sentinel — the review question is whether each new tool's validation matches its route's, one for one.
Give the MCP tools the same reach the page and the terminal have, so a Claude session can finish a piece of work on a board instead of only adding and moving cards.
What it is like today.
src/mcp.tsoffers four tools —list_boards,list_cards,add_card,move_card(five once #52 landslist_columns). A person on the page, or in the terminal (src/keys.ts:a/e/dfor cards,c/r/Dfor columns,ufor undo), can also rename a card, delete one, add a column, rename a column and undo. So the third seat at the board can put cards on it and shuffle them, and cannot correct a typo it made, clear a card it finished, or set up the column it needs.AGENTS.mdasks this of the terminal in so many words — "what a person can do on the web page they should be able to do here too" — and the agent seat is the one the direction names.What done looks like
src/mcp.ts, each built exactly like the ones there now:edit_card(board_id, card_id, title),delete_card(board_id, card_id),add_column(board_id, name).BOARD_ID/ENTITY_IDshapes and the same trimmed, length-capped title (200) and column name (60) the routes use, and returns the error shape #52 settles on — one that names the way out rather than only what was wrong.card.edited,card.deleted,column.added) withbyset from the caller's identity andclient: null, so an agent's change appears on every open page within a second, like a person's does.add_columnpastMAX_COLUMNS_PER_BOARDfails with the number in the message, same as the page.tools/listdescribes each new tool in one sentence a model can act on, including that a card id comes fromlist_cardsand a column id fromlist_columns.src/server.test.ts(where the MCP tests already live): each tool called throughPOST /mcpchanges the board, a watcher onGET /b/:id/eventssees the matching frame within a second, and a bad id is refused without touching the database.undo(board-wide and destructive — an agent reversing a person's last change is a decision for its own issue), deleting a column (cascades every card in it; see #50 and #54), and anything that changes ownership.bun testpasses; the README's Agents bullet lists the full tool set instead of four names.Files I expect to change:
src/mcp.ts,src/server.test.ts,README.md.Risks. Every tool added is another unauthenticated write path onto a board whose id is its access control — none of these grants more than the link already does, but each one must validate exactly as the route does, and
delete_cardis the first destructive thing an agent can do (it stays undoable from the page, which is the mitigation). Keep the tool list small enough that a model picks the right one; if it starts reading like an API, stop. Waits for #52, which reshapes the error text and adds the tool that hands out column ids — building on it avoids two runs rewriting the same block.Who fits: scout to build it, reviewed by sentinel — the review question is whether each new tool's validation matches its route's, one for one.