kanboard-skillInteract with Kanboard project management via JSON-RPC API. Use when working with Kanboard tasks, projects, boards, columns, swimlanes, comments, subtasks, a...
Install via ClawdBot CLI:
clawdbot install bivex/kanboard-skillKanboard uses JSON-RPC 2.0 over HTTP POST. All calls go to a single endpoint.
| Mode | User | Password |
|------|------|----------|
| Application API | jsonrpc | $KANBOARD_API_TOKEN |
| User API | $KANBOARD_USER | $KANBOARD_PASS |
Application API skips permission checks and has no session. Use it for automation.
User API respects project permissions; required for "My…" procedures.
Always use this shell function to call the API:
kb() {
local method="$1"
local params="${2:-{}}"
local user="${KANBOARD_USER:-jsonrpc}"
local pass="${KANBOARD_PASS:-$KANBOARD_API_TOKEN}"
curl -s -X POST \
-u "$user:$pass" \
-H "Content-Type: application/json" \
-d "{\"jsonrpc\":\"2.0\",\"method\":\"$method\",\"id\":1,\"params\":$params}" \
"${KANBOARD_URL}/jsonrpc.php" | jq .
}
Check for errors in every response:
# Always verify result is not null/false
result=$(kb getMe | jq '.result')
if [ "$result" = "null" ] || [ "$result" = "false" ]; then
echo "Error: $(kb getMe | jq -r '.error.message // "unknown error"')"
fi
# List all projects
kb getAllProjects
# Get single project by ID
kb getProjectById '{"project_id": 1}'
# Get project by name
kb getProjectByName '{"name": "My Project"}'
# Create project
kb createProject '{"name": "New Project", "description": "Optional description"}'
# Update project
kb updateProject '{"id": 1, "name": "Renamed", "description": "Updated"}'
# Remove project (irreversible)
kb removeProject '{"project_id": 1}'
# Enable / disable project
kb enableProject '{"project_id": 1}'
kb disableProject '{"project_id": 1}'
# Get project activity feed
kb getProjectActivity '{"project_id": 1}'
# Get full board (columns + tasks) for a project
kb getBoard '{"project_id": 1}'
# List columns
kb getColumns '{"project_id": 1}'
# Get single column
kb getColumn '{"column_id": 5}'
# Create column
kb addColumn '{"project_id": 1, "title": "In Review", "task_limit": 3}'
# Update column
kb updateColumn '{"column_id": 5, "title": "Review", "task_limit": 5}'
# Remove column
kb removeColumn '{"column_id": 5}'
# Change column position
kb changeColumnPosition '{"project_id": 1, "column_id": 5, "position": 2}'
# Create task (minimum required: title + project_id)
kb createTask '{
"title": "Fix login bug",
"project_id": 1,
"column_id": 2,
"swimlane_id": 1,
"color_id": "red",
"priority": 2,
"due_date": "2025-12-31",
"description": "Detailed description here",
"owner_id": 3,
"tags": ["bug", "urgent"]
}'
# Get task by ID
kb getTask '{"task_id": 42}'
# Get task by reference (external ref)
kb getTaskByReference '{"project_id": 1, "reference": "EXT-123"}'
# List all tasks in a project (status: 1=open, 2=closed)
kb getAllTasks '{"project_id": 1, "status_id": 1}'
# Search tasks with advanced query
kb searchTasks '{"project_id": 1, "query": "assignee:me status:open"}'
# Update task
kb updateTask '{
"id": 42,
"title": "Fix login bug (updated)",
"column_id": 3,
"color_id": "green",
"priority": 1,
"due_date": "2025-11-30"
}'
# Move task to another column/swimlane/position
kb moveTaskToColumn '{
"project_id": 1,
"task_id": 42,
"column_id": 3,
"position": 1,
"swimlane_id": 1
}'
# Move task to another project
kb moveTaskToProject '{
"task_id": 42,
"project_id": 2,
"swimlane_id": 1,
"column_id": 1,
"category_id": 0
}'
# Duplicate task to another project
kb duplicateTaskToProject '{
"task_id": 42,
"project_id": 2
}'
# Close / Open task
kb closeTask '{"task_id": 42}'
kb openTask '{"task_id": 42}'
# Remove task (irreversible)
kb removeTask '{"task_id": 42}'
# Get task color list
kb getTaskColors
yellow, blue, green, purple, red, orange, grey, brown, deep_orange, dark_grey, pink, teal, cyan, lime, light_green, amber
# List subtasks for a task
kb getAllSubtasks '{"task_id": 42}'
# Create subtask
kb createSubtask '{
"task_id": 42,
"title": "Write unit tests",
"user_id": 3,
"time_estimated": 4
}'
# Update subtask (status: 0=todo, 1=in-progress, 2=done)
kb updateSubtask '{
"id": 10,
"task_id": 42,
"status": 1,
"time_spent": 2
}'
# Remove subtask
kb removeSubtask '{"subtask_id": 10}'
# List comments for a task
kb getAllComments '{"task_id": 42}'
# Create comment
kb createComment '{
"task_id": 42,
"user_id": 1,
"content": "This is a **markdown** comment."
}'
# Update comment
kb updateComment '{"id": 7, "content": "Updated comment text."}'
# Remove comment
kb removeComment '{"comment_id": 7}'
# List swimlanes for a project
kb getSwimlanes '{"project_id": 1}'
# Get active swimlanes only
kb getActiveSwimlanes '{"project_id": 1}'
# Create swimlane
kb addSwimlane '{"project_id": 1, "name": "Team Alpha"}'
# Update swimlane
kb updateSwimlane '{"swimlane_id": 3, "name": "Team Beta"}'
# Remove swimlane
kb removeSwimlane '{"project_id": 1, "swimlane_id": 3}'
# Change swimlane position
kb changeSwimlanePosition '{"project_id": 1, "swimlane_id": 3, "position": 1}'
# List categories for a project
kb getAllCategories '{"project_id": 1}'
# Create category
kb createCategory '{"project_id": 1, "name": "Backend"}'
# Update category
kb updateCategory '{"id": 5, "name": "Backend & API"}'
# Remove category
kb removeCategory '{"category_id": 5}'
# List all users (Application API only)
kb getAllUsers
# Get user by ID
kb getUserById '{"user_id": 3}'
# Get user by username
kb getUserByName '{"username": "alice"}'
# Create user
kb createUser '{
"username": "bob",
"password": "S3cur3P@ss",
"name": "Bob Smith",
"email": "bob@example.com",
"role": "app-user"
}'
# Roles: app-admin | app-manager | app-user
# Update user
kb updateUser '{"id": 3, "name": "Bob Jones", "email": "bob.jones@example.com"}'
# Disable / Enable user
kb disableUser '{"user_id": 3}'
kb enableUser '{"user_id": 3}'
# Remove user
kb removeUser '{"user_id": 3}'
# Current user (User API only)
kb getMe
kb getMyProjects
kb getMyDashboard
kb getMyActivityStream
kb getMyCalendar
kb getMyNotifications
# List project users
kb getProjectUsers '{"project_id": 1}'
# Add user to project
kb addProjectUser '{
"project_id": 1,
"user_id": 3,
"role": "project-member"
}'
# Roles: project-manager | project-member | project-viewer
# Change user role in project
kb changeProjectUserRole '{"project_id": 1, "user_id": 3, "role": "project-manager"}'
# Remove user from project
kb removeProjectUser '{"project_id": 1, "user_id": 3}'
# Add/remove group to project
kb addProjectGroup '{"project_id": 1, "group_id": 2, "role": "project-member"}'
kb removeProjectGroup '{"project_id": 1, "group_id": 2}'
# Get all tags for a project
kb getTagsByProject '{"project_id": 1}'
# Create tag
kb createTag '{"project_id": 1, "tag": "urgent"}'
# Update tag
kb updateTag '{"id": 4, "tag": "critical"}'
# Remove tag
kb removeTag '{"tag_id": 4}'
# Get tags for a task
kb getTaskTags '{"task_id": 42}'
# Assign tags to a task (replaces existing tags)
kb setTaskTags '{"project_id": 1, "task_id": 42, "tags": ["bug", "urgent"]}'
# Get link types
kb getAllLinks
# Get links for a task
kb getAllTaskLinks '{"task_id": 42}'
# Create task link
kb createTaskLink '{
"task_id": 42,
"opposite_task_id": 55,
"link_id": 1
}'
# Common link_id: 1=relates to, 2=blocks, 3=is blocked by, 4=duplicates, 5=is duplicated by
# Remove task link
kb removeTaskLink '{"task_link_id": 8}'
# Get app version
kb getVersion
# Get app timezone
kb getTimezone
# Get app default language
kb getDefaultLanguage
# Get current datetime
kb now
# Get available board column types
kb getDefaultTaskColors
# 1. Create project
project_id=$(kb createProject '{"name":"Sprint 1"}' | jq '.result')
# 2. Add columns
kb addColumn "{\"project_id\": $project_id, \"title\": \"Backlog\"}"
kb addColumn "{\"project_id\": $project_id, \"title\": \"In Progress\", \"task_limit\": 3}"
kb addColumn "{\"project_id\": $project_id, \"title\": \"Review\"}"
kb addColumn "{\"project_id\": $project_id, \"title\": \"Done\"}"
# 3. Add swimlane
kb addSwimlane "{\"project_id\": $project_id, \"name\": \"Team Alpha\"}"
# 4. Show board
kb getBoard "{\"project_id\": $project_id}"
task_id=42
project_id=1
# Get column IDs first
columns=$(kb getColumns "{\"project_id\": $project_id}" | jq '.result')
in_progress_col=$(echo $columns | jq '[.[] | select(.title=="In Progress")][0].id')
# Move task
kb moveTaskToColumn "{
\"project_id\": $project_id,
\"task_id\": $task_id,
\"column_id\": $in_progress_col,
\"position\": 1
}"
# Create parent task
task_id=$(kb createTask '{
"title": "Implement feature X",
"project_id": 1,
"priority": 2
}' | jq '.result')
# Add subtasks
kb createSubtask "{\"task_id\": $task_id, \"title\": \"Write spec\"}"
kb createSubtask "{\"task_id\": $task_id, \"title\": \"Implement\"}"
kb createSubtask "{\"task_id\": $task_id, \"title\": \"Write tests\"}"
kb createSubtask "{\"task_id\": $task_id, \"title\": \"Code review\"}"
project_id=1
# Get all open tasks, close those tagged "done"
kb getAllTasks "{\"project_id\": $project_id, \"status_id\": 1}" \
| jq -r '.result[] | select(.tags[]? == "done") | .id' \
| while read task_id; do
kb closeTask "{\"task_id\": $task_id}"
echo "Closed task $task_id"
done
# Robust call wrapper
kb_safe() {
local result
result=$(kb "$@")
local error=$(echo "$result" | jq -r '.error // empty')
if [ -n "$error" ]; then
echo "❌ API Error: $(echo "$result" | jq -r '.error.message')" >&2
return 1
fi
echo "$result" | jq '.result'
}
# Usage
kb_safe getAllProjects
kb_safe getTask '{"task_id": 99999}' # returns error if not found
Add to your OpenClaw environment:
# Required
export KANBOARD_URL="https://kanboard.example.com"
export KANBOARD_API_TOKEN="your_token_from_settings_page"
# Optional (for User API / "My…" procedures)
export KANBOARD_USER="your_username"
export KANBOARD_PASS="your_password_or_personal_token"
Getting your API token:
Personal API token (User API):
KANBOARD_PASS with your username as KANBOARD_USERYYYY-MM-DD format or Unix timestampspriority: 0=low, 1=normal, 2=high, 3=urgentstatus_id for tasks: 1=open, 2=closed/jsonrpc.php Generated Mar 1, 2026
A development team uses Kanboard to track bugs, features, and sprints across multiple projects. They create tasks with priorities and due dates, move them through columns like 'Backlog', 'In Progress', and 'Done', and add comments for updates. Subtasks break down complex issues, and swimlanes separate work by team or priority.
A marketing agency manages campaigns for clients by creating projects for each campaign. Tasks represent deliverables such as ad creatives, social media posts, and reports, assigned to team members with deadlines. Columns like 'Ideation', 'Production', and 'Review' track progress, and comments facilitate feedback without email clutter.
An IT department handles support requests by creating tasks for each ticket, categorized by urgency and type using colors and tags. Tasks move from 'Open' to 'In Progress' to 'Resolved' columns, with subtasks for steps like diagnostics and fixes. User API ensures only authorized staff access sensitive projects.
Event planners organize weddings or conferences by setting up a project for each event. Tasks cover venues, catering, and logistics, with due dates aligned to the event timeline. Swimlanes separate vendor management from attendee coordination, and comments log negotiations and changes in real-time.
A university research team uses Kanboard to manage experiments and publications. Projects correspond to studies, with tasks for literature review, data collection, and paper drafting. Columns reflect stages like 'Planning', 'Execution', and 'Analysis', and subtasks track individual researcher contributions.
A company offers integration services to connect Kanboard with other tools like Slack, GitHub, or CRM systems, automating task creation and updates. Revenue comes from subscription fees for managed integrations and custom development for enterprise clients, leveraging the JSON-RPC API for seamless data flow.
Consultants provide setup, customization, and training services for organizations adopting Kanboard, helping configure projects, columns, and workflows tailored to specific industries. Revenue is generated through hourly rates or fixed-price packages for onboarding and ongoing support, using the skill's examples as training materials.
A provider hosts and maintains Kanboard instances for clients, offering enhanced security, backups, and performance optimization. Revenue streams include monthly hosting fees, premium support plans, and add-ons like advanced reporting or mobile apps, utilizing the skill's API for automation and monitoring.
💬 Integration Tip
Use the core helper function 'kb' for all API calls to simplify authentication and error handling; set environment variables like KANBOARD_URL and KANBOARD_API_TOKEN for secure, reusable access across scripts.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Query the DeepWiki MCP server for GitHub repository documentation, wiki structure, and AI-powered questions.
Automated GitHub PR code review with diff analysis, lint integration, and structured reports. Use when reviewing pull requests, checking for security issues,...
Essential Git commands and workflows for version control, branching, and collaboration.
Advanced git operations beyond add/commit/push. Use when rebasing, bisecting bugs, using worktrees for parallel development, recovering with reflog, managing subtrees/submodules, resolving merge conflicts, cherry-picking across branches, or working with monorepos.
Format commit messages using the Conventional Commits specification. Use when creating commits, writing commit messages, or when the user mentions commits, git commits, or commit messages. Ensures commits follow the standard format for automated tooling, changelog generation, and semantic versioning.