@taazkareem/clickup-mcp-server 0.5.1 → 0.6.1

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.
Files changed (36) hide show
  1. package/README.md +29 -38
  2. package/build/config.js +33 -2
  3. package/build/index.js +16 -29
  4. package/build/logger.js +8 -11
  5. package/build/server.js +33 -8
  6. package/build/services/clickup/base.js +3 -0
  7. package/build/services/clickup/bulk.js +3 -0
  8. package/build/services/clickup/folder.js +3 -0
  9. package/build/services/clickup/index.js +9 -1
  10. package/build/services/clickup/list.js +3 -0
  11. package/build/services/clickup/tag.js +190 -0
  12. package/build/services/clickup/task.js +165 -2
  13. package/build/services/clickup/types.js +3 -0
  14. package/build/services/clickup/workspace.js +3 -0
  15. package/build/services/shared.js +3 -0
  16. package/build/tools/folder.js +3 -0
  17. package/build/tools/index.js +4 -0
  18. package/build/tools/list.js +3 -0
  19. package/build/tools/tag.js +824 -0
  20. package/build/tools/task/attachments.js +3 -0
  21. package/build/tools/task/bulk-operations.js +10 -0
  22. package/build/tools/task/handlers.js +76 -10
  23. package/build/tools/task/index.js +8 -1
  24. package/build/tools/task/main.js +18 -2
  25. package/build/tools/task/single-operations.js +64 -46
  26. package/build/tools/task/utilities.js +40 -3
  27. package/build/tools/task/workspace-operations.js +222 -0
  28. package/build/tools/utils.js +3 -0
  29. package/build/tools/workspace.js +9 -46
  30. package/build/utils/color-processor.js +183 -0
  31. package/build/utils/concurrency-utils.js +3 -0
  32. package/build/utils/date-utils.js +3 -0
  33. package/build/utils/resolver-utils.js +3 -0
  34. package/build/utils/sponsor-service.js +5 -2
  35. package/build/utils/token-utils.js +49 -0
  36. package/package.json +1 -1
package/README.md CHANGED
@@ -1,18 +1,12 @@
1
- <img src="https://clickup.com/assets/brand/logo-v3-clickup-dark.svg" alt="ClickUp" height="40" style="vertical-align: middle; margin-top: -4px;">
2
-
3
- # MCP Server
1
+ <img src="assets/images/clickup_mcp_server_social_image.png" alt="ClickUp MCP Server" width="100%">
4
2
 
3
+ ![Total Supporters](https://img.shields.io/badge/🏆%20Total%20Supporters-2-gold)
5
4
  [![GitHub Stars](https://img.shields.io/github/stars/TaazKareem/clickup-mcp-server?style=flat&logo=github)](https://github.com/TaazKareem/clickup-mcp-server/stargazers)
6
- [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://github.com/TaazKareem/clickup-mcp-server/graphs/commit-activity)
5
+ [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-brightgreen.svg)](https://github.com/TaazKareem/clickup-mcp-server/graphs/commit-activity)
7
6
 
8
7
  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.
9
8
 
10
-
11
- > 🚧 **Status Update:** -v0.5.1 beta release with new Attach Task Files tool, Create Task Comments tool, Get Task Comments tool, and Custom ID support across all tools.
12
-
13
-
14
-
15
-
9
+ > 🚧 **Status Update:** Rolling out v0.6.1 which will add Complete Tag Support including natural language tag color commands, Subtasks Support, Custom ID Support, and Logging Fixes
16
10
 
17
11
  ## Setup
18
12
 
@@ -26,13 +20,12 @@ A Model Context Protocol (MCP) server for integrating ClickUp tasks with AI appl
26
20
 
27
21
  [![smithery badge](https://smithery.ai/badge/@TaazKareem/clickup-mcp-server)](https://smithery.ai/server/@TaazKareem/clickup-mcp-server)
28
22
 
29
- The server is hosted on Smithery. There, you can preview the available tools or copy the commands to run on your specific client app.
30
-
23
+ The server is hosted on [Smithery](https://smithery.ai/server/@TaazKareem/clickup-mcp-server). There, you can preview the available tools or copy the commands to run on your specific client app.
31
24
 
32
25
  ## NPX Installation
33
26
 
34
27
  [![NPM Version](https://img.shields.io/npm/v/@taazkareem/clickup-mcp-server.svg?style=flat&logo=npm)](https://www.npmjs.com/package/@taazkareem/clickup-mcp-server)
35
- [![Dependency Status](https://img.shields.io/librariesio/github/TaazKareem/clickup-mcp-server)](https://libraries.io/github/TaazKareem/clickup-mcp-server)
28
+ [![Dependency Status](https://img.shields.io/badge/dependencies-up%20to%20date-brightgreen)](https://github.com/TaazKareem/clickup-mcp-server/blob/main/package.json)
36
29
  [![NPM Downloads](https://img.shields.io/npm/dm/@taazkareem/clickup-mcp-server.svg?style=flat&logo=npm)](https://npmcharts.com/compare/@taazkareem/clickup-mcp-server?minimal=true)
37
30
 
38
31
  Add this entry to your client's MCP settings JSON file:
@@ -61,37 +54,24 @@ Or use this npx command:
61
54
 
62
55
  ## Features
63
56
 
64
- - 🎯 **Task Management**
65
- - Create, retrieve, update, and delete tasks
66
- - Move and duplicate tasks between lists, spaces, and folders
67
- - Single operation or bulk operation
68
- - View and modify task details and properties
69
- - Get task comments
70
- - Set due dates using natural language and relative time expressions
71
- - Attach files to tasks using local file paths, URL, base64, or chunked uploads
72
-
73
- - 📂 **Workspace Organization**
74
- - Complete workspace hierarchy (spaces, folders, lists)
75
- - Tree structure with clear relationships
76
- - Efficient path-based navigation
77
-
78
- - 🔄 **Integration Features**
79
- - Name or ID-based item lookup
80
- - Case-insensitive name matching
81
- - Markdown formatting support
82
- - Built-in API rate limiting
57
+ | 📝 Task Management | 🏷️ Tag Management |
58
+ |----------------------------|----------------------------|
59
+ | • Create, update, and delete tasks<br>• Move and duplicate tasks anywhere<br>• Support for single and bulk operations<br>• Set due dates with natural language<br>• Create and manage subtasks<br>• Add comments and attachments | • Create, update, and delete space tags<br>• Add and remove tags from tasks<br>• Use natural language color commands<br>• Automatic contrasting foreground colors<br>• View all space tags<br>• Tag-based task organization across workspace |
60
+ | 🌳 **Workspace Organization** | ⚡ **Integration Features** |
61
+ | Navigate spaces, folders, and lists<br>• Create and manage folders<br>• Organize lists within spaces<br>• Create lists in folders<br>• View workspace hierarchy<br>• Efficient path navigation | • Name or ID-based lookups<br>• Case-insensitive matching<br>• Markdown formatting support<br>• Built-in rate limiting<br>• Error handling and validation<br>• Comprehensive API coverage |
83
62
 
84
63
  ## Available Tools
85
64
 
86
65
  | Tool | Description | Required Parameters |
87
66
  |------|-------------|-------------------|
88
67
  | [get_workspace_hierarchy](docs/api-reference.md#workspace-navigation) | Get workspace structure | None |
89
- | [create_task](docs/api-reference.md#task-management) | Create a task | `name`, (`listId`/`listName`) |
68
+ | [create_task](docs/api-reference.md#task-management) | Create a task | `name`, (`listId`/`listName`), optional `parent` |
90
69
  | [create_bulk_tasks](docs/api-reference.md#task-management) | Create multiple tasks | `tasks[]` |
91
70
  | [update_task](docs/api-reference.md#task-management) | Modify task | `taskId`/`taskName` |
92
71
  | [update_bulk_tasks](docs/api-reference.md#task-management) | Update multiple tasks | `tasks[]` with IDs or names |
93
- | [get_tasks](docs/api-reference.md#task-management) | Get tasks from list | `listId`/`listName` |
94
- | [get_task](docs/api-reference.md#task-management) | Get task details | `taskId`/`taskName` |
72
+ | [get_tasks](docs/api-reference.md#task-management) | Get tasks from list | `listId`/`listName`, optional `subtasks` |
73
+ | [get_task](docs/api-reference.md#task-management) | Get single task details | `taskId`/`taskName`, optional `subtasks` |
74
+ | [get_workspace_tasks](docs/api-reference.md#task-management) | Get tasks with filtering | At least one filter (tags, list_ids, space_ids, etc.) |
95
75
  | [get_task_comments](docs/api-reference.md#task-management) | Get comments on a task | `taskId`/`taskName` |
96
76
  | [create_task_comment](docs/api-reference.md#task-management) | Add a comment to a task | `commentText`, (`taskId`/(`taskName`+`listName`)) |
97
77
  | [attach_task_file](docs/api-reference.md#task-management) | Attach file to a task | `taskId`/`taskName`, (`file_data` or `file_url`) |
@@ -109,11 +89,17 @@ Or use this npx command:
109
89
  | [get_list](docs/api-reference.md#list-management) | Get list details | `listId`/`listName` |
110
90
  | [update_list](docs/api-reference.md#list-management) | Update list properties | `listId`/`listName` |
111
91
  | [delete_list](docs/api-reference.md#list-management) | Delete list | `listId`/`listName` |
92
+ | [get_space_tags](docs/api-reference.md#tag-management) | Get space tags | `spaceId`/`spaceName` |
93
+ | [create_space_tag](docs/api-reference.md#tag-management) | Create tag | `tagName`, `spaceId`/`spaceName` |
94
+ | [update_space_tag](docs/api-reference.md#tag-management) | Update tag | `tagName`, `spaceId`/`spaceName` |
95
+ | [delete_space_tag](docs/api-reference.md#tag-management) | Delete tag | `tagName`, `spaceId`/`spaceName` |
96
+ | [add_tag_to_task](docs/api-reference.md#tag-management) | Add tag to task | `tagName`, `taskId`/(`taskName`+`listName`) |
97
+ | [remove_tag_from_task](docs/api-reference.md#tag-management) | Remove tag from task | `tagName`, `taskId`/(`taskName`+`listName`) |
112
98
 
113
99
  See [full documentation](docs/api-reference.md) for optional parameters and advanced usage.
114
100
 
115
- ## Available Prompts
116
- Not yet implemented (or needed) For now, you can send a follow up prompt after the tool result.
101
+ ## Prompts
102
+ Not yet implemented and not supported by all client apps. Request a feature for a Prompt implementation that would be most beneficial for your workflow (without it being too specific). Examples:
117
103
 
118
104
  | Prompt | Purpose | Features |
119
105
  |--------|---------|----------|
@@ -131,6 +117,9 @@ The server provides clear error messages for:
131
117
  - API errors
132
118
  - Rate limiting
133
119
 
120
+ The `LOG_LEVEL` environment variable can be specified to control the verbosity of server logs. Valid values are `trace`, `debug`, `info`, `warn`, and `error` (default).
121
+ This can be also be specified on the command line as, e.g. `--env LOG_LEVEL=info`.
122
+
134
123
  ## Support the Developer
135
124
 
136
125
  When using this server, you may occasionally see a small sponsor message with a link to this repository included in tool responses. I hope you can support the project!
@@ -138,10 +127,12 @@ If you find this project useful, please consider supporting:
138
127
 
139
128
  [![Sponsor TaazKareem](https://img.shields.io/badge/Sponsor-TaazKareem-orange?logo=github)](https://github.com/sponsors/TaazKareem)
140
129
 
130
+
141
131
  <a href="https://buymeacoffee.com/taazkareem">
142
132
  <img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" width="200" alt="Buy Me A Coffee">
143
133
  </a>
144
134
 
135
+
145
136
  ## Acknowledgements
146
137
 
147
138
  Special thanks to [ClickUp](https://clickup.com) for their excellent API and services that make this integration possible.
@@ -158,7 +149,7 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
158
149
 
159
150
  ## Disclaimer
160
151
 
161
- Disclaimer: This software makes use of third-party APIs and may reference trademarks
152
+ This software makes use of third-party APIs and may reference trademarks
162
153
  or brands owned by third parties. The use of such APIs or references does not imply
163
154
  any affiliation with or endorsement by the respective companies. All trademarks and
164
155
  brand names are the property of their respective owners. This project is an independent
package/build/config.js CHANGED
@@ -1,5 +1,8 @@
1
1
  /**
2
- * Configuration handling for ClickUp API credentials
2
+ * SPDX-FileCopyrightText: © 2025 Talib Kareem <taazkareem@icloud.com>
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * Configuration handling for ClickUp API credentials and application settings
3
6
  *
4
7
  * The required environment variables (CLICKUP_API_KEY and CLICKUP_TEAM_ID) are passed
5
8
  * securely to this file when running the hosted server at smithery.ai. Optionally,
@@ -15,16 +18,44 @@ for (let i = 0; i < args.length; i++) {
15
18
  envArgs.clickupApiKey = value;
16
19
  if (key === 'CLICKUP_TEAM_ID')
17
20
  envArgs.clickupTeamId = value;
21
+ if (key === 'LOG_LEVEL')
22
+ envArgs.logLevel = value;
18
23
  i++;
19
24
  }
20
25
  }
26
+ // Log levels enum
27
+ export var LogLevel;
28
+ (function (LogLevel) {
29
+ LogLevel[LogLevel["TRACE"] = 0] = "TRACE";
30
+ LogLevel[LogLevel["DEBUG"] = 1] = "DEBUG";
31
+ LogLevel[LogLevel["INFO"] = 2] = "INFO";
32
+ LogLevel[LogLevel["WARN"] = 3] = "WARN";
33
+ LogLevel[LogLevel["ERROR"] = 4] = "ERROR";
34
+ })(LogLevel || (LogLevel = {}));
35
+ // Parse LOG_LEVEL string to LogLevel enum
36
+ export const parseLogLevel = (levelStr) => {
37
+ if (!levelStr)
38
+ return LogLevel.ERROR; // Default to ERROR if not specified
39
+ switch (levelStr.toUpperCase()) {
40
+ case 'TRACE': return LogLevel.TRACE;
41
+ case 'DEBUG': return LogLevel.DEBUG;
42
+ case 'INFO': return LogLevel.INFO;
43
+ case 'WARN': return LogLevel.WARN;
44
+ case 'ERROR': return LogLevel.ERROR;
45
+ default:
46
+ console.error(`Invalid LOG_LEVEL: ${levelStr}, defaulting to ERROR`);
47
+ return LogLevel.ERROR;
48
+ }
49
+ };
21
50
  // Load configuration from command line args or environment variables
22
51
  const configuration = {
23
52
  clickupApiKey: envArgs.clickupApiKey || process.env.CLICKUP_API_KEY || '',
24
53
  clickupTeamId: envArgs.clickupTeamId || process.env.CLICKUP_TEAM_ID || '',
25
54
  enableSponsorMessage: process.env.ENABLE_SPONSOR_MESSAGE !== 'false',
26
- sponsorUrl: process.env.SPONSOR_URL || 'https://github.com/sponsors/taazkareem'
55
+ logLevel: parseLogLevel(envArgs.logLevel || process.env.LOG_LEVEL)
27
56
  };
57
+ // Log the configured log level (but only to console to avoid circular dependency)
58
+ console.debug(`Log level set to: ${LogLevel[configuration.logLevel]}`);
28
59
  // Validate only the required variables are present
29
60
  const requiredVars = ['clickupApiKey', 'clickupTeamId'];
30
61
  const missingEnvVars = requiredVars
package/build/index.js CHANGED
@@ -1,37 +1,27 @@
1
- #!/usr/bin/env node
2
1
  /**
3
- * ClickUp MCP Server - A Model Context Protocol server for ClickUp integration
2
+ * SPDX-FileCopyrightText: © 2025 Talib Kareem <taazkareem@icloud.com>
3
+ * SPDX-License-Identifier: MIT
4
4
  *
5
- * This server enables AI applications to interact with ClickUp through a standardized protocol,
6
- * allowing AI assistants to manage tasks, lists, and folders in ClickUp workspaces.
5
+ * ClickUp MCP Server
7
6
  *
8
- * Key capabilities include:
7
+ * This custom server implements the Model Context Protocol (MCP) specification to enable
8
+ * AI applications to interact with ClickUp workspaces. It provides a standardized
9
+ * interface for managing tasks, lists, folders and other ClickUp entities using Natural Language.
9
10
  *
10
- * Task Management:
11
- * - Create, update, move and duplicate tasks with rich description support
12
- * - Find tasks by name with smart disambiguation
13
- * - Optimized bulk task operations with concurrent processing
14
- * - Comprehensive filtering and sorting options
11
+ * Key Features:
12
+ * - Complete task management (CRUD operations, moving, duplicating)
13
+ * - Workspace organization (spaces, folders, lists)
14
+ * - Bulk operations with concurrent processing
15
+ * - Natural language date parsing
16
+ * - File attachments support
17
+ * - Name-based entity resolution
18
+ * - Markdown formatting
19
+ * - Built-in rate limiting
15
20
  *
16
- * Workspace Organization:
17
- * - Navigate and discover workspace structure with hierarchical views
18
- * - Create and manage lists and folders with proper nesting
19
- * - Smart name-based lookups that eliminate the need for IDs
20
- * - Support for priorities, statuses, and due dates
21
- *
22
- * Technical Features:
23
- * - Full markdown support for rich text content
24
- * - Secure credential handling through configuration
25
- * - Comprehensive error reporting and validation
26
- * - Name-based entity resolution with fuzzy matching
27
- *
28
- * This implementation follows the Model Context Protocol specification and
29
- * is designed to be used with AI assistants that support MCP.
21
+ * For full documentation and usage examples, please refer to the README.md file.
30
22
  */
31
23
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
32
24
  import { configureServer, server } from "./server.js";
33
- import { clickUpServices } from "./services/shared.js";
34
- import { initializeWorkspaceTool } from "./tools/workspace.js";
35
25
  import { info, error, warn } from "./logger.js";
36
26
  import { exec } from 'child_process';
37
27
  import { promisify } from 'util';
@@ -76,9 +66,6 @@ async function main() {
76
66
  os: process.platform,
77
67
  arch: process.arch
78
68
  });
79
- // Initialize tools with services
80
- info("Initializing workspace tools");
81
- initializeWorkspaceTool(clickUpServices);
82
69
  // Configure the server with all handlers
83
70
  info("Configuring server request handlers");
84
71
  await configureServer();
package/build/logger.js CHANGED
@@ -1,4 +1,7 @@
1
1
  /**
2
+ * SPDX-FileCopyrightText: © 2025 Talib Kareem <taazkareem@icloud.com>
3
+ * SPDX-License-Identifier: MIT
4
+ *
2
5
  * Logger module for MCP Server
3
6
  *
4
7
  * This module provides logging functionality for the server,
@@ -7,6 +10,7 @@
7
10
  import { createWriteStream } from 'fs';
8
11
  import { join, dirname } from 'path';
9
12
  import { fileURLToPath } from 'url';
13
+ import config, { LogLevel } from './config.js';
10
14
  // Get the directory name of the current module
11
15
  const __dirname = dirname(fileURLToPath(import.meta.url));
12
16
  // Current process ID for logging
@@ -15,17 +19,10 @@ const pid = process.pid;
15
19
  const logFileName = 'server.log';
16
20
  const logStream = createWriteStream(join(__dirname, logFileName), { flags: 'w' });
17
21
  console.error(`Logging to ${join(__dirname, logFileName)}`);
18
- // Log levels with numeric values for filtering
19
- export var LogLevel;
20
- (function (LogLevel) {
21
- LogLevel[LogLevel["TRACE"] = 0] = "TRACE";
22
- LogLevel[LogLevel["DEBUG"] = 1] = "DEBUG";
23
- LogLevel[LogLevel["INFO"] = 2] = "INFO";
24
- LogLevel[LogLevel["WARN"] = 3] = "WARN";
25
- LogLevel[LogLevel["ERROR"] = 4] = "ERROR";
26
- })(LogLevel || (LogLevel = {}));
27
- // Fixed log level - always use TRACE as the minimum level for complete logging
28
- const configuredLevel = LogLevel.TRACE;
22
+ // Use the configured log level from config.ts
23
+ const configuredLevel = config.logLevel;
24
+ // Re-export LogLevel enum
25
+ export { LogLevel };
29
26
  /**
30
27
  * Check if a log level is enabled based on the configured level
31
28
  * @param level The log level to check
package/build/server.js CHANGED
@@ -1,21 +1,25 @@
1
+ /**
2
+ * SPDX-FileCopyrightText: © 2025 Talib Kareem <taazkareem@icloud.com>
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * MCP Server for ClickUp integration
6
+ */
1
7
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
8
  import { CallToolRequestSchema, ListToolsRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
3
9
  import { workspaceHierarchyTool, handleGetWorkspaceHierarchy } from "./tools/workspace.js";
4
- import { createTaskTool, updateTaskTool, moveTaskTool, duplicateTaskTool, getTaskTool, getTasksTool, deleteTaskTool, getTaskCommentsTool, createTaskCommentTool, createBulkTasksTool, updateBulkTasksTool, moveBulkTasksTool, deleteBulkTasksTool, attachTaskFileTool, handleCreateTask, handleUpdateTask, handleMoveTask, handleDuplicateTask, handleGetTasks, handleDeleteTask, handleGetTaskComments, handleCreateTaskComment, handleCreateBulkTasks, handleUpdateBulkTasks, handleMoveBulkTasks, handleDeleteBulkTasks, handleGetTask, handleAttachTaskFile } from "./tools/task/index.js";
10
+ import { createTaskTool, updateTaskTool, moveTaskTool, duplicateTaskTool, getTaskTool, getTasksTool, deleteTaskTool, getTaskCommentsTool, createTaskCommentTool, createBulkTasksTool, updateBulkTasksTool, moveBulkTasksTool, deleteBulkTasksTool, attachTaskFileTool, getWorkspaceTasksTool, handleCreateTask, handleUpdateTask, handleMoveTask, handleDuplicateTask, handleGetTasks, handleDeleteTask, handleGetTaskComments, handleCreateTaskComment, handleCreateBulkTasks, handleUpdateBulkTasks, handleMoveBulkTasks, handleDeleteBulkTasks, handleGetTask, handleAttachTaskFile, handleGetWorkspaceTasks } from "./tools/task/index.js";
5
11
  import { createListTool, handleCreateList, createListInFolderTool, handleCreateListInFolder, getListTool, handleGetList, updateListTool, handleUpdateList, deleteListTool, handleDeleteList } from "./tools/list.js";
6
12
  import { createFolderTool, handleCreateFolder, getFolderTool, handleGetFolder, updateFolderTool, handleUpdateFolder, deleteFolderTool, handleDeleteFolder } from "./tools/folder.js";
13
+ import { getSpaceTagsTool, handleGetSpaceTags, createSpaceTagTool, handleCreateSpaceTag, updateSpaceTagTool, handleUpdateSpaceTag, deleteSpaceTagTool, handleDeleteSpaceTag, addTagToTaskTool, handleAddTagToTask, removeTagFromTaskTool, handleRemoveTagFromTask } from "./tools/tag.js";
7
14
  import { Logger } from "./logger.js";
8
15
  import { clickUpServices } from "./services/shared.js";
9
16
  // Create a logger instance for server
10
17
  const logger = new Logger('Server');
11
18
  // Use existing services from shared module instead of creating new ones
12
19
  const { workspace } = clickUpServices;
13
- /**
14
- * MCP Server for ClickUp integration
15
- */
16
20
  export const server = new Server({
17
21
  name: "clickup-mcp-server",
18
- version: "0.5.1",
22
+ version: "0.6.1",
19
23
  }, {
20
24
  capabilities: {
21
25
  tools: {},
@@ -47,6 +51,7 @@ export function configureServer() {
47
51
  updateBulkTasksTool,
48
52
  moveBulkTasksTool,
49
53
  deleteBulkTasksTool,
54
+ getWorkspaceTasksTool,
50
55
  createListTool,
51
56
  createListInFolderTool,
52
57
  getListTool,
@@ -55,14 +60,20 @@ export function configureServer() {
55
60
  createFolderTool,
56
61
  getFolderTool,
57
62
  updateFolderTool,
58
- deleteFolderTool
63
+ deleteFolderTool,
64
+ getSpaceTagsTool,
65
+ createSpaceTagTool,
66
+ updateSpaceTagTool,
67
+ deleteSpaceTagTool,
68
+ addTagToTaskTool,
69
+ removeTagFromTaskTool
59
70
  ]
60
71
  };
61
72
  });
62
73
  // Register CallTool handler with proper logging
63
74
  logger.info("Registering tool handlers", {
64
- toolCount: 23,
65
- categories: ["workspace", "task", "list", "folder"]
75
+ toolCount: 31,
76
+ categories: ["workspace", "task", "list", "folder", "tag"]
66
77
  });
67
78
  server.setRequestHandler(CallToolRequestSchema, async (req) => {
68
79
  const { name, arguments: params } = req.params;
@@ -103,6 +114,8 @@ export function configureServer() {
103
114
  return handleMoveBulkTasks(params);
104
115
  case "delete_bulk_tasks":
105
116
  return handleDeleteBulkTasks(params);
117
+ case "get_workspace_tasks":
118
+ return handleGetWorkspaceTasks(params);
106
119
  case "create_list":
107
120
  return handleCreateList(params);
108
121
  case "create_list_in_folder":
@@ -121,6 +134,18 @@ export function configureServer() {
121
134
  return handleUpdateFolder(params);
122
135
  case "delete_folder":
123
136
  return handleDeleteFolder(params);
137
+ case "get_space_tags":
138
+ return handleGetSpaceTags(params);
139
+ case "create_space_tag":
140
+ return handleCreateSpaceTag(params);
141
+ case "update_space_tag":
142
+ return handleUpdateSpaceTag(params);
143
+ case "delete_space_tag":
144
+ return handleDeleteSpaceTag(params);
145
+ case "add_tag_to_task":
146
+ return handleAddTagToTask(params);
147
+ case "remove_tag_from_task":
148
+ return handleRemoveTagFromTask(params);
124
149
  default:
125
150
  logger.error(`Unknown tool requested: ${name}`);
126
151
  throw new Error(`Unknown tool: ${name}`);
@@ -1,4 +1,7 @@
1
1
  /**
2
+ * SPDX-FileCopyrightText: © 2025 Talib Kareem <taazkareem@icloud.com>
3
+ * SPDX-License-Identifier: MIT
4
+ *
2
5
  * Base ClickUp Service Class
3
6
  *
4
7
  * This class provides core functionality for all ClickUp service modules:
@@ -1,4 +1,7 @@
1
1
  /**
2
+ * SPDX-FileCopyrightText: © 2025 Talib Kareem <taazkareem@icloud.com>
3
+ * SPDX-License-Identifier: MIT
4
+ *
2
5
  * ClickUp Bulk Service
3
6
  *
4
7
  * Enhanced implementation for bulk operations that leverages the existing single-operation methods.
@@ -1,4 +1,7 @@
1
1
  /**
2
+ * SPDX-FileCopyrightText: © 2025 Talib Kareem <taazkareem@icloud.com>
3
+ * SPDX-License-Identifier: MIT
4
+ *
2
5
  * ClickUp Folder Service
3
6
  *
4
7
  * Handles all operations related to folders in ClickUp, including:
@@ -1,4 +1,7 @@
1
1
  /**
2
+ * SPDX-FileCopyrightText: © 2025 Talib Kareem <taazkareem@icloud.com>
3
+ * SPDX-License-Identifier: MIT
4
+ *
2
5
  * ClickUp Service Entry Point
3
6
  *
4
7
  * This file re-exports all service modules for the ClickUp API integration.
@@ -13,11 +16,13 @@ export { WorkspaceService } from './workspace.js';
13
16
  export { TaskService } from './task.js';
14
17
  export { ListService } from './list.js';
15
18
  export { FolderService } from './folder.js';
19
+ export { ClickUpTagService } from './tag.js';
16
20
  // Import service classes for the factory function
17
21
  import { WorkspaceService } from './workspace.js';
18
22
  import { TaskService } from './task.js';
19
23
  import { ListService } from './list.js';
20
24
  import { FolderService } from './folder.js';
25
+ import { ClickUpTagService } from './tag.js';
21
26
  import { Logger } from '../../logger.js';
22
27
  // Singleton logger for ClickUp services
23
28
  const logger = new Logger('ClickUpServices');
@@ -43,11 +48,14 @@ export function createClickUpServices(config) {
43
48
  const listService = new ListService(apiKey, teamId, baseUrl, workspaceService);
44
49
  logger.info('Initializing ClickUp Folder service');
45
50
  const folderService = new FolderService(apiKey, teamId, baseUrl, workspaceService);
51
+ logger.info('Initializing ClickUp Tag service');
52
+ const tagService = new ClickUpTagService(apiKey, teamId, baseUrl);
46
53
  const services = {
47
54
  workspace: workspaceService,
48
55
  task: taskService,
49
56
  list: listService,
50
- folder: folderService
57
+ folder: folderService,
58
+ tag: tagService
51
59
  };
52
60
  // Log successful completion
53
61
  logger.info('All ClickUp services initialized successfully', {
@@ -1,4 +1,7 @@
1
1
  /**
2
+ * SPDX-FileCopyrightText: © 2025 Talib Kareem <taazkareem@icloud.com>
3
+ * SPDX-License-Identifier: MIT
4
+ *
2
5
  * ClickUp List Service
3
6
  *
4
7
  * Handles all operations related to lists in ClickUp, including:
@@ -0,0 +1,190 @@
1
+ /**
2
+ * SPDX-FileCopyrightText: © 2025 Talib Kareem <taazkareem@icloud.com>
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * ClickUp Tag Service
6
+ *
7
+ * Provides access to ClickUp API endpoints for tag management:
8
+ * - Space tags (get, create, update, delete)
9
+ * - Task tags (add, remove)
10
+ */
11
+ import { BaseClickUpService } from './base.js';
12
+ /**
13
+ * ClickUp Tag Service class for managing tags
14
+ */
15
+ export class ClickUpTagService extends BaseClickUpService {
16
+ /**
17
+ * Get all tags in a space
18
+ * @param spaceId - ID of the space to get tags from
19
+ * @returns Promise with tags array
20
+ */
21
+ async getSpaceTags(spaceId) {
22
+ try {
23
+ this.logger.debug(`Getting tags for space: ${spaceId}`);
24
+ const response = await this.client.get(`/space/${spaceId}/tag`);
25
+ return {
26
+ success: true,
27
+ data: response.data.tags
28
+ };
29
+ }
30
+ catch (error) {
31
+ this.logger.error(`Failed to get tags for space: ${spaceId}`, error);
32
+ return {
33
+ success: false,
34
+ error: {
35
+ message: error.message || 'Failed to get space tags',
36
+ code: error.code,
37
+ details: error.data
38
+ }
39
+ };
40
+ }
41
+ }
42
+ /**
43
+ * Create a new tag in a space
44
+ * @param spaceId - ID of the space
45
+ * @param tagData - Tag data (name, background color, foreground color)
46
+ * @returns Promise with created tag
47
+ */
48
+ async createSpaceTag(spaceId, tagData) {
49
+ try {
50
+ this.logger.debug(`Creating tag "${tagData.tag_name}" in space: ${spaceId}`);
51
+ // Send tag data wrapped in a 'tag' object
52
+ const response = await this.client.post(`/space/${spaceId}/tag`, {
53
+ tag: {
54
+ name: tagData.tag_name,
55
+ tag_bg: tagData.tag_bg,
56
+ tag_fg: tagData.tag_fg
57
+ }
58
+ });
59
+ return {
60
+ success: true,
61
+ data: response.data.tag
62
+ };
63
+ }
64
+ catch (error) {
65
+ this.logger.error(`Failed to create tag in space: ${spaceId}`, error);
66
+ return {
67
+ success: false,
68
+ error: {
69
+ message: error.message || 'Failed to create space tag',
70
+ code: error.code,
71
+ details: error.data
72
+ }
73
+ };
74
+ }
75
+ }
76
+ /**
77
+ * Update an existing tag in a space
78
+ * @param spaceId - ID of the space
79
+ * @param tagName - Current name of the tag to update
80
+ * @param updateData - Tag data to update (name, colors)
81
+ * @returns Promise with updated tag
82
+ */
83
+ async updateSpaceTag(spaceId, tagName, updateData) {
84
+ try {
85
+ this.logger.debug(`Updating tag "${tagName}" in space: ${spaceId}`);
86
+ // Encode the tag name in the URL
87
+ const encodedTagName = encodeURIComponent(tagName);
88
+ const response = await this.client.put(`/space/${spaceId}/tag/${encodedTagName}`, updateData);
89
+ return {
90
+ success: true,
91
+ data: response.data.tag
92
+ };
93
+ }
94
+ catch (error) {
95
+ this.logger.error(`Failed to update tag "${tagName}" in space: ${spaceId}`, error);
96
+ return {
97
+ success: false,
98
+ error: {
99
+ message: error.message || 'Failed to update space tag',
100
+ code: error.code,
101
+ details: error.data
102
+ }
103
+ };
104
+ }
105
+ }
106
+ /**
107
+ * Delete a tag from a space
108
+ * @param spaceId - ID of the space
109
+ * @param tagName - Name of the tag to delete
110
+ * @returns Promise with success status
111
+ */
112
+ async deleteSpaceTag(spaceId, tagName) {
113
+ try {
114
+ this.logger.debug(`Deleting tag "${tagName}" from space: ${spaceId}`);
115
+ // Encode the tag name in the URL
116
+ const encodedTagName = encodeURIComponent(tagName);
117
+ await this.client.delete(`/space/${spaceId}/tag/${encodedTagName}`);
118
+ return {
119
+ success: true
120
+ };
121
+ }
122
+ catch (error) {
123
+ this.logger.error(`Failed to delete tag "${tagName}" from space: ${spaceId}`, error);
124
+ return {
125
+ success: false,
126
+ error: {
127
+ message: error.message || 'Failed to delete space tag',
128
+ code: error.code,
129
+ details: error.data
130
+ }
131
+ };
132
+ }
133
+ }
134
+ /**
135
+ * Add a tag to a task
136
+ * @param taskId - ID of the task
137
+ * @param tagName - Name of the tag to add
138
+ * @returns Promise with success status
139
+ */
140
+ async addTagToTask(taskId, tagName) {
141
+ try {
142
+ this.logger.debug(`Adding tag "${tagName}" to task: ${taskId}`);
143
+ // Encode the tag name in the URL
144
+ const encodedTagName = encodeURIComponent(tagName);
145
+ await this.client.post(`/task/${taskId}/tag/${encodedTagName}`, {});
146
+ return {
147
+ success: true
148
+ };
149
+ }
150
+ catch (error) {
151
+ this.logger.error(`Failed to add tag "${tagName}" to task: ${taskId}`, error);
152
+ return {
153
+ success: false,
154
+ error: {
155
+ message: error.message || 'Failed to add tag to task',
156
+ code: error.code,
157
+ details: error.data
158
+ }
159
+ };
160
+ }
161
+ }
162
+ /**
163
+ * Remove a tag from a task
164
+ * @param taskId - ID of the task
165
+ * @param tagName - Name of the tag to remove
166
+ * @returns Promise with success status
167
+ */
168
+ async removeTagFromTask(taskId, tagName) {
169
+ try {
170
+ this.logger.debug(`Removing tag "${tagName}" from task: ${taskId}`);
171
+ // Encode the tag name in the URL
172
+ const encodedTagName = encodeURIComponent(tagName);
173
+ await this.client.delete(`/task/${taskId}/tag/${encodedTagName}`);
174
+ return {
175
+ success: true
176
+ };
177
+ }
178
+ catch (error) {
179
+ this.logger.error(`Failed to remove tag "${tagName}" from task: ${taskId}`, error);
180
+ return {
181
+ success: false,
182
+ error: {
183
+ message: error.message || 'Failed to remove tag from task',
184
+ code: error.code,
185
+ details: error.data
186
+ }
187
+ };
188
+ }
189
+ }
190
+ }