Vikunja MCP fork
  • TypeScript 94.8%
  • JavaScript 5.2%
Find a file
Brad Wenner 04ecf9470d
All checks were successful
CI / build (push) Successful in 16s
feat: kanban ergonomics — auto-discover view, move by bucket name
For users who only use kanban (Brad's case), having to track viewId
and bucketId for every move is needless ceremony. Two new shortcuts:

1. viewId is now optional on list-buckets and move-bucket. When
   omitted, we GET /projects/{id}/views and pick the first one with
   view_kind='kanban'. Errors clearly when no kanban view exists.

2. move-bucket accepts bucketName as an alternative to bucketId.
   Case-insensitive title match against the project's buckets. On
   miss, the error lists the available bucket titles so the agent
   can recover.

Result: a kanban move is now just
  { taskId, projectId, bucketName: "Done" }
— no view discovery roundtrip, no ID tracking.

bucketId and viewId are still accepted for projects with multiple
kanban views or callers who already know the IDs.

Helpers live in src/tools/_kanban.ts; consumed by tasks.move-bucket
and projects.list-buckets. Verified end-to-end against the live
Vikunja: list-buckets without viewId returned the right buckets,
move-bucket by name moved the task, mistyped bucket name returned
"No bucket named 'X'. Available: To-Do, Doing, Done".

README and docs/API-NOTES.md updated.
2026-04-27 23:02:10 -07:00
.forgejo/workflows ci: auto-rebuild and commit dist on main 2026-04-27 21:36:01 -07:00
dist feat: kanban ergonomics — auto-discover view, move by bucket name 2026-04-27 23:02:10 -07:00
docs feat: kanban ergonomics — auto-discover view, move by bucket name 2026-04-27 23:02:10 -07:00
src feat: kanban ergonomics — auto-discover view, move by bucket name 2026-04-27 23:02:10 -07:00
.env.example Hard fork: strip and rewrite as a thin node-vikunja wrapper 2026-04-27 19:58:09 -07:00
.gitignore build: ship dist/ in the repo for zero-step deploys 2026-04-27 21:32:19 -07:00
.prettierrc.json 🚀 feat: complete Vikunja MCP Server implementation with enterprise-grade features 2025-12-18 09:02:58 -05:00
CLAUDE.md Hard fork: strip and rewrite as a thin node-vikunja wrapper 2026-04-27 19:58:09 -07:00
eslint.config.mjs Hard fork: strip and rewrite as a thin node-vikunja wrapper 2026-04-27 19:58:09 -07:00
foragent.md ci: auto-rebuild and commit dist on main 2026-04-27 21:36:01 -07:00
LICENSE 🚀 feat: complete Vikunja MCP Server implementation with enterprise-grade features 2025-12-18 09:02:58 -05:00
package-lock.json Hard fork: strip and rewrite as a thin node-vikunja wrapper 2026-04-27 19:58:09 -07:00
package.json Hard fork: strip and rewrite as a thin node-vikunja wrapper 2026-04-27 19:58:09 -07:00
README.md feat: kanban ergonomics — auto-discover view, move by bucket name 2026-04-27 23:02:10 -07:00
tsconfig.json Hard fork: strip and rewrite as a thin node-vikunja wrapper 2026-04-27 19:58:09 -07:00

vikunja-mcp

Model Context Protocol server for Vikunja — a thin wrapper over node-vikunja that lets MCP-aware AI assistants drive a Vikunja instance.

This is a hard fork of @democratize-technology/vikunja-mcp that strips the upstream's enterprise scaffolding (custom rate limiter, V8 memory estimator, regex log scrubber, filter parser, circuit breaker registry, multiple bulk implementations, ~12k LOC of duplicate tool surfaces) down to a small, readable wrapper.

Tools

Tool Subcommands Auth
vikunja_auth connect, status, disconnect
vikunja_tasks list, list-by-project, get, create, update, delete, set-status, assign, unassign, list-assignees, add-label, remove-label, list-labels, list-comments, add-comment, update-comment, delete-comment, create-relation, delete-relation, bulk-update, move-bucket API token or JWT
vikunja_projects list, get, create, update, delete, duplicate, list-shares, get-share, create-share, delete-share, list-views, list-buckets, list-labels API token or JWT
vikunja_labels list, get, create, update, delete API token or JWT
vikunja_teams list, create, delete API token or JWT
vikunja_filters get, create, update, delete API token or JWT
vikunja_users current JWT only

Authentication

Vikunja issues two token flavours:

  • API tokens — start with tk_. Created in Settings → API Keys. Cover most resources but cannot access /user* endpoints.
  • JWTs — start with eyJ. Lifted from a browser session (DevTools → Local Storage). Full access.

vikunja_auth.connect auto-detects the type from the token prefix.

Configuration

Env var Description
VIKUNJA_URL Base URL of your Vikunja instance (e.g. https://vikunja.example.com). Auto-connects on startup if both vars are set.
VIKUNJA_API_TOKEN API token or JWT.
LOG_LEVEL error | warn | info | debug (default info).

Install / run

npm install
npm run build
node dist/index.js

For development:

npm run dev   # tsx watch
npm run typecheck
npm run lint

Wiring into Claude Desktop

claude_desktop_config.json:

{
  "mcpServers": {
    "vikunja": {
      "command": "node",
      "args": ["/absolute/path/to/vikunja-mcp/dist/index.js"],
      "env": {
        "VIKUNJA_URL": "https://vikunja.example.com",
        "VIKUNJA_API_TOKEN": "tk_..."
      }
    }
  }
}

Filtering

The filter argument on vikunja_tasks.list / list-by-project is forwarded verbatim to Vikunja's filter parameter — Vikunja parses the DSL server-side. See Vikunja's filter docs.

Kanban operations

Kanban buckets technically live inside views, but if your project has only one kanban view (the common case) you can skip dealing with viewId entirely.

// 1. List buckets — auto-discovers the project's kanban view
{ "subcommand": "list-buckets", "projectId": 18 }
// → [{id: 64, title: "To-Do"}, {id: 65, title: "Doing"}, {id: 66, title: "Done"}]

// 2. Move a task by bucket name (case-insensitive)
{ "subcommand": "move-bucket", "taskId": 100, "projectId": 18, "bucketName": "Done" }

bucketId and viewId are still accepted if you have multiple kanban views or want to address a bucket by ID. If you misspell bucketName, the error lists the available titles.

vikunja_projects.list-labels { projectId } returns labels used by tasks in the project (Vikunja has no native per-project labels endpoint — we aggregate from up to 5 pages of tasks).

Creating tasks with labels and assignees

vikunja_tasks.create accepts top-level labels: number[] and assignees: number[] arrays alongside the nested task body. The MCP server creates the task, then attaches labels via the bulk endpoint and assigns users individually, returning the populated task.

{
  "subcommand": "create",
  "projectId": 1,
  "task": { "title": "Foo", "priority": 3, "due_date": "2026-05-01T00:00:00Z" },
  "labels": [4, 7],
  "assignees": [2]
}

License

MIT — see LICENSE. Original copyright © 2025 Democratize Technology; fork modifications © 2026 Brad Wenner.