@griffinwork40/clickup-mcp-server 1.1.3 → 1.1.5
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/dist/schemas.d.ts +33 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +34 -0
- package/dist/schemas.js.map +1 -0
- package/dist/server.d.ts +10 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +56 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/comments.d.ts +10 -0
- package/dist/tools/comments.d.ts.map +1 -0
- package/dist/tools/comments.js +123 -0
- package/dist/tools/comments.js.map +1 -0
- package/dist/tools/custom-fields.d.ts +10 -0
- package/dist/tools/custom-fields.d.ts.map +1 -0
- package/dist/tools/custom-fields.js +68 -0
- package/dist/tools/custom-fields.js.map +1 -0
- package/dist/tools/hierarchy.d.ts +10 -0
- package/dist/tools/hierarchy.d.ts.map +1 -0
- package/dist/tools/hierarchy.js +188 -0
- package/dist/tools/hierarchy.js.map +1 -0
- package/dist/tools/index.d.ts +13 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +13 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/lists.d.ts +10 -0
- package/dist/tools/lists.d.ts.map +1 -0
- package/dist/tools/lists.js +148 -0
- package/dist/tools/lists.js.map +1 -0
- package/dist/tools/tasks-analytics.d.ts +10 -0
- package/dist/tools/tasks-analytics.d.ts.map +1 -0
- package/dist/tools/tasks-analytics.js +160 -0
- package/dist/tools/tasks-analytics.js.map +1 -0
- package/dist/tools/tasks-get.d.ts +10 -0
- package/dist/tools/tasks-get.d.ts.map +1 -0
- package/dist/tools/tasks-get.js +209 -0
- package/dist/tools/tasks-get.js.map +1 -0
- package/dist/tools/tasks-read.d.ts +10 -0
- package/dist/tools/tasks-read.d.ts.map +1 -0
- package/dist/tools/tasks-read.js +379 -0
- package/dist/tools/tasks-read.js.map +1 -0
- package/dist/tools/tasks-search.d.ts +10 -0
- package/dist/tools/tasks-search.d.ts.map +1 -0
- package/dist/tools/tasks-search.js +176 -0
- package/dist/tools/tasks-search.js.map +1 -0
- package/dist/tools/tasks-write.d.ts +10 -0
- package/dist/tools/tasks-write.d.ts.map +1 -0
- package/dist/tools/tasks-write.js +232 -0
- package/dist/tools/tasks-write.js.map +1 -0
- package/dist/tools/time-tracking.d.ts +10 -0
- package/dist/tools/time-tracking.d.ts.map +1 -0
- package/dist/tools/time-tracking.js +180 -0
- package/dist/tools/time-tracking.js.map +1 -0
- package/dist/utils/api-client.d.ts +17 -0
- package/dist/utils/api-client.d.ts.map +1 -0
- package/dist/utils/api-client.js +77 -0
- package/dist/utils/api-client.js.map +1 -0
- package/dist/utils/csv-export.d.ts +29 -0
- package/dist/utils/csv-export.d.ts.map +1 -0
- package/dist/utils/csv-export.js +204 -0
- package/dist/utils/csv-export.js.map +1 -0
- package/dist/utils/custom-fields.d.ts +25 -0
- package/dist/utils/custom-fields.d.ts.map +1 -0
- package/dist/utils/custom-fields.js +132 -0
- package/dist/utils/custom-fields.js.map +1 -0
- package/dist/utils/data-processing.d.ts +10 -0
- package/dist/utils/data-processing.d.ts.map +1 -0
- package/dist/utils/data-processing.js +18 -0
- package/dist/utils/data-processing.js.map +1 -0
- package/dist/utils/formatters/base.d.ts +21 -0
- package/dist/utils/formatters/base.d.ts.map +1 -0
- package/dist/utils/formatters/base.js +30 -0
- package/dist/utils/formatters/base.js.map +1 -0
- package/dist/utils/formatters/entities.d.ts +34 -0
- package/dist/utils/formatters/entities.d.ts.map +1 -0
- package/dist/utils/formatters/entities.js +146 -0
- package/dist/utils/formatters/entities.js.map +1 -0
- package/dist/utils/formatters/index.d.ts +6 -0
- package/dist/utils/formatters/index.d.ts.map +1 -0
- package/dist/utils/formatters/index.js +6 -0
- package/dist/utils/formatters/index.js.map +1 -0
- package/dist/utils/index.d.ts +13 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +21 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/task-analytics.d.ts +14 -0
- package/dist/utils/task-analytics.d.ts.map +1 -0
- package/dist/utils/task-analytics.js +67 -0
- package/dist/utils/task-analytics.js.map +1 -0
- package/dist/utils/task-counter.d.ts +24 -0
- package/dist/utils/task-counter.d.ts.map +1 -0
- package/dist/utils/task-counter.js +52 -0
- package/dist/utils/task-counter.js.map +1 -0
- package/dist/utils/truncation.d.ts +14 -0
- package/dist/utils/truncation.d.ts.map +1 -0
- package/dist/utils/truncation.js +124 -0
- package/dist/utils/truncation.js.map +1 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +2 -1
- package/dist/utils.js.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task write tools for ClickUp MCP server.
|
|
3
|
+
* Tools for creating, updating, and deleting tasks.
|
|
4
|
+
*/
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { ResponseFormat, Priority } from "../constants.js";
|
|
7
|
+
import { ResponseFormatSchema } from "../schemas.js";
|
|
8
|
+
import { makeApiRequest, handleApiError, formatTaskMarkdown } from "../utils/index.js";
|
|
9
|
+
/**
|
|
10
|
+
* Register task write tools with the MCP server
|
|
11
|
+
*/
|
|
12
|
+
export function registerTaskWriteTools(server) {
|
|
13
|
+
// Tool 8: Create Task
|
|
14
|
+
server.registerTool("clickup_create_task", {
|
|
15
|
+
title: "Create ClickUp Task",
|
|
16
|
+
description: `Create a new task in a list.
|
|
17
|
+
|
|
18
|
+
Use clickup_get_list_details first to see available statuses.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
- list_id (string): The list ID where task will be created
|
|
22
|
+
- name (string): Task name (required)
|
|
23
|
+
- description (string, optional): Task description (supports markdown)
|
|
24
|
+
- status (string, optional): Task status (must match list statuses)
|
|
25
|
+
- priority (1-4, optional): Priority (1=Urgent, 2=High, 3=Normal, 4=Low)
|
|
26
|
+
- assignees (number[], optional): Array of assignee user IDs
|
|
27
|
+
- due_date (number, optional): Due date as Unix timestamp in milliseconds
|
|
28
|
+
- start_date (number, optional): Start date as Unix timestamp in milliseconds
|
|
29
|
+
- tags (string[], optional): Array of tag names
|
|
30
|
+
- response_format ('markdown' | 'json'): Output format (default: 'markdown')
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
The created task with all properties including the new task ID.
|
|
34
|
+
|
|
35
|
+
Examples:
|
|
36
|
+
- Use when: "Create a task called 'Fix bug' in list 123456"
|
|
37
|
+
- Use when: "Add a new task with priority high and assign to user 789"
|
|
38
|
+
|
|
39
|
+
Error Handling:
|
|
40
|
+
- Returns "Error: Bad request" if status doesn't match list statuses (400)
|
|
41
|
+
- Returns "Error: Resource not found" if list_id is invalid (404)`,
|
|
42
|
+
inputSchema: z.object({
|
|
43
|
+
list_id: z.string().min(1).describe("List ID"),
|
|
44
|
+
name: z.string().min(1).max(1000).describe("Task name"),
|
|
45
|
+
description: z.string().optional().describe("Task description (markdown supported)"),
|
|
46
|
+
status: z.string().optional().describe("Task status (must match list statuses)"),
|
|
47
|
+
priority: z.nativeEnum(Priority).optional().describe("Priority: 1=Urgent, 2=High, 3=Normal, 4=Low"),
|
|
48
|
+
assignees: z.array(z.number()).optional().describe("Assignee user IDs"),
|
|
49
|
+
due_date: z.number().optional().describe("Due date (Unix timestamp in milliseconds)"),
|
|
50
|
+
start_date: z.number().optional().describe("Start date (Unix timestamp in milliseconds)"),
|
|
51
|
+
tags: z.array(z.string()).optional().describe("Tag names"),
|
|
52
|
+
response_format: ResponseFormatSchema
|
|
53
|
+
}).strict(),
|
|
54
|
+
annotations: {
|
|
55
|
+
readOnlyHint: false,
|
|
56
|
+
destructiveHint: false,
|
|
57
|
+
idempotentHint: false,
|
|
58
|
+
openWorldHint: true
|
|
59
|
+
}
|
|
60
|
+
}, async (params) => {
|
|
61
|
+
try {
|
|
62
|
+
const taskData = {
|
|
63
|
+
name: params.name
|
|
64
|
+
};
|
|
65
|
+
if (params.description)
|
|
66
|
+
taskData.description = params.description;
|
|
67
|
+
if (params.status)
|
|
68
|
+
taskData.status = params.status;
|
|
69
|
+
if (params.priority)
|
|
70
|
+
taskData.priority = params.priority;
|
|
71
|
+
if (params.assignees)
|
|
72
|
+
taskData.assignees = params.assignees;
|
|
73
|
+
if (params.due_date)
|
|
74
|
+
taskData.due_date = params.due_date;
|
|
75
|
+
if (params.start_date)
|
|
76
|
+
taskData.start_date = params.start_date;
|
|
77
|
+
if (params.tags)
|
|
78
|
+
taskData.tags = params.tags;
|
|
79
|
+
const task = await makeApiRequest(`list/${params.list_id}/task`, "POST", taskData);
|
|
80
|
+
let result;
|
|
81
|
+
if (params.response_format === ResponseFormat.MARKDOWN) {
|
|
82
|
+
const lines = ["# Task Created Successfully", ""];
|
|
83
|
+
lines.push(formatTaskMarkdown(task));
|
|
84
|
+
result = lines.join("\n");
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
result = JSON.stringify(task, null, 2);
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
content: [{ type: "text", text: result }]
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
return {
|
|
95
|
+
content: [{ type: "text", text: handleApiError(error) }]
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
// Tool 9: Update Task
|
|
100
|
+
server.registerTool("clickup_update_task", {
|
|
101
|
+
title: "Update ClickUp Task",
|
|
102
|
+
description: `Update an existing task's properties.
|
|
103
|
+
|
|
104
|
+
Only include the fields you want to change.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
- task_id (string): The task ID
|
|
108
|
+
- name (string, optional): New task name
|
|
109
|
+
- description (string, optional): New description
|
|
110
|
+
- status (string, optional): New status
|
|
111
|
+
- priority (1-4, optional): New priority
|
|
112
|
+
- assignees_add (number[], optional): User IDs to add as assignees
|
|
113
|
+
- assignees_rem (number[], optional): User IDs to remove from assignees
|
|
114
|
+
- due_date (number, optional): New due date (Unix timestamp in milliseconds)
|
|
115
|
+
- response_format ('markdown' | 'json'): Output format (default: 'markdown')
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
The updated task with all properties.
|
|
119
|
+
|
|
120
|
+
Examples:
|
|
121
|
+
- Use when: "Update task abc123 status to 'complete'"
|
|
122
|
+
- Use when: "Change task priority to urgent and add assignee 789"
|
|
123
|
+
|
|
124
|
+
Error Handling:
|
|
125
|
+
- Returns "Error: Resource not found" if task_id is invalid (404)
|
|
126
|
+
- Returns "Error: Bad request" if status doesn't exist in list (400)`,
|
|
127
|
+
inputSchema: z.object({
|
|
128
|
+
task_id: z.string().min(1).describe("Task ID"),
|
|
129
|
+
name: z.string().optional().describe("New task name"),
|
|
130
|
+
description: z.string().optional().describe("New description"),
|
|
131
|
+
status: z.string().optional().describe("New status"),
|
|
132
|
+
priority: z.nativeEnum(Priority).optional().describe("New priority"),
|
|
133
|
+
assignees_add: z.array(z.number()).optional().describe("User IDs to add as assignees"),
|
|
134
|
+
assignees_rem: z.array(z.number()).optional().describe("User IDs to remove"),
|
|
135
|
+
due_date: z.number().optional().describe("New due date (Unix timestamp)"),
|
|
136
|
+
response_format: ResponseFormatSchema
|
|
137
|
+
}).strict(),
|
|
138
|
+
annotations: {
|
|
139
|
+
readOnlyHint: false,
|
|
140
|
+
destructiveHint: false,
|
|
141
|
+
idempotentHint: false,
|
|
142
|
+
openWorldHint: true
|
|
143
|
+
}
|
|
144
|
+
}, async (params) => {
|
|
145
|
+
try {
|
|
146
|
+
const updateData = {};
|
|
147
|
+
if (params.name)
|
|
148
|
+
updateData.name = params.name;
|
|
149
|
+
if (params.description !== undefined)
|
|
150
|
+
updateData.description = params.description;
|
|
151
|
+
if (params.status)
|
|
152
|
+
updateData.status = params.status;
|
|
153
|
+
if (params.priority)
|
|
154
|
+
updateData.priority = params.priority;
|
|
155
|
+
if (params.due_date !== undefined)
|
|
156
|
+
updateData.due_date = params.due_date;
|
|
157
|
+
// Handle assignee updates separately
|
|
158
|
+
if (params.assignees_add && params.assignees_add.length > 0) {
|
|
159
|
+
updateData.assignees = { add: params.assignees_add };
|
|
160
|
+
}
|
|
161
|
+
if (params.assignees_rem && params.assignees_rem.length > 0) {
|
|
162
|
+
if (!updateData.assignees)
|
|
163
|
+
updateData.assignees = {};
|
|
164
|
+
updateData.assignees.rem = params.assignees_rem;
|
|
165
|
+
}
|
|
166
|
+
const task = await makeApiRequest(`task/${params.task_id}`, "PUT", updateData);
|
|
167
|
+
let result;
|
|
168
|
+
if (params.response_format === ResponseFormat.MARKDOWN) {
|
|
169
|
+
const lines = ["# Task Updated Successfully", ""];
|
|
170
|
+
lines.push(formatTaskMarkdown(task));
|
|
171
|
+
result = lines.join("\n");
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
result = JSON.stringify(task, null, 2);
|
|
175
|
+
}
|
|
176
|
+
return {
|
|
177
|
+
content: [{ type: "text", text: result }]
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
return {
|
|
182
|
+
content: [{ type: "text", text: handleApiError(error) }]
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
// Tool 10: Delete Task
|
|
187
|
+
server.registerTool("clickup_delete_task", {
|
|
188
|
+
title: "Delete ClickUp Task",
|
|
189
|
+
description: `Delete a task permanently.
|
|
190
|
+
|
|
191
|
+
WARNING: This action is destructive and cannot be undone.
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
- task_id (string): The task ID to delete
|
|
195
|
+
|
|
196
|
+
Returns:
|
|
197
|
+
Confirmation message of deletion.
|
|
198
|
+
|
|
199
|
+
Examples:
|
|
200
|
+
- Use when: "Delete task abc123"
|
|
201
|
+
- Don't use when: You want to archive (use update status to 'closed' instead)
|
|
202
|
+
|
|
203
|
+
Error Handling:
|
|
204
|
+
- Returns "Error: Resource not found" if task_id is invalid (404)
|
|
205
|
+
- Returns "Error: Permission denied" if no delete access (403)`,
|
|
206
|
+
inputSchema: z.object({
|
|
207
|
+
task_id: z.string().min(1).describe("Task ID to delete")
|
|
208
|
+
}).strict(),
|
|
209
|
+
annotations: {
|
|
210
|
+
readOnlyHint: false,
|
|
211
|
+
destructiveHint: true,
|
|
212
|
+
idempotentHint: true,
|
|
213
|
+
openWorldHint: true
|
|
214
|
+
}
|
|
215
|
+
}, async (params) => {
|
|
216
|
+
try {
|
|
217
|
+
await makeApiRequest(`task/${params.task_id}`, "DELETE");
|
|
218
|
+
return {
|
|
219
|
+
content: [{
|
|
220
|
+
type: "text",
|
|
221
|
+
text: `Task ${params.task_id} has been deleted successfully.`
|
|
222
|
+
}]
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
catch (error) {
|
|
226
|
+
return {
|
|
227
|
+
content: [{ type: "text", text: handleApiError(error) }]
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=tasks-write.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks-write.js","sourceRoot":"","sources":["../../src/tools/tasks-write.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Time tracking tools for ClickUp MCP server.
|
|
3
|
+
* Tools for managing time entries.
|
|
4
|
+
*/
|
|
5
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6
|
+
/**
|
|
7
|
+
* Register time tracking tools with the MCP server
|
|
8
|
+
*/
|
|
9
|
+
export declare function registerTimeTrackingTools(server: McpServer): void;
|
|
10
|
+
//# sourceMappingURL=time-tracking.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time-tracking.d.ts","sourceRoot":"","sources":["../../src/tools/time-tracking.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAazE;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAmMjE"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Time tracking tools for ClickUp MCP server.
|
|
3
|
+
* Tools for managing time entries.
|
|
4
|
+
*/
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { ResponseFormat } from "../constants.js";
|
|
7
|
+
import { ResponseFormatSchema } from "../schemas.js";
|
|
8
|
+
import { makeApiRequest, handleApiError, formatTimeEntryMarkdown, truncateResponse, formatTruncationInfo } from "../utils/index.js";
|
|
9
|
+
/**
|
|
10
|
+
* Register time tracking tools with the MCP server
|
|
11
|
+
*/
|
|
12
|
+
export function registerTimeTrackingTools(server) {
|
|
13
|
+
// Tool 17: Start Time Entry
|
|
14
|
+
server.registerTool("clickup_start_time_entry", {
|
|
15
|
+
title: "Start Time Tracking",
|
|
16
|
+
description: `Start tracking time on a task.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
- team_id (string): The team ID
|
|
20
|
+
- task_id (string): The task ID to track time for
|
|
21
|
+
- description (string, optional): Description of what you're working on
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
The started time entry with start time and ID.
|
|
25
|
+
|
|
26
|
+
Examples:
|
|
27
|
+
- Use when: "Start tracking time on task abc123"
|
|
28
|
+
- Use when: "Begin time entry for this task"
|
|
29
|
+
|
|
30
|
+
Error Handling:
|
|
31
|
+
- Returns error if already tracking time
|
|
32
|
+
- Returns "Error: Resource not found" if task_id is invalid (404)`,
|
|
33
|
+
inputSchema: z.object({
|
|
34
|
+
team_id: z.string().min(1).describe("Team ID"),
|
|
35
|
+
task_id: z.string().min(1).describe("Task ID"),
|
|
36
|
+
description: z.string().optional().describe("Description of work")
|
|
37
|
+
}).strict(),
|
|
38
|
+
annotations: {
|
|
39
|
+
readOnlyHint: false,
|
|
40
|
+
destructiveHint: false,
|
|
41
|
+
idempotentHint: false,
|
|
42
|
+
openWorldHint: true
|
|
43
|
+
}
|
|
44
|
+
}, async (params) => {
|
|
45
|
+
try {
|
|
46
|
+
const data = { tid: params.task_id };
|
|
47
|
+
if (params.description)
|
|
48
|
+
data.description = params.description;
|
|
49
|
+
const entry = await makeApiRequest(`team/${params.team_id}/time_entries/start`, "POST", data);
|
|
50
|
+
return {
|
|
51
|
+
content: [{
|
|
52
|
+
type: "text",
|
|
53
|
+
text: `Time tracking started successfully\n\n${formatTimeEntryMarkdown(entry.data)}`
|
|
54
|
+
}]
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
return {
|
|
59
|
+
content: [{ type: "text", text: handleApiError(error) }]
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
// Tool 18: Stop Time Entry
|
|
64
|
+
server.registerTool("clickup_stop_time_entry", {
|
|
65
|
+
title: "Stop Time Tracking",
|
|
66
|
+
description: `Stop the currently running time entry.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
- team_id (string): The team ID
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
The completed time entry with duration.
|
|
73
|
+
|
|
74
|
+
Examples:
|
|
75
|
+
- Use when: "Stop tracking time"
|
|
76
|
+
- Use when: "End current time entry"
|
|
77
|
+
|
|
78
|
+
Error Handling:
|
|
79
|
+
- Returns error if no active time tracking
|
|
80
|
+
- Returns "Error: Resource not found" if team_id is invalid (404)`,
|
|
81
|
+
inputSchema: z.object({
|
|
82
|
+
team_id: z.string().min(1).describe("Team ID")
|
|
83
|
+
}).strict(),
|
|
84
|
+
annotations: {
|
|
85
|
+
readOnlyHint: false,
|
|
86
|
+
destructiveHint: false,
|
|
87
|
+
idempotentHint: true,
|
|
88
|
+
openWorldHint: true
|
|
89
|
+
}
|
|
90
|
+
}, async (params) => {
|
|
91
|
+
try {
|
|
92
|
+
const entry = await makeApiRequest(`team/${params.team_id}/time_entries/stop`, "POST");
|
|
93
|
+
return {
|
|
94
|
+
content: [{
|
|
95
|
+
type: "text",
|
|
96
|
+
text: `Time tracking stopped successfully\n\n${formatTimeEntryMarkdown(entry.data)}`
|
|
97
|
+
}]
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
return {
|
|
102
|
+
content: [{ type: "text", text: handleApiError(error) }]
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
// Tool 19: Get Time Entries
|
|
107
|
+
server.registerTool("clickup_get_time_entries", {
|
|
108
|
+
title: "Get Time Entries",
|
|
109
|
+
description: `Get time tracking entries for a team.
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
- team_id (string): The team ID
|
|
113
|
+
- assignee (number, optional): Filter by assignee user ID
|
|
114
|
+
- start_date (number, optional): Filter entries after this date (Unix timestamp)
|
|
115
|
+
- end_date (number, optional): Filter entries before this date (Unix timestamp)
|
|
116
|
+
- response_format ('markdown' | 'json'): Output format (default: 'markdown')
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
List of time entries with task, user, duration, and dates.
|
|
120
|
+
|
|
121
|
+
Examples:
|
|
122
|
+
- Use when: "Show me time entries for team 123456"
|
|
123
|
+
- Use when: "Get time tracked by user 789 this week"
|
|
124
|
+
|
|
125
|
+
Error Handling:
|
|
126
|
+
- Returns "Error: Resource not found" if team_id is invalid (404)`,
|
|
127
|
+
inputSchema: z.object({
|
|
128
|
+
team_id: z.string().min(1).describe("Team ID"),
|
|
129
|
+
assignee: z.number().optional().describe("Filter by assignee user ID"),
|
|
130
|
+
start_date: z.number().optional().describe("Filter after date (Unix timestamp)"),
|
|
131
|
+
end_date: z.number().optional().describe("Filter before date (Unix timestamp)"),
|
|
132
|
+
response_format: ResponseFormatSchema
|
|
133
|
+
}).strict(),
|
|
134
|
+
annotations: {
|
|
135
|
+
readOnlyHint: true,
|
|
136
|
+
destructiveHint: false,
|
|
137
|
+
idempotentHint: true,
|
|
138
|
+
openWorldHint: true
|
|
139
|
+
}
|
|
140
|
+
}, async (params) => {
|
|
141
|
+
try {
|
|
142
|
+
const queryParams = {};
|
|
143
|
+
if (params.assignee)
|
|
144
|
+
queryParams.assignee = params.assignee;
|
|
145
|
+
if (params.start_date)
|
|
146
|
+
queryParams.start_date = params.start_date;
|
|
147
|
+
if (params.end_date)
|
|
148
|
+
queryParams.end_date = params.end_date;
|
|
149
|
+
const data = await makeApiRequest(`team/${params.team_id}/time_entries`, "GET", undefined, queryParams);
|
|
150
|
+
const entries = data.data || [];
|
|
151
|
+
let result;
|
|
152
|
+
if (params.response_format === ResponseFormat.MARKDOWN) {
|
|
153
|
+
const lines = [`# Time Entries for Team ${params.team_id}`, ""];
|
|
154
|
+
lines.push(`Found ${entries.length} time entr${entries.length === 1 ? "y" : "ies"}`, "");
|
|
155
|
+
lines.push("");
|
|
156
|
+
for (const entry of entries) {
|
|
157
|
+
lines.push(formatTimeEntryMarkdown(entry));
|
|
158
|
+
lines.push("");
|
|
159
|
+
lines.push("---");
|
|
160
|
+
lines.push("");
|
|
161
|
+
}
|
|
162
|
+
result = lines.join("\n");
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
result = JSON.stringify({ entries }, null, 2);
|
|
166
|
+
}
|
|
167
|
+
const { content: finalContent, truncation } = truncateResponse(result, entries.length, "entries");
|
|
168
|
+
result = finalContent + formatTruncationInfo(truncation);
|
|
169
|
+
return {
|
|
170
|
+
content: [{ type: "text", text: result }]
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
return {
|
|
175
|
+
content: [{ type: "text", text: handleApiError(error) }]
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=time-tracking.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time-tracking.js","sourceRoot":"","sources":["../../src/tools/time-tracking.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API client utilities for ClickUp MCP server.
|
|
3
|
+
* Handles authentication and HTTP requests to the ClickUp API.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Get ClickUp API token from environment
|
|
7
|
+
*/
|
|
8
|
+
export declare function getApiToken(): string;
|
|
9
|
+
/**
|
|
10
|
+
* Make an authenticated request to the ClickUp API
|
|
11
|
+
*/
|
|
12
|
+
export declare function makeApiRequest<T>(endpoint: string, method?: "GET" | "POST" | "PUT" | "DELETE", data?: any, params?: any): Promise<T>;
|
|
13
|
+
/**
|
|
14
|
+
* Convert API errors to user-friendly messages
|
|
15
|
+
*/
|
|
16
|
+
export declare function handleApiError(error: unknown): string;
|
|
17
|
+
//# sourceMappingURL=api-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/utils/api-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH;;GAEG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAMpC;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,CAAC,EACpC,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAgB,EACjD,IAAI,CAAC,EAAE,GAAG,EACV,MAAM,CAAC,EAAE,GAAG,GACX,OAAO,CAAC,CAAC,CAAC,CAmBZ;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAgCrD"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API client utilities for ClickUp MCP server.
|
|
3
|
+
* Handles authentication and HTTP requests to the ClickUp API.
|
|
4
|
+
*/
|
|
5
|
+
import axios, { AxiosError } from "axios";
|
|
6
|
+
import { API_BASE_URL, DEFAULT_TIMEOUT } from "../constants.js";
|
|
7
|
+
/**
|
|
8
|
+
* Get ClickUp API token from environment
|
|
9
|
+
*/
|
|
10
|
+
export function getApiToken() {
|
|
11
|
+
const token = process.env.CLICKUP_API_TOKEN;
|
|
12
|
+
if (!token) {
|
|
13
|
+
throw new Error("CLICKUP_API_TOKEN environment variable is required");
|
|
14
|
+
}
|
|
15
|
+
return token;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Make an authenticated request to the ClickUp API
|
|
19
|
+
*/
|
|
20
|
+
export async function makeApiRequest(endpoint, method = "GET", data, params) {
|
|
21
|
+
try {
|
|
22
|
+
const token = getApiToken();
|
|
23
|
+
const response = await axios({
|
|
24
|
+
method,
|
|
25
|
+
url: `${API_BASE_URL}/${endpoint}`,
|
|
26
|
+
data,
|
|
27
|
+
params,
|
|
28
|
+
timeout: DEFAULT_TIMEOUT,
|
|
29
|
+
headers: {
|
|
30
|
+
"Authorization": token,
|
|
31
|
+
"Content-Type": "application/json",
|
|
32
|
+
"Accept": "application/json"
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
return response.data;
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Convert API errors to user-friendly messages
|
|
43
|
+
*/
|
|
44
|
+
export function handleApiError(error) {
|
|
45
|
+
if (error instanceof AxiosError) {
|
|
46
|
+
if (error.response) {
|
|
47
|
+
const status = error.response.status;
|
|
48
|
+
const data = error.response.data;
|
|
49
|
+
switch (status) {
|
|
50
|
+
case 400:
|
|
51
|
+
return `Error: Bad request. ${data?.err || "Check your parameters and try again."}`;
|
|
52
|
+
case 401:
|
|
53
|
+
return "Error: Invalid or missing API token. Please check your CLICKUP_API_TOKEN environment variable.";
|
|
54
|
+
case 403:
|
|
55
|
+
return "Error: Permission denied. You don't have access to this resource.";
|
|
56
|
+
case 404:
|
|
57
|
+
return `Error: Resource not found. ${data?.err || "Please check the ID is correct."}`;
|
|
58
|
+
case 429:
|
|
59
|
+
return "Error: Rate limit exceeded. Please wait before making more requests. ClickUp allows 100 requests/minute (Business) or 1000/minute (Business Plus+).";
|
|
60
|
+
case 500:
|
|
61
|
+
case 502:
|
|
62
|
+
case 503:
|
|
63
|
+
return "Error: ClickUp server error. Please try again later or check https://status.clickup.com";
|
|
64
|
+
default:
|
|
65
|
+
return `Error: API request failed with status ${status}. ${data?.err || ""}`;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else if (error.code === "ECONNABORTED") {
|
|
69
|
+
return "Error: Request timed out. Please try again.";
|
|
70
|
+
}
|
|
71
|
+
else if (error.code === "ENOTFOUND" || error.code === "ECONNREFUSED") {
|
|
72
|
+
return "Error: Cannot connect to ClickUp API. Please check your internet connection.";
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return `Error: Unexpected error occurred: ${error instanceof Error ? error.message : String(error)}`;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/utils/api-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEhE;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAC5C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,QAAgB,EAChB,SAA4C,KAAK,EACjD,IAAU,EACV,MAAY;IAEZ,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,WAAW,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC;YAC3B,MAAM;YACN,GAAG,EAAE,GAAG,YAAY,IAAI,QAAQ,EAAE;YAClC,IAAI;YACJ,MAAM;YACN,OAAO,EAAE,eAAe;YACxB,OAAO,EAAE;gBACP,eAAe,EAAE,KAAK;gBACtB,cAAc,EAAE,kBAAkB;gBAClC,QAAQ,EAAE,kBAAkB;aAC7B;SACF,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;QAChC,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACnB,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;YACrC,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;YAEjC,QAAQ,MAAM,EAAE,CAAC;gBACf,KAAK,GAAG;oBACN,OAAO,uBAAuB,IAAI,EAAE,GAAG,IAAI,sCAAsC,EAAE,CAAC;gBACtF,KAAK,GAAG;oBACN,OAAO,gGAAgG,CAAC;gBAC1G,KAAK,GAAG;oBACN,OAAO,mEAAmE,CAAC;gBAC7E,KAAK,GAAG;oBACN,OAAO,8BAA8B,IAAI,EAAE,GAAG,IAAI,iCAAiC,EAAE,CAAC;gBACxF,KAAK,GAAG;oBACN,OAAO,qJAAqJ,CAAC;gBAC/J,KAAK,GAAG,CAAC;gBACT,KAAK,GAAG,CAAC;gBACT,KAAK,GAAG;oBACN,OAAO,yFAAyF,CAAC;gBACnG;oBACE,OAAO,yCAAyC,MAAM,KAAK,IAAI,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC;YACjF,CAAC;QACH,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YACzC,OAAO,6CAA6C,CAAC;QACvD,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YACvE,OAAO,8EAA8E,CAAC;QACxF,CAAC;IACH,CAAC;IAED,OAAO,qCAAqC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;AACvG,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSV export utilities for ClickUp MCP server.
|
|
3
|
+
* Export tasks to CSV format with custom field support.
|
|
4
|
+
*/
|
|
5
|
+
import type { ClickUpTask } from "../types.js";
|
|
6
|
+
/**
|
|
7
|
+
* Options for exporting tasks to CSV
|
|
8
|
+
*/
|
|
9
|
+
export interface ExportCSVOptions {
|
|
10
|
+
archived?: boolean;
|
|
11
|
+
include_closed?: boolean;
|
|
12
|
+
statuses?: string[];
|
|
13
|
+
custom_fields?: string[];
|
|
14
|
+
include_standard_fields?: boolean;
|
|
15
|
+
add_phone_number_column?: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Escape CSV fields to handle commas, quotes, and newlines
|
|
19
|
+
*/
|
|
20
|
+
export declare function escapeCSV(value: any): string;
|
|
21
|
+
/**
|
|
22
|
+
* Convert task to CSV row array
|
|
23
|
+
*/
|
|
24
|
+
export declare function taskToCSVRow(task: ClickUpTask, fieldOrder: string[]): string[];
|
|
25
|
+
/**
|
|
26
|
+
* Export tasks to CSV format
|
|
27
|
+
*/
|
|
28
|
+
export declare function exportTasksToCSV(listId: string, options?: ExportCSVOptions): Promise<string>;
|
|
29
|
+
//# sourceMappingURL=csv-export.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csv-export.d.ts","sourceRoot":"","sources":["../../src/utils/csv-export.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAM/C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,GAAG,GAAG,MAAM,CAQ5C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAuE9E;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,MAAM,CAAC,CA4HjB"}
|