Best for
- Activation Triggers (explicit user phrases)
- Automatic Triggers (keyword patterns)
- When NOT to Use
MichelKerkmeester/opencode--skilled-agent-loops-with-spec-kit-memory/.opencode/skills/mcp-tooling/mcp-click-up/SKILL.md
Routes ClickUp between cupt CLI (daily ops) and official MCP (docs, goals, bulk). Embedded install and agent safety invariants.
Decision brief
ClickUp task management via cupt CLI (primary) and official ClickUp MCP (secondary). Operation-based routing: cupt handles daily task ops, MCP handles documents, goals, and bulk operations.
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/MichelKerkmeester/opencode--skilled-agent-loops-with-spec-kit-memory --skill ".opencode/skills/mcp-tooling/mcp-click-up"Inspect the Agent Skill "mcp-click-up" from https://github.com/MichelKerkmeester/opencode--skilled-agent-loops-with-spec-kit-memory/blob/3d386ee21366523774d89c0aff3ebbbc8fa7ff10/.opencode/skills/mcp-tooling/mcp-click-up/SKILL.md at commit 3d386ee21366523774d89c0aff3ebbbc8fa7ff10. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
ClickUp stores the plain description field literally. Markdown submitted there shows up in the ClickUp UI as raw Heading, bold, and - [ ] text. Whenever the content contains ANY markdown syntax, use the markdown-aware parameter for the operation:
"clickup", "cupt", "mcp-click-up", "click up"
"clickup", "cupt", "mcp-click-up", "click up"
cupt appears in the request
@krodak/clickup-cli (cu command) — different tool entirely; not supported by this skill
Permission review
The documentation asks the agent to create, modify, or delete local files.
"create a folder", "create a space", "manage lists", "task dependencies",The documentation asks the agent to run terminal commands or scripts.
bash .opencode/skills/mcp-tooling/mcp-click-up/scripts/install.shEvidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 92/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 34 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
ClickUp task management via cupt CLI (primary) and official ClickUp MCP (secondary). Operation-based routing: cupt handles daily task ops, MCP handles documents, goals, and bulk operations.
ClickUp stores the plain description field literally. Markdown submitted there shows up in the ClickUp UI as raw ### Heading, **bold**, and - [ ] text. Whenever the content contains ANY markdown syntax, use the markdown-aware parameter for the operation:
| Operation | Required parameter |
|---|---|
| Task create | markdown_description |
| Task update (raw v2 API / Code Mode server) | markdown_content (markdown_description also accepted) |
| Task update (claude.ai ClickUp connector) | markdown_description |
| Document or page create | content plus content_format: "markdown" (connector pages: "text/md") |
| Task read-back | include_markdown_description=true |
This contract applies identically on every surface: Code Mode (clickup_official.clickup_official_*), the claude.ai ClickUp connector (clickup_create_task and friends), and the raw ClickUp v2 REST API. Live-verified 2026-07-15 (scratch-task round trips plus a full Product Owner task export, all rendering headings, bold, dividers, and checkboxes correctly).
Push shape for a markdown artifact: the document's H1 becomes the task name (drop it from the body); strip internal HTML comments and processing metadata; everything else travels verbatim.
Failure symptom: literal ### or ** visible in a ClickUp task means someone used the plain description field. That is the defect, not a rendering bug.
Worked examples: references/mcp-tools.md (Markdown Transport Contract + invocation patterns).
cupt appears in the requestclickup + any action verb (list, show, done, mark, note, time, tag)clickup_create_task, clickup_get_task, clickup_manage_documentscu command) — different tool entirely; not supported by this skillALWAYS: SKILL.md (this file)
ON_DEMAND: references/cupt-commands.md (when cupt command details needed)
references/mcp-tools.md (when MCP tool details needed)
references/troubleshooting.md (when error or auth issue detected)
INSTALL-GUIDE.md (when setup or authentication details needed)
| Operation | Primary Tool | Command | MCP Fallback |
|---|---|---|---|
| List/filter tasks | cupt | cupt list [--today|--week|--tag X] | clickup_search_tasks |
| Task details | cupt | cupt show <id> [--notes] | clickup_get_task |
| Mark task complete | cupt | cupt done <id> [--dry-run] | clickup_update_task |
| Add note/comment | cupt | cupt note <id> "<text>" | clickup_manage_comments |
| Read comments | cupt | cupt notes <id> | clickup_manage_comments |
| Start/stop timer | cupt | cupt time start <id> / cupt time stop | MCP time tracking |
| Log time manually | cupt | cupt time add <id> <dur> | MCP time tracking |
| Add tag | cupt | cupt tag add <id> <name> | clickup_add_tag_to_task |
| Remove tag | cupt | cupt tag remove <id> <name> | clickup_remove_tag_from_task |
| Task context | cupt | cupt context <id> | n/a |
| Discover statuses | cupt | cupt statuses <id> | n/a |
| Documents | MCP only | n/a | clickup_create_document |
| Goals/OKRs | MCP only | n/a | goal management tools |
| Bulk create 5+ | MCP only | n/a | clickup_create_bulk_tasks |
| Webhooks | MCP only | n/a | webhook management tools |
| Chat | MCP only | n/a | chat tools |
| Audit logs | MCP only | n/a | clickup_get_audit_logs |
from pathlib import Path
SKILL_ROOT = Path(__file__).resolve().parent
RESOURCE_BASES = (SKILL_ROOT / "references", SKILL_ROOT / "assets")
DEFAULT_RESOURCE = "references/cupt-commands.md"
# Fallback-only: DEFAULT_RESOURCE is a defer-time suggestion, never unioned
# into a route's loaded set. Scored routes load exactly RESOURCE_MAP[intent];
# zero-score routes load nothing and ask for disambiguation instead.
DEFAULT_RESOURCE_SEMANTICS = "fallback-only"
UNKNOWN_FALLBACK_CHECKLIST = [
"Confirm whether the request is for cupt daily ops, official ClickUp MCP, install/auth, or troubleshooting",
"Provide the task ID, command, error text, or target ClickUp feature",
"Confirm whether cupt CLI or Code Mode MCP is already configured",
"Confirm the verification command before completing any write action",
]
INTENT_SIGNALS = {
"CUPT_DAILY": {
"weight": 5,
"keywords": ["list", "show", "done", "note", "notes", "time", "tag", "context",
"statuses", "summary", "teams", "attach", "work queue", "complete task",
"mark done", "log time", "track time",
"my tasks", "assigned to me", "due today", "due this week", "overdue",
"ticket", "close it out", "jot down",
"wrap up", "close out", "update status", "leave a comment", "add a comment",
"task details", "start timer", "stop timer", "clock in", "clock out",
"log hours", "worklog", "task summary", "list teams", "upload a file",
"download a file", "prefetch", "offline cache"],
},
"MCP_ADVANCED": {
"weight": 5,
"keywords": ["document", "goal", "okr", "bulk", "webhook", "chat", "audit",
"create_bulk", "manage_documents", "checklist", "custom field",
"quarterly goals", "quarterly objective", "objective", "key results",
"doc page", "wiki page", "write-up page",
"create a folder", "create a space", "manage lists", "task dependencies",
"link tasks", "bulk update", "mass create", "batch create", "user groups",
"guest access", "enterprise feature", "task template", "space tags"],
},
"INSTALL": {
"weight": 6,
"keywords": ["install cupt", "setup", "not found", "not installed", "auth",
"authenticate", "api token", "mcp config",
"getting started", "onboarding", "configure", "configuration",
"connect clickup", "link my account", "personal token", "pipx install",
"sign in", "how do i install"],
},
"TROUBLESHOOT": {
"weight": 6,
"keywords": ["error", "failed", "not working", "403", "401", "slow", "timeout",
"empty", "no tasks",
"broken", "doesn't work", "isn't working", "won't load", "stuck",
"unauthorized", "forbidden", "permission denied", "rate limit", "429",
"500", "crash", "bug", "not authenticated", "can't connect",
"connection failed", "timing out"],
},
}
# NOTE: no "DEFAULT" entry — route_clickup_resources() never indexes RESOURCE_MAP
# by that key (the selected `intent` is always one of the four INTENT_SIGNALS
# keys above). The no-match case is owned by DEFAULT_RESOURCE above, whose
# declared fallback-only semantics mean it is SUGGESTED beside the
# disambiguation checklist, never loaded — so cupt-commands.md can never leak
# into MCP_ADVANCED/INSTALL/TROUBLESHOOT routes, and router-doc-aware callers
# (the benchmark replay honors the same declaration) assemble exactly what a
# scored intent's RESOURCE_MAP entry names.
RESOURCE_MAP = {
"CUPT_DAILY": ["references/cupt-commands.md"],
"MCP_ADVANCED": ["references/mcp-tools.md"],
"INSTALL": ["INSTALL-GUIDE.md", "references/troubleshooting.md"],
"TROUBLESHOOT": ["references/troubleshooting.md"],
}
def discover_markdown_resources() -> set[str]:
docs = []
for base in RESOURCE_BASES:
if base.exists():
docs.extend(path for path in base.rglob("*.md") if path.is_file())
return {doc.relative_to(SKILL_ROOT).as_posix() for doc in docs}
def _guard_in_skill(relative_path: str) -> str:
resolved = (SKILL_ROOT / relative_path).resolve()
resolved.relative_to(SKILL_ROOT)
if resolved.suffix.lower() != ".md":
raise ValueError(f"Only markdown skill resources are routable: {relative_path}")
return resolved.relative_to(SKILL_ROOT).as_posix()
def load_if_available(relative_path: str, loaded: list[str], seen: set[str], inventory: set[str]) -> None:
guarded = _guard_in_skill(relative_path)
if guarded in inventory and guarded not in seen:
load(guarded)
loaded.append(guarded)
seen.add(guarded)
def route_clickup_resources(request: str) -> dict:
"""Score intent labels and load available ClickUp reference docs."""
inventory = discover_markdown_resources()
loaded, seen = [], set()
request_lower = request.lower()
scores = {}
for intent, config in INTENT_SIGNALS.items():
score = sum(
config["weight"] for kw in config["keywords"]
if kw in request_lower
)
if score > 0:
scores[intent] = score
if not scores:
# Fallback-only: nothing is loaded on a zero-score route; the default
# reference is offered as a suggestion beside the disambiguation ask.
return {
"load_level": "UNKNOWN_FALLBACK",
"needs_disambiguation": True,
"disambiguation_checklist": UNKNOWN_FALLBACK_CHECKLIST,
"suggested_fallback": DEFAULT_RESOURCE,
"resources": loaded,
}
# Error/install keywords boost TROUBLESHOOT/INSTALL regardless of other signals
if scores.get("TROUBLESHOOT", 0) > 3:
intent = "TROUBLESHOOT"
elif scores.get("INSTALL", 0) > 4:
intent = "INSTALL"
else:
intent = max(scores, key=scores.get)
for resource in RESOURCE_MAP[intent]:
load_if_available(resource, loaded, seen, inventory)
if not loaded:
return {
"load_level": "UNKNOWN_FALLBACK",
"notice": f"No ClickUp reference docs available for intent '{intent}'",
"disambiguation_checklist": UNKNOWN_FALLBACK_CHECKLIST,
"suggested_fallback": DEFAULT_RESOURCE,
"resources": loaded,
}
return {"intent": intent, "resources": loaded}
| Dimension | cupt CLI | Official ClickUp MCP |
|---|---|---|
| Activation | cupt <command> in Bash | Code Mode call_tool_chain() |
| Best for | Daily task ops, time tracking, notes, tags | Documents, goals, bulk ops, webhooks |
| Output | Human-readable + --json flag | Structured JSON always |
| Auth | cupt auth / cupt config --api-token | CLICKUP_API_KEY + CLICKUP_TEAM_ID environment variables |
| Offline | --offline flag uses local cache | Always requires network |
| Install | pipx install cupt (Python) | npx -y @clickup/mcp-server (stdio) |
| Dry-run | cupt done --dry-run | No equivalent |
| Status auto | Yes — resolves per-list | No — must specify status |
Step 1: Verify installation
cupt --version # e.g. cupt 0.7.1
cupt status # Shows workspace + auth status
Step 2: Install if missing
bash .opencode/skills/mcp-tooling/mcp-click-up/scripts/install.sh
Step 3: Authenticate
cupt auth # Interactive wizard
# OR:
cupt config --api-token pk_xxxxx # Direct token setup
Step 4: Set defaults (optional)
cupt config --workspace-id <id> # From cupt status
cupt config --default-list <id> # For quick task creation
Step 5: Use for daily operations
cupt list --today --json # Tasks due today, JSON output
cupt statuses <task_id> # Discover list's status schema FIRST
cupt done <task_id> --dry-run # Preview completion without writing
cupt done <task_id> --note "done" # Mark complete with note
This is ClickUp's official MCP server package, launched over stdio by the registered clickup_official manual with npx -y @clickup/mcp-server. It authenticates with CLICKUP_API_KEY and CLICKUP_TEAM_ID environment variables; this deployment has no browser authorization step.
Prerequisites:
clickup_official manual in .utcp_config.json (not opencode.json, that file is for native/non-Code-Mode MCP tools)CLICKUP_API_KEY and CLICKUP_TEAM_ID set in the environment available to Code ModeConfiguration (.utcp_config.json, manual_call_templates):
{
"name": "clickup_official",
"call_template_type": "mcp",
"config": {
"mcpServers": {
"clickup_official": {
"transport": "stdio",
"command": "npx",
"args": ["-y", "@clickup/mcp-server"],
"env": {
"CLICKUP_API_KEY": "${CLICKUP_API_KEY}",
"CLICKUP_TEAM_ID": "${CLICKUP_TEAM_ID}"
}
}
}
}
}
Reference: references/mcp-tools.md and mcp-servers/clickup-mcp/README.md
Invocation via Code Mode (call_tool_chain takes a single code string, NOT an array of {tool, input} records):
// Tool naming: clickup_official.clickup_official_{tool_name}
const result = await call_tool_chain({
code: `
const doc = await clickup_official.clickup_official_clickup_create_document({
name: "Sprint Notes",
parent: { type: 4, id: "LIST_ID" },
content: "# Sprint Notes\\n\\n...",
content_format: "markdown",
});
return doc;
`,
});
When to prefer MCP:
Limitations:
cupt statuses <id> before any cupt done call — each ClickUp list has its own status schema; the closed status varies (Done, Complete, Closed, etc.). Never assume.cupt done <id> --dry-run before batch completion — verify resolved status for every task before writing. One dry-run per task in a batch loop.--json flag for all cupt read commands when processing output programmatically: cupt list --json, cupt show <id> --json, etc.cupt --version && cupt status as preflight before starting a ClickUp workflow session.cupt list results as valid — an empty queue is not an error. Before escalating: check tag spelling, try --all flag, verify team name via cupt teams.cupt context <id> before acting on a task to understand its parent and sibling relationships.markdown_description; task update: markdown_content (connector: markdown_description); documents and pages: content + content_format: "markdown"; read-back: include_markdown_description=true."Done" in one list may not exist in another. Use cupt statuses <id> to discover the correct status for each task's list.cupt done on multiple tasks without per-task dry-run first — batch status errors are hard to reverse.@krodak/clickup-cli (cu command) — this is a different tool not supported by this skill. The cu binary also conflicts with the system cu command on some Unix systems.opencode.json — print MCP config snippets for user to apply; never write to config files programmatically.cupt list returns empty, the queue is genuinely empty. Report this clearly.description field — it renders as literal ### Heading / **bold** / - [ ] text in ClickUp. Any content containing markdown syntax must use the markdown-aware parameters from ALWAYS rule 7. This is exactly the defect that produced raw-markdown tickets in the Barter workspace.scripts/install.sh fails → report Python version and pip issuescupt status shows auth failure → direct to cupt auth or cupt config --api-tokencupt list --team X is extremely slow (>30s) → team filter is client-side on large workspaces; suggest combining with --tag to reduce result setclickup_official manual in .utcp_config.json launches npx -y @clickup/mcp-server over stdio, and that CLICKUP_API_KEY and CLICKUP_TEAM_ID are set in the Code Mode environmentcupt done is unexpected → run cupt statuses <id> and report available statusescupt --version prints version stringcupt status shows workspace name without errorcupt list --today --json returns valid JSON array (even if empty)cupt statuses <id> returns status list for the task's listcupt done <id> --dry-run shows resolved statusclickup_official.clickup_official_get_workspace returns workspace dataGate 2 (Skill Routing): This skill activates at ≥0.8 confidence for ClickUp task management requests. The skill advisor matches on: clickup, cupt, task management, work queue, time tracking, mark done.
Code Mode MCP: Official ClickUp MCP tools are invoked via mcp__code_mode__call_tool_chain. Tool naming convention: clickup_official.clickup_official_{tool_name}. See references/mcp-tools.md for the full tool catalog.
Memory: Save ClickUp workflow context (current list, active tags, workspace ID) using /memory:save when switching sessions.
Tool Usage: Use Bash for cupt CLI commands. Use mcp__code_mode__call_tool_chain for official MCP operations. Use Read to load references on demand.
| Category | Command | Description |
|---|---|---|
| Auth | cupt auth | Interactive authentication wizard |
cupt config --api-token pk_xxx | Set Personal API Token directly | |
cupt status | Show auth status + workspace | |
cupt logout | Clear stored credentials | |
| Config | cupt config --workspace-id <id> | Set default workspace |
cupt config --default-list <id> | Set default list | |
cupt config --show | Display current configuration | |
| Tasks | cupt list | List assigned tasks |
cupt list --today | Tasks due today | |
cupt list --week | Tasks due this week | |
cupt list --overdue | Overdue tasks | |
cupt list --tag <name> | Filter by tag (server-side, fast) | |
cupt list --team <name> | Filter by team (client-side, slow) | |
cupt list --all | All tasks including team | |
cupt list --mine | Only self-assigned tasks | |
cupt list --json | JSON output for agents | |
cupt show <id> | Full task details | |
cupt show <id> --notes | Include comments | |
cupt show <id> --json | JSON output | |
cupt show <id> --offline | Use cached data | |
cupt context <id> | Parent + siblings + subtasks | |
cupt statuses <id> | Status schema for task's list | |
cupt done <id> | Mark complete (auto-resolves status) | |
cupt done <id> --dry-run | Preview completion, no write | |
cupt done <id> --note "text" | Mark complete with note | |
| Notes | cupt note <id> "<text>" | Add comment to task |
cupt notes <id> | List all comments | |
| Time | cupt time start <id> | Start timer on task |
cupt time stop | Stop running timer | |
cupt time add <id> <dur> | Log time (e.g., 1h30m, 45m) | |
cupt time status | Show current timer state | |
| Tags | cupt tag add <id> <name> | Add tag to task |
cupt tag remove <id> <name> | Remove tag from task | |
| Attach | cupt attach list <id> | List attachments |
cupt attach add <id> <file> | Upload file | |
cupt attach get <id> <sel> | Download attachment | |
| Workspace | cupt teams | List teams (user-groups) |
cupt summary | Task summary overview | |
cupt prefetch | Pre-cache tasks for offline use |
Reference Files (load on demand via router):
references/cupt-commands.md — Full cupt command reference with agent patternsreferences/mcp-tools.md — 46 official MCP tools, priority table, invocationreferences/troubleshooting.md — Auth, status, team-filter, MCP failuresreferences/INSTALL-GUIDE.md — Step-by-step install with validation checkpointsInstall guide (front door): INSTALL-GUIDE.md — condensed top-level install doc; the phase-validation reference above stays the router's INSTALL-intent target.
Scripts:
scripts/install.sh — Installs cupt + prints MCP config snippetEmbedded Servers:
mcp-servers/clickup-mcp/README.md — Configuration notes for the official @clickup/mcp-server package launched over stdio by the clickup_official manual with CLICKUP_API_KEY and CLICKUP_TEAM_ID.mcp-servers/clickup-cli/requirements.txt — cupt CLI pip pin (cupt>=0.7.1). Run setup.sh to install.mcp-servers/clickup-cli/setup.sh — cupt install via pipx or pip.Examples:
examples/task-queue-workflow.sh — Process tagged work queueexamples/time-tracking-workflow.sh — Timer + time log workflowRelated Skills:
mcp-chrome-devtools — Structural template this skill was modeled onmcp-code-mode — Code Mode MCP orchestration (used for official MCP invocation)External:
Frequently asked questions
ClickUp task management via cupt CLI (primary) and official ClickUp MCP (secondary). Operation-based routing: cupt handles daily task ops, MCP handles documents, goals, and bulk operations.
The source record exposes this install command: npx skills add https://github.com/MichelKerkmeester/opencode--skilled-agent-loops-with-spec-kit-memory --skill ".opencode/skills/mcp-tooling/mcp-click-up". Inspect the command and pinned source before running it.
Static rules flagged write-files, exec-script in the source; the page lists the matching lines and excerpts.
Alternatives
oaustegard/claude-skills
Generate hierarchical _FEATURES.md files that describe what a codebase DOES from a user/consumer perspective, anchored to source symbols via tree-sitting. Supports large complex codebases through feature-driven decomposition into sub-feature files. Uses a multi-pass synthesis: orientation → detail → overview rewrite. Use when someone says "what does this do", "document features", "feature inventory", "_FEATURES.md", or needs to understand a codebase's purpose before modifying it. Complements tre
dancingteeth/unified-code-review
Risk-first code review for PRs and branch audits: blast-radius triage, agent-authored discipline (tests first, intent evidence), call-graph pincer for integration defects between modules, then structural code-judo bar. Use when reviewing PRs, auditing agent-written diffs, catching rubber-stamp green CI, or wiring bugs single-file review misses. Prefer over structure-only thermo-nuclear review alone. Do not use for unrelated coding tasks or as an always-on rule.
Postpartum-genushyacinthus29/dotnet-skills
Build long-running .NET background services with `BackgroundService`, Generic Host, graceful shutdown, configuration, logging, and deployment patterns suited to workers and daemons.
enuno/unifi-mcp-server
Specialized guide for adding new MCP tools to the UniFi MCP Server following project standards, UniFi API patterns, and test-driven development practices. Use when implementing new UniFi Network Controller features as MCP tools.