vikunja-mcp
Click on "Install 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., "@vikunja-mcplist my projects"
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.
vikunja-mcp
A FastMCP server that exposes the Vikunja REST API as MCP tools — projects, tasks, labels, comments, saved filters, and webhooks — designed for multi-agent use behind scoped-mcp.
Why it's shaped this way — token passthrough
This server holds no Vikunja credentials. Vikunja issues a per-user API token, and each agent has its own account. Rather than teaching this server to fetch five tokens from Vault and pick one per call, it stays stateless: it reads the caller's bearer token off the incoming request and forwards it to Vikunja unchanged.
The token is injected upstream by each agent's own scoped-mcp instance (from its manifest, resolved out of Vault). The payoff:
Small blast radius — a compromise of this process exposes one in-flight request's token, never the whole set of agent credentials.
Real attribution — every call reaches Vikunja as the agent that made it, so task authorship, comments, and audit trails are per-agent for free.
flowchart LR
A[Agent] -->|MCP + own bearer token| S[scoped-mcp<br/>per-agent process]
S -->|mcp_proxy injects<br/>Authorization header| V[vikunja-mcp<br/>:8501 stateless]
V -->|forwards token verbatim| K[(Vikunja REST API<br/>/api/v1)]
W[Vault] -.->|per-agent token<br/>resolved into manifest| SBecause the token is the credential, a request with no Authorization header is rejected
fail-closed (AuthError) — there is no ambient fallback.
Related MCP server: vikunja-mcp
Tools
As of v0.2.0 the server covers the full Vikunja resource surface — 71 tools, each pinned to the correct verb by a wire test against the live Swagger spec.
Group | Tools |
Identity |
|
Projects |
|
Project sharing |
|
Tasks |
|
Assignees |
|
Relations / reminders |
|
Kanban buckets / views |
|
Labels |
|
Comments |
|
Filters |
|
Attachments |
|
Teams |
|
Webhooks |
|
Vikunja's REST idiom: PUT creates, POST updates. The tool names hide this, but it's why
*_createand*_updatehit the same path with different verbs.
Notes:
No
filter_list— Vikunja has noGET /filters; saved filters are exposed as pseudo-projects, so list them viaproject_listand fetch withfilter_get.Project sharing permission ints:
0= read,1= write,2= admin.Attachments upload base64 (multipart on the wire);
attachment_uploadhandles the encoding.
Extension hooks
Every tool is wrapped by server.instrument, which fires a pre/post hook chain around
each call — third parties can intercept or mutate calls without editing the server:
call → run_before_hooks(tool, kwargs) → [telemetry span] → tool(**kwargs)
→ run_after_hooks(tool, result) → returnRegister handlers with register_before(tool, handler) / register_after(tool, handler)
(hooks.py). Handlers run in registration order and propagate exceptions — they are not
fire-and-forget. contrib/audit_log.py is a worked example that records
actor/tool/args-hash without ever logging raw arguments or the bearer token. Full contract
and handler signatures: docs/extension-hooks.md.
Configuration
All configuration is environment variables. No token is ever configured here.
Var | Purpose | Default |
| Base URL of the Vikunja instance (no |
|
| Bind address |
|
| Bind port |
|
|
|
|
| Upstream timeout (seconds) |
|
| Log verbosity |
|
| Enable OTLP spans + metrics (needs | off |
| Enable the InfluxDB 3 metrics sink | off |
| InfluxDB 3 auth token |
|
| InfluxDB 3 target database |
|
| Enable the NATS metrics sink (e.g. | off |
| NATS subject for metric events |
|
Run
pip install -e ".[dev]"
VIKUNJA_URL=https://vikunja.example.com vikunja-mcpThen, as a caller, present a Vikunja API token as a bearer:
curl -H "Authorization: Bearer <vikunja-token>" http://127.0.0.1:8501/mcp/...In production this header is set by scoped-mcp, not by hand — see
docs/forge.md for the manifest wiring.
Telemetry
Logging (structlog JSON) is on by default. Metrics and tracing are off by default
and enable per-backend when the relevant env var is set — install the extra with
pip install 'vikunja-mcp[telemetry]'. Every tool call records call count, error count, and
upstream latency, plus an OTLP span (tool.<name>). Sinks are best-effort and
fire-and-forget: a telemetry backend being down never breaks a tool call. Forge ships
influxdb:3-core, so the InfluxDB sink uses the v3 write API. See
docs/telemetry.md for the full backend matrix.
Development
pip install -e ".[dev]"
ruff check src/ tests/
ruff format --check src/ tests/
pytest --cov=vikunja_mcp --cov-report=term-missingDeployment
Runs as a PM2 service on forge, fronted by scoped-mcp. See docs/forge.md
for the PM2 config, the scoped-mcp manifest, and the per-agent token wiring.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/TadMSTR/vikunja-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server