🚀 Kanboard MCP Server
Model Context Protocol (MCP) Server for Kanboard Integration
A powerful Go-based MCP server that enables seamless integration between AI assistants (like Claude Desktop, Cursor) and Kanboard project management system. Manage your Kanboard projects, tasks, users, and workflows directly through natural language commands.

⚠️ Warning: To avoid issues like these:
We recommend using mcpproxy as a proxy solution.
📋 Table of Contents
- ✨ Features
- 🚀 Quick Start
- ⚙️ Configuration
- 🛠️ Available Tools
- 📖 Usage Examples
- 🔧 Development
- 📄 License
✨ Features
- 🔗 Seamless Kanboard Integration - Direct API communication with Kanboard
- 🤖 Natural Language Processing - Use plain English to manage your projects
- 📊 Complete Project Management - Handle projects, tasks, users, columns, and more
- 🔐 Secure Authentication - Support for both API key and username/password auth
- ⚡ High Performance - Built with Go for optimal performance
- 🎯 MCP Standard - Compatible with all MCP clients
🚀 Quick Start
Prerequisites
- Go 1.21 or higher
- Kanboard instance with API access
- MCP-compatible client (Cursor, Claude Desktop, etc.)
Installation
-
Clone the repository:
git clone https://github.com/bivex/kanboard-mcp.git cd kanboard-mcp -
Build the executable:
On Windows:
build-release.batOn Linux/macOS:
./build-release.shManual build:
go build -ldflags="-s -w" -o kanboard-mcp .
⚙️ Configuration
1. Environment Variables
Set up your Kanboard credentials and RBAC permissions using environment variables:
Required Credentials:
export KANBOARD_API_ENDPOINT="https://your-kanboard-url/jsonrpc.php"
export KANBOARD_API_KEY="your-kanboard-api-key"
export KANBOARD_USERNAME="your-kanboard-username"
export KANBOARD_PASSWORD="your-kanboard-password"RBAC Configuration (Optional):
Configure user roles for proper access control. If not set, the system will try to get roles from Kanboard API, falling back to app-user role.
# Application-level roles (comma-separated)
# If not set, roles are automatically retrieved from Kanboard API
export KANBOARD_USER_APP_ROLES="app-manager"
# Project-specific roles (format: "project_id:role,project_id:role")
# If not set, project roles are automatically retrieved from Kanboard API
export KANBOARD_USER_PROJECT_ROLES="1:project-manager,2:project-member"
# Debug mode - shows detailed permission checking logs
export KANBOARD_DEBUG="true"
# Skip RBAC checks for debugging (use with caution!)
export KANBOARD_SKIP_RBAC="false"Available Application Roles:
app-admin- Full system administrator accessapp-manager- Can create projects and manage usersapp-user- Basic user access (default)
Available Project Roles:
project-manager- Full project management accessproject-member- Can create/modify tasks and commentsproject-viewer- Read-only access to project
🔐 Authentication Methods:
Kanboard supports different authentication methods via KANBOARD_AUTH_METHOD:
-
global_token(default): Uses global API token withjsonrpc:<token>formatexport KANBOARD_API_KEY="5348e6b4846fe09fd1670e922bc13e086f0827d7a66e45815cd7c3a7f67b" export KANBOARD_AUTH_METHOD="global_token" # or omit (default) -
user_token: Uses user-specific API token with<username>:<token>formatexport KANBOARD_USERNAME="admin" export KANBOARD_API_KEY="81820aeb3454985b0ac12166225f1f072f523175a752541c8670cf44a032d" export KANBOARD_AUTH_METHOD="user_token" -
bearer: Uses Bearer token authenticationexport KANBOARD_API_KEY="your-token-here" export KANBOARD_AUTH_METHOD="bearer"
🔧 Troubleshooting RBAC Issues:
If you're getting "access denied" errors:
-
Check your user role in Kanboard:
- Go to Kanboard web interface
- Check your user profile/role settings
- Ensure you have appropriate permissions
-
Enable debug logging:
export KANBOARD_DEBUG="true"This will show your current roles and permission checks in the console.
-
Temporarily skip RBAC for testing:
export KANBOARD_SKIP_RBAC="true"⚠️ Warning: Only use for debugging! Disables all permission checks.
-
Manually set roles via environment:
export KANBOARD_USER_APP_ROLES="app-admin" export KANBOARD_USER_PROJECT_ROLES="27:project-manager"
2. MCP Client Configuration
Create the MCP configuration file for your client:
Location:
- Windows:
C:\Users\YOUR_USERNAME\AppData\Roaming\Cursor\.cursor\mcp_config.json - Linux/macOS:
~/.cursor/mcp_config.json
Configuration:
{
"mcpServers": {
"kanboard-mcp-server": {
"command": "/path/to/your/kanboard-mcp",
"args": [],
"env": {
"KANBOARD_API_ENDPOINT": "https://your-kanboard-url/jsonrpc.php",
"KANBOARD_API_KEY": "your-kanboard-api-key",
"KANBOARD_USERNAME": "your-kanboard-username",
"KANBOARD_PASSWORD": "your-kanboard-password",
"KANBOARD_USER_APP_ROLES": "app-manager",
"KANBOARD_USER_PROJECT_ROLES": "1:project-manager"
}
}
}
}3. Restart Your Client
After saving the configuration, restart your MCP client (Cursor, Claude Desktop, etc.) for changes to take effect.
🛠️ Available Tools
📁 Project Management
| Tool | Description | Example |
|---|---|---|
get_projects | 📋 List all projects | "Show me all Kanboard projects" |
create_project | ➕ Create new projects | "Create a project called 'Website Redesign' with description 'Redesign the company website' and owner 1" |
get_project_by_id | 🔍 Get project information by ID | "Get project details for ID 123" |
get_project_by_name | 🔍 Get project information by name | "Get project details for name 'My Project'" |
get_project_by_identifier | 🔍 Get project information by identifier | "Get project details for identifier 'WEB-APP'" |
get_project_by_email | 🔍 Get project information by email | "Get project details for email 'project@example.com'" |
get_all_projects | 📋 Get all available projects | "Show me all available projects" |
update_project | ✏️ Update a project | "Update project 1 with new name 'New Website' and description 'Updated description'" |
remove_project | 🗑️ Remove a project | "Remove project with ID 456" |
enable_project | ✅ Enable a project | "Enable project 123" |
disable_project | 🚫 Disable a project | "Disable project 123" |
enable_project_public_access | 🌐 Enable public access for a given project | "Enable public access for project 123" |
disable_project_public_access | 🔒 Disable public access for a given project | "Disable public access for project 123" |
get_project_activity | 📢 Get activity stream for a project | "Show me activity for project 123" |
get_project_activities | 📊 Get Activityfeed for Project(s) | "Get activities for projects 1, 2, and 3" |
📝 Task Management
| Tool | Description | Example |
|---|---|---|
get_tasks | 📋 Get project tasks | "Get tasks for 'Website Redesign' project" |
create_task | ➕ Create new tasks | "Create task 'Design homepage' in 'Website Redesign'" |
update_task | ✏️ Modify existing tasks | "Update task 123 with description 'New requirements'" |
delete_task | 🗑️ Remove tasks | "Delete task with ID 456" |
get_task | 🔍 Get task by the unique id | "Get details for task 789" |
get_task_by_reference | 🔍 Get task by the external reference | "Get task for project 1 with reference 'TICKET-1234'" |
get_all_tasks | 📋 Get all available tasks | "Get all active tasks for project 1" |
get_overdue_tasks | ⏰ Get all overdue tasks | "Show me all overdue tasks" |
get_overdue_tasks_by_project | ⏰ Get all overdue tasks for a special project | "Show me overdue tasks for project 1" |
open_task | ✅ Set a task to the status open | "Open task 123" |
close_task | ❌ Set a task to the status close | "Close task 123" |
move_task_position | ➡️ Move a task to another column, position or swimlane inside the same board | "Move task 123 to column 2, position 1, swimlane 1 in project 1" |
move_task_to_project | ➡️ Move a task to another project | "Move task 123 to project 456" |
duplicate_task_to_project | 📋 Duplicate a task to another project | "Duplicate task 123 to project 456" |
search_tasks | 🔍 Find tasks by using the search engine | "Search tasks in project 2 for query 'assignee:nobody'" |
assign_task | 👤 Assign tasks to users | "Assign the API task to John" |
set_task_due_date | 📅 Set task deadlines | "Set due date for login task to 2024-01-15" |
💬 Comment Management
| Tool | Description | Example |
|---|---|---|
create_comment | ➕ Create a new comment | "Create a comment 'Meeting notes' for task 123 by user 1, visible to app-managers" |
get_task_comments | 📋 Get task comments | "Show all comments for task 123" |
get_comment | 🔍 Get comment information | "Get details for comment 789" |
update_comment | ✏️ Update a comment | "Update comment 456 content to 'Revised notes'" |
remove_comment | 🗑️ Remove a comment | "Remove comment with ID 101" |
🏗️ Column Management
| Tool | Description | Example |
|---|---|---|
get_columns | 📋 List project columns | "Show me all columns in project 123" |
get_column | 🔍 Get a single column | "Get details for column 456" |
create_column | ➕ Add new columns | "Create a 'Testing' column in project 123 with 5 task limit and description 'For UAT testing'" |
update_column | ✏️ Modify column settings | "Change column 123 title to 'Review' and limit to 3 tasks, with description 'Needs final review'" |
change_column_position | 🔄 Change column positions | "Move column 123 to position 3 in project 456" |
delete_column | 🗑️ Remove columns | "Delete the unused 'Draft' column" |
🏷️ Category Management
| Tool | Description | Example |
|---|---|---|
get_categories | 📋 List project categories | "Show me all task categories for project 123" |
get_category | 🔍 Get category information | "Get details for category 456" |
create_category | ➕ Add task categories | "Create a 'Bug Fixes' category in project 123 with color 'red'" |
update_category | ✏️ Modify categories | "Rename category 123 to 'Critical Issues' and set color to 'blue'" |
delete_category | 🗑️ Remove categories | "Delete the unused 'Archive' category" |
🏊 Swimlane Management
| Tool | Description | Example |
|---|---|---|
get_swimlanes | 📋 List all swimlanes of a project (enabled or disabled) and sorted by position | "Show me all swimlanes for project 1" |
get_active_swimlanes | 📋 Get the list of enabled swimlanes of a project (include default swimlane if enabled) | "Get active swimlanes for project 1" |
get_swimlane | 🔍 Get a swimlane by ID | "Get swimlane details for ID 1" |
get_swimlane_by_id | 🔍 Get a swimlane by ID | "Get swimlane det |
…