Skip to content

Vikunja MCP Server — 21 tools via DADL

contains code

The Vikunja DADL turns Vikunja's API into an MCP server that Claude, GPT or any MCP-compatible agent can consume directly. One YAML file declares all 21 tools — task, project, label, bucket, view, comment, and more — and ToolMesh serves them at runtime. No Python boilerplate, no per-endpoint code, no separate MCP server process.

Below: the endpoint coverage matrix, a two-block ToolMesh setup, the full tool reference grouped by Vikunja feature area, required credential scopes.

Source: Vikunja REST API

Credits: Dunkel Cloud GmbH Updated: 2026-03-29

Which Vikunja endpoints are covered?

26% (21 of ~80 endpoints)

Focus: projects, tasks, views, buckets, labels, comments, positions, filters

Missing: teams, users, shares, attachments, assignees, task relations, reactions, notifications, webhooks, subscriptions, saved filters

Last reviewed: 2026-06-18

How do you configure the Vikunja DADL?

  1. Log in to the Vikunja web UI
  2. Open Settings → API Tokens (user menu, top right)
  3. Click 'Create a token', enter a name and an optional expiry
  4. Under Permissions grant at least: Projects (read & write), Tasks (read & write), Labels (read & write), Task Comments (read & write)
  5. Click Create and copy the token immediately — it is shown only once (format: tk_…)

Environment variable: CREDENTIAL_VIKUNJA_API_TOKEN

Authentication docs ↗

Vikunja is self-hosted — replace the URL with your instance address, including the /api/v1 suffix. API tokens are shown only once at creation and their granted permissions cap what these tools can do (a read-only token returns 403 on create/update/delete).

How do you install the Vikunja MCP server with ToolMesh?

Add to your backends.yaml:

- name: vikunja
  transport: rest
  dadl: vikunja.dadl
  url: "https://your-vikunja-instance.com/api/v1"

Set the credential:

CREDENTIAL_VIKUNJA_API_TOKEN=your-token-here

What 21 tools does the Vikunja DADL expose?

POST set_task_position Set task position (sort order) within a project view. The position is a float64 value — use values between existing tasks to insert.
GET list_project_tasks List all tasks in a project view. Use view_id from list_views. Supports sorting by position, due_date, created, etc. Kanban views return buckets with nested tasks, not a flat list.
GET list_tasks Query tasks across ALL projects the user can access (not scoped to a single view). Supports the Vikunja filter DSL, full-text search (s) and multi-field sorting — the best endpoint for analytics/reporting (velocity, ETA, throughput): filter or sort by done_at, created, updated, due_date, percent_done. Returns a flat task array.
GET get_task Get a single task by its ID, including all details, assignees, labels, and relations.
PUT create_task Create a new task in a project. Priority: 0=unset, 1=low, 2=medium, 3=high, 4=urgent, 5=critical.
POST _update_task_raw Internal: raw task update (sends full object). Use the update_task composite instead.
POST move_task_to_bucket Move a task to a different kanban bucket. Use list_buckets to get bucket IDs. This is the only way to move tasks between kanban columns.
DELETE delete_task Permanently delete a task.
GET list_projects List all projects accessible to the authenticated user. Projection now also includes parent_project_id and position (hierarchy + ordering), plus hex_color and owner (username).
GET get_project Get a single project by ID.
PUT create_project Create a new project. Only 'title' is required. Set parent_project_id to nest it under another project (hierarchy). 'identifier' (≤10 chars) is the short prefix used to build task identifiers (e.g. OPS-1); omit to auto-derive. hex_color is a 6-digit hex string without a leading '#'.
POST _update_project_raw Internal: raw project update (sends a full object — omitted fields are reset to zero). Use the update_project composite instead.
DELETE delete_project Permanently delete a project and all of its tasks, views and buckets. Irreversible. Verify the project_id with get_project first. (There is no delete for labels — those must be removed in the Vikunja UI.)
GET list_views List all views (list, kanban, gantt, table) for a project. Each view has its own task positions. Call this first to get view_id for list_project_tasks.
GET list_buckets List all kanban buckets for a project view. Returns bucket id, title, and task count. Use move_task_to_bucket to move tasks between columns.
PUT create_bucket Create a new kanban bucket in a project view.
GET list_labels List all labels the user has access to. Returns id, title, description, hex_color.
PUT create_label Create a new label. NOTE: Vikunja creates labels with PUT (not POST). 'title' is required. hex_color is a 6-digit hex string without a leading '#'. Useful for setting up reusable S/M/L estimate labels.
PUT add_label_to_task Add a label to a task.
GET list_task_comments List all comments on a task.
PUT create_task_comment Add a comment to a task.

What composite workflows does the Vikunja DADL provide? ⚠ contains code

FN update_task Update an existing task. Only include fields you want to change — unchanged fields are preserved. To move between kanban buckets, use move_task_to_bucket instead.
FN update_project Update an existing project. Only include the fields you want to change — unchanged fields are preserved (this composite does GET → merge → POST, because Vikunja's raw project update resets omitted fields). Set parent_project_id to re-parent (0 = top-level). To create a project use create_project.