AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
MCP verified MIT Self-run

Vikunja Mcp

mcp-democratize-technology-vikunja-mcp · by democratize-technology

Model Context Protocol server for Vikunja task management. Enables AI assistants to interact with Vikunja instances via MCP.

No reviews yet
0 installs
3 views
0.0% view→install

Install

$ agentstack add mcp-democratize-technology-vikunja-mcp

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/mcp-democratize-technology-vikunja-mcp)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
5mo ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Vikunja Mcp? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Vikunja MCP Server

A Model Context Protocol (MCP) server that enables AI assistants to interact with Vikunja task management instances.

Features

  • Subcommand-based tools for intuitive AI interactions
  • Session-based authentication with automatic token management
  • Full task management operations implemented
  • Complete project management with CRUD operations
  • Label management for organizing tasks
  • Team operations for collaboration (get/update/members limited by API)
  • User management with settings and search
  • Webhook management for project automation
  • Batch import tasks from CSV or JSON files
  • Input validation for dates, IDs, and hex colors
  • Efficient diff-based updates for assignees
  • TypeScript with strict mode for type safety
  • Comprehensive error handling with typed errors and centralized utilities
  • Production-ready retry logic with opossum circuit breaker for resilience
  • Enhanced security with Zod-based input validation and DoS protection
  • Rate limiting protection against DoS attacks with configurable limits
  • Memory protection with pagination limits and usage monitoring
  • Simplified architecture with 90% code reduction for maintainability

🚀 Major Architectural Improvements (v0.2.0)

This release represents a massive architectural simplification that eliminates technical debt while enhancing security and reliability:

Storage Architecture Refactoring (90% Code Reduction)

  • Before: 33 files, 9,803 lines of over-engineered storage system
  • After: 4 files, essential functionality only
  • Eliminated: Complex orchestrators, health monitors, statistics tracking, migration systems
  • Result: Same external API with dramatically improved maintainability

Zod-Based Filter System (850+ Lines Removed)

  • Before: Custom tokenizer, parser, and validator with security vulnerabilities
  • After: Secure Zod schema validation with production-ready parsing
  • Enhanced: DoS protection, input sanitization, and comprehensive error handling
  • Result: Faster parsing, better security, and enterprise-grade reliability

Production-Ready Retry System (580+ Lines Replaced)

  • Before: Custom retry logic with maintenance overhead
  • After: Battle-tested opossum circuit breaker library
  • Features: Circuit breaker state sharing, automatic recovery, comprehensive monitoring
  • Result: Production resilience with battle-tested patterns

Zero Breaking Changes

All improvements maintain 100% backward compatibility with existing implementations while providing enhanced reliability and security.

Requirements

  • Node.js 20+ (LTS versions only)
  • Vikunja instance with API access
  • API token (starting with tk_) or JWT token for authentication

Installation

Option 1: Install from NPM (Recommended)

The easiest way to use vikunja-mcp is through npx in your Claude Desktop or other MCP-compatible client configuration:

{
  "vikunja": {
    "command": "npx",
    "args": ["-y", "@democratize-technology/vikunja-mcp"],
    "env": {
      "VIKUNJA_URL": "https://your-vikunja-instance.com/api/v1",
      "VIKUNJA_API_TOKEN": "your-api-token"
    }
  }
}

Option 2: Local Development

For development or customization:

git clone https://github.com/democratize-technology/vikunja-mcp.git
cd vikunja-mcp
npm install
npm run build

Then configure your MCP client:

{
  "vikunja": {
    "command": "node",
    "args": ["/path/to/vikunja-mcp/dist/index.js"],
    "env": {
      "VIKUNJA_URL": "https://your-vikunja-instance.com/api/v1",
      "VIKUNJA_API_TOKEN": "your-api-token"
    }
  }
}

Configuration

Logging Configuration

The server includes a structured logging system. Configure it via environment variables:

# Enable debug logging (default: false)
DEBUG=true

# Set specific log level (error, warn, info, debug)
# If not set, defaults to 'info' (or 'debug' if DEBUG=true)
LOG_LEVEL=debug

Log output includes timestamps and log levels:

[2025-05-25T17:00:00.000Z] [INFO] Vikunja MCP server started
[2025-05-25T17:00:00.100Z] [DEBUG] Executing tasks tool { subcommand: 'list', args: {...} }

All logs are written to stderr to keep stdout reserved for MCP protocol communication.

Authentication Methods

The Vikunja MCP server supports two authentication methods, each with different capabilities:

API Token Authentication (Default)

API tokens are the standard authentication method for Vikunja:

  • How to obtain: Go to Vikunja Settings → API Tokens → Create new token
  • Token format: Starts with tk_ (e.g., tk_abc123def456)
  • Capabilities: Full access to tasks, projects, labels, teams, and webhooks
  • Limitations: Cannot access user-specific endpoints (user profile, settings, export)
  • Best for: Automation, CI/CD, and general task management

JWT Authentication (Advanced)

JWT (JSON Web Token) authentication provides full access to all Vikunja endpoints:

  • How to obtain: Extract from your browser session (see instructions below)
  • Token format: Long string starting with eyJ (standard JWT format)
  • Capabilities: Full access to all endpoints including user management and export
  • Limitations: Tokens expire (typically after 24 hours)
  • Best for: User management, data export, and operations requiring user context
How to Extract Your JWT Token
  1. Log into Vikunja in your web browser
  2. Open Developer Tools (F12 or right-click → Inspect)
  3. Go to the Application/Storage tab
  4. Find the JWT token:
  • Look in Local Storage → your Vikunja domain
  • Find the key named token or similar
  • The value is your JWT token
  1. Copy the entire token value (it's quite long)
Using JWT Authentication
// Connect with JWT token - automatically detected!
vikunja_auth.connect({
  apiUrl: "https://your-vikunja-instance.com/api/v1",
  apiToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
})

Important Notes:

  • JWT tokens expire; you'll need to extract a new one when it expires
  • Token type is automatically detected based on format (no flag needed)
  • Some tools (users, export) are only available with JWT authentication

Quick Start

  1. Set up authentication (if not using environment variables):

``typescript vikunja_auth.connect({ apiUrl: "https://your-vikunja-instance.com/api/v1", apiToken: "your-api-token" }) ``

  1. Create your first task:

``typescript vikunja_tasks.create({ projectId: 1, title: "My first task via MCP!" }) ``

  1. List all your tasks:

``typescript vikunja_tasks.list({ allProjects: true }) ``

Usage

The MCP server exposes tools with subcommands. All operations require authentication first (either via environment variables or manual connection).

Authentication

// Connect with API token (automatically detected)
vikunja_auth.connect({
  apiUrl: "https://your-vikunja-instance.com/api/v1",
  apiToken: "tk_your-api-token"
})

// Connect with JWT token (automatically detected, enables additional tools: users, export)
vikunja_auth.connect({
  apiUrl: "https://your-vikunja-instance.com/api/v1",
  apiToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
})

// Check authentication status
vikunja_auth.status()

// Disconnect and clean up resources
vikunja_auth.disconnect()

Task Management Examples

// List all tasks across all projects
vikunja_tasks.list({ allProjects: true })

// List tasks for a specific project with pagination
vikunja_tasks.list({
  projectId: 1,
  page: 1,
  perPage: 20,
  sort: "due_date"
})

// List tasks with filters (high priority, not done)
vikunja_tasks.list({
  filter: "(priority >= 4 && done = false)"
})

// List tasks with simple filter
vikunja_tasks.list({
  filter: "priority >= 3"
})

// List tasks with complex filter conditions
vikunja_tasks.list({
  filter: "(priority >= 3 && priority  '2024-01-01')"
})

// Combine filter with search
vikunja_tasks.list({
  filter: "priority >= 4",
  search: "urgent"
})

// Create a new task with labels and assignees
vikunja_tasks.create({
  projectId: 1,
  title: "Complete documentation",
  description: "Update README with examples",
  dueDate: "2024-12-31T23:59:59Z",
  priority: 3,
  labels: [1, 2],      // Label IDs
  assignees: [1, 3]    // User IDs
})

// Create a recurring task (repeats every week)
vikunja_tasks.create({
  projectId: 1,
  title: "Weekly team meeting",
  description: "Sync up with the team",
  dueDate: "2024-12-01T10:00:00Z",
  repeatAfter: 7,      // Number of units
  repeatMode: "day"    // Unit: "day", "week", "month", or "year"
})

// Create a monthly recurring task
vikunja_tasks.create({
  projectId: 1,
  title: "Monthly report",
  repeatAfter: 1,
  repeatMode: "month"
})

// Get detailed information about a task
vikunja_tasks.get({ id: 123 })

// Update a task (partial updates supported)
vikunja_tasks.update({
  id: 123,
  done: true,
  priority: 5
})

// Update recurring settings on an existing task
vikunja_tasks.update({
  id: 123,
  repeatAfter: 14,     // Change to bi-weekly
  repeatMode: "day"
})

// Update task assignees (uses efficient diff-based approach)
vikunja_tasks.update({
  id: 123,
  assignees: [1, 2, 4]  // Only adds/removes differences
})

// Delete a task
vikunja_tasks.delete({ id: 123 })

// Bulk assign users to a task
vikunja_tasks.assign({
  id: 123,
  assignees: [2, 3, 4]
})

// Remove users from a task
vikunja_tasks.unassign({
  id: 123,
  assignees: [2, 4]  // Removes only these users
})

// List all assignees for a task
vikunja_tasks.list-assignees({ id: 123 })

// Add a comment to a task
vikunja_tasks.comment({
  id: 123,
  comment: "This task is now complete!"
})

// List all comments on a task
vikunja_tasks.comment({ id: 123 })

// Create a task relation (e.g., subtask, blocking, related)
vikunja_tasks.relate({
  id: 123,
  otherTaskId: 124,
  relationKind: "subtask"  // 124 is a subtask of 123
})

// Available relation kinds:
// - subtask: Other task is a subtask of this task
// - parenttask: Other task is the parent of this task
// - related: Tasks are related
// - duplicateof: This task is a duplicate of the other
// - duplicates: Other task is a duplicate of this one
// - blocking: This task blocks the other
// - blocked: This task is blocked by the other
// - precedes: This task precedes the other
// - follows: This task follows the other
// - copiedfrom: This task was copied from the other
// - copiedto: Other task was copied from this one

// Remove a task relation
vikunja_tasks.unrelate({
  id: 123,
  otherTaskId: 124,
  relationKind: "subtask"
})

// Get all relations for a task
vikunja_tasks.relations({ id: 123 })

// Add a reminder to a task
vikunja_tasks.add-reminder({
  id: 123,
  reminderDate: "2024-12-25T10:00:00Z"
})

// List all reminders for a task
vikunja_tasks.list-reminders({ id: 123 })

// Remove a specific reminder from a task
vikunja_tasks.remove-reminder({
  id: 123,
  reminderId: 1
})

// Bulk create multiple tasks at once (max 100)
vikunja_tasks.bulk-create({
  projectId: 1,
  tasks: [
    {
      title: "Task 1",
      description: "First task",
      priority: 3,
      labels: [1, 2]
    },
    {
      title: "Task 2", 
      dueDate: "2024-12-31T23:59:59Z",
      assignees: [1]
    },
    {
      title: "Weekly standup",
      repeatAfter: 7,
      repeatMode: "day"
    }
  ]
})

// Bulk update multiple tasks with the same field value
vikunja_tasks.bulk-update({
  taskIds: [123, 124, 125],
  field: "done",          // Field to update
  value: true             // New value for all tasks
})

// Other bulk update examples
vikunja_tasks.bulk-update({
  taskIds: [123, 124, 125],
  field: "priority",
  value: 5
})

vikunja_tasks.bulk-update({
  taskIds: [123, 124],
  field: "project_id",
  value: 2               // Move tasks to different project
})

vikunja_tasks.bulk-update({
  taskIds: [123, 124, 125],
  field: "labels",
  value: [1, 3, 5]       // Set same labels on all tasks
})

// Bulk delete multiple tasks (max 100)
vikunja_tasks.bulk-delete({
  taskIds: [123, 124, 125]
})

// Batch import tasks from CSV or JSON
vikunja_batch_import({
  projectId: 1,
  format: "json",
  data: JSON.stringify([
    {
      title: "Task 1",
      description: "First imported task",
      priority: 3,
      dueDate: "2024-12-31T23:59:59Z"
    },
    {
      title: "Task 2",
      labels: ["bug", "urgent"],  // Will look up label IDs by name
      assignees: ["john.doe"]      // Will look up user IDs by username
    }
  ])
})

// Import from CSV with headers
vikunja_batch_import({
  projectId: 1,
  format: "csv",
  data: `title,description,priority,dueDate,labels,assignees
"Task 1","Description with, comma",3,2024-12-31T23:59:59Z,"bug;feature","john.doe"
"Task 2","Another task",5,,"urgent","john.doe;jane.smith"`
})

// Dry run to validate without creating tasks
vikunja_batch_import({
  projectId: 1,
  format: "json",
  data: JSON.stringify([...]),
  dryRun: true  // Only validates, doesn't create tasks
})

// Continue on errors instead of stopping
vikunja_batch_import({
  projectId: 1,
  format: "csv",
  data: csvData,
  skipErrors: true  // Skip invalid tasks and continue with valid ones
})

Data Export Examples

// Export a project with all its data
vikunja_export_project({
  projectId: 1,
  includeChildren: false  // Only export the specified project
})

// Export a project including all child projects
vikunja_export_project({
  projectId: 1,
  includeChildren: true  // Recursively export child projects
})

// The export returns JSON data with the following structure:
// {
//   project: { ... },        // Project details
//   tasks: [ ... ],          // All tasks in the project
//   labels: [ ... ],         // All labels used in tasks
//   child_projects: [ ... ], // Nested child project exports (if includeChildren: true)
//   exported_at: "...",      // ISO timestamp of export
//   version: "1.0.0"         // Export format version
// }

// Request a full user data export (sent via email)
vikunja_request_user_export({
  password: "your-password"  // Required for security
})

// Download a previously requested user data export
vikunja_download_user_export({
  password: "your-password"  // Required for security
})

Project Management Examples

// List all projects
vikunja_projects.list()

// List projects with search and pagination
vikunja_projects.list({
  search: "frontend",
  page: 1,
  perPage: 10,
  isArchived: false
})

// Get a specific project
vikunja_projects.get({ id: 1 })

// Create a new project
vikunja_projects.create({
  title: "New Frontend Project",
  description: "React-based web application",
  hexColor: "#4287f5"
})

// Update a project
vikunja_projects.update({
  id: 1,
  title: "Updated Project Name",
  isArchived: true
})

// Archive a project
vikunja_projects.archive({ id: 1 })

// Unarchive a project
vikunja_projects.unarchive({ id: 1 })

// Delete a project
vikunja_projects.delete({ id: 1 })

// --- Project Hierarchy Management ---

// Create a child project
vikunja_projects.create({
  title: "Frontend Module",
  description: "React components",
  parentProjectId: 1,  // Will be a child of project 1
  hexColor: "#3498db"
})

// Get all direct children of a project
vikunja_projects.get-children({ id: 1 })
// Returns: Array of projects that have parentProjectId = 1

// Get complete project hierarchy as a tree
vikunja_projects.get-tree({ id: 1 })
// Returns: Project with nested children structure
// {
//   id: 1,
//   title: "Main Project",
//   children: [
//     {
//       id: 2,
//       title: "Frontend Module",
//       children: [
//         { id: 4, title: "Components", children: [] },
//         { id: 5, title: "Styles", children: [] }
//       ]
//     },
//     {
//       id: 3,
//       title: "Backend Module",
//

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [democratize-technology](https://github.com/democratize-technology)
- **Source:** [democratize-technology/vikunja-mcp](https://github.com/democratize-technology/vikunja-mcp)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.