Skip to main content
Glama
kanboard-mcp-server
by finestream

kanboard-mcp-server

An MCP server for a Kanboard instance: several agents, each acting as its own Kanboard user through Kanboard's JSON-RPC API, with tools for what an agent does with tasks and nothing that changes a project's structure.

Goals

  1. One Kanboard user per agent. The server holds each agent's Kanboard API token and calls /jsonrpc.php as that user, so Kanboard's roles and project permissions decide what is allowed and Kanboard shows the agent as the author of every change. The agent never holds the Kanboard token.

  2. Three ways in, beside each other: a static bearer for a local client, an OAuth 2.1 access token of an external identity provider (docs/oauth.md), or the assertion of Cloudflare Access in front of the server, which lets hosted clients connect without Kanboard or the identity provider being reachable from the internet (docs/cloudflare-access.md).

  3. Tools designed for agents: tasks, search, comments, tags, internal links, subtasks, due dates with a time of day; dates as ISO 8601 in Kanboard's time zone; Kanboard's refusals passed on with their reason. No delete, no project, column, swimlane, category or user administration: those are a person's acts (docs/security.md).

  4. Runs as a container next to Kanboard, secrets from files, read-only root; the image is published on a version tag.

  5. MIT, with code taken only from MIT, Apache or BSD sources.

It replaces a Kanboard plugin that serves MCP from inside Kanboard with a token in the request: a server of its own can authenticate the way hosted clients need, keeps Kanboard off the internet, and can be tested without Kanboard's PHP.

Related MCP server: ClickDown

Status

0.1.0: the server, the 24 tools, the three logins, unit and integration tests against a Kanboard test instance (kanboard/kanboard:v1.2.57), the image and the CI. Not yet run against a production Kanboard or a real identity provider or Access application; the two verifiers are the ones of finestream/silverbullet-mcp, which has.

What is here

Path

What

docs/security.md

The security model: terms, the credentials file, the three ways in, the tool surface, Kanboard's answers, the log

docs/oauth.md

OAuth: what the server verifies, what the identity provider must do, connecting a client

docs/cloudflare-access.md

Cloudflare Access in front of the server: what the server verifies, what the Access application must do, the route

src/

The server: main.ts (entry, --hash), server.ts (HTTP, auth), oauth.ts and cf-access.ts (the two verifiers), kanboard.ts (the JSON-RPC client), tools.ts (the tools), format.ts (dates, task fields), credentials.ts, config.ts; unit tests beside the code

config/credentials.example

The credentials file

test/

A compose test instance, its bootstrap, and the integration tests (test/README.md)

scripts/acceptance.ts

The acceptance test of a running server (Acceptance test below)

Dockerfile, compose.example.yaml

The image (node:24-alpine, non-root) and how to run it next to Kanboard

.github/workflows/ci.yml

Lint, unit and integration tests on every pull request; the image to ghcr.io/finestream/kanboard-mcp-server on a version tag

Run

Needs Node.js 24 or newer (it runs the .ts files directly) and a Kanboard reachable over HTTP.

npm install
KANBOARD_URL=http://127.0.0.1:8580 MCP_CREDENTIALS_FILE=./secrets/credentials node src/main.ts

The server listens on PORT (default 4000): POST /mcp is the MCP endpoint (streamable HTTP, stateless, bearer in the Authorization header), GET /healthz the health check, and, with OAuth configured, GET /.well-known/oauth-protected-resource its metadata. The image does the same: see compose.example.yaml. printf '%s' "$SECRET" | node src/main.ts --hash prints the SHA-256 of a client secret for the credentials file.

Kanboard side

Each agent needs a Kanboard user (role app-user is enough) that is a member of the projects it works in, and that user's personal API token: in Kanboard, the user's profile, API, Generate a new token. The token, or the user's password, is the third field of the agent's line in the credentials file. With two-factor authentication on the user, only the token works. Three failed logins on the user API lock the user until it logs in through the form (Kanboard's rule), so a wrong token in the file is noticed quickly.

Clients

The server speaks MCP over streamable HTTP: POST https://<host>/mcp with the client's bearer in the Authorization header.

claude mcp add --scope user --transport http kanboard https://kanboard-mcp.example.org/mcp --header "Authorization: Bearer $BEARER"   # Claude Code, static bearer
claude mcp add --scope user --transport http kanboard https://kanboard-mcp.example.org/mcp --client-id <client id> --callback-port 8765   # Claude Code, OAuth

Claude on the web, desktop and mobile: Settings → Connectors → Add custom connector with the server's public URL, path included; the login is the identity provider's (docs/oauth.md) or Cloudflare Access's (docs/cloudflare-access.md). A client that speaks only stdio reaches the server through mcp-remote with the bearer as a header.

Acceptance test

scripts/acceptance.ts checks a running server from any machine that reaches it, as one agent, and prints PASS or FAIL per check: a wrong bearer is refused; get_me names the Kanboard user; the project is listed with its columns; a search answers with tags; with MCP_TASK_ID the task is read, and with MCP_COMMENT=yes a comment is added and changed; a project the user may not see is refused with Kanboard's 403.

npm ci
MCP_URL=https://kanboard-mcp.example.org/mcp MCP_BEARER=… MCP_PROJECT_ID=2 MCP_TASK_ID=42 node scripts/acceptance.ts

Exit code 0 when every check passed, 1 otherwise, 2 when the test could not run. Through Cloudflare Access a static bearer is not accepted: run it against the direct route.

Configuration

One file and a few variables. The file is re-read when it changes and on SIGHUP.

File

Variable

What

credentials (a secret)

MCP_CREDENTIALS_FILE, default /run/secrets/credentials

One line per agent: Kanboard user, its API token, the bearer hashes and, optionally, the e-mail addresses for Cloudflare Access (example; docs/security.md, section 2)

Variable

Default

What

KANBOARD_URL

http://kanboard

Kanboard's base URL (or its jsonrpc.php endpoint) on the shared network

KANBOARD_TIMEOUT

30s

The most a call to Kanboard may take

PORT

4000

The listening port

MCP_RATE_LIMIT

120

Tool calls per agent and minute; 0 for none

MCP_LOG_LEVEL

info

info or debug; the log is JSON lines on stdout

MCP_OAUTH_ISSUER, MCP_OAUTH_RESOURCE

none

Both set: the server verifies OAuth access tokens of that issuer for that resource URL, beside static bearers (docs/oauth.md)

MCP_OAUTH_JWKS_URL, MCP_OAUTH_USER_CLAIM, MCP_OAUTH_SCOPES

from the issuer; preferred_username; none

Where the issuer's keys are, which claim names the agent, which scopes a token must carry

MCP_CF_ACCESS_TEAM_DOMAIN, MCP_CF_ACCESS_AUD

none

Both set: a request that came through Cloudflare Access is authenticated by the assertion Access adds (docs/cloudflare-access.md)

Tools

Every tool acts as the agent's Kanboard user. Ids come from the reading tools; dates are YYYY-MM-DD or YYYY-MM-DD HH:MM on the way in and ISO 8601 with Kanboard's time zone on the way out. Names follow the Kanboard MCP plugin where a tool does the same.

Tool

What

get_me

The Kanboard user this connection acts as, and Kanboard's time zone

get_projects

The projects the user is a member of

get_columns, get_swimlanes, get_categories, get_project_tags, get_users

A project's columns, active swimlanes, categories, tags and members, with ids

get_colors, get_link_labels

Kanboard's task colours; the labels of internal links (a plain user gets the built-in defaults, and source says so)

search_tasks

Kanboard's search syntax on one project; up to 200 tasks, with tags

get_task_details

A task with tags, links, subtasks, attachments (names) and, on request, comments

get_task_comments

The comments of a task, oldest first

create_task

Title, required priority, description, column, swimlane, category, colour, assignee, due date, tags, reference

update_task

Title, description, category, colour, assignee, priority, reference, due and start date

move_task

To a column (and swimlane) of its project, at a position

assign_task, set_task_due_date, set_task_tags

Assignee (0 for nobody); due date with or without time, "" clears; tags added or, with replace, set

add_task_comment, update_task_comment

A comment as the user; the text of an own comment

create_task_link, remove_task_link

An internal link by label or id (Kanboard adds the opposite link); its removal

create_subtask, update_subtask

A subtask; its title, status (0 to do, 1 in progress, 2 done) or assignee

What a tool answers when Kanboard refuses, and why there is no delete: docs/security.md, sections 4 and 6.

Tests

npm run lint                                          # eslint and tsc
npm run test:unit                                     # the credentials file, the configuration, the formatting, the client, the verifiers
docker compose -f test/compose.yaml up -d --wait      # Kanboard on http://127.0.0.1:8580
node test/bootstrap.ts                                # users, projects, memberships (idempotent)
npm run test:integration                              # the server against that instance: every tool, the two logins
docker compose -f test/compose.yaml down -v

Details: test/README.md.

Licence

MIT.

Code is taken only from MIT, Apache-2.0 or BSD-licensed projects and is credited here and in the file it lands in.

Attributions

Tool Schema Changelog

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

Loading tool schema changelog…

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      C
      maintenance
      Manage Kanboard projects, tasks, columns, swimlanes, comments, and file attachments via natural language. TypeScript implementation with 37 tools, multi-project routing via .kanboard.yaml, Docker multi-arch image, and provenance-signed npm releases.
      39
      22 npm
      10
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables AI agents to manage Kanban tasks, boards, teams, and checklists via natural language, with full CRUD operations and live updates.
      126 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
    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables AI agents to work a self-hosted kanban board as first-class users, exposing eleven kanban_* tools over a stateless Streamable HTTP endpoint for listing projects, stages, members and custom fields, and for creating, updating, moving and deleting tasks. Authenticates with bearer-token scopes so read-only or write access can be granted per agent, with every mutation audited.
      4
      MIT