Skill

clickup-tool

This skill should be used when the user asks to "check my tasks", "show ClickUp tasks", "get task details", "view task comments", "show project structure", "list sprints", "what am I working on", "show my ClickUp board", "task status", "add a comment", "post a note", "log time", "track time", "delete time entry", "time entries", "timesheet", "how much did I work", "change status", "set status", "move to in progress", "close task", "create task", "new task", "add task", "make a task", "create a ticket", "file a bug", "create issue", or mentions ClickUp, tasks, sprints, or project management queries. Provides read and write access to ClickUp workspace data through the clickup-tool CLI with normalized, compressed JSON output.

From clickup-tool
Install
1
Run in your terminal
$
npx claudepluginhub realvoronvan/clickup-tool-plugin
Tool Access

This skill is limited to using the following tools:

Bash(clickup-tool *)
Supporting Assets
View in Repository
references/commands.md
references/config-guide.md
Skill Content

ClickUp Task Management Skill

Overview

clickup-tool is a CLI for extracting ClickUp task data with configurable output normalization. It connects to the ClickUp API v2 and returns structured JSON to stdout. Raw API responses (32--92 KB per request) are compressed to 1.8--2.5 KB through field filtering, value resolution, and format conversion. The tool handles pagination, deduplication, rate limiting, and automatic retries transparently.

The ClickUp data hierarchy is: Workspace > Space > Folder > List > Task. A workspace contains multiple spaces (e.g., "Engineering", "Design"). Spaces contain folders (project groupings). Folders contain lists, which are often used as sprints or iterations. Lists contain individual tasks. Understanding this hierarchy is essential for navigating the workspace structure using the CLI commands.

Prerequisites

Before invoking any command, verify the following three requirements are met:

  1. clickup-tool CLI installed -- Install globally with uv tool install /path/to/clickup-tool or run from the project directory with uv run python -m clickup_tool.
  2. CLICKUP_API_TOKEN set -- The API token must be available as an environment variable. It can be set in the shell environment or placed in a .env file (searched in the current working directory first, then ~/.config/clickup-tool/.env). The token format is pk_xxx. Never store the token in config.yaml.
  3. config.yaml configured -- The configuration file must contain at minimum the team_id (workspace ID). Search order: --config CLI flag, then ./config.yaml in the current directory, then ~/.config/clickup-tool/config.yaml.

If prerequisites are missing, the tool returns a JSON error object explaining what is needed.

Decision Tree

Map user requests to the appropriate command based on intent:

User IntentCommand
"Create task", "new task", "add task", "file a bug", "create ticket"clickup-tool create-task "Title" [--description-file PATH] [--priority N] [--tag TAG] [--list-id ID] [--status STATUS] [--assignee ID]
"My tasks", "what am I working on", task overview, current sprintclickup-tool get-tasks
Task details, specific task ID, full description, checklistsclickup-tool get-task TASK_ID
Comments, discussion, conversation on a taskclickup-tool get-comments TASK_ID
Workspace structure, list spacesclickup-tool get-spaces
Folders in a space, project structureclickup-tool get-folders SPACE_ID
Lists in a folder, sprints, iterationsclickup-tool get-lists FOLDER_ID
Team members, workspace users, find user ID, "who is on the team"clickup-tool get-members
Auth check, "who am I", verify connectionclickup-tool get-me
Post a comment, leave a note on taskclickup-tool add-comment TASK_ID "text"
Log time, track work, "I spent 2h on this"clickup-tool add-time-entry TASK_ID "2h" --description "work"
Remove wrong time entryclickup-tool delete-time-entry TIMER_ID
Change task status, "move to in progress", "close it"clickup-tool get-statuses TASK_ID then clickup-tool set-status TASK_ID "status"
Time entries, timesheet, "how much did I work this week"clickup-tool get-time-entries --start-date YYYY-MM-DD --end-date YYYY-MM-DD
What statuses are available for a taskclickup-tool get-statuses TASK_ID

For exploring workspace structure, chain commands in sequence: start with get-spaces to obtain space IDs, then get-folders SPACE_ID for folder IDs, then get-lists FOLDER_ID to see lists (sprints) within a folder.

When the user mentions a task by name but not by ID, first run get-tasks with appropriate filters to locate the task ID, then use get-task TASK_ID for full details.

When the user asks about "sprints" or "iterations", map this to the List level of the hierarchy. Run get-lists FOLDER_ID to see sprint names, task counts, and due dates. To see tasks within a sprint, run get-tasks --list-id LIST_ID.

When the user asks about "project structure" or "board overview", start with get-spaces and drill down through folders and lists to present the full hierarchy.

ClickUp Concepts Mapping

Map common project management terms to ClickUp hierarchy and CLI commands:

User saysClickUp conceptCLI approach
"sprint", "iteration"Listget-lists FOLDER_ID to find it, get-tasks --list-id LIST_ID for tasks
"project", "board"Folderget-folders SPACE_ID
"workspace", "team"Spaceget-spaces
"status"Status (per-list or per-space)Use get-statuses TASK_ID for exact names, or get-spaces for space-level defaults
"tag", "label"Tagget-tags SPACE_ID for available tags, get-tasks --tag TAG to filter
"timesheet", "time report", "hours worked"Time entries (team-level)get-time-entries --start-date X --end-date Y for period summary
"Jane", person's nameAssignee (numeric ID)get-members to list all workspace users with IDs, or check assignees[].id in task output

Critical: Status names must be used exactly as returned by get-statuses or get-spaces — do NOT guess. All IDs (assignee, list, space) are numeric — never use names as IDs.

CLI Syntax Rules

All filter flags use --flag VALUE syntax. Do NOT use key:value syntax.

Correct:

clickup-tool get-tasks --status "in progress" --tag "frontend"

Wrong:

# These will NOT work:
clickup-tool get-tasks status:active sprint:A       # wrong syntax
clickup-tool get-tasks --status active               # wrong status name — use exact from get-spaces
clickup-tool get-tasks --assignee Jane               # wrong — must be numeric ID, not name
clickup-tool get-tasks 900000000003                   # wrong — positional arg, need --list-id

Flag values with spaces must be quoted: --status "in progress". All IDs (assignee, list, space) are numeric.

Command Quick Reference

CommandArgumentsReturns
clickup-tool get-me--User {id, username, email}
clickup-tool get-spaces--Spaces [{id, name, archived, statuses: [{status, color}]}]
clickup-tool get-members--Members [{id, username, email}]
clickup-tool get-folders SPACE_IDspace_idFolders [{id, name, task_count}]
clickup-tool get-lists FOLDER_IDfolder_idLists [{id, name, task_count, due_date}]
clickup-tool get-tags SPACE_IDspace_idTag names ["bug", "feature", ...]
clickup-tool get-taskssee filter flags belowTasks [{id, name, status, tags, priority, ...}]
clickup-tool get-task TASK_IDtask_idFull task with description, checklists, time_entries
clickup-tool get-comments TASK_IDtask_idComments [{text, user, date, replies}]
clickup-tool add-comment TASK_ID TEXTtask_id, text, --notify-all{id, hist_id, date}
clickup-tool add-time-entry TASK_ID DURATIONtask_id, duration, --description, --date{data: {id, duration, ...}}
clickup-tool delete-time-entry TIMER_IDtimer_id{data: {id, ...}}
clickup-tool get-time-entries--start-date, --end-date, --assigneeTime entries [{id, task, user, duration, start, description}]
clickup-tool get-statuses TASK_IDtask_idStatus names ["to do", "in progress", ...]
clickup-tool set-status TASK_ID STATUStask_id, exact status stringNormalized task (same as get-task, no time_entries)
clickup-tool create-task NAMEname, --description-file, --priority, --tag, --list-id, --status, --assigneeNormalized task

get-tasks filter flags

FlagTypeDescription
--assignee IDnumeric user ID (e.g., 100000001)Filter by assignee. NOT a name — use numeric ID from get-members to find any user's ID, or from assignees[].id in task output
--status STATUSexact string from get-spaces statuses (e.g., "in progress")Filter by status. Must match exactly
--tag TAGexact string from get-tags (e.g., "bug")Filter by tag name
--list-id IDnumeric list ID from get-lists (e.g., 900000000001)Restrict to specific sprint/list
--space-id IDnumeric space ID from get-spaces (e.g., 12345678)Restrict to specific space
--include-closedflag (no value)Include tasks in closed/done statuses

All flags except --include-closed are repeatable: --status "in progress" --status "review".

When --assignee is omitted, falls back to default_assignee from config.yaml. When --space-id is omitted, falls back to defaults.space_ids from config.yaml.

get-tasks vs get-task

These two commands serve different purposes. Understand the distinction to avoid unnecessary API calls.

get-tasks returns a compact overview (a map of all matching tasks). It includes: id, name, status, assignees, custom_fields, tags, priority, due_date, start_date, date_created, date_updated, time_estimate, parent, linked_tasks, dependencies, list. It deliberately excludes description, checklists, watchers, attachments, time entries, and URL to keep the response small.

get-task returns full details for a single task. In addition to everything in get-tasks, it includes: markdown_description, creator, checklists (with items and resolution status), attachments (with title, url, extension, size), time_spent, time_entries (fetched via a separate API call to /task/{id}/time), url, and watchers (if enabled in config).

Use get-tasks first to survey the landscape and identify relevant task IDs. Then use get-task TASK_ID when the user needs to read the full description, check checklist progress, review attachments, or examine time tracking data. This two-step approach minimizes API calls while providing complete information on demand.

Common workflow pattern: run get-tasks to find the task, note the id, then run get-task TASK_ID for details, and optionally get-comments TASK_ID to see discussion history.

Output Format

All output is JSON printed to stdout. Warnings and diagnostics go to stderr. Parse command output with standard JSON tools. The exit code is 0 on success, 1 on error.

The output is heavily normalized and compressed compared to raw ClickUp API responses. The following transformations are applied automatically:

  • Dates: Millisecond timestamps converted to "YYYY-MM-DD HH:MM" in the configured timezone.
  • Time durations: time_estimate and time_spent converted from milliseconds to "Xh Ym" format (e.g., "6h 30m").
  • Users: Assignees and creators simplified to {id, username, initials, email}. Comment users simplified to username string only.
  • Status: Simplified to {id, status}.
  • Tags: Converted from objects to plain string list. Access directly: task["tags"] returns ["bug", "critical"], NOT objects. No .get("name") needed.
  • Custom fields: Filtered by name whitelist, dropdown values resolved to human-readable names, type_config metadata stripped.
  • Checklists: Simplified to {name, resolved, unresolved, items: [{name, resolved}]}.
  • Attachments: Simplified to {title, url, extension, size}.
  • Empty fields: Fields with null or [] values are stripped when strip_empty: true (the default).
  • List reference: Full list objects simplified to {id, name}, stripping access metadata.
  • Field filtering: Each command has a configurable whitelist of fields to return. Only whitelisted fields appear in the output; all others are silently dropped.

Example compressed output for get-tasks:

[
  {
    "id": "abc123",
    "name": "Implement login page",
    "status": {"id": "s1", "status": "in progress"},
    "assignees": [{"id": "100000001", "username": "john.doe", "initials": "JD", "email": "john@example.com"}],
    "tags": ["frontend", "sprint-12"],
    "priority": {"id": "2", "priority": "high"},
    "due_date": "2026-03-01 18:00",
    "time_estimate": "6h 30m",
    "list": {"id": "901234", "name": "Sprint 12"}
  }
]

Error Handling

Errors are returned as JSON objects with a consistent structure:

{"error": true, "message": "Token invalid", "status_code": 401}

Retry behavior is automatic and transparent:

  • 429 (Rate Limited): Retried using the X-RateLimit-Reset header value. Up to 3 retries.
  • 5xx (Server Error): Retried with exponential backoff (1s, 2s, 4s). Up to 3 retries.
  • 4xx (Client Error): Returned immediately without retry. Check the message for details (e.g., invalid task ID, unauthorized).

When a command returns an error, inspect the message and status_code fields to determine the cause. Common error scenarios:

  • 401 Unauthorized -- API token is expired, invalid, or missing. Verify that CLICKUP_API_TOKEN is set correctly. Run clickup-tool get-me to test authentication.
  • 404 Not Found -- Task ID, space ID, or folder ID does not exist or is not accessible with the current token. Verify the ID is correct.
  • 400 Bad Request -- Often caused by a misconfigured team_id in config.yaml. Verify the workspace ID.
  • Network errors -- Connection timeouts or DNS failures are retried with exponential backoff before returning the error.

Safety Limits

The tool enforces pagination safety limits to prevent runaway requests:

  • Tasks: Maximum 100 pages (10,000 tasks per query).
  • Comments: Maximum 200 pages (5,000 comments per task).

These limits are sufficient for any realistic workspace. If results appear truncated, narrow the query with filters.

Common Invocation Patterns

Below are ready-to-use invocation patterns for the most frequent scenarios.

Show all active tasks for the default user:

clickup-tool get-tasks

Show tasks in a specific sprint/list:

clickup-tool get-tasks --list-id 900000000001

Show tasks filtered by status:

clickup-tool get-tasks --status "in progress" --status "review"

Get full details of a specific task:

clickup-tool get-task abc123def

Read comments and replies on a task:

clickup-tool get-comments abc123def

Explore workspace hierarchy (spaces, then folders, then lists):

clickup-tool get-spaces
clickup-tool get-folders 12345678
clickup-tool get-lists 87654321

Verify API token and connection:

clickup-tool get-me

Status and Tag Discovery

Before filtering by status or tag, discover what values are available:

Discover statuses per space:

clickup-tool get-spaces

Output includes statuses array per space with exact status names and colors. Use these exact names with --status.

Discover tags in a space:

clickup-tool get-tags SPACE_ID

Returns a plain list of tag name strings. Use these exact names with --tag.

Changing Task Status

Always use this deterministic workflow — never guess status names:

  1. clickup-tool get-statuses TASK_ID — returns the exact list of valid statuses for this task's list
  2. Match the user's request to an exact status from the list
  3. If ambiguous (multiple candidates match), ask the user to pick
  4. clickup-tool set-status TASK_ID "exact status name"

get-statuses resolves statuses at the list level (not space level), so it returns the correct statuses even when a list overrides space defaults.

On success, set-status returns the updated task in the same format as get-task (without time_entries). On invalid status, the error message includes the list of available statuses.

Fetching Time Entries

To see time tracking data for a period:

  1. clickup-tool get-time-entries --start-date 2026-02-01 --end-date 2026-02-28

Without --start-date/--end-date, returns entries from the last 30 days. Without --assignee, uses default_assignee from config.yaml.

For time entries on a specific task, use get-task TASK_ID instead — it includes time_entries in its output.

Sprint Task Lookup Workflow

To find tasks in a specific sprint, follow these steps in order:

  1. clickup-tool get-spaces — find the space ID
  2. clickup-tool get-folders SPACE_ID — find the folder (project)
  3. clickup-tool get-lists FOLDER_ID — find the list (sprint) by name
  4. clickup-tool get-tasks --list-id LIST_ID — get all tasks in that sprint

Each step uses the ID from the previous step's output.

Creating Tasks

To create a task, use clickup-tool create-task. The default list is configured in config.yaml (default_list_id).

Minimal task:

clickup-tool create-task "Fix login bug"

Task with description from file:

For multi-line descriptions, write a .md file first, then pass it via --description-file. The file is safely deleted after successful creation if it is in a temp directory.

# 1. Write description to temp file
# (use Write tool to create /tmp/clickup-task-<uuid>.md)

# 2. Create task
clickup-tool create-task "Implement OAuth2" \
  --description-file /tmp/clickup-task-abc123.md \
  --priority 2 \
  --tag bug --tag urgent \
  --status "to do" \
  --assignee 176497309

Key rules:

  • --tag values are validated against existing space tags (case-insensitive). If a tag is not found, the error lists available tags.
  • --priority must be 1 (urgent), 2 (high), 3 (normal), or 4 (low).
  • --assignee must be a numeric user ID (use get-members to find IDs).
  • --list-id defaults to default_list_id from config.yaml if omitted.
  • Description files should be written to /tmp/clickup-task-*.md — the CLI auto-deletes them after success.

Interpreting Output

When presenting task data to users, keep the following in mind:

  • The status field contains a normalized {id, status} object. Use the status string value (e.g., "in progress", "review", "done") for display.
  • The priority field contains priority metadata. The priority string value within it (e.g., "urgent", "high", "normal", "low") is the human-readable label.
  • Custom fields have already been resolved: dropdown values show the option name (not the raw integer index), and label fields show the label strings (not UUIDs).
  • Time values like time_estimate and time_spent are formatted as "Xh Ym" (e.g., "6h 30m", "45m", "2h"). No further conversion is needed.
  • Dates are formatted as "YYYY-MM-DD HH:MM" in the configured timezone. Present them as-is.
  • The list field on each task indicates which sprint/list the task belongs to. Use list.name to show the sprint name.

Additional Resources

For complete details beyond this overview, consult the reference documents:

  • references/commands.md -- Full command reference with all arguments, flags, example invocations, and example normalized JSON output for every command.
  • references/config-guide.md -- Configuration setup guide covering config.yaml structure, .env file placement, how to obtain the API token, and how to find the workspace team_id.
Similar Skills
cache-components

Expert guidance for Next.js Cache Components and Partial Prerendering (PPR). **PROACTIVE ACTIVATION**: Use this skill automatically when working in Next.js projects that have `cacheComponents: true` in their next.config.ts/next.config.js. When this config is detected, proactively apply Cache Components patterns and best practices to all React Server Component implementations. **DETECTION**: At the start of a session in a Next.js project, check for `cacheComponents: true` in next.config. If enabled, this skill's patterns should guide all component authoring, data fetching, and caching decisions. **USE CASES**: Implementing 'use cache' directive, configuring cache lifetimes with cacheLife(), tagging cached data with cacheTag(), invalidating caches with updateTag()/revalidateTag(), optimizing static vs dynamic content boundaries, debugging cache issues, and reviewing Cache Component implementations.

138.5k
Stats
Stars1
Forks0
Last CommitMar 25, 2026