Skip to main content

Altiplano

Altiplano

A small, dependable MCP server for Vikunja. Named after the Andean altiplano, the high plateau that is the Vicuña's native habitat.

Filtering and sorting are passed straight to the Vikunja API (server-side), so there is no client-side filtering engine and no paginate-then-filter pitfall.

Tools

Projects:

  • list_projects (includes parent_project_id, shows sub-project nesting)
  • create_project (title, parent_project_id?, description?) — pass parent_project_id for a sub-project

Tasks:

  • list_tasks (project_id, filter, sort_by, page, per_page)
  • get_task (task_id)
  • create_task (project_id, title, description?, priority?, due_date?, start_date?, end_date?)
  • update_task (task_id, title?, description?, done?, priority?, start_date?, end_date?)
  • set_reminders (task_id, reminders) — replaces the task's reminders with the given ISO 8601 datetimes; empty list clears

Labels:

  • list_labels
  • add_label (task_id, label_id)
  • remove_label (task_id, label_id)

Comments:

  • list_comments (task_id)
  • add_comment (task_id, comment)
  • update_comment (task_id, comment_id, comment) — replaces the comment text; get comment_id from list_comments
  • delete_comment (task_id, comment_id)

Assignees:

  • search_users (query) — find a user_id to assign
  • list_assignees (task_id)
  • add_assignee (task_id, user_id)
  • remove_assignee (task_id, user_id)

Credentials (no secrets in mcp.json)

The server resolves two values, in order:

  1. Environment variables VIKUNJA_URL and VIKUNJA_API_TOKEN.
  2. A per-device file of KEY=VALUE lines, default ~/.config/altiplano/env (override the path with ALTIPLANO_CONFIG).

VIKUNJA_URL is the base API URL including the version prefix (e.g. https://todo.example.com/api/v2).

Recommended so the your mcp.json carries no secrets:

  • Drop a per-device file and lock it down:
    mkdir -p ~/.config/altiplano
    printf 'VIKUNJA_URL=https://todo.example.com/api/v2\nVIKUNJA_API_TOKEN=tk_xxx\n' > ~/.config/altiplano/env
    chmod 600 ~/.config/altiplano/env
    
  • Or inject via the launcher's environment (e.g. a systemd unit EnvironmentFile= pointing at a chmod 600 file), which the server inherits.
  • For stronger setups, source the token from a secret manager/keychain at launch and export it into the environment.

Then mcp.json only needs the command, no env block, no plain-text secrets:

{
  "altiplano": {
    "command": "uvx",
    "args": ["altiplano@latest"]
  }
}

uvx fetches the newest version on its first run, then reuses a cached environment on every run after that. Restarting your MCP client does not change this.

@latest asks for the newest version and refreshes the cache. An exact pin such as altiplano@0.6.0 works too, since requesting a specific version cannot be satisfied from a cache holding a different one, at the cost of editing your MCP file on every upgrade.

If you suspect you are already on a stale version, uv cache clean altiplano then restart your client.

Choosing the API version

Vikunja 2.4.0 added a v2 API alongside v1, and this server speaks both. The version comes from the URL you configure, so there is nothing else to set:

VIKUNJA_URL ends in you get
/api/v2 the v2 API
/api/v1, or anything else the v1 API

Prefer /api/v2 if your server has it, since Vikunja has said v1 will eventually be withdrawn. Stay on /api/v1 for older servers; every tool works the same either way.

The differences are handled internally: v2 uses POST to create and PATCH to update where v1 uses PUT and POST, returns collections in a pagination envelope rather than a bare array, renames the user search parameter from s to q, and answers deletes with 204 rather than a message body. Tool arguments and return shapes are unchanged.

One difference is visible to you, and it is the reason to prefer v2: descriptions and comments are Markdown.

Markdown descriptions and comments (v2 only)

Vikunja stores task descriptions and comments as HTML. On v2 this server asks it to convert, so you write and read Markdown and never touch HTML:

create_task(project_id=12, title="Ship it", description="**bold** and a [link](https://example.com)")

Vikunja stores that as <p><strong>bold</strong> and a <a href="...">link</a></p>, and get_task hands it back as the Markdown you wrote. The same applies to update_task, create_project, add_comment and update_comment.

On v1 there is no conversion and the fields are HTML, so Markdown you send is stored verbatim and renders as literal asterisks.

Two things worth knowing:

  • v2 only converts on create and on full replace, never on a partial update. So changing a description reads the task first and writes it back whole, which costs one extra request and could lose a concurrent edit by something else. Updates that do not touch the description stay a single partial update.
  • Vikunja resolves @mentions during conversion, so writing @someone in a description notifies them.

Run

uv run altiplano                        # dev, from this directory
uvx --from /your/local/path altiplano   # local path
uvx altiplano@latest                    # from PyPI, refreshing the cache

Notes

  • Vikunja priority scale: 0 Unset, 1 Low, 2 Medium, 3 High, 4 Urgent, 5 DO NOW.
  • Dates are ISO 8601 datetimes. start_date/end_date mark the window you plan to work on a task (start work / finish work); due_date is the deadline.
  • The UI shows tasks by their project-local identifier (e.g. #50), which is not the global id the API uses.
  • Verified end to end against Vikunja v2.5.0 on both /api/v1 and /api/v2.
  • list_assignees needs a server where GET /tasks/{id}/assignees works. It answers 500 on v2.3.0, which was a server-side bug, and works on v2.5.0. Every other tool works on both.

Licence

MIT.

Support

RTFM, then RTFC... If you are still stuck or just need an additional feature, file an issue.

✌🏼

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

altiplano-0.7.0.tar.gz (966.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

altiplano-0.7.0-py3-none-any.whl (9.5 kB view details)

Uploaded Python 3

File details

Details for the file altiplano-0.7.0.tar.gz.

File metadata

  • Download URL: altiplano-0.7.0.tar.gz
  • Upload date:
  • Size: 966.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for altiplano-0.7.0.tar.gz
Algorithm Hash digest
SHA256 c730c44a4ffe6f8e9bd527d7a3537562c8812b9253ac208fb2ba289b35a7a1d2
MD5 c36d2c784b0a61d213e8c38d05e828b7
BLAKE2b-256 86f69e615d094a78c75f5fddd191f56e2b1a71ec952e8a0f2a842c294107951a

See more details on using hashes here.

File details

Details for the file altiplano-0.7.0-py3-none-any.whl.

File metadata

  • Download URL: altiplano-0.7.0-py3-none-any.whl
  • Upload date:
  • Size: 9.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for altiplano-0.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 066dcc928e4b6a837e7b74a9ae190d7b5f89706799175a0a7742bc442e512d89
MD5 62adde62f8d38093dc7163cb7fa55c0c
BLAKE2b-256 84b8ca89d54250140cf17321f88c0a142e8fcee444cefc3d6aa47f257198d343

See more details on using hashes here.

Release history Release notifications | RSS feed

2.0.1

2 files

2.0.0

2 files

1.2.0

2 files

1.1.0

2 files

1.0.0

2 files

0.14.1

2 files

0.10.0

2 files

0.8.6

2 files

0.8.5

2 files

0.8.1

2 files

0.8.0

2 files

0.7.1

2 files

This release

0.7.0 This release

2 files

0.6.0

2 files

0.4.0

2 files

0.3.0

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page