Announcing CIMD support for MCP Client registration
Learn more

ClickUp MCP vs ClickUp API for AI Agents

TL;DR

  • ClickUp's official MCP server is in public beta and exposes roughly 40 tools across search, tasks, time tracking, chat, and docs. Goals, webhooks, Custom Field creation, and Space-level tag management exist only in the REST API.
  • MCP auth is OAuth only, with no personal token option and no custom API key path. The REST API supports both a personal token (never expires) and OAuth (access tokens currently do not expire either, though both remain user-revocable).
  • MCP rate limits are aggressive without the Everything AI add-on: 50 calls per 24 hours on the Free Forever plan, 300 calls per 24 hours on Unlimited and above. The REST API uses per-minute limits by plan instead, from 100 to 10,000 requests per minute per token.
  • For multi-tenant B2B agents, neither path solves per-user credential storage, rotation, or revocation. That is infrastructure you build or buy regardless of which path you pick.
  • Scalekit's ClickUp connector wraps the REST API directly, which means goal tracking, webhook management, and task deletion are available as scoped tools even though the official MCP server does not expose them yet.

Your agent needs to read and write ClickUp. ClickUp ships an official hosted MCP server and a REST API that has been production-ready for years. They are not interchangeable: different tool coverage, different auth models, different operational risk. Here is how to pick.

What ClickUp MCP and ClickUp API actually are

ClickUp MCP

ClickUp's MCP server is hosted at https://mcp.clickup.com/mcp and is currently in public beta. It is available on every ClickUp plan, including Free Forever.

Authentication is OAuth only. ClickUp's own FAQ is explicit on this point: you cannot authenticate with a personal API token or a static access token through the MCP server. Every connection goes through a browser-based OAuth consent flow.

The server supports a vetted list of MCP clients, including Claude Desktop, Claude Code, Cursor, VS Code, ChatGPT, and Microsoft Copilot Studio. If your client is not on that list, ClickUp requires a review request before it will accept the connection.

Resource: Clickup MCP Server docs.

ClickUp API

The ClickUp REST API (v2, with some v3 terminology in newer endpoints) covers tasks, lists, folders, spaces, goals, custom fields, time tracking, comments, chat, docs, and webhooks.

Authentication accepts two token types. A personal API token, prefixed pk_, is generated once in account settings and never expires. An OAuth 2.0 authorization code flow issues access tokens for apps built for other users; ClickUp's own documentation notes the access token "currently does not expire," though that is explicitly subject to change.

Resource: Clickup API docs.

Tool inventory: what's actually callable right now

The format most comparison posts use, a single coverage table, hides a detail that matters for production planning: ClickUp's MCP beta is still missing entire categories of write access that the REST API has supported for years. This section breaks that down explicitly so you know what's a configuration gap and what's a structural one.

What ClickUp MCP exposes today

Per the official Supported Tools documentation, the MCP server's roughly 40 tools group into these categories: Search (workspace search, search by task type, search by tag), Task management (create, get, update, delete, set custom fields), Bulk task operations (bulk create, bulk update), Task attachments, Task comments (get, get threaded replies, create), Task tags (add, remove), Task relationships (link, dependency), Move and add tasks across lists, Time tracking (six tools covering timers and entries), Workspace hierarchy (spaces, folders, lists), Members and assignees, Chat (list channels, send message), Docs (create, list pages, get pages, create page, update page), and Time-in-status reporting.

What only the REST API exposes

Four capability areas exist in the REST API with no MCP equivalent as of this writing.

Goals and Targets have no MCP tools at all. Creating, updating, or tracking a Goal requires the REST API.

Webhooks are REST only. The API supports five resource types (task, list, folder, space, and goal and target) with specific event names like taskStatusUpdated, listCreated, and keyResultUpdated. There is no MCP equivalent for subscribing to workspace change events.

Custom Field management is partial in MCP. The MCP server can set a value on an existing Custom Field, but creating new Custom Fields, retrieving the accessible Custom Field list for a Space, or removing a Custom Field value all require the REST API.

Space and Folder creation by template, plus Space-level tag management, are REST only. The MCP tool set covers Folder and List creation directly, but template-based creation and tag CRUD at the Space level are not exposed as MCP tools.

A documentation inconsistency worth flagging

ClickUp's own FAQ states deletion tools were deliberately left out of the MCP server "as a safety measure." The Supported Tools page, published by the same team, lists a "Delete task" tool with a worked example. Both pages are live on developer.clickup.com at the time of writing. Treat task deletion through MCP as unconfirmed until you test it directly against your own workspace, since the two official sources disagree.

Comparing them where it matters for agents

What your agent can actually do

Capability
ClickUp MCP
ClickUp API
Create, update, search tasks
Yes
Yes
Bulk task operations
Yes
Yes
Time tracking and timers
Yes
Yes
Comments and chat
Yes
Yes
Docs (create, read, update pages)
Yes
Yes
Goals and Targets
No
Yes
Webhooks (real-time events)
No
Yes
Create new Custom Fields
No
Yes
Space and Folder creation by template
No
Yes
Task deletion
Disputed across ClickUp's own docs
Yes
Connected Search across other apps
No
Not applicable
Bring your own credential (PAT, API key)
No
Yes

The auth path each one puts you on

MCP gives you exactly one option: OAuth 2.0, browser-based, per user, with no fallback. ClickUp's FAQ confirms you cannot substitute a personal token or any other static credential.

The REST API gives you two real options. A personal token is the right fit for single-workspace internal tooling, since it never expires and requires no consent flow. OAuth is the right fit when your app acts on behalf of other people's workspaces, since each user authorizes independently and access tokens currently do not expire, although ClickUp documents that as subject to change.

The rate limit structure differs by unit, not just by number. MCP limits apply per 24-hour rolling window, separate from the Everything AI add-on: 50 calls a day on Free Forever, 300 a day on Unlimited and above, without the add-on. The REST API limits apply per minute, per token, scaled by plan: 100 requests per minute on Free Forever through Business, 1,000 per minute on Business Plus, and 10,000 per minute on Enterprise. A background agent making frequent small calls will exhaust the MCP daily cap far faster than the equivalent REST calls would hit a per-minute ceiling.

What you own in production

With MCP, ClickUp owns the server, the tool schemas, and the OAuth implementation. You own token storage per user and the operational risk of building against a public beta: ClickUp's own feedback forum shows the tool surface changing during 2026, including a reported 6-to-49 tool expansion tracked by independent MCP ecosystem trackers over the course of the year.

With the REST API, you own the full integration: endpoint selection, pagination, retries, and token lifecycle. The tradeoff is stability. The API is the same surface ClickUp has supported for production integrations for years, with documented rate limit headers (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset) and a published common-errors reference.

When to use MCP, when to use the API

Use ClickUp MCP when:

  • Your agent is interactive and user-present, running inside Claude Desktop, Claude Code, Cursor, or VS Code, where a browser OAuth flow is a natural part of setup
  • The job is conversational: summarizing task status, answering "what's overdue," drafting a comment, or building an executive report from existing tasks and docs
  • You can tolerate a beta surface that may change tool names or add capabilities without a versioning contract
  • Your MCP client is already on ClickUp's vetted allowlist, so you skip the review request

Use the ClickUp API when:

  • Your agent runs headlessly: nightly syncs, scheduled goal tracking, or automated sprint reporting with no user present to complete an OAuth redirect
  • You need Goals, webhooks, new Custom Field creation, or template-based Space and Folder creation, none of which the MCP server exposes
  • You are building a multi-tenant product where a personal token per internal workspace, or OAuth per customer workspace, fits your architecture better than a single shared MCP connection
  • Rate limits matter at volume; per-minute REST limits scale far higher on paid plans than the MCP server's per-24-hour caps

The credential problem that exists on both paths

Both paths still leave you holding a credential per user. MCP's OAuth flow issues a token per person who connects. The REST API's OAuth flow does the same; a personal token is scoped to whoever generated it.

In a multi-tenant agent serving customers across separate ClickUp workspaces, that is N credentials to store encrypted, N credentials to monitor for revocation, and N credentials to remove cleanly when a customer churns or an employee leaves. ClickUp's documentation states OAuth access tokens currently do not expire, which removes proactive refresh logic from your list of problems, but it does not remove the need to detect and react when a user revokes access from inside ClickUp's own settings.

Scalekit's ClickUp connector handles the OAuth flow, encrypted token storage, and revocation detection for both paths, so the MCP versus API decision does not change your auth infrastructure.

Build with Scalekit: connecting your agent to ClickUp

What Scalekit's ClickUp connector actually wraps

Scalekit's ClickUp connector authenticates through ClickUp's own OAuth app (the same Authorization Code flow described in ClickUp's API docs), not through the official MCP server. That distinction is the reason the connector exposes capabilities the MCP beta does not: goal management, webhook CRUD, and task deletion are all available as Scalekit tools, because they are part of the REST API surface Scalekit wraps. Scalekit's prebuilt tool set currently covers 49 named clickup_* tools, spanning tasks, lists, folders, spaces, goals, comments, checklists, time entries, and webhooks.

Quickstart with the Node.js and Python SDK

Install the SDK and set your environment variables once per project.

npm install @scalekit-sdk/node pip install scalekit # .env SCALEKIT_ENVIRONMENT_URL= SCALEKIT_CLIENT_ID= SCALEKIT_CLIENT_SECRET=

Generate an authorization link for the user, then call a tool once they have authorized ClickUp.

import { ScalekitClient } from '@scalekit-sdk/node'; import 'dotenv/config'; const scalekit = new ScalekitClient({ clientId: process.env.SCALEKIT_CLIENT_ID, clientSecret: process.env.SCALEKIT_CLIENT_SECRET, envUrl: process.env.SCALEKIT_ENV_URL, }); const connector = 'clickup'; const identifier = 'user_123'; const { link } = await scalekit.actions.getAuthorizationLink({ connectionName: connector, identifier, }); console.log('Authorize ClickUp:', link); const result = await scalekit.actions.executeTool({ connector, identifier, toolName: 'clickup_user_get', toolInput: {}, }); console.log(result);
import os from scalekit.client import ScalekitClient from dotenv import load_dotenv load_dotenv() scalekit_client = ScalekitClient( env_url=os.getenv("SCALEKIT_ENV_URL"), client_id=os.getenv("SCALEKIT_CLIENT_ID"), client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"), ) actions = scalekit_client.actions connection_name = "clickup" identifier = "user_123" link_response = actions.get_authorization_link( connection_name=connection_name, identifier=identifier, ) print("Authorize ClickUp:", link_response.link) result = actions.execute_tool( tool_input={}, tool_name="clickup_user_get", connection_name=connection_name, identifier=identifier, ) print(result)

Tool discovery with list_scoped_tools

Before your agent calls a ClickUp tool, retrieve the tools the current user's connected account is actually authorized to call. This is not a flat catalog of every clickup_* tool; it is a scoped surface tied to that one user's authorization. Discovery comes first, scope explains why that surface is correct for this user, and execution is the agent loop that follows.

const { tools } = await scalekit.tools.listScopedTools('user_123', { filter: { connectionNames: ['clickup'], toolNames: ['clickup_task_list', 'clickup_task_get', 'clickup_task_create'], }, pageSize: 100, }); // Pass tools directly to your LLM's tool-calling API
result = scalekit_client.tools.list_scoped_tools( identifier="user_123", filter={ "connection_names": ["clickup"], "tool_names": ["clickup_task_list", "clickup_task_get", "clickup_task_create"], }, page_size=100, ) tools = result.tools

Wiring ClickUp into Claude and LangChain

For the Anthropic SDK, pass the scoped tool schemas directly into tools on messages.create.

import { ScalekitClient } from "@scalekit-sdk/node"; import Anthropic from "@anthropic-ai/sdk"; const sk = new ScalekitClient(envUrl, clientId, clientSecret); const anthropic = new Anthropic(); const { tools } = await sk.tools.listScopedTools("user_123", { filter: { connectionNames: ["clickup"], toolNames: ["clickup_task_list", "clickup_task_get", "clickup_task_create"] }, pageSize: 100, }); const llmTools = tools.map((t) => ({ name: t.tool.definition.name, description: t.tool.definition.description, input_schema: t.tool.definition.input_schema, })); const msg = await anthropic.messages.create({ model: "claude-sonnet-4-6", max_tokens: 1024, tools: llmTools, messages: [{ role: "user", content: prompt }], });

For LangChain, wrap each scoped tool in a DynamicStructuredTool and hand the list to a LangGraph React agent.

import { ScalekitClient } from "@scalekit-sdk/node"; import { DynamicStructuredTool } from "@langchain/core/tools"; import { createReactAgent } from "@langchain/langgraph/prebuilt"; import { z } from "zod"; const sk = new ScalekitClient(envUrl, clientId, clientSecret); const { tools } = await sk.tools.listScopedTools("user_123", { filter: { connectionNames: ["clickup"], toolNames: ["clickup_task_list", "clickup_task_get", "clickup_task_create"] }, pageSize: 100, }); const lcTools = tools.map((t) => new DynamicStructuredTool({ name: t.tool.definition.name, description: t.tool.definition.description, schema: z.object({}).passthrough(), func: async (args) => { const { data } = await sk.tools.executeTool({ toolName: t.tool.definition.name, identifier: "user_123", params: args, }); return JSON.stringify(data); }, })); const agent = createReactAgent({ llm, tools: lcTools });

Observability for multi-tool, multi-tenant agents

Every ClickUp tool call through Scalekit resolves the calling user's token server-side. The token never reaches the agent runtime or the LLM context, and never appears in your application logs. That matters specifically for ClickUp because task ownership, comment attribution, and goal ownership are all tied to whichever identity made the call. A shared service account breaks that attribution immediately: every task update, every comment, every goal change logs as the integration instead of the person who triggered it.

Scalekit logs every ClickUp tool call with a 90-day audit trail: who triggered it, which workspace it touched, and what came back. For a multi-tenant agent acting across separate customer ClickUp workspaces, each tenant's credentials sit in an isolated vault namespace, so a misrouted call cannot reach another tenant's tasks or goals.

Missing a ClickUp capability you need

If your agent needs a ClickUp capability that is not yet a prebuilt Scalekit tool, you have two paths that do not require waiting on a roadmap. Scalekit's proxy method, actions.request(), lets you call any ClickUp REST endpoint directly through the same vaulted, per-user token, even before a named tool exists for it.

const result = await scalekit.actions.request({ connectionName: 'clickup', identifier: 'user_123', path: '/api/v2/team/{team_id}/time_entries', method: 'GET', }); console.log(result);

For a capability you would rather see as a named, schema-validated tool, request it in the Scalekit Slack community or talk to the team directly.

Which one to build against

If your agent is interactive and lives inside Claude, Cursor, or VS Code with a user present to authorize it, ClickUp's MCP server gets you running fastest, as long as you accept beta-stage tool coverage and OAuth-only auth.

If your agent runs headlessly, needs Goals, webhooks, or new Custom Fields, or has to scale past the MCP server's per-24-hour rate caps, build against the REST API directly. Either way, the credential storage and revocation problem is identical, and that is the part that needs production-grade infrastructure, not another auth flow.

Next: Browse the Scalekit's ClickUp connector.

No items found.
Agent Auth Quickstart
On this page
Share this article
Agent Auth Quickstart

Acquire enterprise customers with zero upfront cost

Every feature unlocked. No hidden fees.
Start Free
$0
/ month
1 million Monthly Active Users
100 Monthly Active Organizations
1 SSO connection
1 SCIM connection
10K Connected Accounts
Unlimited Dev & Prod environments