@taazkareem/clickup-mcp-server 0.4.48 → 0.4.51

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/package.json CHANGED
@@ -1,22 +1,22 @@
1
1
  {
2
2
  "name": "@taazkareem/clickup-mcp-server",
3
- "version": "0.4.48",
3
+ "version": "0.4.51",
4
4
  "description": "ClickUp MCP Server - Integrate ClickUp tasks with AI through Model Context Protocol",
5
5
  "type": "module",
6
- "main": "./build/index.js",
6
+ "main": "build/index.js",
7
7
  "bin": {
8
- "clickup-mcp-server": "build/index.js",
9
- "@taazkareem/clickup-mcp-server": "build/index.js"
8
+ "clickup-mcp-server": "build/index.js"
10
9
  },
11
10
  "files": [
12
11
  "build",
13
12
  "README.md",
14
- "LICENSE"
13
+ "LICENSE",
14
+ "Dockerfile.smithery",
15
+ "smithery.yaml"
15
16
  ],
16
17
  "scripts": {
17
18
  "build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"",
18
19
  "start": "node build/index.js",
19
- "serve": "node build/index.js --stdio",
20
20
  "dev": "tsc -w",
21
21
  "prepare": "npm run build",
22
22
  "prepublishOnly": "npm test",
@@ -36,18 +36,18 @@
36
36
  "license": "MIT",
37
37
  "repository": {
38
38
  "type": "git",
39
- "url": "git+https://github.com/taazkareem/clickup-mcp-server.git"
39
+ "url": "https://github.com/taazkareem/clickup-mcp-server.git"
40
40
  },
41
41
  "bugs": {
42
42
  "url": "https://github.com/taazkareem/clickup-mcp-server/issues"
43
43
  },
44
44
  "homepage": "https://github.com/taazkareem/clickup-mcp-server#readme",
45
45
  "dependencies": {
46
- "@modelcontextprotocol/sdk": "^1.4.1",
47
- "@modelcontextprotocol/server-github": "^2025.1.23",
46
+ "@modelcontextprotocol/sdk": "0.6.0",
47
+ "@types/express": "^5.0.0",
48
48
  "axios": "^1.6.7",
49
49
  "dotenv": "^16.4.1",
50
- "zod": "^3.24.2"
50
+ "express": "^4.21.2"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@types/node": "^20.11.16",
package/smithery.yaml ADDED
@@ -0,0 +1,23 @@
1
+ # Smithery configuration file: https://smithery.ai/docs/config#smitheryyaml
2
+
3
+ dockerfile: Dockerfile.smithery
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 } })
@@ -1,88 +0,0 @@
1
- import { getAllTasks } from '../utils/resolvers.js';
2
- export async function handleSummarizeTasks(clickup, teamId) {
3
- const { tasks } = await getAllTasks(clickup, teamId);
4
- let output = "Summarized Tasks:\n\n";
5
- for (const task of tasks) {
6
- output += `- ${task.name}: ${task.description}\n`;
7
- }
8
- return output;
9
- }
10
- export async function handleAnalyzeTaskPriorities(clickup, teamId) {
11
- const { tasks } = await getAllTasks(clickup, teamId);
12
- const priorities = tasks.map(task => task.priority?.priority);
13
- const uniquePriorities = [...new Set(priorities.filter(p => p !== undefined))];
14
- const priorityCounts = uniquePriorities.map(priority => ({
15
- priority,
16
- count: priorities.filter(p => p === priority).length
17
- }));
18
- let output = "Task Priorities Analysis:\n\n";
19
- output += "Available Priorities: " + uniquePriorities.join(', ') + "\n\n";
20
- output += "Priority Counts:\n";
21
- for (const priority of priorityCounts) {
22
- output += `- Priority ${priority.priority}: ${priority.count}\n`;
23
- }
24
- return output;
25
- }
26
- export async function handleGenerateDescription(clickup, taskId) {
27
- try {
28
- const task = await clickup.getTask(taskId);
29
- // Generate a structured description based on task properties
30
- let description = "# Task Description\n\n";
31
- // Basic Information
32
- description += "## Overview\n";
33
- description += `${task.name}\n\n`;
34
- // Status and Priority
35
- description += "## Status & Priority\n";
36
- description += `- Status: ${task.status?.status || 'Not set'}\n`;
37
- description += `- Priority: ${task.priority?.priority || 'Not set'}\n\n`;
38
- // Time Information
39
- description += "## Timeline\n";
40
- description += `- Created: ${new Date(task.date_created).toLocaleDateString()}\n`;
41
- if (task.due_date) {
42
- description += `- Due Date: ${new Date(task.due_date).toLocaleDateString()}\n`;
43
- }
44
- description += "\n";
45
- // Dependencies and Relationships
46
- description += "## Dependencies & Relationships\n";
47
- const dependencies = task.dependencies || [];
48
- if (dependencies.length > 0) {
49
- description += "### Dependencies:\n";
50
- dependencies.forEach(dep => {
51
- description += `- ${dep.task_id}\n`;
52
- });
53
- }
54
- else {
55
- description += "No dependencies identified.\n";
56
- }
57
- description += "\n";
58
- // Success Criteria
59
- description += "## Success Criteria\n";
60
- const checkList = task.check_list || [];
61
- if (checkList.length > 0) {
62
- checkList.forEach(item => {
63
- description += `- [ ] ${item.name}\n`;
64
- });
65
- }
66
- else {
67
- description += "- Task completion requirements to be defined\n";
68
- }
69
- description += "\n";
70
- // Resources
71
- description += "## Required Resources\n";
72
- const assignees = task.assignees || [];
73
- if (assignees.length > 0) {
74
- description += "### Assigned Team Members:\n";
75
- assignees.forEach(assignee => {
76
- description += `- ${assignee.username}\n`;
77
- });
78
- }
79
- else {
80
- description += "No team members assigned yet.\n";
81
- }
82
- return description;
83
- }
84
- catch (error) {
85
- console.error('Error generating description:', error);
86
- throw error;
87
- }
88
- }
@@ -1,38 +0,0 @@
1
- import { resolveListId } from '../utils/resolvers.js';
2
- export async function handleWorkspaceHierarchy(clickup, teamId) {
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`;
16
- }
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`;
27
- }
28
- }
29
- output += "\n";
30
- }
31
- return output;
32
- }
33
- export async function handleCreateTask(clickup, teamId, args) {
34
- const listId = await resolveListId(clickup, teamId, args.listId, args.listName);
35
- const { listId: _, listName: __, ...taskData } = args;
36
- return await clickup.createTask(listId, taskData);
37
- }
38
- // Add other handler functions for each tool...
@@ -1,48 +0,0 @@
1
- export async function resolveListId(clickup, teamId, listId, listName) {
2
- if (listId)
3
- return listId;
4
- if (!listName) {
5
- throw new Error("Either listId or listName is required");
6
- }
7
- const result = await clickup.findListByNameGlobally(teamId, listName);
8
- if (!result) {
9
- throw new Error(`List with name "${listName}" not found`);
10
- }
11
- return result.list.id;
12
- }
13
- export async function resolveSpaceId(clickup, teamId, spaceId, spaceName) {
14
- if (spaceId)
15
- return spaceId;
16
- if (!spaceName) {
17
- throw new Error("Either spaceId or spaceName is required");
18
- }
19
- const space = await clickup.findSpaceByName(teamId, spaceName);
20
- if (!space) {
21
- throw new Error(`Space with name "${spaceName}" not found`);
22
- }
23
- return space.id;
24
- }
25
- export async function resolveFolderId(clickup, teamId, folderId, folderName) {
26
- if (folderId)
27
- return folderId;
28
- if (!folderName) {
29
- throw new Error("Either folderId or folderName is required");
30
- }
31
- const result = await clickup.findFolderByNameGlobally(teamId, folderName);
32
- if (!result) {
33
- throw new Error(`Folder with name "${folderName}" not found`);
34
- }
35
- return result.folder.id;
36
- }
37
- export async function getAllTasks(clickup, teamId) {
38
- const spaces = await clickup.getSpaces(teamId);
39
- const spacePromises = spaces.map(async (space) => {
40
- const lists = await clickup.getLists(space.id);
41
- const listPromises = lists.map(list => clickup.getTasks(list.id));
42
- const listResults = await Promise.all(listPromises);
43
- return listResults.flatMap(result => result.tasks);
44
- });
45
- const tasksPerSpace = await Promise.all(spacePromises);
46
- const allTasks = tasksPerSpace.flat();
47
- return { tasks: allTasks, spaces };
48
- }