# ernestocorona/kanboard-mcp [Health: Active]

**Category:** 🏢 Workplace & Productivity  
**Repository:** https://github.com/ErnestoCorona/kanboard-mcp  
**GitHub Stars:** 8  
**npm Downloads (last month):** 84  
**Views:** 3  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/ernestocorona-kanboard-mcp

## Description
TypeScript MCP server for Kanboard with multi-project routing via .kanboard.yaml. 37 tools, 982 unit tests, Docker multi-arch on GHCR, provenance-signed npm releases via OIDC, Diátaxis-structured docs, MIT licensed.

## Tools
Capabilities this server exposes over MCP:

- **add_project_user** — Add a user to a Kanboard project with the given role. Role defaults to 'project-member' if not specified. Use list_project_users to find user ids and list_projects to find project ids; to unlink a member use remove_project_user. Returns { user_id, project_id, role } on success.
- **attach_file_to_task** — Upload a file to a Kanboard task as an attachment. Provide either file_path (local file) or content_base64 (inline base64 content) — not both. project_id is resolved automatically from the task (no need to provide it). Maximum file size: 5 MB (5,242,880 bytes) — larger files return VALIDATION_ERROR before any HTTP request is made. Returns { file_id } on success.
- **close_task** — Close (archive) an active Kanboard task. The task is set inactive and leaves the active board but is preserved — this is NOT a delete. Reversible: restore it with reopen_task. To permanently remove a task instead, use delete_task. Returns { ok: true, task_id } on success.
- **create_column** — Add a column to a Kanboard project board. Project resolved from explicit project_id/project_identifier or .kanboard.yaml. To reorder it use move_column, to rename or change its WIP limit use update_column, to remove it use delete_column. Returns { column_id } on success.
- **create_comment** — Create a comment on a Kanboard task. The comment author is automatically set to the authenticated user (via getMe() cache); do NOT pass user_id — it is injected server-side. To edit a comment's body use update_comment; to remove one use delete_comment. Returns { comment_id } on success.
- **create_project** — Create a new Kanboard project. Requires a name (1–255 chars). Optionally provide a description, short identifier, owner user id, start_date / end_date (ISO 8601 string or epoch seconds), and email. After creating, adjust the board with create_column / create_swimlane, add members with add_project_user, and edit attributes with update_project. Returns { project_id } on success.
- **create_subtask** — Create a subtask under an existing Kanboard task. Status: 0 = todo (default), 1 = in progress, 2 = done. To list a task's subtasks use list_subtasks; to edit one use update_subtask. Returns { subtask_id, task_id } on success.
- **create_swimlane** — Add a swimlane to a Kanboard project. Project resolved from explicit project_id/project_identifier or .kanboard.yaml. To reorder it use move_swimlane, to rename it use update_swimlane, to remove it use delete_swimlane. Returns { swimlane_id } on success.
- **create_task** — Create a new task in a Kanboard project. Project is resolved from explicit project_id or project_identifier, or from .kanboard.yaml. Optional fields (column_id, owner_id, category_id, swimlane_id) fall back to .kanboard.yaml defaults when not provided. To create many tasks at once use create_tasks_batch; to move the task afterward use move_task_position. Returns { task_id, project_id } on success.
- **create_tasks_batch** — Bulk-create tasks in a Kanboard project using a single JSON-RPC batch request. Accepts 1–100 tasks per call. Non-atomic: partial failure is possible — check failed[] for per-task errors. Optional fields (column_id, owner_id, category_id, swimlane_id) fall back to .kanboard.yaml defaults when not provided. Returns { created: [...], failed: [...] } — never throws on partial failure.
- **delete_column** — Permanently delete a Kanboard column from a project board. DESTRUCTIVE and irreversible — requires explicit `confirm: true`. To rename a column or change its WIP limit use update_column; to reorder it use move_column. Returns { ok: true, column_id } on success.
- **delete_comment** — Permanently delete a Kanboard comment. DESTRUCTIVE and irreversible — requires explicit `confirm: true`. To edit a comment's text instead of deleting it use update_comment. Returns { ok: true, comment_id } on success.
- **delete_project** — Permanently delete a Kanboard project and all its tasks, columns, and swimlanes. DESTRUCTIVE and irreversible — requires explicit `confirm: true`. To remove only a member use remove_project_user; to edit project attributes use update_project. Returns { ok: true, project_id } on success.
- **delete_subtask** — Permanently delete a Kanboard subtask. DESTRUCTIVE and irreversible — requires explicit `confirm: true`. To mark a subtask done instead of deleting it, set status=2 via update_subtask. Returns { ok: true, subtask_id } on success.
- **delete_swimlane** — Permanently delete a Kanboard swimlane from a project. DESTRUCTIVE and irreversible — requires explicit `confirm: true`. To rename a swimlane use update_swimlane; to reorder it use move_swimlane. Returns { ok: true, swimlane_id } on success.
- **delete_task** — Permanently delete a Kanboard task. DESTRUCTIVE and irreversible — requires explicit `confirm: true`. Returns { ok: true, task_id } on success.
- **delete_task_file** — Permanently delete a file attachment from a Kanboard task. DESTRUCTIVE and irreversible — requires explicit `confirm: true`. To add an attachment use attach_file_to_task. Returns { ok: true, file_id } on success.
- **get_project** — Retrieve a single Kanboard project. Provide exactly one of: project_id (number), project_identifier (short string like 'PRJ'), or project_name (full name). Returns the full project object. Returns NOT_FOUND when no match exists.
- **get_task** — Retrieve a single Kanboard task by its numeric id. Returns the full task entity including status, dates, column, swimlane, and metadata. Returns NOT_FOUND when the task does not exist.
- **list_categories** — List all categories for a Kanboard project. Provide project_id or project_identifier, or configure .kanboard.yaml in your project root. Returns an array of category objects with id, name, and color_id.
- **list_columns** — List all columns (board stages) for a Kanboard project. Provide project_id or project_identifier, or configure .kanboard.yaml in your project root. Returns an array of column objects with id, title, position, and task_limit.
- **list_my_tasks** — List open tasks assigned to the currently authenticated user in the resolved project. Requires a project_id (explicit or from .kanboard.yaml). Uses Kanboard search query: assignee:me status:open. In app mode (jsonrpc user) returns tasks assigned to the jsonrpc system user. Returns { tasks } on success.
- **list_overdue_tasks** — List overdue tasks with configurable scope. scope="mine" (default): overdue tasks for the authenticated user. scope="all": all overdue tasks across all projects (admin token required). scope="project": overdue tasks for a specific project (pass project_id or use .kanboard.yaml). Note: getOverdueTasksByUser is not supported by the Kanboard JSON-RPC API. Returns an empty array when nothing is overdue.
- **list_projects** — Returns the projects where the authenticated user is a member. Does not list projects in the Kanboard instance that the user has no access to. Returns an array of project objects with id, name, identifier, and status.
- **list_subtasks** — List all subtasks for a given Kanboard task. Returns an array of subtask objects including id, title, status, user_id, time_estimated, and time_spent fields.
- **list_swimlanes** — List active swimlanes for a Kanboard project. Provide project_id or project_identifier, or configure .kanboard.yaml in your project root. Returns an array of swimlane objects with id, name, description, position, and is_active.
- **list_tasks** — List tasks in a Kanboard project. Returns active tasks by default (status_id=1). Pass status_id=0 to list closed/inactive tasks. Project is resolved from explicit project_id or project_identifier, or from .kanboard.yaml.
- **list_project_users** — List the members of a Kanboard project (user_id + username pairs). Provide project_id or project_identifier, or configure .kanboard.yaml in your project root. Works for any user who can see the project — does not require admin permissions. Use the returned user_ids to assign tasks (create_task owner_id), add comments, etc.
- **move_column** — Reorder a column on the Kanboard project board. Provide column_id and the new 1-based position (required — no default). Only ordering changes — to rename a column or change its WIP limit use update_column. Returns { ok: true, column_id, position } on success.
- **move_swimlane** — Reorder a swimlane within a Kanboard project. Provide swimlane_id and the new 1-based position (required — no default). Only ordering changes — to rename a swimlane use update_swimlane. Returns { ok: true, swimlane_id, position } on success.
- **move_task_position** — Move a Kanboard task to a different column, position, or swimlane — this is the only way to change a task's board placement. Provide exactly one of column_id or column_name (column_name is resolved case-insensitively). If swimlane_id is omitted, it is resolved from .kanboard.yaml or the first active swimlane. Project is resolved from explicit project_id or project_identifier, or from .kanboard.yaml. To change other task attributes (title, dates, owner) use update_task instead. Returns { ok: true, task_id, column_id, swimlane_id, position } on success.
- **remove_project_user** — Unlink a user from a Kanboard project (does not delete the user). DESTRUCTIVE on the project-user relationship — requires explicit `confirm: true`. Returns { ok: true, project_id, user_id } on success.
- **reopen_task** — Reopen a closed (inactive) Kanboard task, restoring it to the active board. The inverse of close_task. Returns { ok: true, task_id } on success.
- **update_column** — Update an existing Kanboard column (partial update). Only the fields you pass are changed; omitted fields keep their current values, and validation runs before any write, so an invalid call modifies nothing. At least one field besides 'column_id' must be provided — otherwise VALIDATION_ERROR. NOT for reordering — use move_column instead; to delete a column use delete_column. Returns { ok: true, column_id } on success.
- **update_comment** — Update the body of an existing Kanboard comment. To remove a comment use delete_comment instead. Returns { ok: true, comment_id } on success.
- **update_project** — Update the attributes of an existing Kanboard project (partial update). Only the fields you pass are changed; omitted fields keep their current values, and validation runs before any write, so an invalid call modifies nothing. At least one field besides 'project_id' must be provided — otherwise VALIDATION_ERROR. This tool updates project attributes only: to manage members use add_project_user / remove_project_user, to manage columns use create_column / move_column, and to delete a project use delete_project. Returns { ok: true, project_id } on success.
- **update_subtask** — Update an existing Kanboard subtask (partial update). Only the fields you pass are changed; omitted fields keep their current values, and validation runs before any write, so an invalid call modifies nothing. Both 'subtask_id' and 'task_id' are required as identity fields. At least one of title, status, user_id, time_estimated, or time_spent must also be provided. Status: 0 = todo, 1 = in progress, 2 = done. Returns { subtask_id, task_id } on success.
- **update_swimlane** — Update an existing Kanboard swimlane (partial update). Only the fields you pass are changed; omitted fields keep their current values, and validation runs before any write, so an invalid call modifies nothing. At least one field besides 'swimlane_id' must be provided — otherwise VALIDATION_ERROR. NOT for reordering — use move_swimlane instead; to delete a swimlane use delete_swimlane. Returns { ok: true, swimlane_id } on success.
- **update_task** — Update the attributes of an existing Kanboard task (partial update). Only the fields you pass are changed; omitted fields keep their current values, and validation runs before any write, so an invalid call modifies nothing. At least one field besides 'task_id' must be provided — otherwise VALIDATION_ERROR. Column and swimlane changes must use move_task_position instead. Returns { ok: true, task_id } on success.

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `npx` (confidence: high):

```json
"mcpServers": {
  "kanboard-mcp": {
    "command": "npx",
    "args": ["-y","@ernestocorona/kanboard-mcp"],
    "env": {
      "KANBOARD_URL": "",
      "KANBOARD_USERNAME": "",
      "KANBOARD_API_TOKEN": ""
    }
  }
}
```

**Requires environment variables:** `KANBOARD_URL`, `KANBOARD_USERNAME`, `KANBOARD_API_TOKEN` — the values above are empty placeholders; fill in real credentials before running (see the repository for what each one is for).

## Documentation

## What ernestocorona/kanboard-mcp MCP server does

The ernestocorona/kanboard-mcp MCP server connects an MCP client to a Kanboard instance and exposes tools for reading and changing project data. Its operations cover projects, columns, swimlanes, tasks, subtasks, comments, file attachments, categories, and project members. Agents can inspect projects and tasks, create or update work items, assign users, manage board structure, and retrieve overdue or personally assigned tasks.

Project context can be supplied with a numeric project ID or a short project identifier. Several tools can instead resolve the project from a `.kanboard.yaml` file in the project root. That file can also provide defaults for task fields such as the column, owner, category, and swimlane.

## How it works

The ernestocorona/kanboard-mcp MCP server communicates with clients over MCP stdio and calls Kanboard through its JSON-RPC API. It supports two authentication patterns: a personal token that represents the authenticated Kanboard user, and an application token for a service identity such as a bot or CI process. The authenticated identity affects visible projects, task ownership, comments, and user-scoped queries.

Task creation supports both individual requests and JSON-RPC batching. `create_tasks_batch` accepts between 1 and 100 tasks in one call, but the operation is non-atomic: some tasks can succeed while others fail, so callers should inspect both result arrays. Read requests retry on selected transient HTTP responses, while mutations are not retried. Each request has a timeout, configurable through `KANBOARD_TIMEOUT_MS`, with a default of 15 seconds.

## Setup and configuration

The package is published as `@ernestocorona/kanboard-mcp` and requires Node.js 22 or later. A direct MCP client configuration can run it with:

```json
{
  "command": "npx",
  "args": ["-y", "@ernestocorona/kanboard-mcp"],
  "env": {
    "KANBOARD_URL": "https://kanboard.example.com",
    "KANBOARD_USERNAME": "your-login",
    "KANBOARD_API_TOKEN": "your-token"
  }
}
```

`KANBOARD_URL`, `KANBOARD_USERNAME`, and `KANBOARD_API_TOKEN` identify the Kanboard endpoint and credentials. The server can also run from the published multi-architecture Docker image on GHCR, or from a source checkout after building the project. It is ESM-only. The `selftest` command checks the server version, authentication, and visible projects.

## Tools and capabilities

The available tools include:

- List projects, project users, categories, columns, swimlanes, tasks, subtasks, and overdue work.
- Create, update, move, close, reopen, and permanently delete projects and work items where supported.
- Create up to 100 tasks in a batch and report per-task failures.
- Add, edit, and remove comments, plus upload or delete task attachments.
- Add project members with a role and reorder columns or swimlanes.

Attachments accept either a local file path or inline Base64 content, but not both, and are limited to 5 MB. Closed tasks remain preserved and can be reopened; deletion is a separate permanent operation.

## Limitations and notes

Destructive operations require an explicit `confirm: true` value and cannot be undone through the server. This applies to deleting projects, tasks, subtasks, columns, swimlanes, comments, and task files. Batch task creation can leave partial results after an error. Some queries depend on Kanboard permissions: listing visible projects only returns projects the authenticated user can access, and listing all overdue tasks requires an administrator token.

The server does not retry mutations, so callers should avoid automatically repeating a write after an uncertain network failure without checking the result. MCP clients must keep the process stdin connected when using stdio; Docker runs require the interactive stdin flag. Logs use structured output with secret redaction, but credentials should still be provided through environment configuration rather than task prompts.

_Full upstream README: https://allmcps.com/mcp/ernestocorona-kanboard-mcp/readme_

