Skip to main content
Glama

πŸ“‹ Kanboard MCP

Kanboard, plug-and-play in any AI editor.

A Model Context Protocol server that brings your Kanboard board into Claude Code, Claude Desktop, Cursor, Cline, Zed, and beyond β€” so your agent can read, plan, and update tasks the same way you would.

39 typed tools Β· JSON-RPC batching Β· Dual authentication Β· TypeScript strict Β· 1016 tests

npm version License: MIT Node.js >=22 Tests TypeScript Strict MCP Compatible

Originally developed at aisys-media GmbH


What it looks like

Kanboard MCP in action β€” an agent turning a customer email into a Mobile sprint backlog via JSON-RPC batching

You:    Take this customer email and turn it into a Mobile sprint backlog.

Claude (via kanboard-mcp):
  β†’ list_projects()                    βœ“ resolved "Mobile" = #42
  β†’ list_columns(42)                   βœ“ Backlog = #588
  β†’ create_tasks_batch(42, [...])      βœ“ 8 tasks created in #42/Backlog
  β†’ list_my_tasks()                    βœ“ priorities re-sorted

Done β€” 8 tasks in Mobile/Backlog, sorted by priority.
Top 3:  "Fix login error on iOS 18.2"  (P1)
        "Flaky CI on PR #1247"          (P1)
        "Onboarding redesign review"    (P2)

The same flow works for every kind of board work β€” pulling overdue tasks, opening a daily standup summary, breaking a doc into subtasks, or updating a comment on someone's PR. The agent picks the tools, you stay in the loop.


Related MCP server: Harbor MCP

Why Kanboard MCP

  • 39 typed tools across 9 groups β€” full CRUD on projects, columns, swimlanes, tasks, subtasks, comments, attachments, and members. No half-supported entities, no read-only stubs.

  • JSON-RPC 2.0 batching β€” create up to 100 tasks in one HTTP round-trip. Turn an email, a meeting transcript, or a doc into a sprint backlog in seconds.

  • Dual authentication β€” personal token (acts as you, with your Kanboard identity) or application token (service identity for CI, bots, and shared agents).

  • Walk-up project resolver β€” drop one .kanboard.yaml at your repo root, every tool auto-resolves the project context. Switch repos, your agent switches boards.

  • Zero runtime HTTP dependencies β€” native Node 22 fetch, 4 production deps total. Audit surface is intentionally tiny.

  • Pino structured logging with automatic secret redaction β€” token values never reach stdout, stderr, or any log line, at any log level.

  • TypeScript strict mode + 1016 unit tests across 65 test files. Integration suite gated against accidental writes to non-sandbox projects.

  • Smart retries for reads only β€” idempotent calls retry transparently on transient HTTP failures (429 / 502 / 503 / 504); mutations never retry.

  • Hard per-request timeouts β€” every JSON-RPC call runs under AbortSignal.timeout() (default 15 s, configurable via KANBOARD_TIMEOUT_MS). Requests cannot hang the agent indefinitely β€” slow or unresponsive backends surface as a clean TimeoutError your agent can recover from.

  • Debuggable from day one β€” speaks plain MCP over stdio, so the official MCP Inspector works out of the box. Inspect schemas, fire individual tool calls, watch JSON-RPC traffic in a browser UI. See Debugging with MCP Inspector.

60-second quick start

Kanboard MCP setup β€” drop a JSON config block, run the selftest, see four green checks, you're done

1. Get a Kanboard API token

In Kanboard: Profile β†’ API β†’ Generate token (personal mode), or Settings β†’ API β†’ Application token (app mode for service accounts).

2. Add Kanboard MCP to your client

Recommended path: npx β€” zero install, always latest. Drop this block into your MCP client config:

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

Restart your MCP client. Done β€” the 39 tools are now available to your agent.

Why npx? It fetches @ernestocorona/kanboard-mcp from npm on demand, caches it locally, and runs it as the MCP server. You never run a separate install command, and you always get the latest published version β€” no upgrade chore, no $PATH to manage. This is also why step 3's selftest works without any prior install: npx handles the fetch transparently.

3. Verify

KANBOARD_URL=https://your-kanboard.example.com \
KANBOARD_USERNAME=your-login \
KANBOARD_API_TOKEN=your-token \
npx @ernestocorona/kanboard-mcp selftest

Expected output (exit 0 = ready):

[ok] kanboard server version: 1.x.x
[ok] authenticated as: your-login (id=3)
[ok] visible projects: 7
[ok] selftest passed (3 checks)

Documentation

Full docs live in ./docs/ and follow the DiΓ‘taxis framework:

  • Tutorials β€” hand-held walkthroughs to learn by doing.

  • How-to guides β€” recipes for batching, multi-project setups, integration tests, and CI.

  • Reference β€” exact contracts for every tool, every config knob, and every error.

  • Explanation β€” the why behind authentication modes, the retry policy, and the batch architecture.

Start at the docs index to pick the right entry point.

Installation methods

Just want it working? Use the npx row (first entry below) β€” it's the recommended path for the vast majority of users. The other methods exist for specific use cases (frequent local runs, Bun/pnpm runtimes, production deployments, or hacking on the source).

Method

When to use

Command

npx (recommended)

Most users. Zero install, always uses the latest published version.

npx -y @ernestocorona/kanboard-mcp

Global install

You run the server frequently and want a stable binary on $PATH.

npm i -g @ernestocorona/kanboard-mcp then kanboard-mcp

bunx / pnpm dlx

You use Bun or pnpm as your runner. Same package, same behavior.

bunx @ernestocorona/kanboard-mcp

Docker (GHCR)

Production-style deployment, CI agents, isolated environments. Multi-arch image (linux/amd64, linux/arm64), runs as non-root.

docker run -i --rm -e KANBOARD_URL -e KANBOARD_USERNAME -e KANBOARD_API_TOKEN ghcr.io/ernestocorona/kanboard-mcp:latest

Clone + node

You want to fork, hack, or run from source.

git clone … β†’ npm i β†’ npm run build β†’ node dist/index.js

Heads up: the package is ESM-only and requires Node β‰₯ 22. Older Node versions will fail at startup.

Run with Docker

The published image (ghcr.io/ernestocorona/kanboard-mcp) is built for linux/amd64 and linux/arm64, runs as the non-root node user, and speaks MCP over stdio β€” exactly like the npm version. Point your client at docker instead of npx:

{
  "mcpServers": {
    "kanboard": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-e", "KANBOARD_URL",
        "-e", "KANBOARD_USERNAME",
        "-e", "KANBOARD_API_TOKEN",
        "ghcr.io/ernestocorona/kanboard-mcp:latest"
      ],
      "env": {
        "KANBOARD_URL": "https://your-kanboard.example.com",
        "KANBOARD_USERNAME": "your-kanboard-login",
        "KANBOARD_API_TOKEN": "your-personal-token"
      }
    }
  }
}

The -i flag is mandatory β€” MCP needs stdin attached to pipe JSON-RPC frames. --rm keeps the container ephemeral. Pin to a specific tag (:0.3, :0.3.2) in production instead of :latest.

Compatible MCP clients

MCP is a transport-level standard. The same JSON snippet from the quick start works in every client below β€” only the file path differs.

Client

Config file

Claude Code

.mcp.json (per-project) or ~/.claude.json (global)

Claude Desktop

~/Library/Application Support/Claude/claude_desktop_config.json (macOS) Β· %APPDATA%\Claude\claude_desktop_config.json (Windows)

Cursor

.cursor/mcp.json (per-project) or ~/.cursor/mcp.json (global)

Cline (VS Code extension)

VS Code β†’ Cline panel β†’ MCP Servers β†’ Add

Zed

~/.config/zed/settings.json β†’ context_servers block

Continue (VS Code / JetBrains)

~/.continue/config.json

Goose (Block)

~/.config/goose/profiles.yaml

Windsurf (Codeium)

~/.codeium/windsurf/mcp_config.json

If your editor speaks MCP stdio, this server works in it. If it doesn't speak MCP at all yet (some chat tools still don't), it can't be plugged in until support lands upstream.

Application mode (service identity)

For CI pipelines, bots, and shared agents β€” use Kanboard's protocol-level jsonrpc user instead of a human account:

{
  "mcpServers": {
    "kanboard": {
      "command": "npx",
      "args": ["-y", "@ernestocorona/kanboard-mcp"],
      "env": {
        "KANBOARD_URL": "https://your-kanboard.example.com",
        "KANBOARD_AUTH_MODE": "app",
        "KANBOARD_API_TOKEN": "your-application-token"
      }
    }
  }
}

In app mode, KANBOARD_USERNAME is not required and is ignored. Comments and tasks created via app mode are authored by the jsonrpc system user.

Project context with .kanboard.yaml

Drop a .kanboard.yaml at your repo root and every tool that needs a project auto-resolves it. The server walks up from cwd (stops at $HOME or git root):

# Use exactly one β€” they are mutually exclusive
project_id: 12
# project_identifier: "MYPROJ"

# Optional defaults, override per call if needed
default_column_id: 2
default_swimlane_id: 1
default_owner_id: 5
default_category_id: 3

You can still override per call by passing project_id explicitly. The file is cached for the process lifetime β€” restart the server to pick up changes.

Tool catalog

39 tools across 9 groups. Each one ships with a strict Zod schema for inputs and outputs β€” inputs are validated before any HTTP request; outputs are parsed into a stable, type-safe contract regardless of Kanboard's per-version response shape.

Project Management (8 tools)

Tool

Description

Example Usage

list_projects

List projects you can access

"Show me all my projects"

get_project

Fetch project details by id or identifier

"Show me the Backend project"

create_project

Create a new project

"Create a project called Mobile App"

update_project

Rename or update project metadata

"Rename the V1 project to V2"

delete_project

Permanently delete a project (requires confirmation)

"Delete the archived Sprint 1 project"

add_project_user

Grant a user access with a role

"Add Maria as manager to Mobile"

remove_project_user

Revoke a user's access (requires confirmation)

"Remove John from the Backend project"

list_project_users

List members and their roles

"Who has access to the Backend project?"

Column Management (5 tools)

Tool

Description

Example Usage

list_columns

List board columns in order

"Show me the columns of the Mobile board"

create_column

Add a new column

"Add a 'QA Review' column to Mobile"

update_column

Rename or modify a column

"Rename 'WIP' to 'In Progress'"

move_column

Reorder columns

"Move 'QA Review' before 'Done'"

delete_column

Remove a column (requires confirmation)

"Delete the empty 'On Hold' column"

Swimlane Management (5 tools)

Tool

Description

Example Usage

list_swimlanes

List project swimlanes

"Show me all team swimlanes"

create_swimlane

Add a team or workstream swimlane

"Create a 'Frontend Team' swimlane"

update_swimlane

Rename or modify a swimlane

"Rename Mobile Team to Cross-Platform Team"

move_swimlane

Reorder swimlanes

"Move Backend Team above Frontend"

delete_swimlane

Remove a swimlane (requires confirmation)

"Delete the inactive team swimlane"

Task Management (10 tools)

Tool

Description

Example Usage

list_tasks

List active or closed tasks in a project

"Show me all open tasks in Mobile"

get_task

Fetch full task details with metadata

"Show me task #1234"

create_task

Create a single task

"Create 'Fix login bug' in Backlog"

update_task

Edit any task field, move column, assign owner

"Move task #1234 to In Progress and assign it to me"

delete_task

Permanently delete a task (requires confirmation)

"Delete task #1234"

close_task

Archive a task off the active board β€” reversible, not a delete

"Close task #1234"

reopen_task

Restore a closed task to the active board

"Reopen task #1234"

move_task_position

Reposition a task within or across columns

"Move task #1234 to the top of Done"

list_my_tasks

List tasks assigned to the authenticated user

"What's on my plate?"

list_overdue_tasks

List all tasks past their due date

"Show me what's overdue"

Batch Operations (1 tool)

Tool

Description

Example Usage

create_tasks_batch

Create up to 100 tasks in a single JSON-RPC round-trip

"Turn this email thread into a sprint backlog"

Subtask Management (4 tools)

Tool

Description

Example Usage

list_subtasks

List subtasks of a task

"Show me the subtasks of #1234"

create_subtask

Add a subtask

"Add 'Write tests' as a subtask of #1234"

update_subtask

Edit a subtask or change its status

"Mark subtask #56 as done"

delete_subtask

Remove a subtask (requires confirmation)

"Delete subtask #56"

Comment Management (3 tools)

Tool

Description

Example Usage

create_comment

Add a comment to a task

"Comment 'Blocked on design review' on #1234"

update_comment

Edit one of your comments

"Update my last comment on #1234"

delete_comment

Remove your comment (requires confirmation)

"Delete my last comment on #1234"

Attachment Management (2 tools)

Tool

Description

Example Usage

attach_file_to_task

Attach a file by path or base64, 5 MB cap

"Attach this design.png to #1234"

delete_task_file

Remove an attachment (requires confirmation)

"Delete the old spec.pdf from #1234"

Lookups (1 tool)

Tool

Description

Example Usage

list_categories

List task categories defined in a project

"Show me all task categories"

Destructive tools (delete_*, remove_*) require an explicit confirmation: true flag in the input. Without it, the tool refuses and returns a structured error β€” your agent can't accidentally wipe a project on a typo.

Configuration

Environment variables

Variable

Required

Default

Description

KANBOARD_URL

Yes

β€”

Base URL of your Kanboard instance, e.g. https://kanboard.example.com

KANBOARD_API_TOKEN

Yes

β€”

API token (personal or application, depending on auth mode)

KANBOARD_AUTH_MODE

No

personal

personal (acts as a Kanboard user) or app (service identity)

KANBOARD_USERNAME

personal mode only

β€”

Your Kanboard login username

KANBOARD_TIMEOUT_MS

No

15000

Per-request HTTP timeout in milliseconds

LOG_LEVEL

No

info

Pino log level: trace, debug, info, warn, error, fatal

Required variables are validated at startup. Missing or invalid values cause an immediate non-zero exit before any tool is registered or any network call is made.

.kanboard.yaml schema

project_id: 12                    # numeric project ID
# OR
project_identifier: "MYPROJ"      # string identifier (alphanumeric, dash, underscore)

# Optional defaults
default_column_id: 2
default_swimlane_id: 1
default_owner_id: 5
default_category_id: 3

project_id and project_identifier are mutually exclusive β€” exactly one must be set.

Security

Defaults are designed to fail safe:

  • Access control is Kanboard's job β€” each user runs the server with their own personal token; every tool call is authorized against Kanboard's existing project ACL. There is no parallel permission system to maintain or drift out of sync β€” if a user cannot see a project in Kanboard's UI, the MCP cannot see it either. Application mode is reserved for service identities (CI pipelines, bots, shared agents). See The access-control model.

  • Token storage β€” keep KANBOARD_API_TOKEN in .env (gitignored) or in your MCP client's env block. Never paste a token into chat or commit one to a repository.

  • Automatic redaction β€” the Pino logger redacts apiToken, req.headers.authorization, *.token, *.secret, and credentials.apiToken from every log line at every log level. Token values never appear verbatim in any output.

  • Stdout reserved for MCP β€” all logging goes to stderr exclusively. Stdout is the MCP protocol channel β€” no leaks possible there.

  • Destructive tools require confirmation β€” every delete_* and remove_* tool refuses to run unless the caller passes confirmation: true. This is enforced at the schema layer, not at runtime.

  • Integration test gating β€” integration tests refuse to run unless RUN_INTEGRATION=1 and KANBOARD_TEST_PROJECT_ID are set, AND the target project name contains "sandbox" or "test". The suite aborts before any write request if these conditions aren't met.

  • Auth errors fail loud β€” if getMe() fails at startup (wrong personal token), the server exits β€” it never falls back silently to a default identity.

  • Token rotation β€” rotate your Kanboard API token regularly. The server picks up the new token on next start; no in-memory cache to invalidate.

For vulnerability disclosure, see SECURITY.md.

Roadmap

  • v0.3.x (current) β€” full CRUD across all entities; destructive tools behind confirmation flag; 1016 tests; production-ready stdio transport; official multi-arch Docker image on GHCR.

  • v0.4 β€” HTTP/SSE transport for team deployments; multi-tenant per-user authentication via headers.

  • v0.5 β€” webhooks support; IMAP inbox watcher (email-to-task ingestion); webhook-driven notifications back to Kanboard.

Development

git clone https://github.com/ErnestoCorona/kanboard-mcp.git
cd kanboard-mcp
npm install

npm run typecheck       # tsc --noEmit (TypeScript strict mode)
npm run lint            # ESLint flat config
npm run lint:fix        # ESLint with auto-fix
npm run test            # 1016 unit tests, no network (default for `npm test`)
npm run test:int        # integration tests (requires .env + RUN_INTEGRATION=1)
npm run build           # tsup ESM bundle β†’ dist/
npm run dev             # tsup watch mode
npm run selftest        # smoke test against live Kanboard

Integration tests

Set up a .env (copy from .env.example) pointing to a Kanboard project whose name contains sandbox or test:

RUN_INTEGRATION=1
KANBOARD_URL=https://your-kanboard.example.com
KANBOARD_USERNAME=your-login
KANBOARD_API_TOKEN=your-token
KANBOARD_TEST_PROJECT_ID=42

All test entities are prefixed [TEST-{ISO-timestamp}] and cleaned up by the suite's afterAll hook using the v0.3 destructive tools.

Debugging with MCP Inspector

The fastest way to poke at the server by hand β€” list tool schemas, fire individual calls, and watch the JSON-RPC envelopes β€” is the official MCP Inspector:

KANBOARD_URL=https://your-kanboard.example.com \
KANBOARD_USERNAME=your-login \
KANBOARD_API_TOKEN=your-token \
npx @modelcontextprotocol/inspector -- npx -y @ernestocorona/kanboard-mcp

The -- is required β€” the Inspector CLI consumes flags like -e and -y for its own use, so we tell it explicitly that everything after -- belongs to the spawned MCP server command.

The Inspector opens a local UI (default http://127.0.0.1:6274) with all 39 tools under the Tools tab, each one carrying its full Zod-derived schema. See the full how-to for environment passthrough, app-mode setup, and common gotchas.

Pre-commit

The repo uses husky + gitleaks to block commits containing secrets, plus commitlint on the commit-msg hook to enforce Conventional Commits. Run npm install once after cloning to install hooks.

Troubleshooting

npm run selftest exit-code propagation under tsx

scripts/preflight.sh runs npm run selftest, which delegates to tsx src/cli/selftest.ts. On some host setups, tsx (invoked through the npm wrapper) does not always propagate a non-zero process.exit(N) from the script back to the parent shell β€” so preflight.sh may report exit 0 even when the selftest actually failed internally.

This is a pre-existing tsx / npm behaviour, not specific to kanboard-mcp. Workarounds:

  • Re-run scripts/preflight.sh two or three times before npm publish and confirm a clean run each time.

  • Or check the selftest output explicitly for the selftest pass line on stderr before trusting the exit code.

If you need a hard guarantee, run npx tsx src/cli/selftest.ts directly (without the npm wrapper) β€” that path tends to propagate exit codes more reliably.

Contributing

Issues and pull requests are welcome. Please read CONTRIBUTING.md before opening a PR. All contributors are expected to follow the Code of Conduct.

License

MIT Β© Ernesto Corona

Acknowledgments

This project was originally developed at aisys-media GmbH (WΓΌrzburg, Germany) and is released as open source with their permission. Thanks to the team for the green light to share this work with the wider community.

Author

Ernesto Corona β€” senior architect, TypeScript / Node / MCP servers. GitHub Β· npm

Available Tools

39 tools
add_project_userA

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.

Inputs: project_id (required), user_id (required), role.

attach_file_to_taskA

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.

Inputs: task_id (required), filename (required), file_path, content_base64.

close_taskA

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.

Inputs: task_id (required).

create_columnA

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.

Inputs: title (required), project_id, project_identifier, task_limit, +1 more.

create_commentA

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.

Inputs: task_id (required), content (required), reference, visibility.

create_projectA

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.

Inputs: name (required), description, identifier, owner_id, +3 more.

create_subtaskA

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.

Inputs: task_id (required), title (required), user_id, time_estimated, +2 more.

create_swimlaneA

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.

Inputs: name (required), project_id, project_identifier, description.

create_taskA

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.

Inputs: title (required), project_id, project_identifier, description, +12 more.

create_tasks_batchA

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.

Inputs: tasks (required), project_id, project_identifier.

delete_columnA

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.

Inputs: column_id (required), confirm (required).

delete_commentA

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.

Inputs: comment_id (required), confirm (required).

delete_projectA

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.

Inputs: project_id (required), confirm (required).

delete_subtaskA

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.

Inputs: subtask_id (required), confirm (required).

delete_swimlaneA

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.

Inputs: swimlane_id (required), confirm (required).

delete_taskA

Permanently delete a Kanboard task. DESTRUCTIVE and irreversible β€” requires explicit confirm: true. Returns { ok: true, task_id } on success.

Inputs: task_id (required), confirm (required).

delete_task_fileA

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.

Inputs: file_id (required), confirm (required).

get_projectA

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.

Inputs: project_id, project_identifier, project_name.

get_taskA

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.

Inputs: task_id (required).

list_categoriesA

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.

Inputs: project_id, project_identifier.

list_columnsA

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.

Inputs: project_id, project_identifier.

list_my_tasksA

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.

Inputs: project_id, project_identifier.

list_overdue_tasksA

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.

Inputs: scope, project_id, project_identifier.

list_projectsA

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.

Inputs: no named parameters.

list_project_usersA

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.

Inputs: project_id, project_identifier.

list_subtasksA

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.

Inputs: task_id (required).

list_swimlanesA

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.

Inputs: project_id, project_identifier.

list_tasksA

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.

Inputs: project_id, project_identifier, status_id.

move_columnA

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.

Inputs: column_id (required), position (required).

move_swimlaneA

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.

Inputs: swimlane_id (required), position (required).

move_task_positionA

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.

Inputs: task_id (required), project_id, project_identifier, column_id, +3 more.

remove_project_userA

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.

Inputs: project_id (required), user_id (required), confirm (required).

reopen_taskA

Reopen a closed (inactive) Kanboard task, restoring it to the active board. The inverse of close_task. Returns { ok: true, task_id } on success.

Inputs: task_id (required).

update_columnA

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.

Inputs: column_id (required), title, task_limit, description.

update_commentA

Update the body of an existing Kanboard comment. To remove a comment use delete_comment instead. Returns { ok: true, comment_id } on success.

Inputs: comment_id (required), content (required).

update_projectA

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.

Inputs: project_id (required), name, description, identifier, +4 more.

update_subtaskA

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.

Inputs: subtask_id (required), task_id (required), title, status, +3 more.

update_swimlaneA

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.

Inputs: swimlane_id (required), name, description.

update_taskA

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.

Inputs: task_id (required), title, description, color_id, +9 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.2/5.0

    Scored across 39 tools

    Disambiguation5/5

    Each tool has a clearly distinct purpose, with descriptions explicitly differentiating similar operations (e.g., close_task vs delete_task, create_task vs create_tasks_batch). Overlapping tools are well distinguished by documentation.

    Naming Consistency5/5

    All tool names follow a consistent verb_noun pattern using lowercase snake_case (e.g., create_project, list_tasks, update_column). The naming is predictable and uniform across all entities.

    Tool Count3/5

    With 39 tools, the server covers a comprehensive Kanboard domain but feels heavy. While each tool is justified for full lifecycle management, the count exceeds typical MCP server scope (3-15 tools), making it borderline overwhelming.

    Completeness4/5

    The tool surface is very comprehensive, covering CRUD for projects, tasks, subtasks, comments, columns, swimlanes, users, and files, plus batch and movement operations. Minor gaps exist, such as missing list_comments or get_subtask by id, but the core workflows are well supported.

    Maintenance

    ActivityInactive
    ResponsivenessLimited data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      B
      maintenance
      A remote Model Context Protocol server acting as middleware to the Sentry API, allowing AI assistants like Claude to access Sentry data and functionality through natural language interfaces.
      7
      43 npm
      964
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      Provides MCP tools to manage a local-first Kanban board, including projects, issues, dependencies, and labels. Enables AI clients to interact with the board via a stdio MCP server connected to a NestJS API.
      14 npm
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Self-hosted kanban board that dispatches AI agent fleets against tickets. The embedded Streamable HTTP /mcp endpoint exposes 7 tools to list projects, read boards and tickets, and create, move and comment tickets from any MCP client.
      30
      AGPL 3.0
    • F
      license
      Not graded
      quality
      C
      maintenance
      Enables AI assistants to manage a local-first Kanban board with Azure DevOps-style workflow rules, including task creation, status updates, subtask breakdown, full-text search, daily summaries, and next-task suggestions.
      -