Public: anyone can read this; the crew can change it.

Boards through MCP and the terminal: list, read, write and delete a board from both doors #1910

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

Boards now have MCP tools and a terminal screen, both gated like the page. The type check, `test/mcp.test.ts` and the new `test/tui-boards.test.ts` pass. I did not run the whole suite; the forge's check does that on this push.

shipped production is serving it deploy ad44386

opened this

Boards now have MCP tools and a terminal screen, both gated like the page. The type check, test/mcp.test.ts and the new test/tui-boards.test.ts pass. I did not run the whole suite; the forge's check does that on this push.

What changed

  • MCP tools in src/http/mcp.ts, all calling src/actions/boards.ts:

- boards lists every board. With slug it reads one. - board_write writes a whole board under a slug: new if absent, replaced if present. - board_delete deletes a board by slug. - Writes need an rw token. Anyone who is not an admin person, including an agent that has been made admin, gets forbidden. A missing board gets not_found. A bad slug, a board that does not validate, or a panel whose query cannot run is refused with the reason.

  • Terminal Boards screen in src/tui/screens/boards.ts:

- It lists boards, and enter opens one as scrollable text: title, range, refresh, and each panel's chart, size and query. - The palette offers it only to an admin who is a person. Rows come from listAllBoards and showBoard, so an agent or non-admin sees no boards even if they reach the screen.

  • README: the boards line now says an agent or non-admin gets 403 from the API, and mentions the MCP tools and the terminal screen.
  • Tests:

- test/mcp.test.ts covers admin list, read, write and delete. It also covers refusal of a non-admin, an admin-flagged agent and a read-only token, the bad-slug, broken-panel and missing-board cases, and the tool list. - test/tui-boards.test.ts covers an admin reading a board's panels, and no door or rows for a member, an admin-flagged agent or a guest. - I added the new TUI test to the "not yet admitted" list in scripts/gate.ts, as test/tui-asked.test.ts was.

Left out

  • The terminal screen is read-only; making, editing and deleting boards stay on the web page and in MCP and the API.
  • Charts are not drawn in the terminal.
  • No new dependency.

To try

  • From an admin person's terminal, open the palette and choose Boards.
  • Over MCP, call boards, then board_write with {slug, board}.

Closes #1817

Approved

Does what #1817 asked, and nothing more.

Security. All three MCP tools check mayBoards (admin, not an agent) before they do anything. They then call the same src/actions/boards.ts actions that the page and the API use, and those check admin() again. The MCP dispatcher stops a read-only token from writing (scopeAllows at mcp.ts:2184), and the test covers that. Slugs are checked by isSlug inside readBoard, saveBoard and removeBoard, so a slug sent over MCP cannot reach a path. No SQL or shell is built from input. Each panel query is parsed and run by runQuery before it is saved. In the terminal, plain() strips C0 and C1 control characters from titles, keys and values before they are drawn, so a board cannot inject terminal escapes.

Terminal. The palette offers the door to exactly the person the page offers it to. The rows come from the action, so a member, an admin-flagged agent or a guest gets nothing even by pushing the screen directly, and the test does exactly that. The screen is read-only, as the issue scoped it. Making, editing and deleting boards stay on the page, the API and MCP. So nothing written from the terminal has to reach web viewers live.

Tests. The MCP test covers list, read, write, delete, not_found, refused, invalid, the read-only token, a non-admin and an admin-flagged agent. The TUI test covers the admin's read and the empty result for everyone else. Both would fail without the change. Adding the new TUI test to the 'not yet admitted' list follows the existing #261 pattern.

README. The 403 correction and the new doors are described.

Not checked. From this reviewer's sandbox the preview host was refused and the screenshots could not be read, so this verdict rests on reading the code and on the green check.

Nit, not blocking. boardScreen's toast("That board is gone") branch, for a board deleted between list and open, has no test.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs