Skip to main content
Glama
README.md
# ClickUp MCP

A self-hosted MCP server for managing ClickUp from Claude chat, Claude Desktop and Claude Code. It uses your personal ClickUp API token on the server side and protects access with OAuth and a password login page.

## Tools

| Area | Tools |
|---|---|
| Workspace | list workspaces, list members, get full hierarchy |
| Spaces, folders, lists | list, get, create, update, delete |
| Tasks | search across a workspace, list by list, get, create, update, delete, move, add to or remove from extra lists |
| Task details | tags, dependencies, links, custom fields, checklists and checklist items |
| Comments | list, add, reply, list replies, edit, delete |
| Time tracking | list entries, running timer, start, stop, log manually, delete |
| Docs | search, create, list pages, read page, create page, edit page |

Every tool is marked read-only, write or destructive, so Claude asks before running delete tools.

## How access is protected

- Claude registers itself through OAuth dynamic client registration. Only Claude's callback addresses (`claude.ai`, `claude.com`) and Claude Code's local loopback callback are accepted.
- Connecting opens a login page on this server. Nothing is issued without the `ADMIN_PASSWORD`.
- Five wrong passwords from one address locks that address for 15 minutes. Twenty failures in an hour from anywhere locks the login entirely for the hour.
- Access tokens last 1 hour, refresh tokens 30 days and are replaced on every use. Only SHA-256 hashes of tokens and codes are stored.
- The ClickUp token never leaves the server and no tool returns it.
- Every write and delete call is recorded in the `audit_log` table.

## Environment

| Variable | Purpose |
|---|---|
| `PUBLIC_URL` | Public HTTPS origin, for example `https://clickup-mcp.hamzatasneem.com` |
| `PORT` | Port to listen on, default `3000` |
| `CLICKUP_API_TOKEN` | ClickUp personal API token |
| `ADMIN_PASSWORD` | Login page password, at least 16 characters |
| `DATA_DIR` | Folder for the SQLite file, `/data` in Docker |

## Local development

```
npm install
cp .env.example .env    # fill in the values
npm run dev
npm run typecheck
npm test
```

## Deployment on Dokploy

1. Create an application from this GitHub repository with the Dockerfile build type.
2. Set the environment variables above.
3. Mount a volume at `/data` so logins survive redeploys.
4. Add the domain with HTTPS on container port 3000.

## Connecting

**Claude chat and Claude Desktop:** Settings, Connectors, Add custom connector, URL `https://clickup-mcp.hamzatasneem.com/mcp`, then Connect and enter the password.

**Claude Code:**

```
claude mcp add --transport http --scope user clickup https://clickup-mcp.hamzatasneem.com/mcp
```

Then run `/mcp` inside Claude Code, pick `clickup` and sign in.

## Rotating secrets

- **ClickUp token:** regenerate in ClickUp, update `CLICKUP_API_TOKEN` in Dokploy, redeploy. Claude connections keep working.
- **Password:** update `ADMIN_PASSWORD` and redeploy. Existing connections stay signed in until their refresh token expires.
- **Sign out every client:** delete the `tokens` table rows (or the whole `/data` volume) and redeploy.