Skip to main content
Glama
README.md
<div align="center">

<img src=".github/assets/icon.png" width="112" alt="reclickup-mcp icon" />

# reclickup-mcp

**Every tool of the official ClickUp MCP, plus formatted tables written straight into a ClickUp Doc.**

<p>
  <a href="https://github.com/haonguyenstech/reclickup-mcp/releases/latest"><img alt="Release" src="https://img.shields.io/github/v/release/haonguyenstech/reclickup-mcp?color=1E9E75&logo=github" /></a>
  <img alt="Python ≥3.9" src="https://img.shields.io/badge/python-%E2%89%A53.9-3776AB?logo=python&logoColor=white" />
  <img alt="uv" src="https://img.shields.io/badge/install-uvx-DE5FE9?logo=uv&logoColor=white" />
  <img alt="Node.js" src="https://img.shields.io/badge/node-npx-339933?logo=node.js&logoColor=white" />
  <img alt="macOS | Windows" src="https://img.shields.io/badge/macOS%20%7C%20Windows-Microsoft%20Edge-0078D7?logo=microsoftedge&logoColor=white" />
  <a href="LICENSE"><img alt="MIT" src="https://img.shields.io/badge/license-MIT-6E7781" /></a>
</p>

<a href="https://pub-ad81218f6d26484ab3b7b9f714c38911.r2.dev/videos/reclickup-mcp-windows-setup.mp4"><img src=".github/assets/reclickup-mcp-windows-setup.jpg" width="760" alt="Play the Windows setup video" /></a>

<sub>Setup on Windows in Claude Desktop: install, sign in, add the clickup-user-story skill, write a ticket into a Doc (1:55).</sub>

</div>

An MCP server that gives you **every tool of the official ClickUp MCP** plus one thing it cannot do:
**write formatted tables into a ClickUp Doc** — set column widths, green header cells, bold text —
straight from Markdown, with nothing to copy or paste.

- Proxies the official server (`mcp.clickup.com`), so its tools stay current: read and write tasks, Docs, comments, lists.
- `clickup_doc_write` fills a Doc page from Markdown in a headless Microsoft Edge: tables fitted to the Doc's 720 px column, green header cells, bold scenario titles.
- Installs from this repo with one `uvx` line. Nothing to clone.

## Why

ClickUp's public Docs API (and the official MCP's `create/update_document_page`) only accepts Markdown
or plain text. Tables written that way always get equal-width columns and no cell colours.

The Doc editor does accept a **paste** whose `text/html` carries each table as

```html
<span class="ql-table-embed" data-table-embed-value="BASE64(JSON table-embed)"></span>
```

That is what ClickUp itself puts on the clipboard when you copy a task description. Column widths,
`cell-bg-color`, bold, links and headings all survive, and the result is saved server-side.
reclickup builds that HTML and pastes it inside its own **headless Microsoft Edge**: no window and
no clipboard.

## Tools

| Tool | What it does |
| --- | --- |
| all `clickup_*` tools of the official server | Proxied unchanged from `https://mcp.clickup.com/mcp` through [`mcp-remote`](https://www.npmjs.com/package/mcp-remote), so they stay current. |
| `clickup_doc_write` | Writes into a Doc page (`page_url`) from `markdown` (or a Quill `delta`). `mode` is `replace` (default) or `append`. If the page is untitled, it is named after the first `# ` line. Reloads the page and returns the widths, green cells and alignment of every table. Takes about 25 s. |
| `clickup_relogin` | Refreshes the ClickUp session of reclickup's headless browser. |

### Markdown it understands

- Headings `#`, `##`, `###` (the first `# ` line names an untitled page and is not written into the body).
- Paragraphs, `**bold**`, `*italic*`, `` `code` ``, `~~strike~~`, `[links](url)`, `> quotes`.
- Lists: `- bullet`, `1. ordered`, `- [ ]` / `- [x]` checklists, nested with two spaces.
- Pipe tables, with `<br>` for line breaks and `\|` for a literal pipe in a cell.
- Backslash escapes (`\_`, `\#`, …) as written by ClickUp's own markdown export, so a page read with
  `clickup_get_document_pages` can be edited and written back.

Every table gets a bold header row with green background cells. A table whose first header cell is
`User Story Name` is a key/value table: its first column is styled instead. Lines starting with
`Scenario <n>` in a cell are bold. Columns are sized to the Doc's 720 px text column. Presets cover the
common user-story tables (`md2delta.py` / `delta2doc.py`); any other table is scaled proportionally.

### Errors that mean "retry"

Every call answers within ~50 s (Claude Desktop and Cowork give up on a call to your computer after 60 s).

| Error | Meaning |
| --- | --- |
| `NOT_READY` | The official server is still connecting, or waits for the ClickUp sign-in in the browser. Nothing was sent. |
| `STALE_CONNECTION` | The connection to ClickUp had stopped answering (network or VPN change); reclickup restarted it. |
| `BUSY` | Another Doc write or sign-in is using reclickup's browser. |
| `NOT_LOGGED_IN` / `LOGIN_PENDING` | reclickup's browser needs a ClickUp session: call `clickup_relogin` (again). |
| `TIMEOUT` | The Doc page did not load in time; nothing was pasted. |

Read-only official tools are retried once on a network blip; writes never are.

## How it works

- **Proxy:** `reclickup_mcp/server.py` speaks MCP over stdio. It starts `npx -y mcp-remote@0.15.1 https://mcp.clickup.com/mcp`,
  forwards `tools/list`, `tools/call`, `resources/*` (the official tools' MCP Apps views, e.g. the task card of
  `clickup_get_task`) and `prompts/*`, and adds its own tools. Each request runs in its own thread, so a slow Doc
  write does not block other calls. Until the official server connects, the tool list comes from the last one seen
  (or a snapshot shipped in the package). A call slower than 20 s triggers a ping; a dead connection is restarted.
- **Browser:** `reclickup_mcp/browser.py` runs a private headless Edge on port **9335** with its own profile
  (`~/.reclickup/headless-profile`). It starts on demand and stops after 10 minutes idle
  (`RECLICKUP_IDLE_STOP`). Claude Desktop may start several copies of reclickup; they share that Edge through a
  lock file (`~/.reclickup/browser.lock`), so one copy never closes it under another's write.
- **Session:** the ClickUp session (`cu_jwt` cookie) is copied once into that profile:
  - **macOS:** from a running debug Edge on `:9222` if one is signed in, else decrypted from your
    real Edge profile. Keychain asks once for "Microsoft Edge Safe Storage": click Allow.
  - **Windows:** `clickup_relogin` opens an Edge window at the ClickUp login. Sign in once; the
    profile keeps the session.

## Install

### Let an AI agent do it

Paste one of these into **Claude Code** (or a Claude Desktop task with shell access) on the machine to set up.

<details>
<summary><b>Prompt 1: install reclickup-mcp for me</b></summary>

```text
Install the reclickup-mcp MCP server for Claude Desktop on this computer, following
https://github.com/haonguyenstech/reclickup-mcp (read its README first). Talk to me in my language.

1. Check the requirements: uv (uvx), Node.js (npx) and Microsoft Edge. Install what is missing
   (uv: the official one-line installer; Node: winget on Windows, brew on macOS) and tell me what you installed.
2. Find Claude Desktop's config. macOS: ~/Library/Application Support/Claude/claude_desktop_config.json, or
   Claude-3p/ next to it when Desktop runs through an organization gateway. Windows: %APPDATA%\Claude\,
   %LOCALAPPDATA%\Claude-3p\, or %LOCALAPPDATA%\Packages\Claude_*\LocalCache\Roaming\Claude\ for the Store app.
   If the file has "deploymentMode": "3p", the Claude-3p one is in use. Back the file up, then add ONLY this entry
   under "mcpServers", keeping every other key; write UTF-8 without a BOM:
     "reclickup-mcp": { "command": "uvx",
       "args": ["--from", "git+https://github.com/haonguyenstech/reclickup-mcp", "reclickup-mcp"] }
   (macOS: if Desktop cannot find uvx, use the full path from `which uvx`.)
3. Pre-fetch it: uvx --from git+https://github.com/haonguyenstech/reclickup-mcp python -c "import reclickup_mcp"
4. Ask me to quit Claude Desktop completely (tray / menu bar icon -> Quit) and reopen it. Do not kill it yourself.
   Then Settings -> Developer must show reclickup-mcp "Running".
5. Tell me to start a Claude Desktop task, type "log in to ClickUp", and in the browser page that opens pick the
   workspace and click "Connect Workspace".
6. Download https://github.com/haonguyenstech/reclickup-mcp/releases/latest/download/clickup-user-story.zip and
   tell me where it is: Claude Desktop -> Customize -> Skills -> + -> Upload skill.
7. Report what you changed (config file path, backup path) and what I still have to do.
```

</details>

<details>
<summary><b>Prompt 2: check for an update and update it</b></summary>

```text
Check whether reclickup-mcp (https://github.com/haonguyenstech/reclickup-mcp) on this computer is up to date,
and update it if not. Talk to me in my language.

1. Latest version: the newest commit on master
   (https://api.github.com/repos/haonguyenstech/reclickup-mcp/commits/master) and the latest release.
2. Installed version: the "reclickup-mcp" entry in Claude Desktop's claude_desktop_config.json (see the README for
   where it lives; check Claude-3p too). If it is missing, stop and offer to install it instead. If its git URL is
   pinned to an old tag or commit, tell me before changing it.
3. Update the cached build:
   uvx --refresh --from git+https://github.com/haonguyenstech/reclickup-mcp python -c "import reclickup_mcp"
4. Ask me to quit Claude Desktop completely (do not kill it yourself), then run
   tools/enable_desktop_tools.py from the repo
   (https://raw.githubusercontent.com/haonguyenstech/reclickup-mcp/master/tools/enable_desktop_tools.py):
   first without arguments; if it lists disabled reclickup tools, run it again with --apply. Delete the script after.
5. Ask me to reopen Claude Desktop and check Settings -> Developer: reclickup-mcp "Running".
6. Skill: download the latest
   https://github.com/haonguyenstech/reclickup-mcp/releases/latest/download/clickup-user-story.zip and tell me to
   replace the clickup-user-story skill (Customize -> Skills: delete the old one, Upload skill). For Claude Code,
   unzip it over ~/.claude/skills/clickup-user-story yourself.
7. Report: old -> new version, what changed (the commit messages since the old version), what I still have to do.
```

</details>

### By hand


Nothing to clone. [`uv`](https://docs.astral.sh/uv/) fetches the server straight from this repo,
installs its dependencies in a cached environment, and downloads Python itself if needed.

Requirements: **uv**, **Node.js** (for `npx`), **Microsoft Edge**.

```bash
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```

### Claude Desktop

Add this to `claude_desktop_config.json` (Settings → Developer → Edit Config), then restart Claude Desktop:

```json
{
  "mcpServers": {
    "reclickup-mcp": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/haonguyenstech/reclickup-mcp", "reclickup-mcp"]
    }
  }
}
```

If Claude Desktop cannot find `uvx` or `npx`, use the full path to `uvx` (`which uvx`, e.g.
`/Users/you/.local/bin/uvx`) and add `"env": { "PATH": "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin" }`
so the path reaches `node`/`npx`.

### Claude Code

```bash
claude mcp add reclickup-mcp -- uvx --from git+https://github.com/haonguyenstech/reclickup-mcp reclickup-mcp
```

### First run

- **Official ClickUp tools:** after the restart, start a task and ask Claude something like
  *"log in to ClickUp"*. That opens a browser tab for the official ClickUp MCP: pick your workspace
  and click **Connect Workspace**. The token is cached in `~/.mcp-auth`. Until you approve, only reclickup's
  own tools are listed; the full list appears right after.
- **`clickup_doc_write`:** needs a ClickUp session in reclickup's browser. On macOS it is copied
  automatically. On Windows, call `clickup_relogin` once and sign in in the window it opens.

### Updating

`uvx` caches the build. To pick up a newer commit, run `uvx --refresh --from git+https://github.com/haonguyenstech/reclickup-mcp reclickup-mcp`
once, or pin a version in the config: `git+https://github.com/haonguyenstech/reclickup-mcp@v0.1.0`.

## Skill: clickup-user-story

[`skills/clickup-user-story/SKILL.md`](skills/clickup-user-story/SKILL.md) is a Claude skill built on
this server. It turns a BA user-story spec into a clean draft ticket and publishes it in a fixed team
style: 840 px tables with set column widths, green header cells and bold scenario titles.

- **As a task:** created through the official tools.
- **On a Doc page:** written with `clickup_doc_write`. Give it the Doc page link and the page is
  filled in directly.
- **Edit a Doc page:** reads the page, changes what you ask (e.g. a new scenario under Acceptance
  Criteria) and writes it back with the same formatting.
- **Fix:** it also repairs existing tickets whose tables came out half width.

**Download:** [clickup-user-story.zip](https://github.com/haonguyenstech/reclickup-mcp/releases/latest/download/clickup-user-story.zip)

- **Claude Desktop / claude.ai:** Settings → Capabilities → Skills → **Upload skill**, then pick the zip.
- **Claude Code:**

  ```bash
  curl -fsSL -o /tmp/clickup-user-story.zip \
    https://github.com/haonguyenstech/reclickup-mcp/releases/latest/download/clickup-user-story.zip
  rm -rf ~/.claude/skills/clickup-user-story && unzip -q /tmp/clickup-user-story.zip -d ~/.claude/skills
  ```

  The skill is a folder: `SKILL.md` plus `scripts/` (the converters it runs) and `reference/`.

Then ask, for example: *"make a ticket from this spec into https://app.clickup.com/…/v/dc/…/…"*.
The skill reads the workspace from the link, or asks which list or Doc to use.

## Environment variables

| Variable | Default | |
| --- | --- | --- |
| `RECLICKUP_PORT` | `9335` | CDP port of the headless Edge |
| `RECLICKUP_IDLE_STOP` | `600` | Seconds of inactivity before the headless Edge is closed |
| `RECLICKUP_BROWSER` | auto | Path to the Edge executable |
| `RECLICKUP_EDGE_PROFILE` | `~/Library/Application Support/Microsoft Edge/Default` | Real Edge profile to copy the session from (macOS) |
| `RECLICKUP_CALL_BUDGET` | `50` | Seconds a call to an official tool may take before it answers `NOT_READY` (clients drop calls after ~60 s) |
| `RECLICKUP_LOGIN_WAIT` | `40` | Windows: seconds `clickup_relogin` waits for the sign-in before answering `LOGIN_PENDING` |
| `RECLICKUP_SLOW_CALL` | `20` | Seconds before a slow official call triggers a connection check |
| `RECLICKUP_SAVE_WAIT` | `4` | Seconds `clickup_doc_write` lets ClickUp save before reloading to verify |
| `RECLICKUP_NPX` | `npx` on `PATH` | `npx` to run `mcp-remote` |
| `RECLICKUP_UPSTREAM` | `https://mcp.clickup.com/mcp` | Upstream MCP URL |

Upstream (`mcp-remote`) stderr is logged to `~/.reclickup/upstream.log` (rotated at 2 MB).

## Development

```bash
python -m pip install websocket-client
python -m unittest discover -s tests -v
```

The tests need no ClickUp account: `tests/fake_upstream.py` stands in for the official server (hung, dead, wedged,
slow, flaky, Vietnamese text). CI runs them on Linux, macOS and Windows. `skills/clickup-user-story/scripts/` holds
copies of `md2delta.py` and `delta2doc.py`; a test fails if they drift from the package.

## Troubleshooting

**Claude says it has no tool to create, update or get a task.** Claude Desktop may have switched off the official
tools that come with an MCP Apps view (`clickup_create_task`, `clickup_get_task`, `clickup_update_task`,
`clickup_filter_tasks`, `clickup_search`, the timers): `main.log` shows `Filtering out disabled tool "clickup_create_task"`.
reclickup lists those tools without the view since 0a1f140, but a switch already stored stays off. Quit Claude Desktop, then:

```bash
curl -fsSL -o enable_desktop_tools.py https://raw.githubusercontent.com/haonguyenstech/reclickup-mcp/master/tools/enable_desktop_tools.py
python enable_desktop_tools.py            # shows what is switched off
python enable_desktop_tools.py --apply    # switches it back on
```

## Caveats

- `clickup_doc_write` relies on how ClickUp's web editor handles a paste, not on a public API.
  It can break if ClickUp changes the editor. The read-back check after each write reports
  that right away.
- Doc pages and tasks are different editors. `clickup_doc_write` only targets Doc pages
  (`/v/dc/…` or `/docs/…` links).

## License

MIT

TDQS

A4.1/5.0

Scored across 2 tools

Disambiguation5/5

The two tools have clearly distinct purposes: one writes content to a ClickUp Doc, the other refreshes the browser session. There is no realistic ambiguity when choosing between them, and the dependency is explicitly documented.

Naming Consistency4/5

Both names use snake_case with a consistent clickup_ prefix. However, clickup_doc_write follows a noun_verb pattern while clickup_relogin uses a bare verb, which is a minor inconsistency.

Tool Count3/5

The server has only two tools, which feels thin even for a focused integration. The surface is narrowly scoped, but additional discovery or read operations would make the set more useful.

Completeness2/5

The server supports writing and appending to a known Doc page, but lacks tools to list docs, create a new Doc page, or read existing content. These are significant gaps for an agent that needs to discover or verify ClickUp Docs.

Maintenance

ActivityMaintained
ResponsivenessSyncing