Skip to main content
Glama

vikunja-mcp

An MCP server for Vikunja task management, designed to work as a claude.ai / Claude Desktop custom connector — so Claude can view, add, complete, edit, and delete your tasks from the web or desktop app.

Talks to Vikunja's REST API with a personal API token. Targets Vikunja v0.24+ / v2.x (task listing via project views; updates send the full task object so nothing gets zeroed). Built with FastMCP; authentication uses GitHub OAuth via FastMCP's OAuth proxy, restricted to an allowlist of GitHub usernames.

Tools

Tool

Description

list_projects

Show projects; marks the default

create_project

Create a new project

list_tasks

Open tasks (or all with include_done), sorted by due date

get_task

Full detail for one task, including notes

add_task

Add a task — due date, priority, notes

complete_task / reopen_task

Toggle done

edit_task

Change title / due / priority / notes

delete_task

Permanent delete; requires confirm=true

Tasks are matched by numeric id or title substring; ambiguous matches return candidates so the model can retry with an id. Tools without project target your default project (VIKUNJA_DEFAULT_PROJECT, falling back to Inbox, then the first project). Priority uses Vikunja's scale: 1 low → 5 DO NOW (higher = more urgent).

Related MCP server: Vikunja MCP Server

Setup

1. Vikunja API token

In Vikunja: Settings → API Tokens → Create a token. Grant it read/write on Projects and Tasks (add other scopes only if you extend the server). The token goes in VIKUNJA_API_TOKEN (or a secret file via VIKUNJA_API_TOKEN_FILE).

2. GitHub OAuth app (connector authentication)

  1. https://github.com/settings/developersOAuth Apps → New OAuth App.

  2. Authorization callback URL: https://vikunja-mcp.example.com/auth/callback (your MCP_BASE_URL + /auth/callback).

  3. Register, generate a client secret, and set GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET / ALLOWED_GITHUB_USERS.

Leaving the client ID/secret unset runs the server unauthenticated — local testing only.

3. Configuration reference

Variable

Required

Description

VIKUNJA_URL

yes

Vikunja base URL, e.g. https://tasks.example.com

VIKUNJA_API_TOKEN

yes

API token (or VIKUNJA_API_TOKEN_FILE)

VIKUNJA_DEFAULT_PROJECT

no

Default project title or id (default Inbox)

TZ

no

Timezone for due-date input/display

MCP_BASE_URL

with auth

Public URL of this server

GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET

with auth

OAuth app credentials (or _FILE)

ALLOWED_GITHUB_USERS

with auth

Comma-separated GitHub logins allowed in

CONSENT_MODE

no

external (default), true, remember, false — see below

ALLOWED_CLIENT_REDIRECT_URIS

no

Redirect-URI patterns clients may register (default: claude.ai callback + localhost)

HOST / PORT / MCP_PATH

no

Bind address (0.0.0.0), port (8000), path (/mcp)

FASTMCP_HOME

no

OAuth client-registration storage (/data in Docker)

4. Run it

See compose.example.yml. Expose it publicly at MCP_BASE_URL through your reverse proxy; optionally restrict ingress to Anthropic's egress range (160.79.104.0/21). Persist /data or connected clients must re-authorize after every restart.

5. Verify, then connect Claude

npx @modelcontextprotocol/inspector   # → https://vikunja-mcp.example.com/mcp

Then claude.ai (or Claude Desktop) → Settings → Connectors → Add custom connector with the same URL. You'll land on GitHub's authorize page; approve, and the tools appear. Ask Claude: "what's on my task list?"

Why CONSENT_MODE=external is the default

FastMCP's built-in consent page (as of 3.4.4) regenerates its CSRF token on every GET of the consent URL. Browsers and claude.ai routinely prefetch that URL, invalidating the token the visible page holds, so submitting the form fails with "Invalid or expired consent token". external skips that page and delegates consent to GitHub's own authorization screen. The client redirect-URI allowlist (claude.ai + localhost by default) prevents the classic risk of a consent-less flow — an arbitrary dynamically-registered client silently capturing an authorization code.

Failure modes

  • 401 from Vikunja → the API token is wrong, expired, or revoked; create a new one.

  • 403 from Vikunja → the token is missing a scope for that operation — recreate it with Projects + Tasks read/write.

  • GitHub login succeeds but tools are denied → your login isn't in ALLOWED_GITHUB_USERS (check logs for denied authenticated GitHub user).

  • Connector breaks after a redeploy/data wasn't persisted, or the GitHub client secret changed (registration storage is keyed to it). Re-add the connector.

Development

uv sync
uv run pytest

License

MIT

A
license - permissive license
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

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/crosbyh/vikunja-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server