AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Mcp Click Up

skill-michelkerkmeester-skilled-harness-spec-driven-agent-loops-mcp-click-up · by MichelKerkmeester

Routes ClickUp between cupt CLI (daily ops) and official MCP (docs, goals, bulk). Embedded install and agent safety invariants.

No reviews yet
0 installs
19 views
0.0% view→install

Install

$ agentstack add skill-michelkerkmeester-skilled-harness-spec-driven-agent-loops-mcp-click-up

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access Used
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-michelkerkmeester-skilled-harness-spec-driven-agent-loops-mcp-click-up)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
23d ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Mcp Click Up? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

mcp-click-up Skill

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.


MARKDOWN FORMATTING CONTRACT — READ BEFORE ANY CLICKUP WRITE

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).


1. WHEN TO USE

Activation Triggers (explicit user phrases)

  • "clickup", "cupt", "mcp-click-up", "click up"
  • "manage tasks", "list tasks", "mark task done", "complete task"
  • "log time", "track time", "start timer", "stop timer"
  • "add note to task", "tag task", "show task details"
  • "process work queue", "process task queue"
  • "clickup documents", "clickup goals", "bulk create tasks"

Automatic Triggers (keyword patterns)

  • cupt appears in the request
  • clickup + any action verb (list, show, done, mark, note, time, tag)
  • "work queue" or "task queue" in a ClickUp context
  • "time tracking" or "work log" with project management context
  • MCP tool names: clickup_create_task, clickup_get_task, clickup_manage_documents

When NOT to Use

  • @krodak/clickup-cli (cu command) — different tool entirely; not supported by this skill
  • Community ClickUp MCP servers (@taazkareem/clickup-mcp-server) — use official MCP only
  • Direct ClickUp REST API calls (no CLI/MCP) — this skill adds no value there
  • Browser-based ClickUp automation (Playwright/Puppeteer) — wrong surface

2. SMART ROUTING

Resource Loading Levels

ALWAYS:    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-to-Tool Routing Table

| Operation | Primary Tool | Command | MCP Fallback | |-----------|-------------|---------|-------------| | List/filter tasks | cupt | cupt list [--today\|--week\|--tag X] | clickup_search_tasks | | Task details | cupt | cupt show [--notes] | clickup_get_task | | Mark task complete | cupt | cupt done [--dry-run] | clickup_update_task | | Add note/comment | cupt | cupt note "" | clickup_manage_comments | | Read comments | cupt | cupt notes | clickup_manage_comments | | Start/stop timer | cupt | cupt time start / cupt time stop | MCP time tracking | | Log time manually | cupt | cupt time add | MCP time tracking | | Add tag | cupt | cupt tag add | clickup_add_tag_to_task | | Remove tag | cupt | cupt tag remove | clickup_remove_tag_from_task | | Task context | cupt | cupt context | n/a | | Discover statuses | cupt | cupt statuses | 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 |

Smart Router Pseudocode

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}

3. HOW IT WORKS

Tool Comparison

| Dimension | cupt CLI | Official ClickUp MCP | |-----------|---------|---------------------| | Activation | cupt 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 |

cupt CLI (Primary Path)

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     # From cupt status
cupt config --default-list     # For quick task creation

Step 5: Use for daily operations

cupt list --today --json           # Tasks due today, JSON output
cupt statuses             # Discover list's status schema FIRST
cupt done  --dry-run      # Preview completion without writing
cupt done  --note "done"  # Mark complete with note

Official ClickUp MCP (Secondary Path)

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:

  • Code Mode MCP configured, with the 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 Mode

Configuration (.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:

  • Creating or reading ClickUp Documents
  • Managing Goals and OKRs
  • Bulk-creating 5+ tasks simultaneously
  • Webhooks, custom views, user groups
  • Enterprise features (audit logs, guests)

Limitations:

  • No dry-run for task completion (always specify correct status)
  • No offline mode
  • Requires Code Mode MCP to be configured

4. RULES

✅ ALWAYS

  1. Run cupt statuses before any cupt done call — each ClickUp list has its own status schema; the closed status varies (Done, Complete, Closed, etc.). Never assume.
  2. Use cupt done --dry-run before batch completion — verify resolved status for every task before writing. One dry-run per task in a batch loop.
  3. Use --json flag for all cupt read commands when processing output programmatically: cupt list --json, cupt show --json, etc.
  4. Run cupt --version && cupt status as preflight before starting a ClickUp workflow session.
  5. Treat empty 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.
  6. Use cupt context before acting on a task to understand its parent and sibling relationships.
  7. Route markdown through markdown-aware parameters per the MARKDOWN FORMATTING CONTRACT section at the top of this skill — task create: `markdown

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.