emperor-vikunja
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@emperor-vikunjashow me my open tasks sorted by priority"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
emperor-vikunja
An MCP server for Vikunja, the open-source task manager. Let Claude, kowalski or any MCP client list, read, create and update your tasks, comment on them and see your projects.
Built on emperor-mcp (Emperor Profile P1):
Stateless Streamable HTTP at
/mcp, plus stdio for desktop clients.Your token is forwarded, never stored. Over HTTP each request brings its own
Authorization: Bearer <token>; the server passes it to Vikunja and forgets it. There are no default or test tokens.Framed output. Task text written by people (titles, descriptions, comments) reaches the model marked as messages for the user, never as instructions for the model.
Six annotated tools, a
--read-onlymode, adoctorsubcommand, Markdown in and plain text out.Clear auth failures. When Vikunja refuses the token, the MCP response over HTTP is a
401or403, so the client can ask for a new token.
Tools
Tool | Annotations | What it does |
| read-only | Tasks sorted by priority, then due date. Filters: |
| read-only | One task by |
| write, not idempotent |
|
| write, destructive, idempotent |
|
| write, not idempotent | Add a Markdown comment to task |
| read-only | Projects (up to 100) with id, title, parent and number of open tasks. |
Every tool is marked open-world (it talks to a Vikunja that other people change).
update_task is marked destructive because a new title or description replaces the old text,
which Vikunja does not keep, and labels and assignees can be removed; it is idempotent because
the same call twice leaves the task as one call did.
Labels are named by title. A label that does not exist is an error unless the call passes
create_missing_labels: true, so a typo does not quietly add a new label. Assignees are
usernames (exact, case-insensitive; a leading @ is fine). Names are checked before anything
is written: a bad label or username leaves no half-made task.
Priority: 0 unset, 1 low, 2 medium, 3 high, 4 urgent, 5 do now. Dates: YYYY-MM-DD (read as
00:00 UTC) or ISO-8601; dates come back as RFC 3339, or null when unset.
Descriptions and comments are stored by Vikunja as HTML. What the model writes in Markdown is rendered to HTML on the way in (raw HTML in the Markdown is escaped, not passed through); HTML read back is rendered to plain text.
Related MCP server: vikunja-mcp
Install
From a release (Linux x86_64, macOS arm64 and x86_64, Windows x86_64): download the archive for
your platform from Releases and put
emperor-vikunja on your PATH.
From source (Rust 1.88 or newer):
cargo install --git https://github.com/yarenty/emperor-vikunjaGet a token
In Vikunja open Settings > API Tokens > Create a token, pick an expiry date and tick these permissions (the minimum the six tools need):
Group | Permissions |
projects |
|
tasks |
|
tasks_comments |
|
tasks_labels |
|
tasks_assignees |
|
labels |
|
other |
|
For a read-only assistant start the server with --read-only and give it a token with only the
read_all / read_one permissions.
Run
Local (stdio)
export VIKUNJA_TOKEN=... # from Settings > API Tokens
emperor-vikunja serve --stdio --base-url https://vikunja.example.comDocker (stdio)
docker build -t emperor-vikunja https://github.com/yarenty/emperor-vikunja.git
docker run -i --rm -e VIKUNJA_URL=https://vikunja.example.com -e VIKUNJA_TOKEN emperor-vikunja
# read-only: add -e VIKUNJA_READ_ONLY=true (or --read-only after the image name)The image runs emperor-vikunja serve --stdio as a non-root user; the Vikunja address comes
from VIKUNJA_URL.
Shared (HTTP)
emperor-vikunja serve --base-url https://vikunja.example.com --bind 127.0.0.1:8034
# MCP endpoint: http://127.0.0.1:8034/mcp liveness: http://127.0.0.1:8034/healthEvery MCP request must carry Authorization: Bearer <token>; each user brings their own.
VIKUNJA_TOKEN is ignored in this mode, so one person's token can never answer another
person's request. Tool discovery (tools/list) works without a token.
When Vikunja refuses the token (401) or the token may not do this (403), the MCP response
carries that HTTP status (401 with WWW-Authenticate: Bearer error="invalid_token") and a
JSON-RPC error with code -32040 and data.httpStatus. Over stdio the client gets the same
JSON-RPC error.
Flags and headers
Flag | Env | Meaning |
|
| Vikunja address; |
|
| Serve only |
| Speak MCP over stdin/stdout; the token comes from | |
| HTTP listen address (default | |
| Accept only this | |
| Accept only this |
Request header (HTTP) | Meaning |
| The caller's Vikunja API token. Required for every tool call. |
| The Vikunja instance for this request, overriding |
With X-Upstream-Url one server can front several Vikunja instances. The server will then call
whichever https host a client names, with that client's token; run it where outbound calls to
arbitrary hosts are acceptable, or leave the header out at your proxy and rely on --base-url.
Logs go to stderr; RUST_LOG=debug for more. In production put the HTTP server behind a
reverse proxy that terminates TLS (Emperor Profile E5).
Connect
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"vikunja": {
"command": "emperor-vikunja",
"args": ["serve", "--stdio", "--base-url", "https://vikunja.example.com"],
"env": { "VIKUNJA_TOKEN": "<your token>" }
}
}
}Claude Code:
# stdio
claude mcp add vikunja --env VIKUNJA_TOKEN=<your token> -- \
emperor-vikunja serve --stdio --base-url https://vikunja.example.com
# read-only
claude mcp add vikunja-ro --env VIKUNJA_TOKEN=<your token> -- \
emperor-vikunja serve --stdio --read-only --base-url https://vikunja.example.com
# or against a running HTTP server
claude mcp add --transport http vikunja http://127.0.0.1:8034/mcp \
--header "Authorization: Bearer <your token>" \
--header "X-Upstream-Url: https://vikunja.example.com"kowalski (config.toml):
[[mcp.servers]]
name = "vikunja"
transport = "stdio"
command = ["emperor-vikunja", "serve", "--stdio", "--base-url", "https://vikunja.example.com"]
# VIKUNJA_TOKEN is read from kowalski's environment.
# or over HTTP
[[mcp.servers]]
name = "vikunja-http"
transport = "http"
url = "http://127.0.0.1:8034/mcp"
headers = { Authorization = "Bearer <your token>", X-Upstream-Url = "https://vikunja.example.com" }Doctor
emperor-vikunja doctor checks the setup before you start the server and exits 1 when
something is broken, so scripts and container health checks can use it:
$ VIKUNJA_TOKEN=... emperor-vikunja doctor --base-url https://vikunja.example.com
emperor-vikunja 0.1.2 doctor
[ok ] base url https://vikunja.example.com/
[ok ] vikunja api Vikunja v2.7.1
[ok ] VIKUNJA_TOKEN set (43 chars)
[ok ] vikunja login token works for user alice
[ok ] mode read-write: comment, create_task, get_task, list_projects, list_tasks, update_task
[ok ] listen address 127.0.0.1:8034 is free
[ok ] tool budget 6 of at most 8 tools
all good (0 warning(s))It checks that the URL parses, GET /api/v1/info answers, the token is set (only its length is
shown) and GET /api/v1/user accepts it, which tools the mode serves (--read-only lists the
three read tools), the listen address is free (skipped with --stdio), and the tool count is
within the emperor-mcp budget. Without VIKUNJA_TOKEN in HTTP mode the token line is a
warning, because the token comes per request; with --stdio it is a failure. The same goes for
--base-url: over HTTP its absence is a warning (requests must send X-Upstream-Url), with
--stdio a failure.
Compatibility
Tested against Vikunja v2.7 (the vikunja/vikunja image). Tasks are listed through GET /tasks
with Vikunja's filter syntax (done = false && project = 3 && labels in 5 && due_date < '...');
older releases that serve /tasks/all instead are picked up automatically, and every filter is
applied again locally so results stay right even where the server ignores part of it.
Build and test
cargo test # unit, fake-Vikunja, MCP HTTP and stdio tests
cargo test --test live_vikunja -- --ignored --nocapture # every tool against a real Vikunja in DockerLinks
Crate: crates.io/crates/emperor-vikunja, API docs on docs.rs
Container: build from the
Dockerfile; it serves stdio and readsVIKUNJA_URL,VIKUNJA_TOKENandVIKUNJA_READ_ONLYListed in the official MCP Registry as mcp-name: io.github.yarenty/emperor-vikunja
How it compares with other task-manager MCP servers: docs/COMPARISON.md
License
Licensed under either of
Apache License, Version 2.0 (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in emperor-vikunja by you shall be dual licensed as above, without any additional terms or conditions.
Available Tools
6 toolscommentC
Add a comment (Markdown) to a task.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Task id. | |
| text | Yes | Comment text in Markdown. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly=false, idempotent=false, destructive=false, and openWorld=true, so the safety profile is covered by structured data. The description adds nothing beyond this – it does not mention that repeated calls create duplicate comments (non-idempotent), whether the author is attributed, whether notifications fire, or what happens on an invalid task id.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no waste. It is appropriately terse for a two-parameter tool, though that terseness is partly why usage and behavior are underspecified.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple 2-param mutation with full schema coverage and annotations present, the description is minimally sufficient. It omits return/payload behavior (no output schema exists) and the non-idempotent duplicate-comment caveat, both of which an agent would benefit from knowing before calling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and both parameters (id, text) are fully documented, including the Markdown constraint. The description only restates what the schema already says, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb+resource ("Add a comment") with the format qualifier (Markdown) and target (a task). No sibling among create_task/get_task/update_task/list_* overlaps, so the distinction is implicit rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this versus update_task (e.g. editing an existing comment body) or any prerequisite that the task id must exist. The agent must infer all usage conditions from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_taskA
Create a task in a project, with an optional Markdown description, labels (existing ones unless create_missing_labels is true), assignees by username, priority 0-5 and due date.
| Name | Required | Description | Default |
|---|---|---|---|
| due | No | Due date, YYYY-MM-DD or ISO-8601. | |
| title | Yes | Task title. | |
| labels | No | Label titles. Labels must exist unless create_missing_labels is true. | |
| project | Yes | Project to create the task in (title or id). | |
| priority | No | Priority 0 to 5 (0 unset, 1 low, 2 medium, 3 high, 4 urgent, 5 do now). | |
| assignees | No | Usernames to assign. | |
| description | No | Description in Markdown. | |
| create_missing_labels | No | Create labels that do not exist yet. Default false: an unknown label is an error. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the write/non-idempotent/open-world profile, so the bar is lower. The description's most useful addition is the duplicate-label error condition, but that same constraint is already spelled out in the schema's create_missing_labels parameter; it adds no insight on failure modes for unknown assignees, permission needs, or what object is returned.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One front-loaded sentence with the verb and resource first, followed by the optional field list. It is dense but every clause maps to a real parameter; a short note on the update_task boundary would have improved it further.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With annotations covering the safety profile and a fully documented schema, the description provides enough for correct invocation. The only gap is the lack of guidance on how it relates to update_task and whether repeated calls create duplicates.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so every parameter is already documented, including the 0-5 priority scale and due-date format. The description's mention of 'priority 0-5' and 'assignees by username' restates schema content rather than adding new meaning, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
A specific verb plus resource ('Create a task in a project') that is immediately distinguishable from update_task, get_task, and list_tasks. The sentence also enumerates the creatable attributes, so the agent knows the scope without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Creation is implied as the right operation when a new task is needed, and the label/existence constraint hints at prerequisites. However, it never explicitly contrasts with update_task (e.g., 'use update_task for existing tasks') or states whether the project must already exist.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_taskARead-only
Read one task: every field, the description as text, and its comments with author and date (the 50 most recent; long text is cut).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Task id. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so safety is covered; the description adds genuinely new behavioral detail by disclosing that only the 50 most recent comments are included and that long text is truncated. These are exactly the kind of limits an agent needs before calling, though return-shape caveats like missing-task behavior are absent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence, front-loaded with the core action and followed by a compact parenthetical of return details. No redundant or filler text; every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description carries the burden of describing returns, and it does so well (fields, description text, comment authors/dates, count limit, truncation). It stops short of covering error or not-found behavior, keeping it from a 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With a single parameter and 100% schema description coverage, the schema already documents 'id' as a task id. The description adds no syntax or format detail (e.g., how to obtain the id) beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Read') and resource ('one task') and enumerates what is returned: all fields, description as text, and comments. It implicitly contrasts with list_tasks by emphasizing 'one task', but never names the sibling, so it falls short of full differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Use case is implied ('read one task'), but there is no explicit guidance on when to choose this over list_tasks or comment, and no mention of prerequisites such as needing a valid task id. Adequate but with clear gaps.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_projectsARead-only
List projects with id, title, parent project and number of open tasks (up to 100).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description contributes one genuine behavioral fact not in the structured fields: results are capped at 100. It does not say whether that cap means truncation, pagination, or an error, and gives no ordering or completeness guarantees.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler. The resource comes first and the returned fields and the 100-item cap follow immediately.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-param read tool with no output schema, describing the returned fields is the right move and it does so. The only gap is the ambiguity around the 100-item cap — whether the agent should expect truncation or page through results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4; the schema is empty and the description correctly makes no parameter claims. There is nothing for the description to compensate for.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('List') and resource ('projects') and even enumerates the fields returned (id, title, parent project, open task count). It is clearly distinct from the task-oriented siblings, though the description never explicitly contrasts itself with them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: an agent can infer this is the tool for enumerating projects, but there is no statement of when to prefer it, no prerequisites, and no alternatives named. For a zero-parameter list tool the risk is low, but the guidance is absent rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tasksARead-only
List tasks, open ones by default, sorted by priority then due date. Filters: project, label, done, due_before, search; limit up to 100.
| Name | Required | Description | Default |
|---|---|---|---|
| done | No | Done tasks instead of open ones. Default false (open tasks). | |
| label | No | Only tasks with this label (title). | |
| limit | No | Most tasks to return, 1 to 100 (default 50). | |
| search | No | Text to search for in titles and descriptions. | |
| project | No | Only tasks in this project (title or id). | |
| due_before | No | Only tasks due before this date (YYYY-MM-DD or ISO-8601). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so safety is covered. The description adds genuinely useful behavior beyond that: the default filter (open tasks), the sort order (priority then due date), and the result cap ('limit up to 100'), which warns the agent that output can be truncated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler, and the most important information (subject, default scope, ordering) comes first. Every clause carries content an agent needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a six-parameter, fully documented read tool with no output schema, the description covers defaults, ordering, and truncation risk adequately. It falls short only on return shape and whether the limit implies no pagination, which an agent might wonder about with up to 100 results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameters are already fully documented. The description only enumerates filter names and the limit ceiling, both of which are in the schema; it adds no format or interaction detail (e.g., how search combines with other filters), so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List tasks') plus scope details: open by default, sorted by priority then due date. It is clearly distinguishable from get_task, create_task, and update_task by name and semantics, though it never names those siblings explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It implies the usage context by saying results are 'open ones by default' and that a done filter exists, which lets an agent infer how to retrieve completed tasks. However, it never states when to use this instead of get_task or how to page through large result sets, leaving routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_taskADestructiveIdempotent
Change a task: any of title, description (Markdown, replaces the old one), done, priority, due ("none" clears it), add_labels / remove_labels, add_assignees / remove_assignees (usernames), or move it to another project.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Task id. | |
| due | No | New due date (YYYY-MM-DD or ISO-8601), or "none" to clear it. | |
| done | No | Mark done (true) or reopen (false). | |
| title | No | New title. | |
| project | No | Move the task to this project (title or id). | |
| priority | No | New priority 0 to 5. | |
| add_labels | No | Label titles to add. Labels must exist unless create_missing_labels is true. | |
| description | No | New description in Markdown (replaces the old one). | |
| add_assignees | No | Usernames to assign. | |
| remove_labels | No | Label titles to remove. | |
| remove_assignees | No | Usernames to unassign. | |
| create_missing_labels | No | Create labels in add_labels that do not exist yet. Default false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=true, openWorldHint=true, and readOnlyHint=false, so the safety profile is covered. The description adds replacement/clearing semantics for description and due, but mostly repeats schema details and does not discuss permissions, side effects, or return behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence that efficiently enumerates the supported changes with no wasted wording. The most important operation is stated first.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers most operations for a 12-parameter mutation tool, including labels, assignees, due date, and project moves. It omits create_missing_labels and the required id, but the schema and annotations fill those gaps adequately.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all 12 parameters are already documented in the schema. The description enumerates the same fields and adds little semantic detail beyond what the schema provides, making the baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Change a task") and enumerates the mutable fields, making it clearly distinct from create_task, get_task, and list_tasks. An agent can identify the operation without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implies use for modifying an existing task, but gives no explicit when-to-use or when-not-to-use guidance. It does not name alternatives such as create_task or get_task, nor does it state prerequisites like needing a task id.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v0.2.0- First observed
comment - First observed
create_task - First observed
get_task - First observed
list_projects - First observed
list_tasks - First observed
update_task
TDQS
Scored across 6 tools
Each tool targets a distinct resource+action: listing projects vs listing tasks vs reading one task vs creating/updating a task, plus adding a comment. The only mild overlap is `comment` versus `update_task`, since commenting is arguably a mutation of a task, but the descriptions make the boundary clear.
Five of six tools follow a clean verb_noun pattern (list_projects, list_tasks, get_task, create_task, update_task). The lone `comment` is a bare verb with no object, a minor deviation rather than a different convention.
Six tools is well-scoped for a focused task-management integration, and the design wisely folds labels, assignees, priority, due date and project moves into create/update parameters instead of adding one tool per field. Every tool earns its place.
Task lifecycle is covered for create/read/list/update/comment, but there is no delete or archive operation for tasks and no way to create or manage projects beyond listing them. Comment reading is also capped at the 50 most recent with no pagination escape hatch, which will bite on long threads.
Maintenance
Related MCP Connectors
Local-first task manager: create, edit, and complete tasks, projects, and checklists via MCP.
Headless task management for bots, apps and AI agents. Remote MCP server, OAuth or access token.
Read and write Mission Control state via MCP — projects, tasks, subtasks, templates, status updates.
Create, list, and complete todo items through MCP.
Related MCP Servers
- AlicenseBqualityDmaintenanceEnables interaction with Vikunja task management instances through natural language. Supports comprehensive project and task operations including CRUD, assignments, labels, comments, relations, and attachments.3364 npm2MIT
- AlicenseNot gradedqualityDmaintenanceLightweight MCP server for Vikunja task management, providing tools to manage projects, tasks, labels, and comments via API.64 npmMIT
- AlicenseNot gradedqualityDmaintenanceBridges MCP clients to a self-hosted Vikunja instance, exposing tools for managing projects, tasks, labels, and comments.64 npmMIT
- AlicenseAqualityBmaintenanceEnables MCP clients to interact with a Vikunja instance through tools for listing, creating, updating, and removing tasks, projects, and labels. It deliberately avoids permanent task deletion, using a configurable label for soft removal instead.11MIT