@taazkareem/clickup-mcp-server 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,38 +2,20 @@
2
2
 
3
3
  A Model Context Protocol (MCP) server for integrating ClickUp tasks with AI applications. This server allows AI agents to interact with ClickUp tasks, spaces, lists, and folders through a standardized protocol.
4
4
 
5
- ## Quick Start (Recommended)
5
+ ## Quick Start
6
6
 
7
- 1. Install the server:
8
- ```bash
9
- npm install -g @taazkareem/clickup-mcp-server
10
- ```
7
+ Directions for use with Cursor Composer Agent:
11
8
 
12
- 2. Get your credentials:
9
+ 1. Get your credentials:
13
10
  - ClickUp API key from [ClickUp Settings](https://app.clickup.com/settings/apps)
14
11
  - Team ID from your ClickUp workspace URL
15
-
16
- 3. Start the server:
17
- ```bash
18
- clickup-mcp-server --env CLICKUP_API_KEY=your_api_key_here --env TEAM_ID=your_team_id_here
19
- ```
20
-
21
- > **Security Note**: Your API key will be stored securely and not exposed to AI models.
22
-
23
- ## Using with Cursor AI Composer
24
-
25
- 1. Go to Features in settings
26
- 2. Add under MCP Servers:
27
- ```bash
28
- clickup-mcp-server --env CLICKUP_API_KEY=your_api_key_here --env TEAM_ID=your_team_id_here
29
- ```
30
- 3. Replace the credentials and click Save
31
-
32
- ## Alternative Installation
33
- Run directly without installing:
12
+ 2. Go to Features in settings
13
+ 3. Add under MCP Servers:
34
14
  ```bash
35
- npx @taazkareem/clickup-mcp-server --env CLICKUP_API_KEY=your_api_key_here --env TEAM_ID=your_team_id_here
15
+ npx -y @taazkareem/clickup-mcp-server --env CLICKUP_API_KEY=your_api_key_here --env CLICKUP_TEAM_ID=your_team_id_here
36
16
  ```
17
+ 4. Replace the credentials and click Save
18
+ 5. Use Natural Language to interact with your ClickUp Workspace!
37
19
 
38
20
  ## Features
39
21
 
@@ -65,224 +47,44 @@ npx @taazkareem/clickup-mcp-server --env CLICKUP_API_KEY=your_api_key_here --env
65
47
 
66
48
  ## Available Tools
67
49
 
68
- 1. **get_workspace_hierarchy**
69
- - Gets complete hierarchy of spaces, folders, and lists
70
- - No parameters required
71
- - Returns tree structure showing:
72
- ```
73
- Workspace (root)
74
- ├── Space A
75
- │ ├── List 1
76
- │ └── Folder 1
77
- │ ├── List 2
78
- │ └── List 3
79
- └── Space B
80
- └── List 4
81
- ```
82
-
83
- 2. **get_tasks**
84
- - Gets tasks from a ClickUp list with optional filters
85
- - List Identification (required):
86
- ```
87
- listId: "123" # List ID from ClickUp
88
- -- OR --
89
- listName: "My List" # List name (case insensitive)
90
- ```
91
- - Optional Filters:
92
- ```
93
- archived: true/false # Include archived tasks
94
- page: number # Page number for pagination
95
- order_by: string # Field to sort by
96
- reverse: true/false # Reverse sort order
97
- subtasks: true/false # Include subtasks
98
- statuses: ["status1",..] # Filter by status
99
- include_closed: true/false # Include closed tasks
100
- assignees: ["user1",..] # Filter by assignee
101
- due_date_gt: timestamp # Due after date
102
- due_date_lt: timestamp # Due before date
103
- custom_fields: {...} # Filter by custom fields
104
- ```
105
-
106
- 3. **get_task**
107
- - Gets detailed information about a specific task
108
- - Task Identification (required):
109
- ```
110
- taskId: "123" # Task ID from ClickUp
111
- -- OR --
112
- taskName: "My Task" # Task name (case insensitive)
113
- ```
114
- - Optional:
115
- ```
116
- listName: "My List" # Narrow search to specific list
117
- ```
118
- - Returns full task details including attachments and custom fields
119
-
120
- 4. **create_task**
121
- - Creates a new task in ClickUp
122
- - List Identification (required):
123
- ```
124
- listId: "123" # List ID from ClickUp
125
- -- OR --
126
- listName: "My List" # List name (case insensitive)
127
- ```
128
- - Task Details:
129
- ```
130
- # Required
131
- taskName: "New Task" # Name of the task to create
132
-
133
- # Optional
134
- description: "..." # Task description (markdown supported)
135
- status: "In Progress" # Task status
136
- priority: 1-4 # Priority level (1=Urgent, 4=Low)
137
- dueDate: timestamp # Due date
138
- ```
139
-
140
- 5. **create_bulk_tasks**
141
- - Creates multiple tasks in a list
142
- - List Identification (required):
143
- ```
144
- listId: "123" # List ID from ClickUp
145
- -- OR --
146
- listName: "My List" # List name (case insensitive)
147
- ```
148
- - Tasks Array (required):
149
- ```
150
- tasks: [
151
- {
152
- taskName: "Task 1", # Required
153
- description: "...", # Optional
154
- status: "In Progress", # Optional
155
- priority: 1-4, # Optional
156
- dueDate: timestamp # Optional
157
- },
158
- // ... more tasks
159
- ]
160
- ```
161
- - Handles rate limiting automatically
162
-
163
- 6. **update_task**
164
- - Updates an existing task
165
- - Task Identification (required):
166
- ```
167
- taskId: "123" # Task ID from ClickUp
168
- -- OR --
169
- taskName: "My Task" # Task name (case insensitive)
170
- ```
171
- - Optional Updates:
172
- ```
173
- listName: "My List" # Narrow search to specific list
174
- newName: "Updated Task" # New task name
175
- description: "..." # New description
176
- status: "Done" # New status
177
- priority: 1-4 # New priority
178
- dueDate: timestamp # New due date
179
- ```
180
-
181
- 7. **delete_task**
182
- - Permanently deletes a task
183
- - Task Identification (required):
184
- ```
185
- taskId: "123" # Task ID from ClickUp
186
- -- OR --
187
- taskName: "My Task" # Task name (case insensitive)
188
- ```
189
- - Optional:
190
- ```
191
- listName: "My List" # Narrow search to specific list
192
- ```
193
-
194
- 8. **move_task**
195
- - Moves a task to a different list
196
- - Source Task (required):
197
- ```
198
- taskId: "123" # Task ID from ClickUp
199
- -- OR --
200
- taskName: "My Task" # Task name (case insensitive)
201
- ```
202
- - Destination List (required):
203
- ```
204
- destinationListId: "456" # Target list ID
205
- -- OR --
206
- destinationListName: "My List" # Target list name
207
- ```
208
- - Optional:
209
- ```
210
- sourceListName: "Old List" # Narrow task search to specific list
211
- ```
212
-
213
- 9. **duplicate_task**
214
- - Creates a copy of a task in specified list
215
- - Source Task (required):
216
- ```
217
- taskId: "123" # Task ID from ClickUp
218
- -- OR --
219
- taskName: "My Task" # Task name (case insensitive)
220
- ```
221
- - Destination List (required):
222
- ```
223
- destinationListId: "456" # Target list ID
224
- -- OR --
225
- destinationListName: "My List" # Target list name
226
- ```
227
- - Optional:
228
- ```
229
- sourceListName: "Current List" # Narrow task search to specific list
230
- ```
231
-
232
- 10. **create_list**
233
- - Creates a new list in a space
234
- - Space Identification (required):
235
- ```
236
- spaceId: "123" # Space ID from ClickUp
237
- -- OR --
238
- spaceName: "My Space" # Space name (case insensitive)
239
- ```
240
- - List Details:
241
- ```
242
- # Required
243
- listName: "New List" # Name for the new list
244
-
245
- # Optional
246
- content: "..." # List description
247
- dueDate: timestamp # List due date
248
- priority: 1-4 # List priority
249
- assignee: "user_id" # Assign to user
250
- ```
251
-
252
- 11. **create_folder**
253
- - Creates a new folder in a space
254
- - Space Identification (required):
255
- ```
256
- spaceId: "123" # Space ID from ClickUp
257
- -- OR --
258
- spaceName: "My Space" # Space name (case insensitive)
259
- ```
260
- - Folder Details:
261
- ```
262
- # Required
263
- folderName: "New Folder" # Name for the new folder
264
-
265
- # Optional
266
- overrideStatuses: true/false # Override space statuses
267
- ```
268
-
269
- 12. **create_list_in_folder**
270
- - Creates a new list within a folder
271
- - Folder Identification (required):
272
- ```
273
- folderId: "123" # Folder ID from ClickUp
274
- -- OR --
275
- folderName: "My Folder" # Folder name (case insensitive)
276
- ```
277
- - List Details:
278
- ```
279
- # Required
280
- listName: "New List" # Name for the new list
281
-
282
- # Optional
283
- content: "..." # List description
284
- status: "Active" # Initial list status
285
- ```
50
+ ### Workspace Tools
51
+ **get_workspace_hierarchy**
52
+ Returns complete workspace structure (spaces, folders, lists). No parameters required.
53
+
54
+ ### Task Tools
55
+ **get_tasks** `(listId|listName)`
56
+ Get tasks from list with optional filters (archived, page, order_by, reverse, subtasks, statuses, include_closed, assignees, due_date_gt/lt, custom_fields).
57
+
58
+ **get_task** `(taskId|taskName, ?listName)`
59
+ Get detailed task info including attachments and custom fields.
60
+
61
+ **create_task** `(listId|listName, taskName)`
62
+ Create task with optional description (markdown), status, priority (1-4), dueDate.
63
+
64
+ **create_bulk_tasks** `(listId|listName, tasks[])`
65
+ Bulk create tasks with automatic rate limiting. Each task: name (required), description, status, priority, dueDate (optional).
66
+
67
+ **update_task** `(taskId|taskName, ?listName)`
68
+ Update task name, description, status, priority (1-4), dueDate.
69
+
70
+ **delete_task** `(taskId|taskName, ?listName)`
71
+ Permanently delete a task.
72
+
73
+ **move_task** `(taskId|taskName, destinationListId|destinationListName, ?sourceListName)`
74
+ Move task to different list, preserving task data.
75
+
76
+ **duplicate_task** `(taskId|taskName, destinationListId|destinationListName, ?sourceListName)`
77
+ Create copy of task in specified list.
78
+
79
+ ### List & Folder Tools
80
+ **create_list** `(spaceId|spaceName, listName)`
81
+ Create list with optional content, dueDate, priority (1-4), assignee.
82
+
83
+ **create_folder** `(spaceId|spaceName, folderName, ?overrideStatuses)`
84
+ Create folder in space.
85
+
86
+ **create_list_in_folder** `(folderId|folderName, listName)`
87
+ Create list in folder with optional content and status.
286
88
 
287
89
  ## Available Prompts
288
90
 
package/build/config.js CHANGED
@@ -1,4 +1,3 @@
1
- // Parse command line arguments for --env flags
2
1
  const args = process.argv.slice(2);
3
2
  const envArgs = {};
4
3
  for (let i = 0; i < args.length; i++) {
@@ -6,16 +5,15 @@ for (let i = 0; i < args.length; i++) {
6
5
  const [key, value] = args[i + 1].split('=');
7
6
  if (key === 'CLICKUP_API_KEY')
8
7
  envArgs.clickupApiKey = value;
9
- if (key === 'TEAM_ID')
10
- envArgs.teamId = value;
11
- i++; // Skip the next argument since we used it
8
+ if (key === 'CLICKUP_TEAM_ID')
9
+ envArgs.clickupTeamId = value;
10
+ i++;
12
11
  }
13
12
  }
14
13
  const configuration = {
15
- clickupApiKey: envArgs.clickupApiKey || '',
16
- teamId: envArgs.teamId || '',
14
+ clickupApiKey: envArgs.clickupApiKey || process.env.CLICKUP_API_KEY || '',
15
+ clickupTeamId: envArgs.clickupTeamId || process.env.CLICKUP_TEAM_ID || '',
17
16
  };
18
- // Check for missing environment variables
19
17
  const missingEnvVars = Object.entries(configuration)
20
18
  .filter(([_, value]) => !value)
21
19
  .map(([key]) => key);
package/build/index.js CHANGED
@@ -25,7 +25,7 @@ import { CallToolRequestSchema, ListToolsRequestSchema, ListPromptsRequestSchema
25
25
  import { ClickUpService } from "./services/clickup.js";
26
26
  import config from "./config.js";
27
27
  // Initialize ClickUp service
28
- const clickup = ClickUpService.initialize(config.clickupApiKey, config.teamId);
28
+ const clickup = ClickUpService.initialize(config.clickupApiKey, config.clickupTeamId);
29
29
  /**
30
30
  * Create an MCP server with capabilities for tools and prompts.
31
31
  * Resources have been removed as they are being replaced with direct tool calls.
@@ -852,7 +852,7 @@ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
852
852
  try {
853
853
  switch (request.params.name) {
854
854
  case "summarize_tasks": {
855
- const spaces = await clickup.getSpaces(config.teamId);
855
+ const spaces = await clickup.getSpaces(config.clickupTeamId);
856
856
  const tasks = [];
857
857
  // Gather all tasks
858
858
  for (const space of spaces) {
@@ -893,7 +893,7 @@ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
893
893
  };
894
894
  }
895
895
  case "analyze_priorities": {
896
- const spaces = await clickup.getSpaces(config.teamId);
896
+ const spaces = await clickup.getSpaces(config.clickupTeamId);
897
897
  const tasks = [];
898
898
  for (const space of spaces) {
899
899
  const lists = await clickup.getLists(space.id);
@@ -6,10 +6,10 @@ import axios from 'axios';
6
6
  export class ClickUpService {
7
7
  client;
8
8
  static instance;
9
- teamId;
9
+ clickupTeamId;
10
10
  rateLimitRemaining = 100; // Default to lowest tier limit
11
11
  rateLimitReset = 0;
12
- constructor(apiKey, teamId) {
12
+ constructor(apiKey, clickupTeamId) {
13
13
  this.client = axios.create({
14
14
  baseURL: 'https://api.clickup.com/api/v2',
15
15
  headers: {
@@ -35,7 +35,7 @@ export class ClickUpService {
35
35
  }
36
36
  throw error;
37
37
  });
38
- this.teamId = teamId;
38
+ this.clickupTeamId = clickupTeamId;
39
39
  }
40
40
  /**
41
41
  * Checks if we're close to hitting rate limits and waits if necessary.
@@ -73,13 +73,13 @@ export class ClickUpService {
73
73
  /**
74
74
  * Initializes the ClickUpService singleton instance.
75
75
  * @param apiKey - The ClickUp API key for authentication
76
- * @param teamId - The team/workspace ID to operate on
76
+ * @param clickupTeamId - The team/workspace ID to operate on
77
77
  * @returns The singleton instance of ClickUpService
78
78
  * @throws Error if initialization fails
79
79
  */
80
- static initialize(apiKey, teamId) {
80
+ static initialize(apiKey, clickupTeamId) {
81
81
  if (!ClickUpService.instance) {
82
- ClickUpService.instance = new ClickUpService(apiKey, teamId);
82
+ ClickUpService.instance = new ClickUpService(apiKey, clickupTeamId);
83
83
  }
84
84
  return ClickUpService.instance;
85
85
  }
@@ -244,13 +244,13 @@ export class ClickUpService {
244
244
  }
245
245
  /**
246
246
  * Gets all lists in the workspace.
247
- * @param teamId - ID of the team/workspace
247
+ * @param clickupTeamId - ID of the team/workspace
248
248
  * @returns Promise resolving to array of ClickUpList objects
249
249
  * @throws Error if the API request fails
250
250
  */
251
- async getAllLists(teamId) {
251
+ async getAllLists(clickupTeamId) {
252
252
  return this.makeRequest(async () => {
253
- const response = await this.client.get(`/team/${teamId}/list`);
253
+ const response = await this.client.get(`/team/${clickupTeamId}/list`);
254
254
  return response.data.lists;
255
255
  });
256
256
  }
@@ -267,9 +267,9 @@ export class ClickUpService {
267
267
  });
268
268
  }
269
269
  // Spaces
270
- async getSpaces(teamId) {
270
+ async getSpaces(clickupTeamId) {
271
271
  return this.makeRequest(async () => {
272
- const response = await this.client.get(`/team/${teamId}/space`);
272
+ const response = await this.client.get(`/team/${clickupTeamId}/space`);
273
273
  return response.data.spaces;
274
274
  });
275
275
  }
@@ -279,8 +279,8 @@ export class ClickUpService {
279
279
  return response.data;
280
280
  });
281
281
  }
282
- async findSpaceByName(teamId, spaceName) {
283
- const spaces = await this.getSpaces(teamId);
282
+ async findSpaceByName(clickupTeamId, spaceName) {
283
+ const spaces = await this.getSpaces(clickupTeamId);
284
284
  return spaces.find(space => space.name.toLowerCase() === spaceName.toLowerCase()) || null;
285
285
  }
286
286
  /**
@@ -448,7 +448,7 @@ export class ClickUpService {
448
448
  }
449
449
  async findListByNameGlobally(listName) {
450
450
  // First try the direct lists
451
- const lists = await this.getAllLists(this.teamId);
451
+ const lists = await this.getAllLists(this.clickupTeamId);
452
452
  const directList = lists.find(list => list.name.toLowerCase() === listName.toLowerCase());
453
453
  if (directList)
454
454
  return directList;
@@ -477,9 +477,9 @@ export class ClickUpService {
477
477
  * @throws Error if API requests fail
478
478
  */
479
479
  async getWorkspaceHierarchy() {
480
- const spaces = await this.getSpaces(this.teamId);
480
+ const spaces = await this.getSpaces(this.clickupTeamId);
481
481
  const root = {
482
- id: this.teamId,
482
+ id: this.clickupTeamId,
483
483
  name: 'Workspace',
484
484
  type: 'workspace',
485
485
  children: []
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taazkareem/clickup-mcp-server",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "ClickUp MCP Server - Integrate ClickUp tasks with AI through Model Context Protocol",
5
5
  "type": "module",
6
6
  "main": "build/index.js",