MCP server for Zuuna — agent-native board access for Claude Code, Cursor and Codex. 67 tools over the Zuuna v1 API: boards, cards, comments, checklists, relations, attachments, time tracking, sprints, recurring cards, releases, deployments, webhooks and git-on-board linking.
Strong naming conventions (verb_noun pattern consistently applied: zuuna_list_*, zuuna_create_*, zuuna_update_*, zuuna_delete_*, zuuna_move_*, zuuna_archive_*). All 25 tools have descriptions (avg ~120 chars, within 10-1024 baseline). All parameters have type definitions and descriptions. Input schemas are explicit and well-structured using Zod. Output schemas are documented in descriptions. Error handling via wrap() function catches ZuunaApiError, ZuunaNetworkError, and local errors, returning structured error results. Tool annotations (readOnlyHint, destructiveHint) present for risk classification. Gaps: some parameter descriptions could be more prescriptive about constraints (e.g., zuuna_create_card's idempotencyKey lacks format guidance); output field documentation is implicit rather than explicit; no per-tool recovery guidance in error messages.
Add a checklist item to a card (appended at the end).
Archive a card (reversible — see zuuna_unarchive_card).
Get one board assembled: its columns (in order, with WIP limits and SLA hours) and its cards (key, title, column, priority, type). The card list pages at 200; when more cards exist the response carries cardsTruncated and a nextCursor — pass that back as cardsCursor for the next page. Accepts the board id, its key (card prefix) or its title.
List the workspace's boards (non-archived, non-private). Each entry carries id, title, key (card prefix), groupId. Use the id with zuuna_board.
Get a card's full detail: description, priority, type, due/start dates, checklist counts, assignees, epic, custom field values, attachment metadata.
Output schemas not explicitly documented. Tool descriptions state what is returned (e.g., 'carries id, title, key, groupId') but no formal JSON Schema for responses. LLMs cannot reliably parse unstructured output or plan downstream tool calls.
Parameter constraints not fully specified. zuuna_create_card's idempotencyKey, zuuna_report_deployment's environment/state, and zuuna_create_column's position lack format/range guidance. Descriptions say 'optional' but not min/max, regex, or valid enum values.
Error messages lack recovery guidance. errorResult() in tool-helpers.ts returns API error code/message but does not suggest next steps (e.g., 'Try zuuna_list_groups() to find a valid groupId'). Agents cannot self-correct from validation failures.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 66 | 2026-07-28+ | v2 |
Add a comment to a card. The author is the user who created the API token. @mentions notify.
Create an empty board (no columns yet — add them with zuuna_create_column) in a group. Body: title, groupId.
Create a card on a board. Title is required; give the target column by id or by title (omitted = the board's first column). idempotencyKey makes a retry safe: re-sending the same key after a lost response or a 5xx returns the ORIGINAL card instead of a duplicate.
Add a column to an existing (non-archived) board.
Remove an attachment from a card. Requires confirm: true.
Remove a checklist item. Requires confirm: true.
Get one attachment's metadata (filename, MIME type, byte size). Never returns the file's bytes — use zuuna_list_attachments first to find the attachmentId.
List a card's attachments (metadata only: id, filename, MIME type, size, who uploaded it).
Read a board's automation rules: trigger, conditions, actions, enabled, recent run outcomes. Read-only — automations cannot be created or edited through this server, only inspected. A sendWebhook action's URL is redacted (it can carry a chat-app incoming-webhook secret).
List a board's cards, in board order by default (column then position). `archived` narrows to false|true|all (default false); `updatedSince` (ISO 8601) narrows to cards changed after it, for incremental sync.
Read a card's checklist: every item plus the total/completed counts the card face shows.
List a board's columns in order — id, title, isDone, statusCategory, position, WIP limit, SLA hours. These columnId values are what a card move expects.
Read a card's discussion, oldest first — the order it happened, and the order an incremental sync appends in.
List deployment history, optionally narrowed to a group and/or environment.
Move a card to another column on the SAME board. Give the target column by id or by title (resolved against the card's own board). For moving to a DIFFERENT board use zuuna_move_card_to_board.
Move a card to a DIFFERENT board (cross-board move). Optional targetColumnId; omitted, the card lands in the target's default column for its current status category.
Report a deployment's progress (building|succeeded|failed|...) or update the one in flight. Idempotent on (environment, externalId) — repeat callbacks from the same CI run update ONE row. groupId binds it to a release/board pipeline; omitted, it is still recorded workspace-wide.
Restore an archived card to active (the inverse of zuuna_archive_card).
Edit a card. Only the fields you send change: title, description, priority, type, dueDate, startDate, estimateSeconds, storyPoints, ready, columnId (move within the SAME board — a cross-board move is zuuna_move_card_to_board), assigneeIds (REPLACES the full set; [] clears everyone), customFields (object keyed by field id; null/empty clears one).
Rename and/or tick a checklist item. Only the fields you send change.
Confirmation pattern incomplete. zuuna_delete_attachment and zuuna_delete_checklist_item require confirm:true, but no dry-run or preview is offered. Agents cannot inspect what will be deleted before confirming.
Pagination not fully documented. zuuna_list_board_cards and zuuna_list_comments accept limit/cursor but descriptions do not explain when pagination is required or what happens if limit is omitted. No guidance on result caps.