@hauptsache.net/clickup-mcp 1.6.0 → 1.6.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 +28 -0
- package/dist/shared/image-processing.d.ts.map +1 -1
- package/dist/shared/image-processing.js +48 -2
- package/dist/tools/task-tools.d.ts.map +1 -1
- package/dist/tools/task-tools.js +8 -3
- package/dist/tools/time-tools.d.ts.map +1 -1
- package/dist/tools/time-tools.js +2 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,6 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
Model Context Protocol (MCP) server enabling AI assistants to interact with ClickUp workspaces. Get complete task context with comments and images, search across projects, create and update tasks, collaborate through comments, and track time - all through natural language.
|
|
4
4
|
|
|
5
|
+
## This MCP vs Official ClickUp MCP
|
|
6
|
+
|
|
7
|
+
> See also: [Official ClickUp MCP Documentation](https://developer.clickup.com/docs/connect-an-ai-assistant-to-clickups-mcp-server)
|
|
8
|
+
|
|
9
|
+
| Feature | This MCP | Official ClickUp MCP |
|
|
10
|
+
|----------------------|-------------------------------------------------------|---------------------------------------------|
|
|
11
|
+
| **Setup** | Local npm/npx install | Remote MCP (no install) |
|
|
12
|
+
| **Authentication** | API key only | OAuth only |
|
|
13
|
+
| **Task Context** | Complete with comments, status history, inline images | Requires mutiple tool calls for full contxt |
|
|
14
|
+
| **Image Support** | Inline images with smart size budgeting | Not documented |
|
|
15
|
+
| **Search** | Fuzzy search on recent tasks (limited scope) | Full ClickUp search database |
|
|
16
|
+
| **Documents** | CRUD operations | CRUD + document search |
|
|
17
|
+
| **Time Tracking** | View and create entries | Timers and entries |
|
|
18
|
+
| **Chat Integration** | Not supported | Supported |
|
|
19
|
+
| **Connected Apps** | Not supported | Connected Search |
|
|
20
|
+
| **Best For** | Coding tools, automation, context gathering | Chat apps, task management |
|
|
21
|
+
| **Support** | Community (open source) | Official ClickUp |
|
|
22
|
+
|
|
23
|
+
**Choose this MCP when:**
|
|
24
|
+
- You need rich task context with inline images for AI coding tools
|
|
25
|
+
- You need API key authentication for automation or CI/CD pipelines
|
|
26
|
+
- You want the `read-minimal` mode optimized for development workflows
|
|
27
|
+
|
|
28
|
+
**Choose Official MCP when:**
|
|
29
|
+
- You need OAuth authentication for enterprise security compliance
|
|
30
|
+
- You need Chat integration or Connected Search features
|
|
31
|
+
- You want official support and no local installation
|
|
32
|
+
|
|
5
33
|
## What You Can Do
|
|
6
34
|
|
|
7
35
|
Turn natural language into powerful ClickUp actions:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-processing.d.ts","sourceRoot":"","sources":["../../src/shared/image-processing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,kBAAkB,EAAC,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"image-processing.d.ts","sourceRoot":"","sources":["../../src/shared/image-processing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,kBAAkB,EAAC,MAAM,SAAS,CAAC;AAmDzD;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,CAAC,YAAY,GAAG,kBAAkB,CAAC,EAAE,EAAE,SAAS,GAAE,MAAyB,EAAE,SAAS,GAAE,MAAiC,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CA0BhM"}
|
|
@@ -4,6 +4,46 @@ exports.downloadImages = downloadImages;
|
|
|
4
4
|
const config_1 = require("./config");
|
|
5
5
|
const data_uri_1 = require("./data-uri");
|
|
6
6
|
const buffer_1 = require("buffer");
|
|
7
|
+
/**
|
|
8
|
+
* Detect MIME type from image binary data using magic bytes (file signatures)
|
|
9
|
+
* Returns null if the format is not recognized
|
|
10
|
+
*/
|
|
11
|
+
function detectMimeTypeFromBuffer(buffer) {
|
|
12
|
+
const bytes = new Uint8Array(buffer);
|
|
13
|
+
if (bytes.length < 12)
|
|
14
|
+
return null;
|
|
15
|
+
// PNG: 89 50 4E 47 (‰PNG)
|
|
16
|
+
if (bytes[0] === 0x89 && bytes[1] === 0x50 && bytes[2] === 0x4E && bytes[3] === 0x47) {
|
|
17
|
+
return "image/png";
|
|
18
|
+
}
|
|
19
|
+
// JPEG: FF D8 FF
|
|
20
|
+
if (bytes[0] === 0xFF && bytes[1] === 0xD8 && bytes[2] === 0xFF) {
|
|
21
|
+
return "image/jpeg";
|
|
22
|
+
}
|
|
23
|
+
// GIF: 47 49 46 38 (GIF8)
|
|
24
|
+
if (bytes[0] === 0x47 && bytes[1] === 0x49 && bytes[2] === 0x46 && bytes[3] === 0x38) {
|
|
25
|
+
return "image/gif";
|
|
26
|
+
}
|
|
27
|
+
// WebP: RIFF....WEBP
|
|
28
|
+
if (bytes[0] === 0x52 && bytes[1] === 0x49 && bytes[2] === 0x46 && bytes[3] === 0x46 &&
|
|
29
|
+
bytes[8] === 0x57 && bytes[9] === 0x45 && bytes[10] === 0x42 && bytes[11] === 0x50) {
|
|
30
|
+
return "image/webp";
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Detect MIME type from base64-encoded image data
|
|
36
|
+
* Decodes just enough bytes to check magic numbers
|
|
37
|
+
*/
|
|
38
|
+
function detectMimeTypeFromBase64(base64Data) {
|
|
39
|
+
// Need at least 16 base64 chars to decode 12 bytes for magic number detection
|
|
40
|
+
if (base64Data.length < 16)
|
|
41
|
+
return null;
|
|
42
|
+
// Create a Uint8Array directly from the decoded bytes to avoid Buffer pooling issues
|
|
43
|
+
const header = buffer_1.Buffer.from(base64Data.slice(0, 16), "base64");
|
|
44
|
+
const bytes = new Uint8Array(header);
|
|
45
|
+
return detectMimeTypeFromBuffer(bytes.buffer);
|
|
46
|
+
}
|
|
7
47
|
/**
|
|
8
48
|
* Downloads images from image_metadata blocks and applies smart size/count limiting
|
|
9
49
|
* Prioritizes keeping the most recent images (assumes content is ordered with newest items last)
|
|
@@ -98,9 +138,12 @@ async function downloadSingleImage(imageMetadata, perImageBudget) {
|
|
|
98
138
|
const actualSizeBytes = imageBuffer.byteLength;
|
|
99
139
|
// Double-check actual size (in case Content-Length was missing or incorrect)
|
|
100
140
|
if (actualSizeBytes <= perImageBudget) {
|
|
141
|
+
// Detect actual MIME type from binary data, fall back to header or default
|
|
142
|
+
const detectedMimeType = detectMimeTypeFromBuffer(imageBuffer);
|
|
143
|
+
const mimeType = detectedMimeType || response.headers.get("Content-Type") || "image/png";
|
|
101
144
|
return {
|
|
102
145
|
type: "image",
|
|
103
|
-
mimeType
|
|
146
|
+
mimeType,
|
|
104
147
|
data: buffer_1.Buffer.from(imageBuffer).toString("base64"),
|
|
105
148
|
};
|
|
106
149
|
}
|
|
@@ -145,9 +188,12 @@ function convertInlineImage(imageMetadata, perImageBudget) {
|
|
|
145
188
|
console.error(`Inline image for "${imageMetadata.alt}" is ${estimatedSize} bytes, exceeds budget of ${perImageBudget} bytes`);
|
|
146
189
|
return createImageFallback(imageMetadata);
|
|
147
190
|
}
|
|
191
|
+
// Detect actual MIME type from binary data, fall back to declared type or default
|
|
192
|
+
const detectedMimeType = detectMimeTypeFromBase64(inlineData.base64Data);
|
|
193
|
+
const mimeType = detectedMimeType || inlineData.mimeType || "image/png";
|
|
148
194
|
return {
|
|
149
195
|
type: "image",
|
|
150
|
-
mimeType
|
|
196
|
+
mimeType,
|
|
151
197
|
data: inlineData.base64Data,
|
|
152
198
|
};
|
|
153
199
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-tools.d.ts","sourceRoot":"","sources":["../../src/tools/task-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,OAAO,EAAE,YAAY,EAAyC,MAAM,iBAAiB,CAAC;AAOtF,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,QA2DrE;AA+MD;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,GAAG,EAAE,WAAW,CAAC,EAAE,GAAG,EAAE,EAAE,YAAY,GAAE,OAAe,GAAG,OAAO,CAAC,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"task-tools.d.ts","sourceRoot":"","sources":["../../src/tools/task-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,OAAO,EAAE,YAAY,EAAyC,MAAM,iBAAiB,CAAC;AAOtF,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,QA2DrE;AA+MD;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,GAAG,EAAE,WAAW,CAAC,EAAE,GAAG,EAAE,EAAE,YAAY,GAAE,OAAe,GAAG,OAAO,CAAC,YAAY,CAAC,CAmH/H"}
|
package/dist/tools/task-tools.js
CHANGED
|
@@ -229,9 +229,14 @@ async function generateTaskMetadata(task, timeEntries, isDetailView = false) {
|
|
|
229
229
|
let spaceName = task.space?.name || 'Unknown Space';
|
|
230
230
|
let spaceIdForDisplay = task.space?.id || 'N/A';
|
|
231
231
|
if (spaceName === 'Unknown Space' && task.space?.id) {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
232
|
+
try {
|
|
233
|
+
const spaceDetails = await (0, utils_1.getSpaceDetails)(task.space.id);
|
|
234
|
+
if (spaceDetails && spaceDetails.name) {
|
|
235
|
+
spaceName = spaceDetails.name;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
// Space details fetch can fail (e.g. 401) - gracefully keep "Unknown Space"
|
|
235
240
|
}
|
|
236
241
|
}
|
|
237
242
|
const metadataLines = [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"time-tools.d.ts","sourceRoot":"","sources":["../../src/tools/time-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAyDpE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,QAgFtD;
|
|
1
|
+
{"version":3,"file":"time-tools.d.ts","sourceRoot":"","sources":["../../src/tools/time-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAyDpE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,QAgFtD;AAyLD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,QAwFvD"}
|
package/dist/tools/time-tools.js
CHANGED
|
@@ -243,7 +243,8 @@ function processTimeEntriesData(data, task_id, start_date, end_date, include_all
|
|
|
243
243
|
else {
|
|
244
244
|
entryDuration = formatDuration(rawDuration);
|
|
245
245
|
}
|
|
246
|
-
|
|
246
|
+
const entryDescription = entry.description ? ` | ${entry.description}` : '';
|
|
247
|
+
outputLines.push(`${entryPrefix} ${entryStart} - ${entryDuration}${entryDescription}`);
|
|
247
248
|
});
|
|
248
249
|
}
|
|
249
250
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hauptsache.net/clickup-mcp",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.2",
|
|
4
4
|
"description": "Search, create, and retrieve tasks, add comments, and track time through natural language commands.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
},
|
|
41
41
|
"license": "MIT",
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@modelcontextprotocol/sdk": "
|
|
43
|
+
"@modelcontextprotocol/sdk": "1.15.1",
|
|
44
44
|
"fuse.js": "^7.1.0",
|
|
45
45
|
"remark-gfm": "^4.0.1",
|
|
46
46
|
"remark-parse": "^11.0.0",
|