@taazkareem/clickup-mcp-server 0.4.41 → 0.4.42
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 +26 -45
- package/build/config.js +4 -14
- package/build/handlers/prompts.js +0 -53
- package/build/handlers/tools.js +30 -303
- package/build/index.js +978 -77
- package/build/services/clickup.js +5 -171
- package/build/types/clickup.js +0 -7
- package/build/utils/resolvers.js +0 -50
- package/package.json +4 -3
- package/build/utils/logger.js +0 -47
package/README.md
CHANGED
|
@@ -2,14 +2,6 @@
|
|
|
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
|
|
6
|
-
```bash
|
|
7
|
-
npx clickup-mcp-server --stdio --env CLICKUP_API_KEY=your_api_key_here --env TEAM_ID=your_team_id_here
|
|
8
|
-
```
|
|
9
|
-
That's it! No installation needed. Just replace the credentials with your own:
|
|
10
|
-
- Get your API key from [ClickUp Settings](https://app.clickup.com/settings/apps)
|
|
11
|
-
- Find your Team ID in your ClickUp workspace URL or settings
|
|
12
|
-
|
|
13
5
|
## Features
|
|
14
6
|
|
|
15
7
|
- 🔄 **Resource Management**
|
|
@@ -51,44 +43,36 @@ That's it! No installation needed. Just replace the credentials with your own:
|
|
|
51
43
|
- Secure API key management
|
|
52
44
|
- Environment-based configuration
|
|
53
45
|
|
|
46
|
+
## Installation
|
|
47
|
+
|
|
48
|
+
### Using npx
|
|
49
|
+
```bash
|
|
50
|
+
npx @taazkareem/clickup-mcp-server
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Configuration
|
|
54
|
+
|
|
55
|
+
1. Get your ClickUp API key from [ClickUp Settings](https://app.clickup.com/settings/apps)
|
|
56
|
+
2. Create a `.env` file:
|
|
57
|
+
```env
|
|
58
|
+
CLICKUP_API_KEY=your_api_key_here
|
|
59
|
+
TEAM_ID=your_team_id_here
|
|
60
|
+
```
|
|
61
|
+
|
|
54
62
|
## Using with Cursor AI Composer Agent
|
|
55
63
|
|
|
56
|
-
To add this server to Cursor AI Composer:
|
|
57
|
-
|
|
58
|
-
1. Go to Features → MCP Servers in settings
|
|
59
|
-
2. Paste this command:
|
|
60
|
-
```bash
|
|
61
|
-
npx clickup-mcp-server --stdio --env CLICKUP_API_KEY=your_api_key_here --env TEAM_ID=your_team_id_here
|
|
62
|
-
```
|
|
63
|
-
3. Replace the credentials with your own
|
|
64
|
-
4. Click 'Save'
|
|
65
|
-
|
|
66
|
-
## Using with Roo Code (formerly Cline)
|
|
67
|
-
|
|
68
|
-
To add this server to Roo Code:
|
|
69
|
-
|
|
70
|
-
1. Open Roo Code (formerly Cline).
|
|
71
|
-
2. Ask Roo Code to add the ClickUp MCP Server to your project. It should add this to your `cline_mcp_settings.json` file:
|
|
72
|
-
```json
|
|
73
|
-
"clickup-mcp-server": {
|
|
74
|
-
"command": "npx",
|
|
75
|
-
"args": [
|
|
76
|
-
"clickup-mcp-server",
|
|
77
|
-
"--stdio"
|
|
78
|
-
],
|
|
79
|
-
"env": {
|
|
80
|
-
"CLICKUP_API_KEY": "your_api_key_here",
|
|
81
|
-
"TEAM_ID": "your_team_id_here"
|
|
82
|
-
},
|
|
83
|
-
"disabled": false,
|
|
84
|
-
"alwaysAllow": []
|
|
85
|
-
}
|
|
86
|
-
```
|
|
87
|
-
4. Replace `your_api_key_here` and `your_team_id_here` with your actual ClickUp API key and Team ID.
|
|
88
|
-
**Note:** Do not use the example settings and credentials provided here; use your own.
|
|
89
|
-
5. Save the `cline_mcp_settings.json` file.
|
|
64
|
+
To add this server to Cursor AI Composer, follow these steps:
|
|
90
65
|
|
|
66
|
+
1. Go to the Features section in the settings.
|
|
67
|
+
2. Add the following command under MCP Servers:
|
|
91
68
|
|
|
69
|
+
```bash
|
|
70
|
+
npx -y @taazkareem/clickup-mcp-server --stdio \
|
|
71
|
+
--env CLICKUP_API_KEY=your_api_key_here \
|
|
72
|
+
--env TEAM_ID=your_team_id_here
|
|
73
|
+
```
|
|
74
|
+
3. Replace `your_api_key_here` and `your_team_id_here` with your actual ClickUp credentials.
|
|
75
|
+
4. Click on 'Save' to add the server.
|
|
92
76
|
|
|
93
77
|
> **Security Note**: Your API key will be stored securely and will not be exposed to AI models.
|
|
94
78
|
|
|
@@ -254,6 +238,3 @@ Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md)
|
|
|
254
238
|
## License
|
|
255
239
|
|
|
256
240
|
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
257
|
-
|
|
258
|
-
## Support My Work! 👍
|
|
259
|
-
Solana Wallet: GjtRksihd7SWQw7hJSCDMcTxPHbgpNs7xPW3nFubNjVM
|
package/build/config.js
CHANGED
|
@@ -1,23 +1,13 @@
|
|
|
1
1
|
import dotenv from 'dotenv';
|
|
2
|
-
// Function to format messages as JSON-RPC 2.0
|
|
3
|
-
function logMessage(method, params) {
|
|
4
|
-
const jsonRpcMessage = {
|
|
5
|
-
jsonrpc: "2.0",
|
|
6
|
-
method,
|
|
7
|
-
params,
|
|
8
|
-
id: Date.now()
|
|
9
|
-
};
|
|
10
|
-
console.log(JSON.stringify(jsonRpcMessage));
|
|
11
|
-
}
|
|
12
2
|
// Load environment variables from .env file
|
|
13
3
|
dotenv.config();
|
|
14
|
-
|
|
4
|
+
console.log('Environment variables received:', {
|
|
15
5
|
CLICKUP_API_KEY: process.env.CLICKUP_API_KEY,
|
|
16
6
|
TEAM_ID: process.env.TEAM_ID
|
|
17
7
|
});
|
|
18
8
|
// Parse command line arguments for --env flags
|
|
19
9
|
const args = process.argv.slice(2);
|
|
20
|
-
|
|
10
|
+
console.log('Command line arguments:', args);
|
|
21
11
|
const envArgs = {};
|
|
22
12
|
for (let i = 0; i < args.length; i++) {
|
|
23
13
|
if (args[i] === '--env' && i + 1 < args.length) {
|
|
@@ -29,12 +19,12 @@ for (let i = 0; i < args.length; i++) {
|
|
|
29
19
|
i++; // Skip the next argument since we used it
|
|
30
20
|
}
|
|
31
21
|
}
|
|
32
|
-
|
|
22
|
+
console.log('Parsed environment arguments:', envArgs);
|
|
33
23
|
const configuration = {
|
|
34
24
|
clickupApiKey: envArgs.clickupApiKey || process.env.CLICKUP_API_KEY || '',
|
|
35
25
|
teamId: envArgs.teamId || process.env.TEAM_ID || ''
|
|
36
26
|
};
|
|
37
|
-
|
|
27
|
+
console.log('Final configuration:', configuration);
|
|
38
28
|
// Check for missing environment variables
|
|
39
29
|
const missingEnvVars = Object.entries(configuration)
|
|
40
30
|
.filter(([_, value]) => !value)
|
|
@@ -1,28 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Prompt handlers for ClickUp MCP server.
|
|
3
|
-
* Implements handlers for AI-powered analysis and summarization of ClickUp data.
|
|
4
|
-
* Each handler processes ClickUp data and returns formatted text output.
|
|
5
|
-
* @module handlers/prompts
|
|
6
|
-
*/
|
|
7
1
|
import { getAllTasks } from '../utils/resolvers.js';
|
|
8
|
-
/**
|
|
9
|
-
* Generates a summary of all tasks in the workspace
|
|
10
|
-
* Lists each task with its name and description, providing a quick overview
|
|
11
|
-
* of all work items across spaces and lists.
|
|
12
|
-
*
|
|
13
|
-
* @param clickup - ClickUp service instance for API operations
|
|
14
|
-
* @param teamId - Team ID to fetch tasks for
|
|
15
|
-
* @returns Promise resolving to formatted text summary of all tasks
|
|
16
|
-
*
|
|
17
|
-
* @example
|
|
18
|
-
* Output format:
|
|
19
|
-
* ```
|
|
20
|
-
* Summarized Tasks:
|
|
21
|
-
*
|
|
22
|
-
* - Task Name 1: Description of first task
|
|
23
|
-
* - Task Name 2: Description of second task
|
|
24
|
-
* ```
|
|
25
|
-
*/
|
|
26
2
|
export async function handleSummarizeTasks(clickup, teamId) {
|
|
27
3
|
const { tasks } = await getAllTasks(clickup, teamId);
|
|
28
4
|
let output = "Summarized Tasks:\n\n";
|
|
@@ -31,35 +7,6 @@ export async function handleSummarizeTasks(clickup, teamId) {
|
|
|
31
7
|
}
|
|
32
8
|
return output;
|
|
33
9
|
}
|
|
34
|
-
/**
|
|
35
|
-
* Analyzes task priorities across the workspace
|
|
36
|
-
* Provides a statistical breakdown of task priorities, showing the distribution
|
|
37
|
-
* of priority levels and identifying potential workload patterns.
|
|
38
|
-
*
|
|
39
|
-
* @param clickup - ClickUp service instance for API operations
|
|
40
|
-
* @param teamId - Team ID to analyze tasks for
|
|
41
|
-
* @returns Promise resolving to formatted text analysis of task priorities
|
|
42
|
-
*
|
|
43
|
-
* @example
|
|
44
|
-
* Output format:
|
|
45
|
-
* ```
|
|
46
|
-
* Task Priorities Analysis:
|
|
47
|
-
*
|
|
48
|
-
* Available Priorities: 1, 2, 3, 4
|
|
49
|
-
*
|
|
50
|
-
* Priority Counts:
|
|
51
|
-
* - Priority 1: 5
|
|
52
|
-
* - Priority 2: 3
|
|
53
|
-
* - Priority 3: 8
|
|
54
|
-
* - Priority 4: 2
|
|
55
|
-
* ```
|
|
56
|
-
*
|
|
57
|
-
* Priority levels:
|
|
58
|
-
* 1 - Urgent
|
|
59
|
-
* 2 - High
|
|
60
|
-
* 3 - Normal
|
|
61
|
-
* 4 - Low
|
|
62
|
-
*/
|
|
63
10
|
export async function handleAnalyzeTaskPriorities(clickup, teamId) {
|
|
64
11
|
const { tasks } = await getAllTasks(clickup, teamId);
|
|
65
12
|
const priorities = tasks.map(task => task.priority?.priority);
|
package/build/handlers/tools.js
CHANGED
|
@@ -1,311 +1,38 @@
|
|
|
1
|
-
|
|
2
|
-
* Tool handlers for ClickUp MCP server.
|
|
3
|
-
* Implements the business logic for each tool operation.
|
|
4
|
-
* @module handlers/tools
|
|
5
|
-
*/
|
|
6
|
-
import { resolveListId, resolveSpaceId, resolveFolderId } from '../utils/resolvers.js';
|
|
7
|
-
import { logError } from '../utils/logger.js';
|
|
8
|
-
/**
|
|
9
|
-
* Handles the workspace_hierarchy tool request
|
|
10
|
-
* Returns a formatted tree view of the ClickUp workspace structure
|
|
11
|
-
* @param clickup - ClickUp service instance
|
|
12
|
-
* @param teamId - Team ID to fetch hierarchy for
|
|
13
|
-
* @returns Promise resolving to MCP-formatted response
|
|
14
|
-
*/
|
|
1
|
+
import { resolveListId } from '../utils/resolvers.js';
|
|
15
2
|
export async function handleWorkspaceHierarchy(clickup, teamId) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
output += ` │ Available Statuses: ${statuses.join(', ')}\n`;
|
|
30
|
-
}
|
|
3
|
+
const spaces = await clickup.getSpaces(teamId);
|
|
4
|
+
const allLists = await clickup.getAllLists(teamId);
|
|
5
|
+
let output = "ClickUp Workspace Hierarchy:\n\n";
|
|
6
|
+
for (const space of spaces) {
|
|
7
|
+
output += `Space: ${space.name} (ID: ${space.id})\n`;
|
|
8
|
+
const folders = await clickup.getFolders(space.id);
|
|
9
|
+
for (const folder of folders) {
|
|
10
|
+
output += ` ├─ Folder: ${folder.name} (ID: ${folder.id})\n`;
|
|
11
|
+
const folderLists = folder.lists || [];
|
|
12
|
+
for (const list of folderLists) {
|
|
13
|
+
const { statuses } = await clickup.getTasks(list.id);
|
|
14
|
+
output += ` │ └─ List: ${list.name} (ID: ${list.id})\n`;
|
|
15
|
+
output += ` │ Available Statuses: ${statuses.join(', ')}\n`;
|
|
31
16
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
17
|
+
}
|
|
18
|
+
const spaceLists = allLists.filter(list => list.space &&
|
|
19
|
+
list.space.id === space.id &&
|
|
20
|
+
!folders.some(folder => folder.lists?.some(fl => fl.id === list.id)));
|
|
21
|
+
if (spaceLists.length > 0) {
|
|
22
|
+
output += " ├─ Lists (not in folders):\n";
|
|
23
|
+
for (const list of spaceLists) {
|
|
24
|
+
const { statuses } = await clickup.getTasks(list.id);
|
|
25
|
+
output += ` │ └─ List: ${list.name} (ID: ${list.id})\n`;
|
|
26
|
+
output += ` │ Available Statuses: ${statuses.join(', ')}\n`;
|
|
42
27
|
}
|
|
43
|
-
output += "\n";
|
|
44
28
|
}
|
|
45
|
-
|
|
46
|
-
content: [{
|
|
47
|
-
type: 'text',
|
|
48
|
-
text: output
|
|
49
|
-
}]
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
catch (error) {
|
|
53
|
-
logError('tool.workspace_hierarchy', error);
|
|
54
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
55
|
-
return {
|
|
56
|
-
content: [{
|
|
57
|
-
type: 'error',
|
|
58
|
-
text: `Failed to fetch workspace hierarchy: ${errorMessage}`
|
|
59
|
-
}]
|
|
60
|
-
};
|
|
29
|
+
output += "\n";
|
|
61
30
|
}
|
|
31
|
+
return output;
|
|
62
32
|
}
|
|
63
|
-
/**
|
|
64
|
-
* Handles the create_task tool request
|
|
65
|
-
* Creates a new task in the specified list
|
|
66
|
-
* @param clickup - ClickUp service instance
|
|
67
|
-
* @param teamId - Team ID to create task in
|
|
68
|
-
* @param args - Task creation arguments
|
|
69
|
-
* @returns Promise resolving to MCP-formatted response
|
|
70
|
-
*/
|
|
71
33
|
export async function handleCreateTask(clickup, teamId, args) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const task = await clickup.createTask(listId, taskData);
|
|
76
|
-
return {
|
|
77
|
-
content: [{
|
|
78
|
-
type: 'text',
|
|
79
|
-
text: `Successfully created task "${task.name}" (ID: ${task.id})`
|
|
80
|
-
}]
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
catch (error) {
|
|
84
|
-
logError('tool.create_task', error);
|
|
85
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
86
|
-
return {
|
|
87
|
-
content: [{
|
|
88
|
-
type: 'error',
|
|
89
|
-
text: `Failed to create task: ${errorMessage}`
|
|
90
|
-
}]
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Handles the create_bulk_tasks tool request
|
|
96
|
-
* Creates multiple tasks in the specified list
|
|
97
|
-
* @param clickup - ClickUp service instance
|
|
98
|
-
* @param teamId - Team ID to create tasks in
|
|
99
|
-
* @param args - Bulk task creation arguments
|
|
100
|
-
* @returns Promise resolving to MCP-formatted response
|
|
101
|
-
*/
|
|
102
|
-
export async function handleCreateBulkTasks(clickup, teamId, args) {
|
|
103
|
-
try {
|
|
104
|
-
const listId = await resolveListId(clickup, teamId, args.listId, args.listName);
|
|
105
|
-
const { listId: _, listName: __, tasks } = args;
|
|
106
|
-
const createdTasks = await Promise.all(tasks.map(taskData => clickup.createTask(listId, taskData)));
|
|
107
|
-
return {
|
|
108
|
-
content: [{
|
|
109
|
-
type: 'text',
|
|
110
|
-
text: `Successfully created ${createdTasks.length} tasks in list ${listId}`
|
|
111
|
-
}]
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
catch (error) {
|
|
115
|
-
logError('tool.create_bulk_tasks', error);
|
|
116
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
117
|
-
return {
|
|
118
|
-
content: [{
|
|
119
|
-
type: 'error',
|
|
120
|
-
text: `Failed to create bulk tasks: ${errorMessage}`
|
|
121
|
-
}]
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Handles the create_list tool request
|
|
127
|
-
* Creates a new list in the specified space
|
|
128
|
-
* @param clickup - ClickUp service instance
|
|
129
|
-
* @param teamId - Team ID to create list in
|
|
130
|
-
* @param args - List creation arguments
|
|
131
|
-
* @returns Promise resolving to MCP-formatted response
|
|
132
|
-
*/
|
|
133
|
-
export async function handleCreateList(clickup, teamId, args) {
|
|
134
|
-
try {
|
|
135
|
-
const spaceId = await resolveSpaceId(clickup, teamId, args.spaceId, args.spaceName);
|
|
136
|
-
const { spaceId: _, spaceName: __, ...listData } = args;
|
|
137
|
-
const list = await clickup.createList(spaceId, listData);
|
|
138
|
-
return {
|
|
139
|
-
content: [{
|
|
140
|
-
type: 'text',
|
|
141
|
-
text: `Successfully created list "${list.name}" (ID: ${list.id})`
|
|
142
|
-
}]
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
catch (error) {
|
|
146
|
-
logError('tool.create_list', error);
|
|
147
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
148
|
-
return {
|
|
149
|
-
content: [{
|
|
150
|
-
type: 'error',
|
|
151
|
-
text: `Failed to create list: ${errorMessage}`
|
|
152
|
-
}]
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Handles the create_folder tool request
|
|
158
|
-
* Creates a new folder in the specified space
|
|
159
|
-
* @param clickup - ClickUp service instance
|
|
160
|
-
* @param teamId - Team ID to create folder in
|
|
161
|
-
* @param args - Folder creation arguments
|
|
162
|
-
* @returns Promise resolving to MCP-formatted response
|
|
163
|
-
*/
|
|
164
|
-
export async function handleCreateFolder(clickup, teamId, args) {
|
|
165
|
-
try {
|
|
166
|
-
const spaceId = await resolveSpaceId(clickup, teamId, args.spaceId, args.spaceName);
|
|
167
|
-
const { spaceId: _, spaceName: __, ...folderData } = args;
|
|
168
|
-
const folder = await clickup.createFolder(spaceId, folderData);
|
|
169
|
-
return {
|
|
170
|
-
content: [{
|
|
171
|
-
type: 'text',
|
|
172
|
-
text: `Successfully created folder "${folder.name}" (ID: ${folder.id})`
|
|
173
|
-
}]
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
catch (error) {
|
|
177
|
-
logError('tool.create_folder', error);
|
|
178
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
179
|
-
return {
|
|
180
|
-
content: [{
|
|
181
|
-
type: 'error',
|
|
182
|
-
text: `Failed to create folder: ${errorMessage}`
|
|
183
|
-
}]
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* Handles the create_list_in_folder tool request
|
|
189
|
-
* Creates a new list within a specified folder
|
|
190
|
-
* @param clickup - ClickUp service instance
|
|
191
|
-
* @param teamId - Team ID to create list in
|
|
192
|
-
* @param args - List creation arguments
|
|
193
|
-
* @returns Promise resolving to MCP-formatted response
|
|
194
|
-
*/
|
|
195
|
-
export async function handleCreateListInFolder(clickup, teamId, args) {
|
|
196
|
-
try {
|
|
197
|
-
let folderId = args.folderId;
|
|
198
|
-
if (!folderId) {
|
|
199
|
-
const spaceId = await resolveSpaceId(clickup, teamId, args.spaceId, args.spaceName);
|
|
200
|
-
folderId = await resolveFolderId(clickup, teamId, undefined, args.folderName);
|
|
201
|
-
}
|
|
202
|
-
const { folderId: _, folderName: __, spaceId: ___, spaceName: ____, ...listData } = args;
|
|
203
|
-
const list = await clickup.createListInFolder(folderId, listData);
|
|
204
|
-
return {
|
|
205
|
-
content: [{
|
|
206
|
-
type: 'text',
|
|
207
|
-
text: `Successfully created list "${list.name}" (ID: ${list.id}) in folder`
|
|
208
|
-
}]
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
|
-
catch (error) {
|
|
212
|
-
logError('tool.create_list_in_folder', error);
|
|
213
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
214
|
-
return {
|
|
215
|
-
content: [{
|
|
216
|
-
type: 'error',
|
|
217
|
-
text: `Failed to create list in folder: ${errorMessage}`
|
|
218
|
-
}]
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
/**
|
|
223
|
-
* Handles the move_task tool request
|
|
224
|
-
* Moves a task to a different list
|
|
225
|
-
* @param clickup - ClickUp service instance
|
|
226
|
-
* @param teamId - Team ID
|
|
227
|
-
* @param args - Task move arguments
|
|
228
|
-
* @returns Promise resolving to MCP-formatted response
|
|
229
|
-
*/
|
|
230
|
-
export async function handleMoveTask(clickup, teamId, args) {
|
|
231
|
-
try {
|
|
232
|
-
const listId = await resolveListId(clickup, teamId, args.listId, args.listName);
|
|
233
|
-
await clickup.moveTask(args.taskId, listId);
|
|
234
|
-
return {
|
|
235
|
-
content: [{
|
|
236
|
-
type: 'text',
|
|
237
|
-
text: `Successfully moved task ${args.taskId} to list ${listId}`
|
|
238
|
-
}]
|
|
239
|
-
};
|
|
240
|
-
}
|
|
241
|
-
catch (error) {
|
|
242
|
-
logError('tool.move_task', error);
|
|
243
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
244
|
-
return {
|
|
245
|
-
content: [{
|
|
246
|
-
type: 'error',
|
|
247
|
-
text: `Failed to move task: ${errorMessage}`
|
|
248
|
-
}]
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* Handles the duplicate_task tool request
|
|
254
|
-
* Creates a copy of a task in a specified list
|
|
255
|
-
* @param clickup - ClickUp service instance
|
|
256
|
-
* @param teamId - Team ID
|
|
257
|
-
* @param args - Task duplication arguments
|
|
258
|
-
* @returns Promise resolving to MCP-formatted response
|
|
259
|
-
*/
|
|
260
|
-
export async function handleDuplicateTask(clickup, teamId, args) {
|
|
261
|
-
try {
|
|
262
|
-
const listId = await resolveListId(clickup, teamId, args.listId, args.listName);
|
|
263
|
-
const task = await clickup.duplicateTask(args.taskId, listId);
|
|
264
|
-
return {
|
|
265
|
-
content: [{
|
|
266
|
-
type: 'text',
|
|
267
|
-
text: `Successfully duplicated task "${task.name}" (ID: ${task.id})`
|
|
268
|
-
}]
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
catch (error) {
|
|
272
|
-
logError('tool.duplicate_task', error);
|
|
273
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
274
|
-
return {
|
|
275
|
-
content: [{
|
|
276
|
-
type: 'error',
|
|
277
|
-
text: `Failed to duplicate task: ${errorMessage}`
|
|
278
|
-
}]
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
/**
|
|
283
|
-
* Handles the update_task tool request
|
|
284
|
-
* Updates an existing task with new data
|
|
285
|
-
* @param clickup - ClickUp service instance
|
|
286
|
-
* @param teamId - Team ID
|
|
287
|
-
* @param args - Task update arguments
|
|
288
|
-
* @returns Promise resolving to MCP-formatted response
|
|
289
|
-
*/
|
|
290
|
-
export async function handleUpdateTask(clickup, teamId, args) {
|
|
291
|
-
try {
|
|
292
|
-
const { taskId, ...updateData } = args;
|
|
293
|
-
const task = await clickup.updateTask(taskId, updateData);
|
|
294
|
-
return {
|
|
295
|
-
content: [{
|
|
296
|
-
type: 'text',
|
|
297
|
-
text: `Successfully updated task "${task.name}" (ID: ${task.id})`
|
|
298
|
-
}]
|
|
299
|
-
};
|
|
300
|
-
}
|
|
301
|
-
catch (error) {
|
|
302
|
-
logError('tool.update_task', error);
|
|
303
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
304
|
-
return {
|
|
305
|
-
content: [{
|
|
306
|
-
type: 'error',
|
|
307
|
-
text: `Failed to update task: ${errorMessage}`
|
|
308
|
-
}]
|
|
309
|
-
};
|
|
310
|
-
}
|
|
34
|
+
const listId = await resolveListId(clickup, teamId, args.listId, args.listName);
|
|
35
|
+
const { listId: _, listName: __, ...taskData } = args;
|
|
36
|
+
return await clickup.createTask(listId, taskData);
|
|
311
37
|
}
|
|
38
|
+
// Add other handler functions for each tool...
|