Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
VIKUNJA_URLNoThe URL of the Vikunja API. Must end in /api/v1 or /api/v2 (e.g., https://todo.example.com/api/v2).
ALTIPLANO_CONFIGNoPath to a file containing KEY=VALUE pairs (defaulting to ~/.config/altiplano/env) with VIKUNJA_URL and VIKUNJA_API_TOKEN. Use absolute paths; ~ is not expanded in custom paths.
VIKUNJA_API_TOKENNoThe Vikunja API token with scopes covering the tools you intend to call.

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
search_usersA

Search users by name or username. Use this to find a user_id for assignees.

list_assigneesC

List the users assigned to a task.

add_assigneeC

Assign a user to a task.

remove_assigneeB

Unassign a user from a task.

list_commentsA

List comments on a task.

add_commentC

Add a comment to a task.

update_commentA

Replace the text of an existing comment. Get comment_id from list_comments.

delete_commentB

Delete a comment from a task. Get comment_id from list_comments.

list_kanban_viewsA

List a project's kanban views, with the bucket ids that give them meaning.

Most projects have one. Pass an id from here as view_id to the bucket tools to target a specific one.

bucket_configuration_mode is manual when you arrange tasks yourself, or filter when Vikunja builds a bucket per filter. In filter mode, moving a task between buckets is unavailable.

list_bucketsA

List the columns of a project's kanban view, in board order.

The columns alone, with no tasks in them. list_board takes the same arguments and returns each column with its tasks.

limit is the most tasks the bucket accepts, where 0 means no limit; a move into a full bucket is refused. Vikunja does not populate task counts on this endpoint, and list_board reports them.

create_bucketA

Add a column to a project's kanban view. It goes on the right-hand end.

limit caps how many tasks the column accepts, and moves into a full one are refused; leave it out, or pass 0, for no limit.

update_bucketA

Rename a column, or change how many tasks it accepts.

limit is the most tasks the column takes, and 0 means no limit. Lowering it below the number already there is allowed: Vikunja keeps them and refuses the next move in.

Neither API version has a partial update for a bucket. This reads the column and writes it back whole, and a body with only a title resets limit to 0 on both versions. There is also no endpoint for reading one bucket. The read comes from the view's bucket list, and a bucket_id absent from that view is refused before anything is written.

Position is preserved. To move a column, use the Vikunja web interface: this API exposes no ordering call.

delete_bucketA

Delete a column from a project's kanban view.

Vikunja moves the tasks it held to the default bucket, leaving them intact. A view keeps at least one column, and the last one cannot be removed.

list_boardA

The whole board: a kanban view's columns with the tasks sitting in each.

list_buckets answers the thinner question, the columns alone, and takes the same arguments. Reach for that one when the tasks are of no interest, and for this one when they are.

task_count is the column's true size, which can exceed the tasks returned: Vikunja caps how many it sends per column. To reach the rest, narrow with filter, the same server-side syntax list_tasks takes.

list_task_placementsC

Where one task sits: the column holding it, one entry per kanban view.

A task holds a position in every kanban view of its project. A project with two boards puts the task in two columns. Usually there is one.

The bucket_id on a task read any other way is 0. That field only means something inside a view.

move_task_to_bucketA

Move a task into a kanban bucket. Re-sending the same bucket does nothing.

This changes more than the column, and list_kanban_views tells you which bucket is which:

  • Moving into the done bucket marks the task done, and moving it out un-marks it.

  • A repeating task moved into the done bucket is reopened and sent to the default bucket.

  • A bucket at its task limit refuses the move.

Only meaningful when the view's bucket_configuration_mode is manual. In filter mode the filters decide which bucket a task sits in.

The project is read from the task. That costs a request and removes an argument that could contradict the task it was given.

list_labelsA

List all labels.

create_labelA

Create a label, which add_label can then attach to tasks.

hex_color is six hex digits with no leading #, as list_labels reports them.

description is rich text, written as Markdown. Vikunja stores it as HTML and v2 converts on the way in.

update_labelB

Update a label. Only the fields you pass change. Every task with the label sees the change.

hex_color is six hex digits with no leading #, and an empty string clears it. description is Markdown.

v1 has no partial update, and neither does a description change on v2. Both read the label and write it back with your changes merged in, at the cost of one extra request. Everything else on v2 is a single PATCH.

delete_labelA

Delete a label everywhere. It comes off every task that has it.

remove_label takes a label off one task and leaves the label itself alone.

add_labelB

Attach a label to a task.

remove_labelB

Remove a label from a task.

list_projectsA

List all projects (boards). parent_project_id shows sub-project nesting.

Vikunja leaves archived projects out of this endpoint. include_archived adds them back alongside the active ones, and is_archived on each result says which is which. An archived project is otherwise unreachable through this tool, and its id is what update_project needs to bring it back.

create_projectA

Create a project. Pass parent_project_id to create it as a sub-project.

update_projectA

Update a project. Only the fields you pass change.

is_archived archives and unarchives, and Vikunja has no separate archive endpoint. Archiving has two consequences worth knowing before using it. The project drops out of list_projects unless that call is given include_archived: true. And Vikunja then refuses every other edit to it, and to the tasks in it, with a 412 naming the archive. Unarchive it before changing anything else on it.

parent_project_id re-parents the project. Pass the id of the project it should sit under. hex_color is six hex digits with no leading #, and an empty string clears it. description is Markdown.

v1 has no partial update, and neither does a description change on v2. Both read the project and write it back with your changes merged in, at the cost of one extra request. Everything else on v2 is a single PATCH.

delete_projectA

Delete a project, everything in it, and every project under it.

This cascades. Deleting a parent takes its sub-projects, every task in all of them, and each task's comments, labels, and assignees. Checked against Vikunja 2.5.0 with a parent, one sub-project, and a task: all three ids read 404 afterwards.

Vikunja soft-deletes and documents a 30 day retention window, while exposing no endpoint to list or restore anything deleted. Through this API the call is permanent. Confirm the id with list_projects first, and look there for a parent_project_id matching this one: any project that names it goes too.

To put a project out of the way and keep it, call update_project with is_archived: true.

add_relationA

Relate one task to another. Defaults to a plain, symmetric related link.

Kinds: subtask, parenttask, related, duplicateof, duplicates, blocking, blocked, precedes, follows, copiedfrom, copiedto.

task_id is the base task and other_task_id is the one being related to it. That direction decides the asymmetric kinds: subtask makes the other task a child of this one. Needs write access to the base task and read access to the other; they do not have to be in the same project.

remove_relationA

Remove a relation between two tasks.

The kind has to match the one the relation was created with; see add_relation for the list. get_task reports what a task currently has.

list_tasksA

List tasks in a project.

filter and sort_by are passed to Vikunja and applied server-side, e.g. filter="done = false && priority >= 4", sort_by="priority". Vikunja filters then paginates. Results are complete at any page size.

search_tasksA

Search tasks across every project you can see.

list_tasks needs to be told a project. This is the tool for "find this task, I do not remember where it lives", and every result reports its project_id.

query is a text search over titles and descriptions. filter and sort_by are the same server-side syntax list_tasks takes. Vikunja documents the text search as incompatible with a filter. Use one or the other.

get_taskB

Get a single task with full detail. On v2 the description is Markdown.

create_taskA

Create a task in a project.

start_date and end_date are ISO 8601 datetimes marking the window you plan to work on the task (start work / finish work), distinct from due_date (the deadline).

percent_done is a fraction despite the name. A quarter done is 0.25. Vikunja does not validate it, and 50 is stored as 50.

repeat_after is a number of seconds, and repeating happens when the task is marked done: it reopens itself and moves its due date and reminders forward. repeat_mode is 0 to advance by repeat_after, 1 to repeat monthly and ignore repeat_after, or 2 to count from the day it was completed. Give a repeating task a due_date. It reopens whether or not there is a date to advance, and one with no dates can never be closed.

bulk_create_tasksA

Create several tasks in one project, in one request. Needs the v2 API.

Vikunja creates the batch atomically: if one entry is invalid then none are created, and the error names the entry that failed. The tasks also keep the order they were given. A loop of create_task calls races: a numbered plan can come back shuffled, and a failure halfway through leaves the rest uncreated.

Each entry is an object taking the same fields as create_task. title is required; description, priority, due_date, start_date, end_date, percent_done, is_favorite, repeat_after, and repeat_mode are optional and mean what they do there, including an empty string to clear a date. Anything else is refused. A dropped key would read as a task created with a date or a priority it never got. Vikunja caps a batch at 100.

Returns a summary per created task, in creation order. Call get_task for the full detail of one.

update_taskA

Update a task. Only the fields you pass change. Use done to open/close it.

v1 has no partial update. There, this reads the task and writes it back with your changes merged in, at the cost of one extra request. v2 is a single PATCH unless a description is involved.

due_date is the deadline. start_date and end_date are ISO 8601 datetimes marking the window you plan to work on the task (start work / finish work). Pass an empty string to any of the three to clear it.

percent_done is a fraction despite the name. A quarter done is 0.25. Vikunja does not validate it, and 50 is stored as 50.

repeat_after is a number of seconds. Setting it changes what done means for this task: it reopens itself with its dates moved forward. repeat_mode is 0 to advance by repeat_after, 1 to repeat monthly and ignore repeat_after, or 2 to count from the day it was completed. A repeating task with no dates can never be closed: it reopens regardless.

Two wrinkles in what comes back. On v2 a partial update returns the description as the stored HTML. v2 does not convert on a PATCH. Call get_task when you need it as Markdown. And a write that changes nothing returns {"ok": true, "unchanged": true} there, which is Vikunja answering 304.

move_taskA

Move a task to another project. Needs write access to the target.

Vikunja has no endpoint for this. A task's project_id is writable and setting it is the move. This costs what an update costs: two requests on v1, one on v2.

Labels, assignees, comments, relations, and dates all come along. The project-local identifier derives from the project the task is in, and is reassigned on arrival.

duplicate_taskA

Copy a task, with its labels, assignees, attachments, and reminders.

The copy lands in the same project as the original and links back to it with a copiedfrom relation. Vikunja offers no way to duplicate straight into another project; call move_task on the copy for that.

Returns the copy, with the id a caller needs to act on it. Vikunja wraps this one response in a duplicated_task envelope on both API versions, and that wrapper is removed here. A body without the key is passed through whole.

bulk_update_tasksA

Set done or priority on many tasks in one request.

Only the fields you pass are written, on either API version. This endpoint takes the field names separately from the values. That makes it a genuine partial update on v1 too, where updating a single task is a replace.

You need write access to every project involved. If it is missing on even one, the whole request is refused and nothing changes.

set_remindersA

Replace a task's reminders with the given ISO 8601 datetimes. Empty list clears them.

Nothing else about the task changes. On v1 that costs an extra request: its update endpoint is a replace, and the task has to be read and written back whole. On v2 it is a single partial update.

delete_taskA

Delete a task. There is no way to undo this through the API.

Vikunja soft-deletes, and documents deleted tasks as retained for 30 days before permanent removal, while exposing no endpoint to list or restore them. The row outlives the task and stays unreachable from here. Treat this as irreversible and confirm the id first. Deleting a task also takes its comments, labels, and assignees with it.

Prompts

Interactive templates invoked by user choice

NameDescription
altiplano_guideHow to drive Altiplano's tools: resolving ids, sequencing calls across tools, the calls that cannot be undone, the v1 and v2 differences, and what breaks when deploying `altiplano-http` as a shared service. Load this before making changes through the tools.

Resources

Contextual data attached and managed by the client

NameDescription

No resources

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/aichholzer/altiplano'

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