Files
vikunja-mcp/instructions.txt
2026-04-15 01:00:10 -04:00

9.1 KiB

Vikunja MCP usage guide. This MCP server is your persistent memory and project management layer, backed by a self-hosted Vikunja instance. You are the only user. Follow these conventions exactly so that memories stored today remain findable in six months. VOCABULARY project container of tasks. One per repo, one for general memory, one per life area. Create once, reuse forever. task a single unit of work, note, or memory entry. Fields: title, description (markdown), done, priority (1-5), labels, bucket_id, created, updated. label a reusable tag. Cross-cutting across all projects. Labels have a numeric id that filters require. view a saved layout for a project (list, kanban, gantt, table). bucket a column inside a kanban view (Todo, In Progress, Done, ...). filter a saved query recallable by id. TAGGING RULES (MANDATORY) Labels are the primary recall mechanism. Without discipline here, memory becomes unsearchable noise. 1. Always namespace labels as "namespace:value". The only exceptions are the universal workflow tags listed below. Good: topic:postgres, kind:decision, area:homelab Bad: postgres, decision, homelab 2. Always lowercase. "topic:Postgres" and "topic:postgres" are two labels and will fragment recall. 3. Before creating a label, search with get__labels s=. Only create if no match exists. Reuse is the whole point. 4. Never invent synonyms. Once "topic:postgres" exists, never create "topic:postgresql" or "topic:pg". One canonical form per concept. 5. Tag aggressively. Every memory gets two to five labels. A decision about Postgres replication that you discovered reading the docs should carry: topic:postgres, topic:replication, kind:decision, source:docs. More angles means more recall paths. 6. Cache label ids within a session. Resolve each label once, build a local name-to-id map, stop re-resolving on every write. CANONICAL NAMESPACES topic: Technical subjects, tools, concepts, systems, protocols, anything you might want to recall by subject matter. Examples: topic:postgres, topic:docker, topic:auth, topic:networking, topic:dns, topic:linux, topic:irc, topic:nginx, topic:zfs, topic:wireguard, topic:bgp, topic:python, topic:golang, topic:bash. kind: The shape of the memory entry. What kind of thing is this? Examples: kind:fact, kind:decision, kind:preference, kind:reference, kind:snippet, kind:question, kind:lesson, kind:idea, kind:config, kind:howto, kind:troubleshoot, kind:workaround. repo: Cross-reference a memory to a specific codebase. Use ONLY in the Memory project to link a general memory back to a repo. Do NOT tag tasks inside a repo project with their own repo name, that is redundant since they already live in that project. Examples: repo:dotfiles, repo:vikunja-mcp. area: Broader life or work domain. Examples: area:infra, area:homelab, area:networking, area:security, area:learning. source: Where the information originated, when it matters. Examples: source:docs, source:manpage, source:rfc, source:github, source:irc, source:experiment. status: Temporal relevance markers for things that expire. Examples: status:current, status:outdated, status:blocked, status:wontfix. Add new namespaces when you genuinely need one. Keep the format namespace:value. If a candidate namespace would only ever have one or two entries, it probably belongs under topic: instead. Note on topic: scope. Programming languages, protocols, tools, and services all go under topic:. Do not create separate namespaces for languages or tools. topic:python, topic:go, topic:bash, topic:nginx are all correct. The following tags are allowed un-namespaced because they are universal workflow labels in a repo context: bug, feature, refactor, docs, breaking. Do not use these outside code projects. MEMORY CONVENTIONS One project titled "Memory" holds general long-term knowledge: facts, decisions, preferences, references, snippets, and anything that does not belong to a specific repo. Create it on first use if missing. Cache its id for the rest of the session. Every memory is a single task: title short headline, 3 to 10 words. Treat it like a filename. description full markdown body, arbitrarily long. This is the content. labels two to five tags following the rules above. priority 1-5, default 2. Reserve 4-5 for truly critical info. Evolving memories: add comments via put__tasks_taskID_comments rather than rewriting the description. Comments preserve the timeline. Superseded memories: set done=true. They stay searchable but are excluded from default "active" queries. NEVER store secrets, credentials, tokens, API keys, or private keys. PER REPOSITORY PROJECT CONVENTIONS One Vikunja project per code repository. Title must match the repo name. On first touch: 1. get__projects s= to check for an existing project 2. If missing, put__projects with {"title": "", "description": ""} 3. Ensure workflow labels exist: bug, feature, refactor, docs, breaking Task workflow: - Create tasks via put__projects_id_tasks - Every task gets a type label (bug | feature | refactor | docs) - Use the priority field (1-5) based on how critical the issue is. 5 = drop everything, 4 = important, 3 = normal, 2 = low, 1 = trivial. Do NOT use label-based priority. The numeric field is sufficient. - Mark done=true when complete. Never delete. History matters. - Record implementation notes via put__tasks_taskID_comments Session startup: call get__tasks with filter="project = && done = false" to see what is in flight. FILTER SYNTAX (CRITICAL) Operators: = != > >= < <= like in Combinators: && (and), || (or). Parentheses for grouping. Strings are double-quoted. Numbers and booleans are bare. Fields: title, description, done, priority, due_date, start_date, end_date, created, updated, labels, assignees, project, bucket_id. LABEL FILTERS USE NUMERIC IDS, NOT NAMES. 1. Resolve each tag name to its id via get__labels s= 2. Filter: labels = 3 3. Multiple: labels in 3,5,7 (comma separated, NO brackets, NO quotes, NO spaces after commas) Wrong: labels in ["topic:postgres"] Wrong: labels = "topic:postgres" Right: labels = 3 Right: labels in 3,5,7 Text search with like against title or description: title like "postgres" description like "replication" Dates are RFC3339 in double quotes: created > "2026-01-01" due_date < "2026-04-20" && done = false Combined examples: project = 5 && done = false labels = 3 && priority >= 4 (labels = 3 || labels = 5) && done = false title like "postgres" || description like "postgres" project = 5 && labels in 8,9 && done = false WRITE WORKFLOW (STORING A NEW MEMORY) 1. Decide the tag set. Aim for 2 to 5 labels. 2. For each tag, call get__labels s=. If missing, create with put__labels using a hex_color by namespace: topic=3b82f6 kind=8b5cf6 repo=10b981 area=f59e0b source=6b7280 status=ef4444 Cache ids for the session. 3. Resolve the Memory project id once via get__projects s=Memory. 4. Create the task via put__projects_id_tasks with {title, description, priority}. 5. Attach each label via put__tasks_task_labels with {"label_id": }. 6. Confirm by echoing the stored title and tag set. READ WORKFLOW (RECALLING MEMORIES) 1. Translate the question into candidate tags. 2. Resolve each tag to its id (cached when possible). 3. Build a filter: labels in 3,5,7. Add && done = false unless historical entries are explicitly wanted. 4. Call get__tasks with the filter, per_page 5-15. 5. Zero hits? Fall back to text search: title like "" || description like "" 6. Surface 1-3 matches concisely. Full descriptions only on request. DEFAULTS priority 1..5, 5 is highest. Set based on how critical the item is. hex_color 6-char hex, no leading hash done false by default per_page keep <= 20 unless a full dump is requested timezone UTC unless specified otherwise SAFETY - Always check-or-create for projects and labels. A duplicate Memory project splits the memory store and is a critical failure. - Confirm before destructive calls (delete, bulk update, label removal) when the target is ambiguous. - Verify ids by reading first when intent is vague. - Never store secrets, credentials, tokens, or private keys. - Security, password, token, migration, and test-fixture endpoints are not exposed by this MCP.