@alanse/clickup-multi-mcp-server 1.0.0
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/Dockerfile +38 -0
- package/LICENSE +21 -0
- package/README.md +470 -0
- package/build/config.js +237 -0
- package/build/index.js +87 -0
- package/build/logger.js +163 -0
- package/build/middleware/security.js +231 -0
- package/build/server.js +288 -0
- package/build/services/clickup/base.js +432 -0
- package/build/services/clickup/bulk.js +180 -0
- package/build/services/clickup/document.js +159 -0
- package/build/services/clickup/folder.js +136 -0
- package/build/services/clickup/index.js +76 -0
- package/build/services/clickup/list.js +191 -0
- package/build/services/clickup/tag.js +239 -0
- package/build/services/clickup/task/index.js +32 -0
- package/build/services/clickup/task/task-attachments.js +105 -0
- package/build/services/clickup/task/task-comments.js +114 -0
- package/build/services/clickup/task/task-core.js +604 -0
- package/build/services/clickup/task/task-custom-fields.js +107 -0
- package/build/services/clickup/task/task-search.js +986 -0
- package/build/services/clickup/task/task-service.js +104 -0
- package/build/services/clickup/task/task-tags.js +113 -0
- package/build/services/clickup/time.js +244 -0
- package/build/services/clickup/types.js +33 -0
- package/build/services/clickup/workspace.js +397 -0
- package/build/services/shared.js +61 -0
- package/build/sse_server.js +277 -0
- package/build/tools/documents.js +489 -0
- package/build/tools/folder.js +331 -0
- package/build/tools/index.js +16 -0
- package/build/tools/list.js +428 -0
- package/build/tools/member.js +106 -0
- package/build/tools/tag.js +833 -0
- package/build/tools/task/attachments.js +357 -0
- package/build/tools/task/attachments.types.js +9 -0
- package/build/tools/task/bulk-operations.js +338 -0
- package/build/tools/task/handlers.js +919 -0
- package/build/tools/task/index.js +30 -0
- package/build/tools/task/main.js +233 -0
- package/build/tools/task/single-operations.js +469 -0
- package/build/tools/task/time-tracking.js +575 -0
- package/build/tools/task/utilities.js +310 -0
- package/build/tools/task/workspace-operations.js +258 -0
- package/build/tools/tool-enhancer.js +37 -0
- package/build/tools/utils.js +12 -0
- package/build/tools/workspace-helper.js +44 -0
- package/build/tools/workspace.js +73 -0
- package/build/utils/color-processor.js +183 -0
- package/build/utils/concurrency-utils.js +248 -0
- package/build/utils/date-utils.js +542 -0
- package/build/utils/resolver-utils.js +135 -0
- package/build/utils/sponsor-service.js +93 -0
- package/build/utils/token-utils.js +49 -0
- package/package.json +77 -0
- package/smithery.yaml +23 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPDX-FileCopyrightText: © 2025 Talib Kareem <taazkareem@icloud.com>
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*
|
|
5
|
+
* Sponsor Service Module
|
|
6
|
+
*
|
|
7
|
+
* Provides configuration and utilities for sponsorship functionality
|
|
8
|
+
*/
|
|
9
|
+
import { Logger } from '../logger.js';
|
|
10
|
+
import config from '../config.js';
|
|
11
|
+
// Create logger instance for this module
|
|
12
|
+
const logger = new Logger('SponsorService');
|
|
13
|
+
/**
|
|
14
|
+
* SponsorService - Provides sponsorship configuration and message handling
|
|
15
|
+
*/
|
|
16
|
+
export class SponsorService {
|
|
17
|
+
constructor() {
|
|
18
|
+
this.sponsorUrl = 'https://github.com/sponsors/taazkareem';
|
|
19
|
+
this.isEnabled = config.enableSponsorMessage;
|
|
20
|
+
logger.info('SponsorService initialized', { enabled: this.isEnabled });
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Get sponsor information (for documentation/reference purposes)
|
|
24
|
+
*/
|
|
25
|
+
getSponsorInfo() {
|
|
26
|
+
return {
|
|
27
|
+
isEnabled: this.isEnabled,
|
|
28
|
+
url: this.sponsorUrl
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Creates a response with optional sponsorship message
|
|
33
|
+
*/
|
|
34
|
+
createResponse(data, includeSponsorMessage = false) {
|
|
35
|
+
const content = [];
|
|
36
|
+
// Special handling for workspace hierarchy which contains a preformatted tree
|
|
37
|
+
if (data && typeof data === 'object' && 'hierarchy' in data && typeof data.hierarchy === 'string') {
|
|
38
|
+
// Handle workspace hierarchy specially - it contains a preformatted tree
|
|
39
|
+
content.push({
|
|
40
|
+
type: "text",
|
|
41
|
+
text: data.hierarchy
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
else if (typeof data === 'string') {
|
|
45
|
+
// If it's already a string, use it directly
|
|
46
|
+
content.push({
|
|
47
|
+
type: "text",
|
|
48
|
+
text: data
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
// Otherwise, stringify the JSON object
|
|
53
|
+
content.push({
|
|
54
|
+
type: "text",
|
|
55
|
+
text: JSON.stringify(data, null, 2)
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
// Then add sponsorship message if enabled
|
|
59
|
+
if (this.isEnabled && includeSponsorMessage) {
|
|
60
|
+
content.push({
|
|
61
|
+
type: "text",
|
|
62
|
+
text: `\n♥ Support this project by sponsoring the developer at ${this.sponsorUrl}`
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return { content };
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Creates an error response
|
|
69
|
+
*/
|
|
70
|
+
createErrorResponse(error, context) {
|
|
71
|
+
return this.createResponse({
|
|
72
|
+
error: typeof error === 'string' ? error : error.message,
|
|
73
|
+
...context
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Creates a bulk operation response with sponsorship message
|
|
78
|
+
*/
|
|
79
|
+
createBulkResponse(result) {
|
|
80
|
+
return this.createResponse({
|
|
81
|
+
success: true,
|
|
82
|
+
total: result.totals.total,
|
|
83
|
+
successful: result.totals.success,
|
|
84
|
+
failed: result.totals.failure,
|
|
85
|
+
failures: result.failed.map((failure) => ({
|
|
86
|
+
id: failure.item?.id || failure.item,
|
|
87
|
+
error: failure.error.message
|
|
88
|
+
}))
|
|
89
|
+
}, true); // Always include sponsor message for bulk operations
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Export a singleton instance
|
|
93
|
+
export const sponsorService = new SponsorService();
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPDX-FileCopyrightText: © 2025 Talib Kareem <taazkareem@icloud.com>
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*
|
|
5
|
+
* Token Utilities
|
|
6
|
+
*
|
|
7
|
+
* Functions for estimating token counts for LLM processing
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Simple heuristic to estimate token count from text
|
|
11
|
+
* Based on the approximate ratio of 4 characters per token for English text
|
|
12
|
+
*
|
|
13
|
+
* @param text Text to estimate tokens for
|
|
14
|
+
* @returns Estimated token count
|
|
15
|
+
*/
|
|
16
|
+
export function estimateTokensFromText(text) {
|
|
17
|
+
if (!text)
|
|
18
|
+
return 0;
|
|
19
|
+
// Characters per token varies by language, but ~4 chars per token
|
|
20
|
+
// is a reasonable approximation for English text
|
|
21
|
+
const CHARS_PER_TOKEN = 4;
|
|
22
|
+
// Add some overhead for non-text elements and special tokens
|
|
23
|
+
const OVERHEAD_FACTOR = 1.1;
|
|
24
|
+
return Math.ceil((text.length / CHARS_PER_TOKEN) * OVERHEAD_FACTOR);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Estimate tokens for a JSON object
|
|
28
|
+
*
|
|
29
|
+
* @param obj Object to estimate tokens for
|
|
30
|
+
* @returns Estimated token count
|
|
31
|
+
*/
|
|
32
|
+
export function estimateTokensFromObject(obj) {
|
|
33
|
+
// Convert to JSON string
|
|
34
|
+
const jsonString = JSON.stringify(obj);
|
|
35
|
+
// Use text estimation on the JSON string
|
|
36
|
+
// JSON has more special chars than plain text, so we adjust overhead
|
|
37
|
+
return Math.ceil(estimateTokensFromText(jsonString) * 1.2);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Check if an object would exceed the token limit when serialized to JSON
|
|
41
|
+
*
|
|
42
|
+
* @param obj Object to check
|
|
43
|
+
* @param tokenLimit Token limit to check against
|
|
44
|
+
* @returns Whether the object would exceed the token limit
|
|
45
|
+
*/
|
|
46
|
+
export function wouldExceedTokenLimit(obj, tokenLimit) {
|
|
47
|
+
const estimatedTokens = estimateTokensFromObject(obj);
|
|
48
|
+
return estimatedTokens > tokenLimit;
|
|
49
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@alanse/clickup-multi-mcp-server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "ClickUp MCP Server with Multi-Workspace Support - Integrate multiple ClickUp workspaces with AI through Model Context Protocol",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "build/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"clickup-mcp-server": "build/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"build",
|
|
12
|
+
"README.md",
|
|
13
|
+
"LICENSE",
|
|
14
|
+
"Dockerfile",
|
|
15
|
+
"smithery.yaml"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"",
|
|
19
|
+
"start": "node build/index.js",
|
|
20
|
+
"dev": "tsc -w",
|
|
21
|
+
"prepare": "npm run build"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"clickup",
|
|
25
|
+
"mcp",
|
|
26
|
+
"ai",
|
|
27
|
+
"tasks",
|
|
28
|
+
"project-management",
|
|
29
|
+
"model-context-protocol",
|
|
30
|
+
"clickup-server",
|
|
31
|
+
"clickup-mcp-server",
|
|
32
|
+
"task-management",
|
|
33
|
+
"productivity",
|
|
34
|
+
"automation",
|
|
35
|
+
"workflow",
|
|
36
|
+
"team-collaboration",
|
|
37
|
+
"artificial-intelligence",
|
|
38
|
+
"project-tracking",
|
|
39
|
+
"task-tracking",
|
|
40
|
+
"project-planning",
|
|
41
|
+
"clickup-integration",
|
|
42
|
+
"clickup-api",
|
|
43
|
+
"clickup-automation",
|
|
44
|
+
"task-organization",
|
|
45
|
+
"project-organization"
|
|
46
|
+
],
|
|
47
|
+
"author": "Daichi Okazaki(Alanse)",
|
|
48
|
+
"license": "MIT",
|
|
49
|
+
"repository": {
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "git+https://github.com/da-okazaki/clickup-multi-mcp-server.git"
|
|
52
|
+
},
|
|
53
|
+
"bugs": {
|
|
54
|
+
"url": "https://github.com/da-okazaki/clickup-multi-mcp-server/issues"
|
|
55
|
+
},
|
|
56
|
+
"homepage": "https://github.com/da-okazaki/clickup-multi-mcp-server#readme",
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"@modelcontextprotocol/sdk": "^1.11.3",
|
|
59
|
+
"axios": "^1.6.7",
|
|
60
|
+
"cors": "^2.8.5",
|
|
61
|
+
"dotenv": "^16.5.0",
|
|
62
|
+
"express": "^5.1.0",
|
|
63
|
+
"zod": "^3.23.8"
|
|
64
|
+
},
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"@types/cors": "^2.8.17",
|
|
67
|
+
"@types/express": "^5.0.1",
|
|
68
|
+
"@types/node": "^20.11.16",
|
|
69
|
+
"typescript": "^5.3.3"
|
|
70
|
+
},
|
|
71
|
+
"engines": {
|
|
72
|
+
"node": ">=18.0.0 <23.0.0"
|
|
73
|
+
},
|
|
74
|
+
"publishConfig": {
|
|
75
|
+
"access": "public"
|
|
76
|
+
}
|
|
77
|
+
}
|
package/smithery.yaml
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Smithery configuration file: https://smithery.ai/docs/config#smitheryyaml
|
|
2
|
+
|
|
3
|
+
dockerfile: Dockerfile
|
|
4
|
+
|
|
5
|
+
startCommand:
|
|
6
|
+
type: stdio
|
|
7
|
+
configSchema:
|
|
8
|
+
# JSON Schema defining the configuration options for the MCP.
|
|
9
|
+
type: object
|
|
10
|
+
required:
|
|
11
|
+
- clickupApiKey
|
|
12
|
+
- clickupTeamId
|
|
13
|
+
properties:
|
|
14
|
+
clickupApiKey:
|
|
15
|
+
type: string
|
|
16
|
+
description: Your ClickUp API key.
|
|
17
|
+
clickupTeamId:
|
|
18
|
+
type: string
|
|
19
|
+
description: Your ClickUp Team ID.
|
|
20
|
+
commandFunction:
|
|
21
|
+
# A function that produces the CLI command to start the MCP on stdio.
|
|
22
|
+
|-
|
|
23
|
+
(config) => ({ command: 'node', args: ['build/index.js'], env: { CLICKUP_API_KEY: config.clickupApiKey, CLICKUP_TEAM_ID: config.clickupTeamId } })
|