@taazkareem/clickup-mcp-server 0.4.69 → 0.4.71

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
@@ -3,35 +3,49 @@
3
3
  # MCP Server
4
4
  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.
5
5
 
6
- > 🚧 **Status Update:** -Improved task name matching and fixed workspace hierarchy display
6
+ > 🚧 **Status Update:** -Added get_task_comments tool -Improved task name matching -Fixed workspace hierarchy display
7
7
 
8
8
  <a href="https://glama.ai/mcp/servers/iwjvs2zy63">
9
9
  <img width="380" height="200" src="https://glama.ai/mcp/servers/iwjvs2zy63/badge" alt="ClickUp Server MCP server" />
10
10
  </a>
11
11
 
12
- ## Quick Start
13
-
14
- Directions for use with Cursor Composer Agent:
12
+ ## Setup
15
13
 
16
14
  1. Get your credentials:
17
15
  - ClickUp API key from [ClickUp Settings](https://app.clickup.com/settings/apps)
18
16
  - Team ID from your ClickUp workspace URL
19
- 2. Go to Features in settings (or MCP Servers depending on version)
20
- 3. Add under MCP Servers:
21
- ```bash
22
- npx -y @taazkareem/clickup-mcp-server@latest \
23
- --env CLICKUP_API_KEY=your_api_key_here \
24
- --env CLICKUP_TEAM_ID=your_team_id_here
25
- ```
26
- 4. Replace the credentials and click Save
27
- 5. Use Natural Language to interact with your ClickUp Workspace!
28
-
17
+ 2. Choose either hosted installation (sends webhooks) or NPX installation (downloads to local path and installs dependencies)
29
18
 
30
- ## Smithery Installation
19
+ ## Smithery Installation (Quick Start)
31
20
 
32
21
  [![smithery badge](https://smithery.ai/badge/@TaazKareem/clickup-mcp-server)](https://smithery.ai/server/@TaazKareem/clickup-mcp-server)
33
22
 
34
- The server is also hosted on Smithery. There, you can preview the available tools or copy the commands to run on your specific client app.
23
+ The server is hosted on Smithery. There, you can preview the available tools or copy the commands to run on your specific client app.
24
+
25
+
26
+ ## NPX Installation
27
+
28
+ Add this entry to your client's MCP settings JSON file:
29
+
30
+ {
31
+ "mcpServers": {
32
+ "ClickUp": {
33
+ "command": "npx",
34
+ "args": [
35
+ "-y",
36
+ "@taazkareem/clickup-mcp-server@latest"
37
+ ],
38
+ "env": {
39
+ "CLICKUP_API_KEY": "your-api-key",
40
+ "CLICKUP_TEAM_ID": "your-team-id"
41
+ }
42
+ }
43
+ }
44
+ }
45
+
46
+ -OR- Use this npx command:
47
+
48
+ `npx -y @taazkareem/clickup-mcp-server@latest`
35
49
 
36
50
  ## Features
37
51
 
@@ -63,8 +77,9 @@ The server is also hosted on Smithery. There, you can preview the available tool
63
77
  | [create_bulk_tasks](docs/api-reference.md#task-management) | Create multiple tasks | `tasks[]` |
64
78
  | [update_task](docs/api-reference.md#task-management) | Modify task | `taskId`/`taskName` |
65
79
  | [update_bulk_tasks](docs/api-reference.md#task-management) | Update multiple tasks | `tasks[]` with IDs or names |
66
- | [get_tasks](docs/api-reference.md#task-retrieval) | Get tasks from list | `listId`/`listName` |
67
- | [get_task](docs/api-reference.md#task-retrieval) | Get task details | `taskId`/`taskName` |
80
+ | [get_tasks](docs/api-reference.md#task-management) | Get tasks from list | `listId`/`listName` |
81
+ | [get_task](docs/api-reference.md#task-management) | Get task details | `taskId`/`taskName` |
82
+ | [get_task_comments](docs/api-reference.md#task-management) | Get comments on a task | `taskId`/`taskName` |
68
83
  | [delete_task](docs/api-reference.md#task-management) | Remove task | `taskId`/`taskName` |
69
84
  | [delete_bulk_tasks](docs/api-reference.md#task-management) | Remove multiple tasks | `tasks[]` with IDs or names |
70
85
  | [move_task](docs/api-reference.md#task-management) | Move task | `taskId`/`taskName`, `listId`/`listName` |
@@ -101,6 +116,10 @@ The server provides clear error messages for:
101
116
  - API errors
102
117
  - Rate limiting
103
118
 
119
+ ## Sponsor Message
120
+
121
+ When using this server, you may occasionally see a small sponsor message with a link to this repository included in tool responses. I hope you can support the project!
122
+
104
123
  ## Support the Developer
105
124
 
106
125
  If you find this project useful, please consider supporting
@@ -122,4 +141,3 @@ or brands owned by third parties. The use of such APIs or references does not im
122
141
  any affiliation with or endorsement by the respective companies. All trademarks and
123
142
  brand names are the property of their respective owners. This project is an independent
124
143
  work and is not officially associated with or sponsored by any third-party company mentioned.
125
-
package/build/config.js CHANGED
@@ -22,11 +22,14 @@ for (let i = 0; i < args.length; i++) {
22
22
  const configuration = {
23
23
  clickupApiKey: envArgs.clickupApiKey || process.env.CLICKUP_API_KEY || '',
24
24
  clickupTeamId: envArgs.clickupTeamId || process.env.CLICKUP_TEAM_ID || '',
25
+ enableSponsorMessage: process.env.ENABLE_SPONSOR_MESSAGE === 'true' || false,
26
+ sponsorUrl: process.env.SPONSOR_URL || 'https://github.com/sponsors/taazkareem'
25
27
  };
26
- // Validate all required variables are present
27
- const missingEnvVars = Object.entries(configuration)
28
- .filter(([_, value]) => !value)
29
- .map(([key]) => key);
28
+ // Validate only the required variables are present
29
+ const requiredVars = ['clickupApiKey', 'clickupTeamId'];
30
+ const missingEnvVars = requiredVars
31
+ .filter(key => !configuration[key])
32
+ .map(key => key);
30
33
  if (missingEnvVars.length > 0) {
31
34
  throw new Error(`Missing required environment variables: ${missingEnvVars.join(', ')}`);
32
35
  }
package/build/index.js CHANGED
@@ -10,7 +10,7 @@
10
10
  * Task Management:
11
11
  * - Create, update, move and duplicate tasks with rich description support
12
12
  * - Find tasks by name with smart disambiguation
13
- * - Bulk task creation for efficient workflow setup
13
+ * - Optimized bulk task operations with concurrent processing
14
14
  * - Comprehensive filtering and sorting options
15
15
  *
16
16
  * Workspace Organization:
@@ -0,0 +1,64 @@
1
+ import { Logger } from "./logger.js";
2
+ // Create a logger instance
3
+ const logger = new Logger('MCPTools');
4
+ /**
5
+ * Register a handler for a tool that may receive JSON string parameters
6
+ * This wrapper ensures that array and object parameters are properly parsed
7
+ *
8
+ * @param server MCP Server instance
9
+ * @param name Tool name
10
+ * @param handler Handler function
11
+ */
12
+ export function registerToolHandler(server, name, handler) {
13
+ // Create a wrapper handler that pre-processes parameters
14
+ const wrappedHandler = async (params) => {
15
+ logger.debug(`Processing parameters for tool ${name}`, { params });
16
+ try {
17
+ // Process the parameters before passing them to the actual handler
18
+ const processedParams = {};
19
+ // Process each parameter - try to parse strings that might be JSON
20
+ for (const [key, value] of Object.entries(params)) {
21
+ if (typeof value === 'string') {
22
+ try {
23
+ // Check if this might be a JSON array or object
24
+ if ((value.startsWith('[') && value.endsWith(']')) ||
25
+ (value.startsWith('{') && value.endsWith('}'))) {
26
+ try {
27
+ processedParams[key] = JSON.parse(value);
28
+ logger.debug(`Parsed JSON parameter: ${key}`, { original: value, parsed: processedParams[key] });
29
+ }
30
+ catch (parseError) {
31
+ // If parsing fails, use the original string
32
+ processedParams[key] = value;
33
+ logger.debug(`Failed to parse JSON for parameter: ${key}, using original`, { error: parseError.message });
34
+ }
35
+ }
36
+ else {
37
+ processedParams[key] = value;
38
+ }
39
+ }
40
+ catch (error) {
41
+ // If there's any error, use the original value
42
+ processedParams[key] = value;
43
+ logger.debug(`Error processing parameter: ${key}`, { error: error.message });
44
+ }
45
+ }
46
+ else {
47
+ // Non-string values are used as-is
48
+ processedParams[key] = value;
49
+ }
50
+ }
51
+ logger.debug(`Processed parameters for tool ${name}`, { processedParams });
52
+ // Call the original handler with processed parameters
53
+ return handler(processedParams);
54
+ }
55
+ catch (error) {
56
+ logger.error(`Error in wrapped handler for tool ${name}:`, { error: error.stack || error.message });
57
+ throw error;
58
+ }
59
+ };
60
+ // Use setRequestHandler to register the wrapped handler
61
+ logger.info(`Registering wrapped handler for tool: ${name}`);
62
+ // Override the tool's handler in the CallTool switch statement
63
+ // The server.ts file will use the switch case to call this handler
64
+ }
package/build/server.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
2
  import { CallToolRequestSchema, ListToolsRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
3
3
  import { workspaceHierarchyTool, handleGetWorkspaceHierarchy } from "./tools/workspace.js";
4
- import { createTaskTool, handleCreateTask, updateTaskTool, handleUpdateTask, moveTaskTool, handleMoveTask, duplicateTaskTool, handleDuplicateTask, getTaskTool, getTasksTool, handleGetTasks, deleteTaskTool, handleDeleteTask, createBulkTasksTool, handleCreateBulkTasks, updateBulkTasksTool, handleUpdateBulkTasks, moveBulkTasksTool, handleMoveBulkTasks, deleteBulkTasksTool, handleDeleteBulkTasks, getTaskCommentsTool, handleGetTaskComments } from "./tools/task.js";
4
+ import { createTaskTool, handleCreateTask, updateTaskTool, handleUpdateTask, moveTaskTool, handleMoveTask, duplicateTaskTool, handleDuplicateTask, getTaskTool, getTasksTool, handleGetTasks, deleteTaskTool, handleDeleteTask, getTaskCommentsTool, handleGetTaskComments, createBulkTasksTool, handleCreateBulkTasks, updateBulkTasksTool, handleUpdateBulkTasks, moveBulkTasksTool, handleMoveBulkTasks, deleteBulkTasksTool, handleDeleteBulkTasks } from "./tools/task.js";
5
5
  import { createListTool, handleCreateList, createListInFolderTool, handleCreateListInFolder, getListTool, handleGetList, updateListTool, handleUpdateList, deleteListTool, handleDeleteList } from "./tools/list.js";
6
6
  import { createFolderTool, handleCreateFolder, getFolderTool, handleGetFolder, updateFolderTool, handleUpdateFolder, deleteFolderTool, handleDeleteFolder } from "./tools/folder.js";
7
7
  import { Logger } from "./logger.js";
@@ -40,11 +40,11 @@ export function configureServer() {
40
40
  moveTaskTool,
41
41
  duplicateTaskTool,
42
42
  deleteTaskTool,
43
+ getTaskCommentsTool,
43
44
  createBulkTasksTool,
44
45
  updateBulkTasksTool,
45
46
  moveBulkTasksTool,
46
47
  deleteBulkTasksTool,
47
- getTaskCommentsTool,
48
48
  createListTool,
49
49
  createListInFolderTool,
50
50
  getListTool,
@@ -87,6 +87,8 @@ export function configureServer() {
87
87
  return handleGetTasks(params);
88
88
  case "delete_task":
89
89
  return handleDeleteTask(params);
90
+ case "get_task_comments":
91
+ return handleGetTaskComments(params);
90
92
  case "create_bulk_tasks":
91
93
  return handleCreateBulkTasks(params);
92
94
  case "update_bulk_tasks":
@@ -95,8 +97,6 @@ export function configureServer() {
95
97
  return handleMoveBulkTasks(params);
96
98
  case "delete_bulk_tasks":
97
99
  return handleDeleteBulkTasks(params);
98
- case "get_task_comments":
99
- return handleGetTaskComments(params);
100
100
  case "create_list":
101
101
  return handleCreateList(params);
102
102
  case "create_list_in_folder":