Skill flagged — suspicious patterns detected

ClawHub Security flagged this skill as suspicious. Review the scan results before using.

Kanboard

Interact with Kanboard project management via JSON-RPC API. Use when working with Kanboard tasks, projects, boards, columns, swimlanes, comments, subtasks, a...

MIT-0 · Free to use, modify, and redistribute. No attribution required.
0 · 26 · 0 current installs · 0 all-time installs
MIT-0
Security Scan
VirusTotalVirusTotal
Benign
View report →
OpenClawOpenClaw
Suspicious
medium confidence
!
Purpose & Capability
The SKILL.md clearly targets Kanboard JSON-RPC and requires KANBOARD_URL and KANBOARD_API_TOKEN and common CLI tools (curl, jq). However the registry metadata reported with the skill lists no required env vars or required binaries — a clear mismatch between what the skill claims to need and what the package metadata declares.
Instruction Scope
The instructions are narrowly scoped to calling Kanboard's JSON-RPC endpoint via curl and processing results with jq; they do not instruct reading arbitrary files or exfiltrating data. One minor issue: the runtime function references KANBOARD_PASS as an alternate env var fallback which is not declared elsewhere in the skill metadata.
Install Mechanism
There is no install spec and no code files — the skill is instruction-only. This minimizes disk-write and arbitrary code installation risk.
!
Credentials
The skill legitimately needs the Kanboard server URL and an API token. Those are proportional to the stated purpose. However: (1) the registry metadata did not list these required env vars (inconsistency), (2) the Application API token used as a password is described as skipping permission checks and thus is powerful — providing it to an agent gives broad access to the Kanboard instance.
Persistence & Privilege
The skill does not request persistent installation or system-wide changes; always:false and no install script are appropriate. Note the skill allows normal autonomous invocation (disable-model-invocation=false) which is platform default — combined with a powerful API token, autonomous calls could take sensitive actions, but autonomous invocation itself is not unusual.
What to consider before installing
This skill is an instruction-only Kanboard helper and largely matches its description, but there are metadata inconsistencies and the Kanboard API token it needs is powerful. Before installing: 1) Confirm the source and trustworthiness of the skill (homepage/source unknown). 2) Correct or confirm the registry metadata — it should declare KANBOARD_URL and KANBOARD_API_TOKEN and required binaries (curl, jq). 3) Provide a scoped or temporary API token if possible (prefer a token with limited scope or test on a non-production Kanboard instance) and rotate it after testing. 4) Note the SKILL.md references KANBOARD_PASS as an alternate env var — ensure you won't accidentally expose secrets via fallback vars. 5) If you are uncomfortable with the agent making changes autonomously, consider disabling autonomous invocation for this skill or restrict when it can be used.

Like a lobster shell, security has layers — review code before you run it.

Current versionv1.0.0
Download zip
latestvk97csx9425p5fn8phe14y0sq1x831cbz

License

MIT-0
Free to use, modify, and redistribute. No attribution required.

Runtime requirements

Environment variables
KANBOARD_URLrequired
KANBOARD_API_TOKENrequired

SKILL.md

Kanboard Skill

Overview

Kanboard uses JSON-RPC 2.0 over HTTP POST. All calls go to a single endpoint.

Make sure you have follow parameter to to access Kanboard:

  1. KANBOARD_URL, the server url.
  2. KANBOARD_API_TOKEN, the access api token.

Auth modes

Application API skips permission checks and has no session. Use it for automation.

Here is an example of curl:

curl "${KANBOARD_URL}/jsonrpc.php" -u "jsonrpc:$token" -H "Content-Type: application/json" -d "{\"jsonrpc\":\"2.0\",\"method\":\"$method\",\"id\":1,\"params\":$params}"

Core Helper

Always use this shell function to call the API:

kb() {
  local method="$1"
  local params="${2:-{}}"
  local token="${KANBOARD_PASS:-$KANBOARD_API_TOKEN}"

  curl -s -X POST \
    -u "jsonrpc:$token" \
    -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

Projects

# 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}'

Board & Columns

# 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}'

Tasks

# 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

Task color IDs

yellow, blue, green, purple, red, orange, grey, brown, deep_orange, dark_grey, pink, teal, cyan, lime, light_green, amber


Subtasks

# 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}'

Comments

# 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}'

Swimlanes

# 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}'

Categories

# 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}'

Users

# 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

Project Permissions

# 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}'

Tags

# 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"]}'

Task Links (Internal)

# 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}'

Application

# 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

Common Workflows

Create project with full setup

# 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}"

Move task through workflow

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 moveTaskPosition "{
  \"project_id\":  $project_id,
  \"task_id\":     $task_id,
  \"column_id\":   $in_progress_col,
  \"position\":    1,
  \"swimlane_id\": 1
}"

Create task with subtasks

# 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\"}"

Bulk close completed tasks

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

Setup & Configuration

Add to your OpenClaw environment:

# Required
export KANBOARD_URL="https://kanboard.example.com"
export KANBOARD_API_TOKEN="your_token_from_settings_page"

Getting your API token:

  1. Log in to Kanboard as admin
  2. Go to Settings → API
  3. Copy the token shown there

Notes

  • Kanboard use Http basic auth, pass token by --user/-u parameter. You must not set token at http header.
  • All dates use YYYY-MM-DD format or Unix timestamps
  • Task priority: 0=low, 1=normal, 2=high, 3=urgent
  • Kanboard supports batch requests — multiple JSON-RPC calls in one HTTP request (useful for bulk ops)
  • status_id for tasks: 1=open, 2=closed
  • API endpoint is always <KANBOARD_URL>/jsonrpc.php

Files

1 total
Select a file
Select a file to preview.

Comments

Loading comments…