| kanbini_list_boardsA | Enumerate every board in the database with id, name, description, archived flag, list/card counts, and updatedAt (epoch ms; blends the board's own timestamp with the most recent activity-log entry for it, so the array sorts by real recency). Use this first to discover boardIds before calling kanbini_get_board. Returns [] if no boards exist. When the desktop app is closed, falls back to the last on-disk export and prefixes the response with a notice. |
| kanbini_get_boardA | Return one Kanbini board view (project, lists, cards, labels). Each card carries number, the short #N the app shows on it (counted per board, so #12 exists on many boards); mention it when you name a card. Archived cards are left out; archived lists are included with closed: true (the app hides them) - kanbini_list_archived lists both. Every other card is returned in full regardless of how the app draws it (collapsed, and each list's cardDensity and visibleCardLimit are display settings). If boardId is omitted, returns the first board; call kanbini_list_boards first if the database may have multiple boards. Returns null if the id does not match anything. When the desktop app is closed, falls back to the last on-disk export. |
| kanbini_get_cardA | Return one Kanbini card by id OR by its number - #142 or 142, the short #N the app shows on the card, which is how the user refers to cards. Numbers are counted per board, so a number needs its boardId (the board the user means; without one this errors and lists the boards that have that number). Numbers handed out before they were per board are gone: look a card up again rather than trusting an old number. Use this to turn a number the user gives you into the card id the write tools need; boardId is ignored for an id. Includes its number and boardId (keep the two together), title, description, priority (low/medium/high/urgent or null), checklists, comments, attachments, recent activity feed, and its "waiting on" links: blockedBy (cards it waits on) and blocking (cards waiting on it), each with title, completed, archived, board, and list. A card is blocked while any blockedBy card is neither completed nor archived. Works for archived cards too (see kanbini_list_archived). Returns null if the id, or the number on that board, does not exist. When the desktop app is closed, falls back to the last on-disk export. |
| kanbini_search_cardsA | Global card search by case-insensitive substring on title, description, and label name; a query like #142 or 142 also finds each board's card with that number (numbers are per board; check boardName). Returns up to limit (default 50, max 100) hits, each carrying cardId + number + title + boardId + boardName + listName + matchedLabels + matchKind ("number" | "title" | "label" | "description") + updatedAt. Sort puts the numbered cards first, then title matches, then label, then description; ties break by recency. Archived cards and closed lists are excluded. Use cardId with kanbini_get_card to fetch full detail for any hit. When the desktop app is closed, falls back to the last on-disk export. |
| kanbini_get_agendaA | What's on the user's plate, across every board in one call. Returns four sections: overdue (open cards due before today), today (open cards due today), upcoming (open cards due in the next upcomingDays, default 7), and completed (cards marked complete today or in the previous completedDays, default 7, newest first). Due sections are ordered soonest first, then by priority. Each item carries cardId, title, boardId, boardName, listName, dueAt (epoch ms, local midnight of the due day), priority, completedAt, and blocked (still waiting on an open card, so it cannot really start yet). totals counts every card per section even when limit (default 50 per section, max 100) trims the arrays. "Today" is the local calendar day on the user's machine; dayStart is its midnight. Archived cards, archived lists, and archived boards are left out. Use this for "what should I work on", "what is overdue", or "what did I get done this week" instead of walking every board. When the desktop app is closed, falls back to the last on-disk export. |
| kanbini_create_boardA | Create a new empty board (no lists, no cards). name is the required board title; description is an optional short blurb shown on the home picker. Returns { id, boardId } - both equal the new board's id. The board is added to Kanbini's default project automatically (projects are hidden in the UI). Add columns next with kanbini_create_list, then populate them with kanbini_create_card. |
| kanbini_create_listA | Create a new list (column) at the right end of a board. Returns { id, boardId }; use the returned id as the listId for kanbini_create_card. Board ids come from kanbini_list_boards or a fresh kanbini_create_board. |
| kanbini_create_cardA | Create a new card at the end of a list. Returns { id, boardId }. Use kanbini_get_board first to find a listId. priority optionally sets one of 'low' | 'medium' | 'high' | 'urgent' at creation (omit for unprioritised); use kanbini_update_card for the description and other fields. Respect a list's wipLimit (visible in the board view): the limit is advisory and not enforced server-side, so check the list's current card count before adding when a limit is set. |
| kanbini_update_cardA | Patch one or more card fields. title and description are strings; description accepts Markdown - use real line breaks for paragraphs and lists (a literal backslash-n renders as text, not a break). dueAt is epoch ms or null to clear. completed toggles the checkbox. coverAttachmentId is the attachment id to use as the cover banner, or null to clear. priority is one of 'low' | 'medium' | 'high' | 'urgent', or null to clear. collapsed only changes how the card is DRAWN in its list: true shows it compact (title, labels, one badge row), false keeps it full even in a compact list, null follows the list's cardDensity. It hides nothing from you - every read still returns the full card - so change it only when the user asks for a tidier board. repeat makes the card repeat: { unit: 'day' | 'week' | 'month' | 'year', every: 1-99 } (e.g. { unit: 'week', every: 2 } for every two weeks), or null to stop. When a repeating card is completed, the app adds the next one to the list it was worked in, due one repeat after the old due date (always in the future), with the same title, description, labels, priority, and unticked checklists; the rule moves to the new card. Omit fields you do not want to change. |
| kanbini_move_cardA | Move a card between lists, or reorder within its current list. toListId is the destination list. beforeId is the id of the card that should sit immediately ABOVE the moved card; afterId is the card immediately BELOW. Pass null/omit either for start/end of list. Server mints a fractional-index position between the two neighbours, so calls never collide. Respect the destination list's wipLimit when one is set (advisory, not enforced server-side - check its card count first). Note: lists with a non-null sortMode order themselves; a move into one lands wherever the sort puts it, not at the requested slot. Card numbers are per board: a move to a list on another board gives the card that board's next number (kanbini_get_card shows it). |
| kanbini_delete_cardA | Permanently delete a card. Its checklists, comments, and attachment rows are removed by the FK cascade. Files attached to the card stay on disk until the GC sweep - they cannot be restored from the UI, so confirm intent before calling. |
| kanbini_set_card_labelsA | Replace the full set of label ids on a card (idempotent). Pass an empty array to remove all labels. Label ids come from the board view's top-level labels[], and must belong to the card's board; make a missing one with kanbini_create_label. |
| kanbini_add_blockerA | Record that card cardId waits on card blockerId (a "blocked by" link). The card shows as blocked in the app until the blocker is completed or archived. The two cards may be on different boards. Adding a link that already exists does nothing. Rejected when both ids are the same card, or when blockerId already waits on cardId directly or through other cards (that would make a loop). A card's links are in the blockedBy and blocking arrays of kanbini_get_card / kanbini_get_board. The user can undo in the app. |
| kanbini_remove_blockerA | Remove the link that makes card cardId wait on card blockerId. Removing a link that doesn't exist does nothing. Neither card changes otherwise. |
| kanbini_post_commentB | Post a comment on a card. Author is automatically set to 'ai' so it renders with the AI badge in the UI (and is distinguishable from human-written comments). Body is Markdown - put real line breaks between paragraphs and list items. A literal backslash-n renders as the text "\n", not a line break. |
| kanbini_create_checklistA | Create a new checklist on a card. Returns { id, boardId }; use the returned id with kanbini_add_checklist_item to populate it. |
| kanbini_add_checklist_itemC | Append an item to an existing checklist. Returns { id, boardId }. |
| kanbini_toggle_checklist_itemC | Set the completed flag on a checklist item. Pass true to mark it done, false to reopen. |
| kanbini_update_boardA | Patch a board. name renames it; description is the short blurb on the home picker (null clears it); color is the board accent shown on its home card and header tint (null clears it); pinned favourites it to the top of the home picker. Omit fields you do not want to change. To archive a board use kanbini_archive_board. Colours: pass a palette name (red, orange, amber, yellow, lime, green, teal, cyan, sky, blue, indigo, purple, pink, rose) so it matches the app's swatch picker. |
| kanbini_update_listA | Patch a list (column). name renames it. color tints the list header and border (null clears it). wipLimit sets a work-in-progress cap - a positive integer, or null to remove it; the app shows the count against the cap and blocks drags past it, but the limit is NOT enforced for writes, so check the card count yourself before adding. sortMode orders the cards: "manual" (drag order, the default), "created-asc"/"created-desc" (card creation time), "added-asc"/"added-desc" (when the card entered this list), "due-asc" (soonest due first, undated last), "title-asc"/"title-desc" (alphabetical), "priority-desc" (urgent first). Switching back to "manual" freezes the current sorted order as the new drag order. onEnter runs when a card is moved INTO this list from another one: "complete" marks it done, "uncomplete" reopens it, null removes the rule. cardDensity "compact" draws every card in the list compact (a card can opt out with kanbini_update_card collapsed: false); "full" is the default. visibleCardLimit shows at most that many cards on screen, then a "Show N more" button (1-1000, or null for all). Both are display only: kanbini_get_board always returns EVERY card with its full content, so never read a limit as the list being shorter. Change them only when the user asks. To reorder lists use kanbini_move_list; to hide one use kanbini_archive_list. Colours: pass a palette name (red, orange, amber, yellow, lime, green, teal, cyan, sky, blue, indigo, purple, pink, rose) so it matches the app's swatch picker. |
| kanbini_move_listA | Move a list (column) to a new position on its board. beforeId is the list that should sit immediately to the LEFT of it; afterId the list immediately to the RIGHT. Omit or pass null for the far left / far right. Both neighbours must be lists on the same board, in their current left-to-right order (get it from kanbini_get_board; closed lists count too, since they keep their slot). |
| kanbini_create_labelA | Create a new label on a board. Labels are board-scoped: the returned id can be put on any card of THAT board with kanbini_set_card_labels. Check the board view's labels[] first so you reuse an existing label instead of making a near-duplicate. Returns { id, boardId }. Colours: pass a palette name (red, orange, amber, yellow, lime, green, teal, cyan, sky, blue, indigo, purple, pink, rose) so it matches the app's swatch picker. |
| kanbini_update_labelA | Patch a label. name renames it and color recolours it - the change shows on every card carrying the label. Omit fields you do not want to change. Colours: pass a palette name (red, orange, amber, yellow, lime, green, teal, cyan, sky, blue, indigo, purple, pink, rose) so it matches the app's swatch picker. |
| kanbini_delete_labelA | Delete a label from its board. It is removed from EVERY card that carries it. The user can undo this in the app (Ctrl+Z), which puts it back on the same cards, but confirm intent first when the label is in use. |
| kanbini_archive_cardA | Archive (archived: true) or restore (archived: false) a card. An archived card disappears from the board, search, and card counts but keeps its list, position, checklists, comments, and attachments, so restoring puts it back exactly where it was. Tell the user the card was archived rather than deleted: they can see and restore it in the app from the board's pencil menu > Archived..., and kanbini_list_archived finds it too. Prefer this over kanbini_delete_card when the user wants a card "out of the way". |
| kanbini_archive_listA | Archive (archived: true) or restore (archived: false) a whole list (column). An archived list is hidden from the board along with every card in it, and its cards drop out of search and counts; nothing is deleted, and restoring brings the list back in its original slot with its cards. Tell the user: they can see and restore it in the app from the board's pencil menu > Archived..., and kanbini_list_archived finds it too. |
| kanbini_archive_boardA | Archive (archived: true) or restore (archived: false) a board. An archived board is hidden from the home picker (the user can still reach it with "Show archived") and its cards drop out of search. Nothing is deleted. kanbini_list_boards still returns archived boards, flagged archived: true. |
| kanbini_list_archivedA | Return what a board has archived: lists (archived lists, with how many live cards are inside) and cards (archived cards, most recently touched first, each with its list name). A card whose listClosed is true sits in an archived list, so restoring the card alone will not make it visible - restore the list too. Use the ids with kanbini_archive_card / kanbini_archive_list (archived: false) to bring things back. Returns null for an unknown boardId. When the desktop app is closed, falls back to the last on-disk export. |
| kanbini_add_attachmentA | Attach a file to a card, from ONE of two sources. (1) path: an absolute path to a local file, which the app copies in (up to 100 MB) - use this for files that already exist on disk. (2) filename + content: inline data you produce yourself, as encoding: "utf8" text (the default - notes, CSV, code) or encoding: "base64" for small binaries (up to 10 MB decoded). The filename's extension sets the file type; unsafe characters are replaced. Returns the stored attachment ({ id, filename, mime, size, ... , boardId }). To show an image as the card's cover, pass the returned id as coverAttachmentId to kanbini_update_card. |
| kanbini_delete_attachmentA | Delete an attachment from its card, including the stored file. If it was the card's cover, the cover is cleared. The user can undo this in the app (Ctrl+Z) but the undo restores only the entry, NOT the file, so confirm intent first. Attachment ids come from kanbini_get_card. |