Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
KANBANTOOL_DOMAINYesYour account's subdomain prefix (e.g., 'acme' for https://acme.kanbantool.com).
KANBANTOOL_API_TOKENYesBearer token for the Kanban Tool API v3. Obtain from Profile -> API tokens in your Kanban Tool account.
KANBANTOOL_LOG_LEVELNoOptional. Set to 'INFO' for one stderr line per request, 'DEBUG' for more detail. Output goes to stderr. Default silent.
KANBANTOOL_READ_ONLYNoOptional. Set to '1', 'true', 'yes', or 'on' to register only read-class tools. Default unset (full tool surface).

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{
  "listChanged": true
}
logging
{}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
extensions
{
  "io.modelcontextprotocol/ui": {}
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
pingA

Smoke-test the MCP transport. Returns the literal string pong.

list_boardsA

List boards visible to the authenticated user. Use this to discover board_id values for the other tools.

whoamiA

Fetch the authenticated user's profile.

Returns the User you're acting as — id, name, role flags, locale, timezone. Use this to resolve "me" / "myself" references in user requests (assign to meassigned_user_id from this response) or to show the LLM whose perspective it's operating from.

get_userA

Fetch one user by id. Useful after list_board_collaborators finds a candidate by name — call this to confirm role flags and active state before assigning. Raises KanbanToolHTTPError(404) for unknown ids.

list_board_collaboratorsA

List the users with access to board_id.

The Kanban Tool API v3 has no bulk list-users endpoint, so this is the canonical way to discover user IDs for assigned_user_id on tasks. Costs one HTTP call (the same as get_board — collaborators come inline on the detail payload). For richer per-user fields, follow up with get_user(id).

list_custom_field_definitionsA

List the per-board metadata for the 15 custom-field slots.

Each task has up to 15 custom_field_N values surfaced as Task.custom_fields["custom_field_N"]. The slot number alone tells you nothing about what's IN it on a given board — call this tool once per board to learn the labels, types, and enabled state, then interpret task values accordingly.

Returns the 15 definitions in slot order (1..15) regardless of which are enabled. Slots with enabled=False are usually dormant on that board's UI even if individual tasks happen to carry values.

get_boardA

Fetch one board with its columns, swimlanes, and custom-field definitions.

Use this when you need column/lane ids for move_task or create_task. Raises KanbanToolHTTPError(404) if the board id is unknown or hidden.

get_taskA

Fetch one task by id. Returns a Task with subtask/comment counts, total tracked time, and inline subtasks.

Subtasks live on Task.subtasks directly — no extra round-trip needed (use list_subtasks only when you want just the list and not the rest of the task).

Raises KanbanToolHTTPError(404) if the task is unknown or inaccessible.

recent_changesA

Fetch a board's changelog (Kanban Tool has no webhooks; poll this instead).

since is required. Pass the created_at of the newest entry you've already seen; on the first poll, use datetime.now(UTC) - timedelta(hours=1) (or whichever lookback window matches your use case). Entries come newest-first. Poll sparingly: 30-120s cadence, not per-keystroke.

Raises ValueError if since is None (rather than fetching the full history) — keeps responses bounded by construction.

search_tasksA

Search tasks across boards using Kanban Tool's query DSL.

query is forwarded verbatim — do not URL-encode, do not wrap the whole expression in quotes. Quote individual values only when they contain spaces (e.g. name:"ship the thing"). Terms combine with spaces and are AND-ed.

Supported operators:

  • @username — assignee, e.g. @alice

  • name:<text> — title contains

  • priority:<level> — e.g. priority:high

  • tags:<tag> — tag match

  • due_date=<iso-date> — e.g. due_date=2026-05-01

  • subtasks_count<N> — also >, =

  • archived:<bool> — include archived

Unknown operators silently return zero results, so don't invent syntax for things the DSL doesn't cover (comment full-text, fuzzy match) — say so instead. board_id scopes to one board (omit to search all visible). limit is clamped to 50; paginate further with page (1-indexed).

Returns a SearchResults wrapper:

  • results — the list of matched Task objects on this page.

  • total_count — total matches across all pages (from the API's pagination envelope; None if the API omits the envelope).

  • page — 1-indexed page number of this response.

  • has_moreTrue when at least one further page exists. Use this to decide whether to bump page and call again, instead of heuristics on len(results) == limit (which is wrong on the last page).

create_taskA

Create a new task on a board. Only name and board_id are required.

lane_id is the target column (matches Task.lane_id on fetched tasks). assigned_user_id sets the single assignee — Kanban Tool tasks have one assignee, not a list. (The API silently ignores a legacy assignees: [int] payload on writes, so this kwarg is the wire field name directly.) priority accepts the string enum or the raw integer; tags is a comma-separated string; due_date is an ISO 8601 string forwarded as-is. Unset kwargs are omitted from the request, never sent as explicit null.

Common 422s (KanbanToolValidationError with parsed field_errors): name empty/missing → fix by passing a non-empty string; lane_id belongs to a different board → resolve column ids on the target board first via get_board(board_id).columns; assigned_user_id not a board collaborator → check via list_board_collaborators(board_id).

update_taskA

Partially update a task's fields. Only the kwargs you pass are sent; None means omit, not clear (the API ignores nulls, doesn't wipe).

Field set mirrors create_task; same wire conventions for priority, tags, and date fields. assigned_user_id sets the single assignee — Kanban Tool tasks have one assignee, not a list. For column/lane/position changes prefer move_task — it's the intent-revealing surface for that workflow.

Raises ValueError if every field is None (no-op guard).

Common 422s (KanbanToolValidationError with parsed field_errors): lane_id from a different board → use get_board(board_id).columns on the destination board first; assigned_user_id not a board collaborator → list_board_collaborators(board_id) to confirm.

move_taskA

Move a task between columns, swimlanes, or positions on its board.

At least one of column_id / swimlane_id / position must be set, otherwise raises ValueError before issuing HTTP. column_id matches the Task.lane_id on fetched tasks. Moves are scoped to the task's current board — there is no cross-board move surface.

Common 422s (KanbanToolValidationError with parsed field_errors): column_id doesn't belong to the task's board → fetch valid column ids via get_board(get_task(task_id).board_id).columns and pick from those; swimlane_id doesn't exist on the task's board → same fix via .swimlanes on the same Board.

archive_taskA

Archive a task. Returns the updated Task (caller can confirm is_archived=True).

Idempotent: re-archiving an already-archived task succeeds. There is no unarchive_task yet — archiving is currently one-way from this surface.

Failure modes: KanbanToolHTTPError(404) when the task id is unknown (verify via get_task(task_id) first if you're unsure); KanbanToolPermissionError(403) when the authenticated user lacks write access to the task's board.

set_custom_fieldA

Set or clear one of the 15 custom_field_* slots on a task.

slot selects which numbered slot to write (1..15 inclusive — the Kanban Tool API exposes exactly 15). Pair with list_custom_field_definitions(board_id) to learn each slot's label and type on a given board before writing.

value is sent verbatim — strings, numbers, and booleans all work. Pass value=None to clear the slot: the wire body explicitly sends null (not omits the key), and a subsequent get_task will see custom_field_N: null. This differs from update_task semantics where None means omit; for custom fields None means clear.

Common 422 (KanbanToolValidationError with parsed field_errors): type mismatch — e.g. writing "hi" into a numeric slot, or a value not in options for a dropdown-typed slot. Inspect the slot's type/options via list_custom_field_definitions(board_id) before writing if the slot purpose is uncertain.

add_commentA

Post a comment on a task. Returns the created Comment with id, content, author, and timestamps.

Common 422 (KanbanToolValidationError with parsed field_errors): content empty or whitespace-only — fix by passing a non-empty string; the field_errors key matches the parameter name.

delete_commentA

Delete a comment (soft-delete). Returns the deleted Comment with deleted_at populated.

Like subtasks, the Kanban Tool API soft-deletes — the comment record is retained server-side with a deleted_at timestamp and stops appearing on the parent task's comments. The MCP-visible effect is "the comment is gone." There is no edit endpoint on the API; if you need to "fix" a comment, delete it and post a replacement.

Failure modes: KanbanToolHTTPError(404) when either id is unknown or the comment isn't on that task — common cause is reusing a stale comment_id from a previous list. Re-fetch the task's current comments before retrying.

list_subtasksA

List subtasks on a task — id, name, completion state, position.

Subtasks are returned inline on Task.subtasks whenever you fetch a task; this tool is sugar for callers that only want the list. Costs one HTTP call (the same as get_task) — the Kanban Tool API has no dedicated list-subtasks endpoint.

add_subtaskA

Add a subtask to a task. Returns the created Subtask.

name is the human-readable label. Mirrors the parameter name used by update_subtask and the wire/model field on Subtask.name.

Common 422 (KanbanToolValidationError with parsed field_errors): name empty or whitespace-only — fix by passing a non-empty string.

update_subtaskA

Partial update of an existing subtask. Returns the updated Subtask.

Only kwargs the caller passes are sent — None means omit, not clear. Use this to mark complete (is_completed=True), rename (name="..."), or change the assignee (assigned_user_id=42). The position field is read-only on this endpoint; use reorder_subtasks to change ordering.

Common 422 (KanbanToolValidationError with parsed field_errors): assigned_user_id not a collaborator on the parent task's board — use list_board_collaborators(board_id) to confirm before retrying.

delete_subtaskA

Delete a subtask (soft-delete). Returns the deleted Subtask with deleted_at populated.

The Kanban Tool API soft-deletes — the subtask record is retained server-side with a deleted_at timestamp and stops appearing on the parent task's subtasks array. This operation is not strictly irreversible from an audit perspective, but the MCP-visible effect is "the subtask is gone."

Failure modes: KanbanToolHTTPError(404) when the subtask id is unknown OR was already soft-deleted in a previous call (the API returns 404 in both cases). Re-fetch the parent task's subtasks list to confirm the current state before retrying.

reorder_subtasksA

Reorder subtasks under a task. Returns the subtasks in the new order.

ids must be the full set of subtask ids on task_id in the desired order.

Common 422s (KanbanToolValidationError with parsed field_errors): ids is a partial set (missing some of the task's current subtask ids) → list current ids via list_subtasks(task_id) and pass them all in the new order; one or more ids belong to a different task → same fix, since the API rejects cross-task references.

start_timerA

Start a new time tracker on a task for the authenticated user.

Returns the created TimeTracker. The new timer starts in the running state (ended_at is None); call stop_timer when work pauses or ends.

board_id is required by the Kanban Tool API but may be omitted here — when not supplied the tool resolves it via an internal get_task(task_id) call (one extra HTTP round-trip). Pass it explicitly when you already have it (e.g. you just listed tasks for a board) to avoid the second request. Either way, the resulting wire body sends both ids.

Note: timers are per-user — starting one creates a record for the authenticated user only. Use whoami if you need to know whose timer it is.

Common 422: the API rejects starting a timer on a task whose board you don't have access to with a typed KanbanToolValidationError. Verify the task is on a board you can list via list_boards.

stop_timerA

Stop a running time tracker. Returns the stopped TimeTracker.

ended_at is an ISO 8601 timestamp; defaults to the current UTC time if not provided. Stopping an already-stopped timer is harmless — the API just updates the ended_at to the new value.

Wire shape: PUT /time_trackers/{id}.json with a flat {"ended_at": ...} body. Same flat-body convention as the subtask endpoints — no {"time_tracker": {...}} envelope.

Raises KanbanToolHTTPError(404) if the timer id is unknown or belongs to another user.

delete_timerA

Delete a time tracker entirely (e.g. cancel a mistakenly-started one). Unlike subtasks, timer deletion is hard — the record is gone, not soft-flagged.

Returns None because the API responds with an empty body to DELETE /time_trackers/{id}.json. The caller should treat the timer id as invalidated after this call.

Failure modes: KanbanToolHTTPError(404) when the timer id is unknown, was already deleted, or belongs to another user (the API scopes timer ids to the authenticated user). Use list_my_timers() to confirm the current set of timer ids you own before retrying.

list_my_timersA

List the authenticated user's time trackers across all tasks.

Returns one TimeTracker per active or finished timer the current user owns; the wire data lives on the time_trackers field of the /users/current.json response (no dedicated list endpoint).

Use Task.time_trackers instead when you only want one task's timers across all users.

Prompts

Interactive templates invoked by user choice

NameDescription
daily_standupSummarise everything that changed on a board in the last N hours. Default window is 24 hours — adjust for half-day standups (``hours=12``) or weekend catch-ups (``hours=72``).
triage_backlogSurface unassigned high-priority tasks on a board and propose owners. Use at sprint start or when the backlog grows fast enough that nobody is sure who's holding what.
my_workloadAggregate the authenticated user's open work across multiple boards. Pass the boards you actively work on; cross-board search isn't a thing in Kanban Tool's DSL, so this fans out one search per board.

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/VeryLongOrgNameSuchWow/kanbantool-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server