@denisixnpm/planka-mcp
v2.6.0
Published
MCP server for Planka - Real-Time Collaborative Kanban Board
Maintainers
Readme
Planka MCP Server
MCP server for Planka (real-time Kanban), tuned for AI coding agents:
Claude Code, Codex, opencode and any MCP client. Works with Planka v2 and v1 (≤ 1.26.x).
No build step, no Docker required — npx runs the prebuilt package over stdio.
Auth: PLANKA_USERNAME/PLANKA_PASSWORD works on every Planka version (login, token
cache, and silent re-login are automatic). PLANKA_API_KEY is v2 only — generate one in
Planka user settings → API keys (v1.26.x has none; X-Api-Key returns 401 there, verified).
All examples below use username/password; on v2 you may swap the two auth envs for
PLANKA_API_KEY=your-api-key.
Install
Claude Code
claude mcp add planka \
--env PLANKA_BASE_URL=http://localhost:3000 \
--env PLANKA_USERNAME=your-email-or-username \
--env PLANKA_PASSWORD=your-password \
-- npx -y @denisixnpm/planka-mcpOr in claude_desktop_config.json / .mcp.json:
{
"mcpServers": {
"planka": {
"command": "npx",
"args": ["-y", "@denisixnpm/planka-mcp"],
"env": { "PLANKA_BASE_URL": "http://localhost:3000", "PLANKA_USERNAME": "your-email-or-username", "PLANKA_PASSWORD": "your-password" }
}
}
}Codex (~/.codex/config.toml)
[mcp_servers.planka]
command = "npx"
args = ["-y", "@denisixnpm/planka-mcp"]
env = { PLANKA_BASE_URL = "http://localhost:3000", PLANKA_USERNAME = "your-email-or-username", PLANKA_PASSWORD = "your-password" }opencode (opencode.json)
{
"mcp": {
"planka": {
"type": "local",
"command": ["npx", "-y", "@denisixnpm/planka-mcp"],
"environment": { "PLANKA_BASE_URL": "http://localhost:3000", "PLANKA_USERNAME": "your-email-or-username", "PLANKA_PASSWORD": "your-password" }
}
}
}Requires Node.js ≥ 22.19 (or Bun ≥ 1.3). Debug: npx -y @denisixnpm/planka-mcp 2>&1 | tee debug.log.
Attachments & files
cards.get returns the full working context in one call — description, tasks, task lists,
attachments, and the activity log (actions). Attachment records are normalized across versions
(v2's nested data.url flattened to url/size/mimeType).
- Create with files:
cards { action: "create", data: { name, attachments: [{ name?, filePath | text | contentBase64, mimeType? }] } }— uploads happen in the same tool call. WithfilePaththe server reads the local file itself and auto-detects name + MIME from the extension (.png, .jpg, .webp, .gif, .pdf, .doc(x), .xls(x), .ppt(x), .txt, .md, .csv, .json, and more). - Upload later:
attachments { action: "upload", id: <cardId>, data: { name?, filePath | text | contentBase64 | url, mimeType? } }—urlcreates a link attachment (v2 only). - Download:
attachments { action: "download", id: <attachmentId>, data: { cardId } }— images (image/*) come back as a rendered MCP image block, text files as decodedtext, other binary ascontentBase64(≤ 10 MB inline). - Rename / delete:
attachments { action: "rename" | "delete", id, data: { name? } }.
Downloads need username/password auth: Planka's file route authenticates via cookie only (Bearer/API keys get 401 — verified on 1.26.2 and 2.0.3).
Agent workflow
Minimal card creation — cards { action: "create", data: { name: "Fix login" } } is enough:
type and position (append at end) are defaulted; add description, dueDate, listId
(move), and inline attachments as needed.
Find without walking lists — cards { action: "find", data: { boardId?, name: "login" } }
searches every card on the board case-insensitively and returns matches with their list names
(boardId can come from the context tool).
Scoped context — select a project/board/list/card once, then omit ids:
{ "action": "set", "data": { "boardId": "..." } }context.set returns an overview of what you opened; setting a higher level resets deeper ones.
Scope is per SSE session, process-wide for stdio.
Condensed output — responses keep only agent-relevant fields (ids, names, positions, states);
timestamps, password hashes, and audit metadata are stripped, long text truncated, included
sidecars reduced per entity. Escape hatches: per-call raw: true or PLANKA_CONDENSED_OUTPUT=false.
Configuration
| Variable | Default | Description |
|----------|---------|-------------|
| PLANKA_BASE_URL | http://localhost:3000 | Planka instance URL |
| PLANKA_USERNAME / PLANKA_PASSWORD | — | Login auth — all Planka versions; token is fetched, cached, and refreshed automatically |
| PLANKA_API_KEY | — | API key auth — Planka v2 only (user settings → API keys); wins if both are set |
| PLANKA_HTTP_TIMEOUT_MS | 30000 | Per-request timeout (aborts, then retries) |
| PLANKA_HTTP_MAX_RETRIES | 2 | Retries for 408/429/5xx and network errors |
| PLANKA_HTTP_RETRY_BASE_DELAY_MS | 250 | Exponential backoff base (base * 2^attempt) |
| PLANKA_CONDENSED_OUTPUT | true | Condensed agent output; false = raw payloads |
| ENABLE_ALL_TOOLS | false | Enable all 28 tools (otherwise 12 core) |
| ENABLE_ADMIN_TOOLS / ENABLE_OPTIONAL_TOOLS | false | Enable one extra category |
| MCP_TRANSPORT | stdio | stdio (single client) or sse (multi-client) |
| MCP_PORT / MCP_HOST | 3001 / 127.0.0.1 | SSE mode bind; 0.0.0.0 in Docker |
| MCP_AUTH_TOKEN | — | If set, SSE endpoints require Authorization: Bearer <token> |
| MCP_HEARTBEAT_INTERVAL_MS | 30000 | SSE keep-alive interval for strict proxies |
Bun auto-loads .env from the working directory (real env vars win); the Node/npx path does not.
Tools (28)
Every tool takes action, optional id/data/query, and optional raw: true.
| Category | Tools |
|----------|-------|
| Core (12, always on) | auth, bootstrap, context, projects, boards, lists, cards, attachments, comments, tasks, labels, cardMembers |
| Admin (4) | users, projectManagers, webhooks, notificationServices |
| Optional (12) | actions, boardMembers, customFields, notifications, backgroundImages, cardExtras, commentExtras, listExtras, taskExtras, labelExtras, cardMemberExtras, userInfo |
Actions per tool are enumerated in the MCP tools/list response. Live-verified semantics worth
knowing: project managers exist only on shared projects; notification services are self-only;
v1.26.2 lacks REST task-lists/custom-fields/webhooks (clean 404s); renamed v1 membership/label/
comment routes are retried automatically; labels.list and cards.find derive from boards.get
(Planka has no labels GET route on either major); link attachments to some URLs (e.g.
example.com) HTTP 500 inside Planka 2.0.3 itself.
If a tool reports "returned an HTML page"
Planka serves its web UI from the same origin as the API, so a route the server does not have may
answer 200 text/html (the SPA's index.html) instead of 404. The server refuses to pass that
off as data and tells you which call hit it. Usually it means the route is newer than your Planka:
on 1.26.x the server transparently retries the v1 route, or derives the answer from boards.get /
the card activity log and marks the result with a _compat note. If it names a route with no v1
equivalent (task lists), the error also names what to use instead. A page returned for every
call, including login, means PLANKA_BASE_URL points at a proxy or portal rather than at Planka.
Multi-client SSE mode (optional)
MCP_TRANSPORT=sse npx -y @denisixnpm/planka-mcpConnect MCP clients to http://127.0.0.1:3001/sse. Set MCP_AUTH_TOKEN whenever binding beyond
loopback — without it, anyone who can reach the port has full tool access. A --healthcheck
mode is built in for orchestrators.
Prefer a container? hub.docker.com/r/denisix/planka-mcp:
docker run -d --name planka-mcp -p 3001:3001 \
-e PLANKA_BASE_URL=http://host.docker.internal:3000 \
-e PLANKA_USERNAME -e PLANKA_PASSWORD \
denisix/planka-mcpCompiled Bun binary on distroless (no shell, no node_modules).
Development
bun install
npm test # build + hermetic suite (222 tests)
npm run e2e # + live Planka 2.0.3 and 1.26.2: up, test, tear down
npm run check # lockfile + version-trio guards, then the suite (run before tagging)Details in CONTRIBUTING.md and CLAUDE.md.
Credits
Fork of planka-mcp by Christopher Maldonado — credit for the original server goes to him. Maintained by denisix, published as @denisixnpm/planka-mcp.
What this fork improves: security hardening (0 npm audit findings, loopback-only SSE,
timing-safe auth, single-flight login, per-request timeouts); Planka v1 compatibility with
automatic legacy-route fallbacks; condensed agent output and scoped working context; full
attachment support (upload/download/create-with-files, both Planka majors); agent-first card
workflows (minimal create, board-wide find); npm + Docker Hub release pipelines with provenance
and SBOM.
License
MIT — see LICENSE. Issues: github.com/denisix/planka-mcp/issues.
