@rv404/mcp-launchpad 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.
Files changed (139) hide show
  1. package/.env.example +29 -0
  2. package/README.md +248 -0
  3. package/dist/backends/clickup.d.ts +3 -0
  4. package/dist/backends/clickup.d.ts.map +1 -0
  5. package/dist/backends/clickup.js +1550 -0
  6. package/dist/backends/clickup.js.map +1 -0
  7. package/dist/backends/email.d.ts +9 -0
  8. package/dist/backends/email.d.ts.map +1 -0
  9. package/dist/backends/email.js +452 -0
  10. package/dist/backends/email.js.map +1 -0
  11. package/dist/backends/firecrawl.d.ts +3 -0
  12. package/dist/backends/firecrawl.d.ts.map +1 -0
  13. package/dist/backends/firecrawl.js +297 -0
  14. package/dist/backends/firecrawl.js.map +1 -0
  15. package/dist/backends/gemini.d.ts +3 -0
  16. package/dist/backends/gemini.d.ts.map +1 -0
  17. package/dist/backends/gemini.js +702 -0
  18. package/dist/backends/gemini.js.map +1 -0
  19. package/dist/backends/github.d.ts +3 -0
  20. package/dist/backends/github.d.ts.map +1 -0
  21. package/dist/backends/github.js +2129 -0
  22. package/dist/backends/github.js.map +1 -0
  23. package/dist/backends/index.d.ts +2 -0
  24. package/dist/backends/index.d.ts.map +1 -0
  25. package/dist/backends/index.js +27 -0
  26. package/dist/backends/index.js.map +1 -0
  27. package/dist/backends/kie.d.ts +3 -0
  28. package/dist/backends/kie.d.ts.map +1 -0
  29. package/dist/backends/kie.js +399 -0
  30. package/dist/backends/kie.js.map +1 -0
  31. package/dist/backends/n8n.d.ts +3 -0
  32. package/dist/backends/n8n.d.ts.map +1 -0
  33. package/dist/backends/n8n.js +414 -0
  34. package/dist/backends/n8n.js.map +1 -0
  35. package/dist/backends/notion.d.ts +3 -0
  36. package/dist/backends/notion.d.ts.map +1 -0
  37. package/dist/backends/notion.js +375 -0
  38. package/dist/backends/notion.js.map +1 -0
  39. package/dist/backends/quickbooks.d.ts +3 -0
  40. package/dist/backends/quickbooks.d.ts.map +1 -0
  41. package/dist/backends/quickbooks.js +2183 -0
  42. package/dist/backends/quickbooks.js.map +1 -0
  43. package/dist/backends/slack.d.ts +3 -0
  44. package/dist/backends/slack.d.ts.map +1 -0
  45. package/dist/backends/slack.js +1725 -0
  46. package/dist/backends/slack.js.map +1 -0
  47. package/dist/backends/youtube.d.ts +3 -0
  48. package/dist/backends/youtube.d.ts.map +1 -0
  49. package/dist/backends/youtube.js +936 -0
  50. package/dist/backends/youtube.js.map +1 -0
  51. package/dist/index.d.ts +3 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +150 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/router.d.ts +36 -0
  56. package/dist/router.d.ts.map +1 -0
  57. package/dist/router.js +283 -0
  58. package/dist/router.js.map +1 -0
  59. package/dist/types.d.ts +103 -0
  60. package/dist/types.d.ts.map +1 -0
  61. package/dist/types.js +65 -0
  62. package/dist/types.js.map +1 -0
  63. package/lib/mcp-file-output/dist/index.d.ts +99 -0
  64. package/lib/mcp-file-output/dist/index.d.ts.map +1 -0
  65. package/lib/mcp-file-output/dist/index.js +215 -0
  66. package/lib/mcp-file-output/dist/index.js.map +1 -0
  67. package/lib/mcp-file-output/node_modules/@types/node/LICENSE +21 -0
  68. package/lib/mcp-file-output/node_modules/@types/node/README.md +15 -0
  69. package/lib/mcp-file-output/node_modules/@types/node/assert/strict.d.ts +8 -0
  70. package/lib/mcp-file-output/node_modules/@types/node/assert.d.ts +1062 -0
  71. package/lib/mcp-file-output/node_modules/@types/node/async_hooks.d.ts +605 -0
  72. package/lib/mcp-file-output/node_modules/@types/node/buffer.buffer.d.ts +471 -0
  73. package/lib/mcp-file-output/node_modules/@types/node/buffer.d.ts +1936 -0
  74. package/lib/mcp-file-output/node_modules/@types/node/child_process.d.ts +1475 -0
  75. package/lib/mcp-file-output/node_modules/@types/node/cluster.d.ts +577 -0
  76. package/lib/mcp-file-output/node_modules/@types/node/compatibility/disposable.d.ts +16 -0
  77. package/lib/mcp-file-output/node_modules/@types/node/compatibility/index.d.ts +9 -0
  78. package/lib/mcp-file-output/node_modules/@types/node/compatibility/indexable.d.ts +20 -0
  79. package/lib/mcp-file-output/node_modules/@types/node/compatibility/iterators.d.ts +21 -0
  80. package/lib/mcp-file-output/node_modules/@types/node/console.d.ts +452 -0
  81. package/lib/mcp-file-output/node_modules/@types/node/constants.d.ts +21 -0
  82. package/lib/mcp-file-output/node_modules/@types/node/crypto.d.ts +4590 -0
  83. package/lib/mcp-file-output/node_modules/@types/node/dgram.d.ts +597 -0
  84. package/lib/mcp-file-output/node_modules/@types/node/diagnostics_channel.d.ts +578 -0
  85. package/lib/mcp-file-output/node_modules/@types/node/dns/promises.d.ts +479 -0
  86. package/lib/mcp-file-output/node_modules/@types/node/dns.d.ts +871 -0
  87. package/lib/mcp-file-output/node_modules/@types/node/domain.d.ts +170 -0
  88. package/lib/mcp-file-output/node_modules/@types/node/events.d.ts +977 -0
  89. package/lib/mcp-file-output/node_modules/@types/node/fs/promises.d.ts +1270 -0
  90. package/lib/mcp-file-output/node_modules/@types/node/fs.d.ts +4375 -0
  91. package/lib/mcp-file-output/node_modules/@types/node/globals.d.ts +172 -0
  92. package/lib/mcp-file-output/node_modules/@types/node/globals.typedarray.d.ts +38 -0
  93. package/lib/mcp-file-output/node_modules/@types/node/http.d.ts +2049 -0
  94. package/lib/mcp-file-output/node_modules/@types/node/http2.d.ts +2631 -0
  95. package/lib/mcp-file-output/node_modules/@types/node/https.d.ts +578 -0
  96. package/lib/mcp-file-output/node_modules/@types/node/index.d.ts +93 -0
  97. package/lib/mcp-file-output/node_modules/@types/node/inspector.generated.d.ts +3966 -0
  98. package/lib/mcp-file-output/node_modules/@types/node/module.d.ts +539 -0
  99. package/lib/mcp-file-output/node_modules/@types/node/net.d.ts +1012 -0
  100. package/lib/mcp-file-output/node_modules/@types/node/os.d.ts +506 -0
  101. package/lib/mcp-file-output/node_modules/@types/node/package.json +140 -0
  102. package/lib/mcp-file-output/node_modules/@types/node/path.d.ts +200 -0
  103. package/lib/mcp-file-output/node_modules/@types/node/perf_hooks.d.ts +961 -0
  104. package/lib/mcp-file-output/node_modules/@types/node/process.d.ts +1957 -0
  105. package/lib/mcp-file-output/node_modules/@types/node/punycode.d.ts +117 -0
  106. package/lib/mcp-file-output/node_modules/@types/node/querystring.d.ts +152 -0
  107. package/lib/mcp-file-output/node_modules/@types/node/readline/promises.d.ts +162 -0
  108. package/lib/mcp-file-output/node_modules/@types/node/readline.d.ts +589 -0
  109. package/lib/mcp-file-output/node_modules/@types/node/repl.d.ts +430 -0
  110. package/lib/mcp-file-output/node_modules/@types/node/sea.d.ts +153 -0
  111. package/lib/mcp-file-output/node_modules/@types/node/stream/consumers.d.ts +38 -0
  112. package/lib/mcp-file-output/node_modules/@types/node/stream/promises.d.ts +90 -0
  113. package/lib/mcp-file-output/node_modules/@types/node/stream/web.d.ts +533 -0
  114. package/lib/mcp-file-output/node_modules/@types/node/stream.d.ts +1675 -0
  115. package/lib/mcp-file-output/node_modules/@types/node/string_decoder.d.ts +67 -0
  116. package/lib/mcp-file-output/node_modules/@types/node/test.d.ts +1787 -0
  117. package/lib/mcp-file-output/node_modules/@types/node/timers/promises.d.ts +108 -0
  118. package/lib/mcp-file-output/node_modules/@types/node/timers.d.ts +286 -0
  119. package/lib/mcp-file-output/node_modules/@types/node/tls.d.ts +1255 -0
  120. package/lib/mcp-file-output/node_modules/@types/node/trace_events.d.ts +197 -0
  121. package/lib/mcp-file-output/node_modules/@types/node/ts5.6/buffer.buffer.d.ts +468 -0
  122. package/lib/mcp-file-output/node_modules/@types/node/ts5.6/globals.typedarray.d.ts +34 -0
  123. package/lib/mcp-file-output/node_modules/@types/node/ts5.6/index.d.ts +93 -0
  124. package/lib/mcp-file-output/node_modules/@types/node/tty.d.ts +208 -0
  125. package/lib/mcp-file-output/node_modules/@types/node/url.d.ts +964 -0
  126. package/lib/mcp-file-output/node_modules/@types/node/util.d.ts +2331 -0
  127. package/lib/mcp-file-output/node_modules/@types/node/v8.d.ts +809 -0
  128. package/lib/mcp-file-output/node_modules/@types/node/vm.d.ts +1001 -0
  129. package/lib/mcp-file-output/node_modules/@types/node/wasi.d.ts +181 -0
  130. package/lib/mcp-file-output/node_modules/@types/node/web-globals/abortcontroller.d.ts +34 -0
  131. package/lib/mcp-file-output/node_modules/@types/node/web-globals/domexception.d.ts +68 -0
  132. package/lib/mcp-file-output/node_modules/@types/node/web-globals/events.d.ts +97 -0
  133. package/lib/mcp-file-output/node_modules/@types/node/web-globals/fetch.d.ts +46 -0
  134. package/lib/mcp-file-output/node_modules/@types/node/worker_threads.d.ts +715 -0
  135. package/lib/mcp-file-output/node_modules/@types/node/zlib.d.ts +540 -0
  136. package/lib/mcp-file-output/package.json +19 -0
  137. package/lib/mcp-file-output/src/index.ts +309 -0
  138. package/lib/mcp-file-output/tsconfig.json +20 -0
  139. package/package.json +64 -0
@@ -0,0 +1,1550 @@
1
+ import axios from 'axios';
2
+ const CLICKUP_API_KEY = process.env.CLICKUP_API_KEY || '';
3
+ const CLICKUP_TEAM_ID = process.env.CLICKUP_TEAM_ID || '';
4
+ const BASE_URL = 'https://api.clickup.com/api/v2';
5
+ const headers = () => ({
6
+ 'Authorization': CLICKUP_API_KEY,
7
+ 'Content-Type': 'application/json',
8
+ });
9
+ const actions = [
10
+ // ===================
11
+ // WORKSPACE / HIERARCHY
12
+ // ===================
13
+ {
14
+ name: 'get_workspace_hierarchy',
15
+ description: 'Gets complete workspace hierarchy (spaces, folders, lists). Returns tree structure with names and IDs for navigation.',
16
+ params: [],
17
+ },
18
+ {
19
+ name: 'get_workspace_members',
20
+ description: 'Returns all members (users) in the ClickUp workspace.',
21
+ params: [],
22
+ },
23
+ {
24
+ name: 'find_member_by_name',
25
+ description: 'Finds a member by name or email.',
26
+ params: [
27
+ { name: 'nameOrEmail', type: 'string', required: true, description: 'Name or email to search' },
28
+ ],
29
+ },
30
+ // ===================
31
+ // SPACES
32
+ // ===================
33
+ {
34
+ name: 'get_spaces',
35
+ description: 'Gets all spaces in the workspace.',
36
+ params: [
37
+ { name: 'archived', type: 'boolean', required: false, description: 'Include archived spaces (default: false)' },
38
+ ],
39
+ },
40
+ {
41
+ name: 'get_space',
42
+ description: 'Gets a space by ID or name.',
43
+ params: [
44
+ { name: 'spaceId', type: 'string', required: false, description: 'Space ID' },
45
+ { name: 'spaceName', type: 'string', required: false, description: 'Space name' },
46
+ ],
47
+ },
48
+ {
49
+ name: 'create_space',
50
+ description: 'Creates a new space in the workspace.',
51
+ params: [
52
+ { name: 'name', type: 'string', required: true, description: 'Space name' },
53
+ { name: 'features', type: 'object', required: false, description: 'Space features configuration' },
54
+ ],
55
+ },
56
+ {
57
+ name: 'update_space',
58
+ description: 'Updates a space.',
59
+ params: [
60
+ { name: 'spaceId', type: 'string', required: false, description: 'Space ID' },
61
+ { name: 'spaceName', type: 'string', required: false, description: 'Space name to find' },
62
+ { name: 'name', type: 'string', required: false, description: 'New space name' },
63
+ { name: 'color', type: 'string', required: false, description: 'Space color' },
64
+ { name: 'private', type: 'boolean', required: false, description: 'Make space private' },
65
+ ],
66
+ },
67
+ {
68
+ name: 'delete_space',
69
+ description: 'Deletes a space (DESTRUCTIVE).',
70
+ params: [
71
+ { name: 'spaceId', type: 'string', required: false, description: 'Space ID' },
72
+ { name: 'spaceName', type: 'string', required: false, description: 'Space name' },
73
+ ],
74
+ },
75
+ // ===================
76
+ // FOLDERS
77
+ // ===================
78
+ {
79
+ name: 'create_folder',
80
+ description: 'Creates a folder in a ClickUp space.',
81
+ params: [
82
+ { name: 'spaceId', type: 'string', required: false, description: 'Space ID' },
83
+ { name: 'spaceName', type: 'string', required: false, description: 'Space name' },
84
+ { name: 'name', type: 'string', required: true, description: 'Folder name' },
85
+ ],
86
+ },
87
+ {
88
+ name: 'get_folder',
89
+ description: 'Gets folder details.',
90
+ params: [
91
+ { name: 'folderId', type: 'string', required: false, description: 'Folder ID' },
92
+ { name: 'folderName', type: 'string', required: false, description: 'Folder name' },
93
+ { name: 'spaceId', type: 'string', required: false, description: 'Space ID' },
94
+ { name: 'spaceName', type: 'string', required: false, description: 'Space name' },
95
+ ],
96
+ },
97
+ {
98
+ name: 'update_folder',
99
+ description: 'Updates a folder.',
100
+ params: [
101
+ { name: 'folderId', type: 'string', required: true, description: 'Folder ID' },
102
+ { name: 'name', type: 'string', required: false, description: 'New folder name' },
103
+ ],
104
+ },
105
+ {
106
+ name: 'delete_folder',
107
+ description: 'Deletes a folder (DESTRUCTIVE).',
108
+ params: [
109
+ { name: 'folderId', type: 'string', required: true, description: 'Folder ID' },
110
+ ],
111
+ },
112
+ // ===================
113
+ // LISTS
114
+ // ===================
115
+ {
116
+ name: 'create_list',
117
+ description: 'Creates a list in a ClickUp space or folder.',
118
+ params: [
119
+ { name: 'spaceId', type: 'string', required: false, description: 'Space ID (for folderless list)' },
120
+ { name: 'spaceName', type: 'string', required: false, description: 'Space name' },
121
+ { name: 'folderId', type: 'string', required: false, description: 'Folder ID (to create in folder)' },
122
+ { name: 'name', type: 'string', required: true, description: 'List name' },
123
+ { name: 'content', type: 'string', required: false, description: 'List description' },
124
+ ],
125
+ },
126
+ {
127
+ name: 'get_list',
128
+ description: 'Gets details of a ClickUp list.',
129
+ params: [
130
+ { name: 'listId', type: 'string', required: false, description: 'List ID' },
131
+ { name: 'listName', type: 'string', required: false, description: 'List name' },
132
+ ],
133
+ },
134
+ {
135
+ name: 'update_list',
136
+ description: 'Updates a list.',
137
+ params: [
138
+ { name: 'listId', type: 'string', required: false, description: 'List ID' },
139
+ { name: 'listName', type: 'string', required: false, description: 'List name to find' },
140
+ { name: 'name', type: 'string', required: false, description: 'New list name' },
141
+ { name: 'content', type: 'string', required: false, description: 'New description' },
142
+ { name: 'status', type: 'string', required: false, description: 'List status (red, yellow, green)' },
143
+ ],
144
+ },
145
+ {
146
+ name: 'delete_list',
147
+ description: 'Deletes a list (DESTRUCTIVE).',
148
+ params: [
149
+ { name: 'listId', type: 'string', required: false, description: 'List ID' },
150
+ { name: 'listName', type: 'string', required: false, description: 'List name' },
151
+ ],
152
+ },
153
+ // ===================
154
+ // TASKS - Core CRUD
155
+ // ===================
156
+ {
157
+ name: 'list_tasks',
158
+ description: 'Gets tasks from a list or across the workspace with filtering. Essential for "what\'s on my plate" queries.',
159
+ params: [
160
+ { name: 'listId', type: 'string', required: false, description: 'List ID to get tasks from' },
161
+ { name: 'listName', type: 'string', required: false, description: 'List name to get tasks from' },
162
+ { name: 'spaceId', type: 'string', required: false, description: 'Space ID (for cross-list search)' },
163
+ { name: 'spaceName', type: 'string', required: false, description: 'Space name (for cross-list search)' },
164
+ { name: 'archived', type: 'boolean', required: false, description: 'Include archived tasks' },
165
+ { name: 'page', type: 'number', required: false, description: 'Page number (0-indexed)' },
166
+ { name: 'orderBy', type: 'string', required: false, description: 'Order by: id, created, updated, due_date' },
167
+ { name: 'reverse', type: 'boolean', required: false, description: 'Reverse order' },
168
+ { name: 'subtasks', type: 'boolean', required: false, description: 'Include subtasks' },
169
+ { name: 'statuses', type: 'array', required: false, description: 'Filter by statuses (e.g., ["to do", "in progress"])' },
170
+ { name: 'includeClosed', type: 'boolean', required: false, description: 'Include closed/completed tasks' },
171
+ { name: 'assignees', type: 'array', required: false, description: 'Filter by assignee user IDs' },
172
+ { name: 'tags', type: 'array', required: false, description: 'Filter by tag names' },
173
+ { name: 'dueDateGt', type: 'number', required: false, description: 'Due date greater than (Unix ms)' },
174
+ { name: 'dueDateLt', type: 'number', required: false, description: 'Due date less than (Unix ms)' },
175
+ { name: 'dateCreatedGt', type: 'number', required: false, description: 'Created after (Unix ms)' },
176
+ { name: 'dateCreatedLt', type: 'number', required: false, description: 'Created before (Unix ms)' },
177
+ { name: 'dateUpdatedGt', type: 'number', required: false, description: 'Updated after (Unix ms)' },
178
+ { name: 'dateUpdatedLt', type: 'number', required: false, description: 'Updated before (Unix ms)' },
179
+ { name: 'customFields', type: 'array', required: false, description: 'Filter by custom field values' },
180
+ ],
181
+ },
182
+ {
183
+ name: 'search_tasks',
184
+ description: 'Search for tasks across the entire workspace by name or custom task ID.',
185
+ params: [
186
+ { name: 'query', type: 'string', required: true, description: 'Search query (task name or custom ID)' },
187
+ { name: 'includeClosed', type: 'boolean', required: false, description: 'Include closed tasks' },
188
+ ],
189
+ },
190
+ {
191
+ name: 'get_my_tasks',
192
+ description: 'Gets tasks assigned to you (or a specific user) due today, overdue, or upcoming.',
193
+ params: [
194
+ { name: 'userId', type: 'string', required: false, description: 'User ID (defaults to API key owner)' },
195
+ { name: 'filter', type: 'string', required: false, description: 'Filter: today, overdue, upcoming, all (default: all)' },
196
+ { name: 'includeClosed', type: 'boolean', required: false, description: 'Include closed tasks' },
197
+ ],
198
+ },
199
+ {
200
+ name: 'create_task',
201
+ description: 'Creates a single task in a ClickUp list. Use listId (preferred) or listName.',
202
+ params: [
203
+ { name: 'listId', type: 'string', required: false, description: 'ID of the list to create the task in (preferred)' },
204
+ { name: 'listName', type: 'string', required: false, description: 'Name of the list (alternative to listId)' },
205
+ { name: 'name', type: 'string', required: true, description: 'Name of the task (put emoji prefix if appropriate)' },
206
+ { name: 'description', type: 'string', required: false, description: 'Plain text description' },
207
+ { name: 'markdown_description', type: 'string', required: false, description: 'Markdown description (takes precedence)' },
208
+ { name: 'priority', type: 'number', required: false, description: 'Priority 1-4 (1=urgent, 4=low)' },
209
+ { name: 'dueDate', type: 'string', required: false, description: 'Due date (Unix ms or natural language)' },
210
+ { name: 'startDate', type: 'string', required: false, description: 'Start date (Unix ms or natural language)' },
211
+ { name: 'timeEstimate', type: 'number', required: false, description: 'Time estimate in milliseconds' },
212
+ { name: 'status', type: 'string', required: false, description: 'Task status' },
213
+ { name: 'assignees', type: 'array', required: false, description: 'Array of user IDs, emails, or usernames' },
214
+ { name: 'tags', type: 'array', required: false, description: 'Array of tag names' },
215
+ { name: 'parent', type: 'string', required: false, description: 'Parent task ID for subtasks' },
216
+ { name: 'customFields', type: 'array', required: false, description: 'Custom field values [{id, value}]' },
217
+ ],
218
+ },
219
+ {
220
+ name: 'get_task',
221
+ description: 'Gets task details by taskId or taskName. Set subtasks=true to include subtask details.',
222
+ params: [
223
+ { name: 'taskId', type: 'string', required: false, description: 'Task ID (handles both regular and custom IDs)' },
224
+ { name: 'taskName', type: 'string', required: false, description: 'Task name to search for' },
225
+ { name: 'listName', type: 'string', required: false, description: 'List name to narrow search' },
226
+ { name: 'subtasks', type: 'boolean', required: false, description: 'Include subtask details' },
227
+ { name: 'includeCustomFields', type: 'boolean', required: false, description: 'Include custom fields' },
228
+ ],
229
+ },
230
+ {
231
+ name: 'update_task',
232
+ description: 'Updates task properties. Use taskId (preferred) or taskName.',
233
+ params: [
234
+ { name: 'taskId', type: 'string', required: false, description: 'Task ID to update' },
235
+ { name: 'taskName', type: 'string', required: false, description: 'Task name to find and update' },
236
+ { name: 'listName', type: 'string', required: false, description: 'List name to narrow search' },
237
+ { name: 'name', type: 'string', required: false, description: 'New task name' },
238
+ { name: 'description', type: 'string', required: false, description: 'New description' },
239
+ { name: 'status', type: 'string', required: false, description: 'New status' },
240
+ { name: 'priority', type: 'number', required: false, description: 'New priority (1-4)' },
241
+ { name: 'dueDate', type: 'string', required: false, description: 'New due date' },
242
+ { name: 'startDate', type: 'string', required: false, description: 'New start date' },
243
+ { name: 'timeEstimate', type: 'number', required: false, description: 'Time estimate in ms' },
244
+ { name: 'assignees', type: 'object', required: false, description: 'Assignees {add: [], rem: []}' },
245
+ { name: 'archived', type: 'boolean', required: false, description: 'Archive/unarchive task' },
246
+ ],
247
+ },
248
+ {
249
+ name: 'delete_task',
250
+ description: 'Deletes a task (DESTRUCTIVE - moves to trash).',
251
+ params: [
252
+ { name: 'taskId', type: 'string', required: false, description: 'Task ID' },
253
+ { name: 'taskName', type: 'string', required: false, description: 'Task name' },
254
+ { name: 'listName', type: 'string', required: false, description: 'List name to narrow search' },
255
+ ],
256
+ },
257
+ // ===================
258
+ // TASK COMMENTS
259
+ // ===================
260
+ {
261
+ name: 'get_task_comments',
262
+ description: 'Gets task comments by taskId or taskName.',
263
+ params: [
264
+ { name: 'taskId', type: 'string', required: false, description: 'Task ID' },
265
+ { name: 'taskName', type: 'string', required: false, description: 'Task name' },
266
+ { name: 'listName', type: 'string', required: false, description: 'List name' },
267
+ ],
268
+ },
269
+ {
270
+ name: 'create_task_comment',
271
+ description: 'Creates a comment on a task.',
272
+ params: [
273
+ { name: 'taskId', type: 'string', required: false, description: 'Task ID' },
274
+ { name: 'taskName', type: 'string', required: false, description: 'Task name' },
275
+ { name: 'listName', type: 'string', required: false, description: 'List name' },
276
+ { name: 'commentText', type: 'string', required: true, description: 'Comment text' },
277
+ { name: 'assignee', type: 'number', required: false, description: 'User ID to assign comment to' },
278
+ { name: 'notifyAll', type: 'boolean', required: false, description: 'Notify all assignees' },
279
+ ],
280
+ },
281
+ {
282
+ name: 'update_comment',
283
+ description: 'Updates a comment.',
284
+ params: [
285
+ { name: 'commentId', type: 'string', required: true, description: 'Comment ID' },
286
+ { name: 'commentText', type: 'string', required: true, description: 'New comment text' },
287
+ { name: 'resolved', type: 'boolean', required: false, description: 'Resolve/unresolve comment' },
288
+ ],
289
+ },
290
+ {
291
+ name: 'delete_comment',
292
+ description: 'Deletes a comment.',
293
+ params: [
294
+ { name: 'commentId', type: 'string', required: true, description: 'Comment ID' },
295
+ ],
296
+ },
297
+ // ===================
298
+ // TASK CHECKLISTS
299
+ // ===================
300
+ {
301
+ name: 'create_checklist',
302
+ description: 'Creates a checklist on a task.',
303
+ params: [
304
+ { name: 'taskId', type: 'string', required: false, description: 'Task ID' },
305
+ { name: 'taskName', type: 'string', required: false, description: 'Task name' },
306
+ { name: 'listName', type: 'string', required: false, description: 'List name' },
307
+ { name: 'name', type: 'string', required: true, description: 'Checklist name' },
308
+ ],
309
+ },
310
+ {
311
+ name: 'update_checklist',
312
+ description: 'Updates a checklist name or position.',
313
+ params: [
314
+ { name: 'checklistId', type: 'string', required: true, description: 'Checklist ID' },
315
+ { name: 'name', type: 'string', required: false, description: 'New checklist name' },
316
+ { name: 'position', type: 'number', required: false, description: 'New position' },
317
+ ],
318
+ },
319
+ {
320
+ name: 'delete_checklist',
321
+ description: 'Deletes a checklist.',
322
+ params: [
323
+ { name: 'checklistId', type: 'string', required: true, description: 'Checklist ID' },
324
+ ],
325
+ },
326
+ {
327
+ name: 'create_checklist_item',
328
+ description: 'Adds an item to a checklist.',
329
+ params: [
330
+ { name: 'checklistId', type: 'string', required: true, description: 'Checklist ID' },
331
+ { name: 'name', type: 'string', required: true, description: 'Item name' },
332
+ { name: 'assignee', type: 'number', required: false, description: 'Assignee user ID' },
333
+ ],
334
+ },
335
+ {
336
+ name: 'update_checklist_item',
337
+ description: 'Updates a checklist item (name, resolved status, assignee).',
338
+ params: [
339
+ { name: 'checklistId', type: 'string', required: true, description: 'Checklist ID' },
340
+ { name: 'checklistItemId', type: 'string', required: true, description: 'Checklist item ID' },
341
+ { name: 'name', type: 'string', required: false, description: 'New item name' },
342
+ { name: 'resolved', type: 'boolean', required: false, description: 'Mark as resolved/unresolved' },
343
+ { name: 'assignee', type: 'number', required: false, description: 'New assignee' },
344
+ ],
345
+ },
346
+ {
347
+ name: 'delete_checklist_item',
348
+ description: 'Deletes a checklist item.',
349
+ params: [
350
+ { name: 'checklistId', type: 'string', required: true, description: 'Checklist ID' },
351
+ { name: 'checklistItemId', type: 'string', required: true, description: 'Checklist item ID' },
352
+ ],
353
+ },
354
+ // ===================
355
+ // TIME TRACKING
356
+ // ===================
357
+ {
358
+ name: 'get_task_time_entries',
359
+ description: 'Gets all time entries for a task.',
360
+ params: [
361
+ { name: 'taskId', type: 'string', required: false, description: 'Task ID' },
362
+ { name: 'taskName', type: 'string', required: false, description: 'Task name' },
363
+ { name: 'listName', type: 'string', required: false, description: 'List name' },
364
+ ],
365
+ },
366
+ {
367
+ name: 'create_time_entry',
368
+ description: 'Creates a manual time entry for a task.',
369
+ params: [
370
+ { name: 'taskId', type: 'string', required: false, description: 'Task ID' },
371
+ { name: 'taskName', type: 'string', required: false, description: 'Task name' },
372
+ { name: 'listName', type: 'string', required: false, description: 'List name' },
373
+ { name: 'start', type: 'number', required: true, description: 'Start time (Unix ms)' },
374
+ { name: 'duration', type: 'number', required: true, description: 'Duration in milliseconds' },
375
+ { name: 'description', type: 'string', required: false, description: 'Time entry description' },
376
+ { name: 'billable', type: 'boolean', required: false, description: 'Mark as billable' },
377
+ ],
378
+ },
379
+ {
380
+ name: 'start_time_entry',
381
+ description: 'Starts a timer on a task.',
382
+ params: [
383
+ { name: 'taskId', type: 'string', required: false, description: 'Task ID' },
384
+ { name: 'taskName', type: 'string', required: false, description: 'Task name' },
385
+ { name: 'listName', type: 'string', required: false, description: 'List name' },
386
+ { name: 'description', type: 'string', required: false, description: 'Timer description' },
387
+ { name: 'billable', type: 'boolean', required: false, description: 'Mark as billable' },
388
+ ],
389
+ },
390
+ {
391
+ name: 'stop_time_entry',
392
+ description: 'Stops the running timer.',
393
+ params: [],
394
+ },
395
+ {
396
+ name: 'get_running_time_entry',
397
+ description: 'Gets the currently running time entry.',
398
+ params: [],
399
+ },
400
+ {
401
+ name: 'delete_time_entry',
402
+ description: 'Deletes a time entry.',
403
+ params: [
404
+ { name: 'timeEntryId', type: 'string', required: true, description: 'Time entry ID' },
405
+ ],
406
+ },
407
+ // ===================
408
+ // TASK DEPENDENCIES
409
+ // ===================
410
+ {
411
+ name: 'add_task_dependency',
412
+ description: 'Adds a dependency between tasks (task depends on dependsOnTaskId).',
413
+ params: [
414
+ { name: 'taskId', type: 'string', required: true, description: 'Task that has the dependency' },
415
+ { name: 'dependsOnTaskId', type: 'string', required: true, description: 'Task that must be completed first' },
416
+ ],
417
+ },
418
+ {
419
+ name: 'delete_task_dependency',
420
+ description: 'Removes a dependency between tasks.',
421
+ params: [
422
+ { name: 'taskId', type: 'string', required: true, description: 'Task ID' },
423
+ { name: 'dependsOnTaskId', type: 'string', required: true, description: 'Dependency to remove' },
424
+ ],
425
+ },
426
+ {
427
+ name: 'add_task_link',
428
+ description: 'Links two tasks together (bidirectional relationship).',
429
+ params: [
430
+ { name: 'taskId', type: 'string', required: true, description: 'First task ID' },
431
+ { name: 'linksToTaskId', type: 'string', required: true, description: 'Second task ID' },
432
+ ],
433
+ },
434
+ {
435
+ name: 'delete_task_link',
436
+ description: 'Removes a link between tasks.',
437
+ params: [
438
+ { name: 'taskId', type: 'string', required: true, description: 'First task ID' },
439
+ { name: 'linksToTaskId', type: 'string', required: true, description: 'Second task ID' },
440
+ ],
441
+ },
442
+ // ===================
443
+ // TAGS
444
+ // ===================
445
+ {
446
+ name: 'get_space_tags',
447
+ description: 'Gets all tags in a ClickUp space.',
448
+ params: [
449
+ { name: 'spaceId', type: 'string', required: false, description: 'Space ID' },
450
+ { name: 'spaceName', type: 'string', required: false, description: 'Space name' },
451
+ ],
452
+ },
453
+ {
454
+ name: 'create_tag',
455
+ description: 'Creates a new tag in a space.',
456
+ params: [
457
+ { name: 'spaceId', type: 'string', required: false, description: 'Space ID' },
458
+ { name: 'spaceName', type: 'string', required: false, description: 'Space name' },
459
+ { name: 'name', type: 'string', required: true, description: 'Tag name' },
460
+ { name: 'bgColor', type: 'string', required: false, description: 'Background color hex' },
461
+ ],
462
+ },
463
+ {
464
+ name: 'update_tag',
465
+ description: 'Updates a tag.',
466
+ params: [
467
+ { name: 'spaceId', type: 'string', required: false, description: 'Space ID' },
468
+ { name: 'spaceName', type: 'string', required: false, description: 'Space name' },
469
+ { name: 'tagName', type: 'string', required: true, description: 'Current tag name' },
470
+ { name: 'newName', type: 'string', required: false, description: 'New tag name' },
471
+ { name: 'bgColor', type: 'string', required: false, description: 'New background color' },
472
+ ],
473
+ },
474
+ {
475
+ name: 'delete_tag',
476
+ description: 'Deletes a tag from a space.',
477
+ params: [
478
+ { name: 'spaceId', type: 'string', required: false, description: 'Space ID' },
479
+ { name: 'spaceName', type: 'string', required: false, description: 'Space name' },
480
+ { name: 'tagName', type: 'string', required: true, description: 'Tag name to delete' },
481
+ ],
482
+ },
483
+ {
484
+ name: 'add_tag_to_task',
485
+ description: 'Adds an existing tag to a task.',
486
+ params: [
487
+ { name: 'taskId', type: 'string', required: false, description: 'Task ID' },
488
+ { name: 'taskName', type: 'string', required: false, description: 'Task name' },
489
+ { name: 'listName', type: 'string', required: false, description: 'List name' },
490
+ { name: 'tagName', type: 'string', required: true, description: 'Tag name to add' },
491
+ ],
492
+ },
493
+ {
494
+ name: 'remove_tag_from_task',
495
+ description: 'Removes a tag from a task.',
496
+ params: [
497
+ { name: 'taskId', type: 'string', required: false, description: 'Task ID' },
498
+ { name: 'taskName', type: 'string', required: false, description: 'Task name' },
499
+ { name: 'listName', type: 'string', required: false, description: 'List name' },
500
+ { name: 'tagName', type: 'string', required: true, description: 'Tag name to remove' },
501
+ ],
502
+ },
503
+ // ===================
504
+ // CUSTOM FIELDS
505
+ // ===================
506
+ {
507
+ name: 'get_custom_fields',
508
+ description: 'Gets accessible custom fields for a list.',
509
+ params: [
510
+ { name: 'listId', type: 'string', required: false, description: 'List ID' },
511
+ { name: 'listName', type: 'string', required: false, description: 'List name' },
512
+ ],
513
+ },
514
+ {
515
+ name: 'set_custom_field_value',
516
+ description: 'Sets a custom field value on a task.',
517
+ params: [
518
+ { name: 'taskId', type: 'string', required: true, description: 'Task ID' },
519
+ { name: 'fieldId', type: 'string', required: true, description: 'Custom field ID' },
520
+ { name: 'value', type: 'any', required: true, description: 'Value to set (type depends on field)' },
521
+ ],
522
+ },
523
+ {
524
+ name: 'remove_custom_field_value',
525
+ description: 'Removes a custom field value from a task.',
526
+ params: [
527
+ { name: 'taskId', type: 'string', required: true, description: 'Task ID' },
528
+ { name: 'fieldId', type: 'string', required: true, description: 'Custom field ID' },
529
+ ],
530
+ },
531
+ // ===================
532
+ // GOALS
533
+ // ===================
534
+ {
535
+ name: 'get_goals',
536
+ description: 'Gets all goals in the workspace.',
537
+ params: [
538
+ { name: 'includeCompleted', type: 'boolean', required: false, description: 'Include completed goals' },
539
+ ],
540
+ },
541
+ {
542
+ name: 'get_goal',
543
+ description: 'Gets a specific goal by ID.',
544
+ params: [
545
+ { name: 'goalId', type: 'string', required: true, description: 'Goal ID' },
546
+ ],
547
+ },
548
+ {
549
+ name: 'create_goal',
550
+ description: 'Creates a new goal.',
551
+ params: [
552
+ { name: 'name', type: 'string', required: true, description: 'Goal name' },
553
+ { name: 'dueDate', type: 'number', required: false, description: 'Due date (Unix ms)' },
554
+ { name: 'description', type: 'string', required: false, description: 'Goal description' },
555
+ { name: 'color', type: 'string', required: false, description: 'Goal color hex' },
556
+ ],
557
+ },
558
+ {
559
+ name: 'update_goal',
560
+ description: 'Updates a goal.',
561
+ params: [
562
+ { name: 'goalId', type: 'string', required: true, description: 'Goal ID' },
563
+ { name: 'name', type: 'string', required: false, description: 'New goal name' },
564
+ { name: 'dueDate', type: 'number', required: false, description: 'New due date' },
565
+ { name: 'description', type: 'string', required: false, description: 'New description' },
566
+ { name: 'color', type: 'string', required: false, description: 'New color' },
567
+ ],
568
+ },
569
+ {
570
+ name: 'delete_goal',
571
+ description: 'Deletes a goal.',
572
+ params: [
573
+ { name: 'goalId', type: 'string', required: true, description: 'Goal ID' },
574
+ ],
575
+ },
576
+ {
577
+ name: 'create_key_result',
578
+ description: 'Creates a key result for a goal.',
579
+ params: [
580
+ { name: 'goalId', type: 'string', required: true, description: 'Goal ID' },
581
+ { name: 'name', type: 'string', required: true, description: 'Key result name' },
582
+ { name: 'type', type: 'string', required: true, description: 'Type: number, currency, boolean, percentage, automatic' },
583
+ { name: 'stepsStart', type: 'number', required: false, description: 'Start value' },
584
+ { name: 'stepsEnd', type: 'number', required: false, description: 'Target value' },
585
+ { name: 'unit', type: 'string', required: false, description: 'Unit label' },
586
+ { name: 'taskIds', type: 'array', required: false, description: 'Task IDs (for automatic type)' },
587
+ { name: 'listIds', type: 'array', required: false, description: 'List IDs (for automatic type)' },
588
+ ],
589
+ },
590
+ {
591
+ name: 'update_key_result',
592
+ description: 'Updates a key result.',
593
+ params: [
594
+ { name: 'keyResultId', type: 'string', required: true, description: 'Key result ID' },
595
+ { name: 'stepsCurrent', type: 'number', required: false, description: 'Current progress value' },
596
+ { name: 'note', type: 'string', required: false, description: 'Progress note' },
597
+ ],
598
+ },
599
+ {
600
+ name: 'delete_key_result',
601
+ description: 'Deletes a key result.',
602
+ params: [
603
+ { name: 'keyResultId', type: 'string', required: true, description: 'Key result ID' },
604
+ ],
605
+ },
606
+ // ===================
607
+ // WEBHOOKS
608
+ // ===================
609
+ {
610
+ name: 'get_webhooks',
611
+ description: 'Gets all webhooks in the workspace.',
612
+ params: [],
613
+ },
614
+ {
615
+ name: 'create_webhook',
616
+ description: 'Creates a webhook for events.',
617
+ params: [
618
+ { name: 'endpoint', type: 'string', required: true, description: 'Webhook endpoint URL' },
619
+ { name: 'events', type: 'array', required: true, description: 'Events to subscribe to (e.g., taskCreated, taskUpdated)' },
620
+ { name: 'spaceId', type: 'string', required: false, description: 'Filter to specific space' },
621
+ { name: 'folderId', type: 'string', required: false, description: 'Filter to specific folder' },
622
+ { name: 'listId', type: 'string', required: false, description: 'Filter to specific list' },
623
+ { name: 'taskId', type: 'string', required: false, description: 'Filter to specific task' },
624
+ ],
625
+ },
626
+ {
627
+ name: 'update_webhook',
628
+ description: 'Updates a webhook.',
629
+ params: [
630
+ { name: 'webhookId', type: 'string', required: true, description: 'Webhook ID' },
631
+ { name: 'endpoint', type: 'string', required: false, description: 'New endpoint URL' },
632
+ { name: 'events', type: 'array', required: false, description: 'New events list' },
633
+ { name: 'status', type: 'string', required: false, description: 'active or suspended' },
634
+ ],
635
+ },
636
+ {
637
+ name: 'delete_webhook',
638
+ description: 'Deletes a webhook.',
639
+ params: [
640
+ { name: 'webhookId', type: 'string', required: true, description: 'Webhook ID' },
641
+ ],
642
+ },
643
+ ];
644
+ // ===================
645
+ // HELPER FUNCTIONS
646
+ // ===================
647
+ async function findSpaceByName(spaceName) {
648
+ const response = await axios.get(`${BASE_URL}/team/${CLICKUP_TEAM_ID}/space`, {
649
+ headers: headers(),
650
+ params: { archived: false },
651
+ });
652
+ return response.data.spaces?.find((s) => s.name.toLowerCase() === spaceName.toLowerCase()) || null;
653
+ }
654
+ async function findListByName(listName) {
655
+ const hierarchy = await getWorkspaceHierarchy();
656
+ for (const space of hierarchy.spaces || []) {
657
+ for (const list of space.lists || []) {
658
+ if (list.name.toLowerCase() === listName.toLowerCase()) {
659
+ return list.id;
660
+ }
661
+ }
662
+ for (const folder of space.folders || []) {
663
+ for (const list of folder.lists || []) {
664
+ if (list.name.toLowerCase() === listName.toLowerCase()) {
665
+ return list.id;
666
+ }
667
+ }
668
+ }
669
+ }
670
+ return null;
671
+ }
672
+ async function findTaskByName(taskName, listName) {
673
+ if (listName) {
674
+ const listId = await findListByName(listName);
675
+ if (listId) {
676
+ const response = await axios.get(`${BASE_URL}/list/${listId}/task`, {
677
+ headers: headers(),
678
+ params: { subtasks: true },
679
+ });
680
+ const task = response.data.tasks?.find((t) => t.name.toLowerCase() === taskName.toLowerCase());
681
+ if (task)
682
+ return task;
683
+ }
684
+ }
685
+ const response = await axios.get(`${BASE_URL}/team/${CLICKUP_TEAM_ID}/task`, {
686
+ headers: headers(),
687
+ params: { subtasks: true, include_closed: true },
688
+ });
689
+ return response.data.tasks?.find((t) => t.name.toLowerCase() === taskName.toLowerCase()) || null;
690
+ }
691
+ async function resolveTaskId(params) {
692
+ let taskId = params.taskId;
693
+ if (!taskId && params.taskName) {
694
+ const task = await findTaskByName(params.taskName, params.listName);
695
+ if (!task)
696
+ throw new Error(`Task not found: ${params.taskName}`);
697
+ taskId = task.id;
698
+ }
699
+ if (!taskId)
700
+ throw new Error('taskId or taskName is required');
701
+ return taskId;
702
+ }
703
+ async function resolveSpaceId(params) {
704
+ let spaceId = params.spaceId;
705
+ if (!spaceId && params.spaceName) {
706
+ const space = await findSpaceByName(params.spaceName);
707
+ if (space)
708
+ spaceId = space.id;
709
+ }
710
+ if (!spaceId)
711
+ throw new Error('spaceId or spaceName is required');
712
+ return spaceId;
713
+ }
714
+ async function resolveListId(params) {
715
+ let listId = params.listId;
716
+ if (!listId && params.listName) {
717
+ listId = await findListByName(params.listName) || '';
718
+ }
719
+ if (!listId)
720
+ throw new Error('listId or listName is required');
721
+ return listId;
722
+ }
723
+ // ===================
724
+ // IMPLEMENTATION FUNCTIONS
725
+ // ===================
726
+ async function getWorkspaceHierarchy() {
727
+ const response = await axios.get(`${BASE_URL}/team/${CLICKUP_TEAM_ID}/space`, {
728
+ headers: headers(),
729
+ params: { archived: false },
730
+ });
731
+ const spaces = await Promise.all(response.data.spaces.map(async (space) => {
732
+ const foldersRes = await axios.get(`${BASE_URL}/space/${space.id}/folder`, {
733
+ headers: headers(),
734
+ params: { archived: false },
735
+ });
736
+ const listsRes = await axios.get(`${BASE_URL}/space/${space.id}/list`, {
737
+ headers: headers(),
738
+ params: { archived: false },
739
+ });
740
+ return {
741
+ id: space.id,
742
+ name: space.name,
743
+ folders: foldersRes.data.folders,
744
+ lists: listsRes.data.lists,
745
+ };
746
+ }));
747
+ return { spaces };
748
+ }
749
+ async function getWorkspaceMembers() {
750
+ const response = await axios.get(`${BASE_URL}/team/${CLICKUP_TEAM_ID}`, {
751
+ headers: headers(),
752
+ });
753
+ return response.data.team?.members || [];
754
+ }
755
+ async function findMemberByName(params) {
756
+ if (!params.nameOrEmail)
757
+ throw new Error('nameOrEmail is required');
758
+ const members = await getWorkspaceMembers();
759
+ const search = params.nameOrEmail.toLowerCase();
760
+ return members.find((m) => m.user?.username?.toLowerCase().includes(search) ||
761
+ m.user?.email?.toLowerCase().includes(search) ||
762
+ `${m.user?.first_name} ${m.user?.last_name}`.toLowerCase().includes(search)) || null;
763
+ }
764
+ // SPACES
765
+ async function getSpaces(params) {
766
+ const response = await axios.get(`${BASE_URL}/team/${CLICKUP_TEAM_ID}/space`, {
767
+ headers: headers(),
768
+ params: { archived: params.archived || false },
769
+ });
770
+ return response.data.spaces;
771
+ }
772
+ async function getSpace(params) {
773
+ const spaceId = await resolveSpaceId(params);
774
+ const response = await axios.get(`${BASE_URL}/space/${spaceId}`, { headers: headers() });
775
+ return response.data;
776
+ }
777
+ async function createSpace(params) {
778
+ if (!params.name)
779
+ throw new Error('name is required');
780
+ const response = await axios.post(`${BASE_URL}/team/${CLICKUP_TEAM_ID}/space`, {
781
+ name: params.name,
782
+ features: params.features || {},
783
+ }, { headers: headers() });
784
+ return response.data;
785
+ }
786
+ async function updateSpace(params) {
787
+ const spaceId = await resolveSpaceId(params);
788
+ const body = {};
789
+ if (params.name)
790
+ body.name = params.name;
791
+ if (params.color)
792
+ body.color = params.color;
793
+ if (params.private !== undefined)
794
+ body.private = params.private;
795
+ const response = await axios.put(`${BASE_URL}/space/${spaceId}`, body, { headers: headers() });
796
+ return response.data;
797
+ }
798
+ async function deleteSpace(params) {
799
+ const spaceId = await resolveSpaceId(params);
800
+ const response = await axios.delete(`${BASE_URL}/space/${spaceId}`, { headers: headers() });
801
+ return response.data;
802
+ }
803
+ // FOLDERS
804
+ async function createFolder(params) {
805
+ const spaceId = await resolveSpaceId(params);
806
+ if (!params.name)
807
+ throw new Error('name is required');
808
+ const response = await axios.post(`${BASE_URL}/space/${spaceId}/folder`, {
809
+ name: params.name,
810
+ }, { headers: headers() });
811
+ return response.data;
812
+ }
813
+ async function getFolder(params) {
814
+ let folderId = params.folderId;
815
+ if (!folderId && params.folderName) {
816
+ const hierarchy = await getWorkspaceHierarchy();
817
+ for (const space of hierarchy.spaces || []) {
818
+ if (params.spaceId && space.id !== params.spaceId)
819
+ continue;
820
+ if (params.spaceName && space.name.toLowerCase() !== params.spaceName.toLowerCase())
821
+ continue;
822
+ const folder = space.folders?.find((f) => f.name.toLowerCase() === params.folderName.toLowerCase());
823
+ if (folder) {
824
+ folderId = folder.id;
825
+ break;
826
+ }
827
+ }
828
+ }
829
+ if (!folderId)
830
+ throw new Error('folderId or folderName is required');
831
+ const response = await axios.get(`${BASE_URL}/folder/${folderId}`, { headers: headers() });
832
+ return response.data;
833
+ }
834
+ async function updateFolder(params) {
835
+ if (!params.folderId)
836
+ throw new Error('folderId is required');
837
+ const body = {};
838
+ if (params.name)
839
+ body.name = params.name;
840
+ const response = await axios.put(`${BASE_URL}/folder/${params.folderId}`, body, { headers: headers() });
841
+ return response.data;
842
+ }
843
+ async function deleteFolder(params) {
844
+ if (!params.folderId)
845
+ throw new Error('folderId is required');
846
+ const response = await axios.delete(`${BASE_URL}/folder/${params.folderId}`, { headers: headers() });
847
+ return response.data;
848
+ }
849
+ // LISTS
850
+ async function createList(params) {
851
+ if (!params.name)
852
+ throw new Error('name is required');
853
+ // Create in folder if folderId provided, otherwise in space
854
+ if (params.folderId) {
855
+ const response = await axios.post(`${BASE_URL}/folder/${params.folderId}/list`, {
856
+ name: params.name,
857
+ content: params.content || '',
858
+ }, { headers: headers() });
859
+ return response.data;
860
+ }
861
+ const spaceId = await resolveSpaceId(params);
862
+ const response = await axios.post(`${BASE_URL}/space/${spaceId}/list`, {
863
+ name: params.name,
864
+ content: params.content || '',
865
+ }, { headers: headers() });
866
+ return response.data;
867
+ }
868
+ async function getList(params) {
869
+ const listId = await resolveListId(params);
870
+ const response = await axios.get(`${BASE_URL}/list/${listId}`, { headers: headers() });
871
+ return response.data;
872
+ }
873
+ async function updateList(params) {
874
+ const listId = await resolveListId(params);
875
+ const body = {};
876
+ if (params.name)
877
+ body.name = params.name;
878
+ if (params.content)
879
+ body.content = params.content;
880
+ if (params.status)
881
+ body.status = params.status;
882
+ const response = await axios.put(`${BASE_URL}/list/${listId}`, body, { headers: headers() });
883
+ return response.data;
884
+ }
885
+ async function deleteList(params) {
886
+ const listId = await resolveListId(params);
887
+ const response = await axios.delete(`${BASE_URL}/list/${listId}`, { headers: headers() });
888
+ return response.data;
889
+ }
890
+ // TASKS
891
+ async function listTasks(params) {
892
+ // Build query params
893
+ const queryParams = {
894
+ archived: params.archived || false,
895
+ page: params.page || 0,
896
+ subtasks: params.subtasks || false,
897
+ include_closed: params.includeClosed || false,
898
+ };
899
+ if (params.orderBy)
900
+ queryParams.order_by = params.orderBy;
901
+ if (params.reverse)
902
+ queryParams.reverse = params.reverse;
903
+ if (params.statuses)
904
+ queryParams.statuses = params.statuses;
905
+ if (params.assignees)
906
+ queryParams.assignees = params.assignees;
907
+ if (params.tags)
908
+ queryParams.tags = params.tags;
909
+ if (params.dueDateGt)
910
+ queryParams.due_date_gt = params.dueDateGt;
911
+ if (params.dueDateLt)
912
+ queryParams.due_date_lt = params.dueDateLt;
913
+ if (params.dateCreatedGt)
914
+ queryParams.date_created_gt = params.dateCreatedGt;
915
+ if (params.dateCreatedLt)
916
+ queryParams.date_created_lt = params.dateCreatedLt;
917
+ if (params.dateUpdatedGt)
918
+ queryParams.date_updated_gt = params.dateUpdatedGt;
919
+ if (params.dateUpdatedLt)
920
+ queryParams.date_updated_lt = params.dateUpdatedLt;
921
+ if (params.customFields)
922
+ queryParams.custom_fields = JSON.stringify(params.customFields);
923
+ // If listId/listName provided, get tasks from that list
924
+ if (params.listId || params.listName) {
925
+ const listId = await resolveListId(params);
926
+ const response = await axios.get(`${BASE_URL}/list/${listId}/task`, {
927
+ headers: headers(),
928
+ params: queryParams,
929
+ });
930
+ return response.data;
931
+ }
932
+ // If spaceId/spaceName provided, get filtered team tasks
933
+ // Otherwise get all team tasks
934
+ const response = await axios.get(`${BASE_URL}/team/${CLICKUP_TEAM_ID}/task`, {
935
+ headers: headers(),
936
+ params: queryParams,
937
+ });
938
+ return response.data;
939
+ }
940
+ async function searchTasks(params) {
941
+ if (!params.query)
942
+ throw new Error('query is required');
943
+ // ClickUp doesn't have a direct search endpoint, so we get all tasks and filter
944
+ const response = await axios.get(`${BASE_URL}/team/${CLICKUP_TEAM_ID}/task`, {
945
+ headers: headers(),
946
+ params: {
947
+ include_closed: params.includeClosed || false,
948
+ subtasks: true,
949
+ },
950
+ });
951
+ const query = params.query.toLowerCase();
952
+ const filtered = response.data.tasks?.filter((t) => t.name.toLowerCase().includes(query) ||
953
+ t.custom_id?.toLowerCase() === query) || [];
954
+ return { tasks: filtered };
955
+ }
956
+ async function getMyTasks(params) {
957
+ const now = Date.now();
958
+ const today = new Date();
959
+ today.setHours(23, 59, 59, 999);
960
+ const endOfToday = today.getTime();
961
+ const queryParams = {
962
+ include_closed: params.includeClosed || false,
963
+ subtasks: true,
964
+ };
965
+ // If userId specified, filter by assignee
966
+ if (params.userId) {
967
+ queryParams.assignees = [params.userId];
968
+ }
969
+ const response = await axios.get(`${BASE_URL}/team/${CLICKUP_TEAM_ID}/task`, {
970
+ headers: headers(),
971
+ params: queryParams,
972
+ });
973
+ let tasks = response.data.tasks || [];
974
+ // Apply filter
975
+ const filter = params.filter || 'all';
976
+ if (filter === 'today') {
977
+ tasks = tasks.filter((t) => t.due_date && parseInt(t.due_date) <= endOfToday && parseInt(t.due_date) >= now - 86400000);
978
+ }
979
+ else if (filter === 'overdue') {
980
+ tasks = tasks.filter((t) => t.due_date && parseInt(t.due_date) < now);
981
+ }
982
+ else if (filter === 'upcoming') {
983
+ tasks = tasks.filter((t) => t.due_date && parseInt(t.due_date) > endOfToday);
984
+ }
985
+ return { tasks };
986
+ }
987
+ async function createTask(params) {
988
+ const listId = await resolveListId(params);
989
+ if (!params.name)
990
+ throw new Error('name is required');
991
+ const body = { name: params.name };
992
+ if (params.description)
993
+ body.description = params.description;
994
+ if (params.markdown_description)
995
+ body.markdown_description = params.markdown_description;
996
+ if (params.priority)
997
+ body.priority = params.priority;
998
+ if (params.dueDate)
999
+ body.due_date = params.dueDate;
1000
+ if (params.startDate)
1001
+ body.start_date = params.startDate;
1002
+ if (params.timeEstimate)
1003
+ body.time_estimate = params.timeEstimate;
1004
+ if (params.status)
1005
+ body.status = params.status;
1006
+ if (params.assignees)
1007
+ body.assignees = params.assignees;
1008
+ if (params.tags)
1009
+ body.tags = params.tags;
1010
+ if (params.parent)
1011
+ body.parent = params.parent;
1012
+ if (params.customFields)
1013
+ body.custom_fields = params.customFields;
1014
+ const response = await axios.post(`${BASE_URL}/list/${listId}/task`, body, { headers: headers() });
1015
+ return response.data;
1016
+ }
1017
+ async function getTask(params) {
1018
+ const taskId = await resolveTaskId(params);
1019
+ const response = await axios.get(`${BASE_URL}/task/${taskId}`, {
1020
+ headers: headers(),
1021
+ params: {
1022
+ include_subtasks: params.subtasks === true,
1023
+ custom_fields: params.includeCustomFields === true,
1024
+ },
1025
+ });
1026
+ return response.data;
1027
+ }
1028
+ async function updateTask(params) {
1029
+ const taskId = await resolveTaskId(params);
1030
+ const body = {};
1031
+ if (params.name)
1032
+ body.name = params.name;
1033
+ if (params.description)
1034
+ body.description = params.description;
1035
+ if (params.status)
1036
+ body.status = params.status;
1037
+ if (params.priority)
1038
+ body.priority = params.priority;
1039
+ if (params.dueDate)
1040
+ body.due_date = params.dueDate;
1041
+ if (params.startDate)
1042
+ body.start_date = params.startDate;
1043
+ if (params.timeEstimate)
1044
+ body.time_estimate = params.timeEstimate;
1045
+ if (params.assignees)
1046
+ body.assignees = params.assignees;
1047
+ if (params.archived !== undefined)
1048
+ body.archived = params.archived;
1049
+ const response = await axios.put(`${BASE_URL}/task/${taskId}`, body, { headers: headers() });
1050
+ return response.data;
1051
+ }
1052
+ async function deleteTask(params) {
1053
+ const taskId = await resolveTaskId(params);
1054
+ const response = await axios.delete(`${BASE_URL}/task/${taskId}`, { headers: headers() });
1055
+ return response.data;
1056
+ }
1057
+ // COMMENTS
1058
+ async function getTaskComments(params) {
1059
+ const taskId = await resolveTaskId(params);
1060
+ const response = await axios.get(`${BASE_URL}/task/${taskId}/comment`, { headers: headers() });
1061
+ return response.data;
1062
+ }
1063
+ async function createTaskComment(params) {
1064
+ const taskId = await resolveTaskId(params);
1065
+ if (!params.commentText)
1066
+ throw new Error('commentText is required');
1067
+ const body = {
1068
+ comment_text: params.commentText,
1069
+ notify_all: params.notifyAll || false,
1070
+ };
1071
+ if (params.assignee)
1072
+ body.assignee = params.assignee;
1073
+ const response = await axios.post(`${BASE_URL}/task/${taskId}/comment`, body, { headers: headers() });
1074
+ return response.data;
1075
+ }
1076
+ async function updateComment(params) {
1077
+ if (!params.commentId)
1078
+ throw new Error('commentId is required');
1079
+ if (!params.commentText)
1080
+ throw new Error('commentText is required');
1081
+ const body = { comment_text: params.commentText };
1082
+ if (params.resolved !== undefined)
1083
+ body.resolved = params.resolved;
1084
+ const response = await axios.put(`${BASE_URL}/comment/${params.commentId}`, body, { headers: headers() });
1085
+ return response.data;
1086
+ }
1087
+ async function deleteComment(params) {
1088
+ if (!params.commentId)
1089
+ throw new Error('commentId is required');
1090
+ const response = await axios.delete(`${BASE_URL}/comment/${params.commentId}`, { headers: headers() });
1091
+ return response.data;
1092
+ }
1093
+ // CHECKLISTS
1094
+ async function createChecklist(params) {
1095
+ const taskId = await resolveTaskId(params);
1096
+ if (!params.name)
1097
+ throw new Error('name is required');
1098
+ const response = await axios.post(`${BASE_URL}/task/${taskId}/checklist`, {
1099
+ name: params.name,
1100
+ }, { headers: headers() });
1101
+ return response.data;
1102
+ }
1103
+ async function updateChecklist(params) {
1104
+ if (!params.checklistId)
1105
+ throw new Error('checklistId is required');
1106
+ const body = {};
1107
+ if (params.name)
1108
+ body.name = params.name;
1109
+ if (params.position !== undefined)
1110
+ body.position = params.position;
1111
+ const response = await axios.put(`${BASE_URL}/checklist/${params.checklistId}`, body, { headers: headers() });
1112
+ return response.data;
1113
+ }
1114
+ async function deleteChecklist(params) {
1115
+ if (!params.checklistId)
1116
+ throw new Error('checklistId is required');
1117
+ const response = await axios.delete(`${BASE_URL}/checklist/${params.checklistId}`, { headers: headers() });
1118
+ return response.data;
1119
+ }
1120
+ async function createChecklistItem(params) {
1121
+ if (!params.checklistId)
1122
+ throw new Error('checklistId is required');
1123
+ if (!params.name)
1124
+ throw new Error('name is required');
1125
+ const body = { name: params.name };
1126
+ if (params.assignee)
1127
+ body.assignee = params.assignee;
1128
+ const response = await axios.post(`${BASE_URL}/checklist/${params.checklistId}/checklist_item`, body, { headers: headers() });
1129
+ return response.data;
1130
+ }
1131
+ async function updateChecklistItem(params) {
1132
+ if (!params.checklistId)
1133
+ throw new Error('checklistId is required');
1134
+ if (!params.checklistItemId)
1135
+ throw new Error('checklistItemId is required');
1136
+ const body = {};
1137
+ if (params.name)
1138
+ body.name = params.name;
1139
+ if (params.resolved !== undefined)
1140
+ body.resolved = params.resolved;
1141
+ if (params.assignee)
1142
+ body.assignee = params.assignee;
1143
+ const response = await axios.put(`${BASE_URL}/checklist/${params.checklistId}/checklist_item/${params.checklistItemId}`, body, { headers: headers() });
1144
+ return response.data;
1145
+ }
1146
+ async function deleteChecklistItem(params) {
1147
+ if (!params.checklistId)
1148
+ throw new Error('checklistId is required');
1149
+ if (!params.checklistItemId)
1150
+ throw new Error('checklistItemId is required');
1151
+ const response = await axios.delete(`${BASE_URL}/checklist/${params.checklistId}/checklist_item/${params.checklistItemId}`, { headers: headers() });
1152
+ return response.data;
1153
+ }
1154
+ // TIME TRACKING
1155
+ async function getTaskTimeEntries(params) {
1156
+ const taskId = await resolveTaskId(params);
1157
+ const response = await axios.get(`${BASE_URL}/task/${taskId}/time`, { headers: headers() });
1158
+ return response.data;
1159
+ }
1160
+ async function createTimeEntry(params) {
1161
+ const taskId = await resolveTaskId(params);
1162
+ if (!params.start)
1163
+ throw new Error('start is required');
1164
+ if (!params.duration)
1165
+ throw new Error('duration is required');
1166
+ const body = {
1167
+ start: params.start,
1168
+ duration: params.duration,
1169
+ tid: taskId,
1170
+ };
1171
+ if (params.description)
1172
+ body.description = params.description;
1173
+ if (params.billable !== undefined)
1174
+ body.billable = params.billable;
1175
+ const response = await axios.post(`${BASE_URL}/team/${CLICKUP_TEAM_ID}/time_entries`, body, { headers: headers() });
1176
+ return response.data;
1177
+ }
1178
+ async function startTimeEntry(params) {
1179
+ const taskId = await resolveTaskId(params);
1180
+ const body = { tid: taskId };
1181
+ if (params.description)
1182
+ body.description = params.description;
1183
+ if (params.billable !== undefined)
1184
+ body.billable = params.billable;
1185
+ const response = await axios.post(`${BASE_URL}/team/${CLICKUP_TEAM_ID}/time_entries/start`, body, { headers: headers() });
1186
+ return response.data;
1187
+ }
1188
+ async function stopTimeEntry() {
1189
+ const response = await axios.post(`${BASE_URL}/team/${CLICKUP_TEAM_ID}/time_entries/stop`, {}, { headers: headers() });
1190
+ return response.data;
1191
+ }
1192
+ async function getRunningTimeEntry() {
1193
+ const response = await axios.get(`${BASE_URL}/team/${CLICKUP_TEAM_ID}/time_entries/current`, { headers: headers() });
1194
+ return response.data;
1195
+ }
1196
+ async function deleteTimeEntry(params) {
1197
+ if (!params.timeEntryId)
1198
+ throw new Error('timeEntryId is required');
1199
+ const response = await axios.delete(`${BASE_URL}/team/${CLICKUP_TEAM_ID}/time_entries/${params.timeEntryId}`, { headers: headers() });
1200
+ return response.data;
1201
+ }
1202
+ // DEPENDENCIES
1203
+ async function addTaskDependency(params) {
1204
+ if (!params.taskId)
1205
+ throw new Error('taskId is required');
1206
+ if (!params.dependsOnTaskId)
1207
+ throw new Error('dependsOnTaskId is required');
1208
+ const response = await axios.post(`${BASE_URL}/task/${params.taskId}/dependency`, {
1209
+ depends_on: params.dependsOnTaskId,
1210
+ }, { headers: headers() });
1211
+ return response.data;
1212
+ }
1213
+ async function deleteTaskDependency(params) {
1214
+ if (!params.taskId)
1215
+ throw new Error('taskId is required');
1216
+ if (!params.dependsOnTaskId)
1217
+ throw new Error('dependsOnTaskId is required');
1218
+ const response = await axios.delete(`${BASE_URL}/task/${params.taskId}/dependency`, {
1219
+ headers: headers(),
1220
+ params: { depends_on: params.dependsOnTaskId },
1221
+ });
1222
+ return response.data;
1223
+ }
1224
+ async function addTaskLink(params) {
1225
+ if (!params.taskId)
1226
+ throw new Error('taskId is required');
1227
+ if (!params.linksToTaskId)
1228
+ throw new Error('linksToTaskId is required');
1229
+ const response = await axios.post(`${BASE_URL}/task/${params.taskId}/link/${params.linksToTaskId}`, {}, { headers: headers() });
1230
+ return response.data;
1231
+ }
1232
+ async function deleteTaskLink(params) {
1233
+ if (!params.taskId)
1234
+ throw new Error('taskId is required');
1235
+ if (!params.linksToTaskId)
1236
+ throw new Error('linksToTaskId is required');
1237
+ const response = await axios.delete(`${BASE_URL}/task/${params.taskId}/link/${params.linksToTaskId}`, { headers: headers() });
1238
+ return response.data;
1239
+ }
1240
+ // TAGS
1241
+ async function getSpaceTags(params) {
1242
+ const spaceId = await resolveSpaceId(params);
1243
+ const response = await axios.get(`${BASE_URL}/space/${spaceId}/tag`, { headers: headers() });
1244
+ return response.data;
1245
+ }
1246
+ async function createTag(params) {
1247
+ const spaceId = await resolveSpaceId(params);
1248
+ if (!params.name)
1249
+ throw new Error('name is required');
1250
+ const body = { tag: { name: params.name } };
1251
+ if (params.bgColor)
1252
+ body.tag.tag_bg = params.bgColor;
1253
+ const response = await axios.post(`${BASE_URL}/space/${spaceId}/tag`, body, { headers: headers() });
1254
+ return response.data;
1255
+ }
1256
+ async function updateTag(params) {
1257
+ const spaceId = await resolveSpaceId(params);
1258
+ if (!params.tagName)
1259
+ throw new Error('tagName is required');
1260
+ const body = { tag: {} };
1261
+ if (params.newName)
1262
+ body.tag.name = params.newName;
1263
+ if (params.bgColor)
1264
+ body.tag.tag_bg = params.bgColor;
1265
+ const response = await axios.put(`${BASE_URL}/space/${spaceId}/tag/${params.tagName}`, body, { headers: headers() });
1266
+ return response.data;
1267
+ }
1268
+ async function deleteTag(params) {
1269
+ const spaceId = await resolveSpaceId(params);
1270
+ if (!params.tagName)
1271
+ throw new Error('tagName is required');
1272
+ const response = await axios.delete(`${BASE_URL}/space/${spaceId}/tag/${params.tagName}`, { headers: headers() });
1273
+ return response.data;
1274
+ }
1275
+ async function addTagToTask(params) {
1276
+ const taskId = await resolveTaskId(params);
1277
+ if (!params.tagName)
1278
+ throw new Error('tagName is required');
1279
+ const response = await axios.post(`${BASE_URL}/task/${taskId}/tag/${params.tagName}`, {}, { headers: headers() });
1280
+ return response.data;
1281
+ }
1282
+ async function removeTagFromTask(params) {
1283
+ const taskId = await resolveTaskId(params);
1284
+ if (!params.tagName)
1285
+ throw new Error('tagName is required');
1286
+ const response = await axios.delete(`${BASE_URL}/task/${taskId}/tag/${params.tagName}`, { headers: headers() });
1287
+ return response.data;
1288
+ }
1289
+ // CUSTOM FIELDS
1290
+ async function getCustomFields(params) {
1291
+ const listId = await resolveListId(params);
1292
+ const response = await axios.get(`${BASE_URL}/list/${listId}/field`, { headers: headers() });
1293
+ return response.data;
1294
+ }
1295
+ async function setCustomFieldValue(params) {
1296
+ if (!params.taskId)
1297
+ throw new Error('taskId is required');
1298
+ if (!params.fieldId)
1299
+ throw new Error('fieldId is required');
1300
+ if (params.value === undefined)
1301
+ throw new Error('value is required');
1302
+ const response = await axios.post(`${BASE_URL}/task/${params.taskId}/field/${params.fieldId}`, { value: params.value }, { headers: headers() });
1303
+ return response.data;
1304
+ }
1305
+ async function removeCustomFieldValue(params) {
1306
+ if (!params.taskId)
1307
+ throw new Error('taskId is required');
1308
+ if (!params.fieldId)
1309
+ throw new Error('fieldId is required');
1310
+ const response = await axios.delete(`${BASE_URL}/task/${params.taskId}/field/${params.fieldId}`, { headers: headers() });
1311
+ return response.data;
1312
+ }
1313
+ // GOALS
1314
+ async function getGoals(params) {
1315
+ const response = await axios.get(`${BASE_URL}/team/${CLICKUP_TEAM_ID}/goal`, {
1316
+ headers: headers(),
1317
+ params: { include_completed: params.includeCompleted || false },
1318
+ });
1319
+ return response.data;
1320
+ }
1321
+ async function getGoal(params) {
1322
+ if (!params.goalId)
1323
+ throw new Error('goalId is required');
1324
+ const response = await axios.get(`${BASE_URL}/goal/${params.goalId}`, { headers: headers() });
1325
+ return response.data;
1326
+ }
1327
+ async function createGoal(params) {
1328
+ if (!params.name)
1329
+ throw new Error('name is required');
1330
+ const body = { name: params.name };
1331
+ if (params.dueDate)
1332
+ body.due_date = params.dueDate;
1333
+ if (params.description)
1334
+ body.description = params.description;
1335
+ if (params.color)
1336
+ body.color = params.color;
1337
+ const response = await axios.post(`${BASE_URL}/team/${CLICKUP_TEAM_ID}/goal`, body, { headers: headers() });
1338
+ return response.data;
1339
+ }
1340
+ async function updateGoal(params) {
1341
+ if (!params.goalId)
1342
+ throw new Error('goalId is required');
1343
+ const body = {};
1344
+ if (params.name)
1345
+ body.name = params.name;
1346
+ if (params.dueDate)
1347
+ body.due_date = params.dueDate;
1348
+ if (params.description)
1349
+ body.description = params.description;
1350
+ if (params.color)
1351
+ body.color = params.color;
1352
+ const response = await axios.put(`${BASE_URL}/goal/${params.goalId}`, body, { headers: headers() });
1353
+ return response.data;
1354
+ }
1355
+ async function deleteGoal(params) {
1356
+ if (!params.goalId)
1357
+ throw new Error('goalId is required');
1358
+ const response = await axios.delete(`${BASE_URL}/goal/${params.goalId}`, { headers: headers() });
1359
+ return response.data;
1360
+ }
1361
+ async function createKeyResult(params) {
1362
+ if (!params.goalId)
1363
+ throw new Error('goalId is required');
1364
+ if (!params.name)
1365
+ throw new Error('name is required');
1366
+ if (!params.type)
1367
+ throw new Error('type is required');
1368
+ const body = {
1369
+ name: params.name,
1370
+ type: params.type,
1371
+ };
1372
+ if (params.stepsStart !== undefined)
1373
+ body.steps_start = params.stepsStart;
1374
+ if (params.stepsEnd !== undefined)
1375
+ body.steps_end = params.stepsEnd;
1376
+ if (params.unit)
1377
+ body.unit = params.unit;
1378
+ if (params.taskIds)
1379
+ body.task_ids = params.taskIds;
1380
+ if (params.listIds)
1381
+ body.list_ids = params.listIds;
1382
+ const response = await axios.post(`${BASE_URL}/goal/${params.goalId}/key_result`, body, { headers: headers() });
1383
+ return response.data;
1384
+ }
1385
+ async function updateKeyResult(params) {
1386
+ if (!params.keyResultId)
1387
+ throw new Error('keyResultId is required');
1388
+ const body = {};
1389
+ if (params.stepsCurrent !== undefined)
1390
+ body.steps_current = params.stepsCurrent;
1391
+ if (params.note)
1392
+ body.note = params.note;
1393
+ const response = await axios.put(`${BASE_URL}/key_result/${params.keyResultId}`, body, { headers: headers() });
1394
+ return response.data;
1395
+ }
1396
+ async function deleteKeyResult(params) {
1397
+ if (!params.keyResultId)
1398
+ throw new Error('keyResultId is required');
1399
+ const response = await axios.delete(`${BASE_URL}/key_result/${params.keyResultId}`, { headers: headers() });
1400
+ return response.data;
1401
+ }
1402
+ // WEBHOOKS
1403
+ async function getWebhooks() {
1404
+ const response = await axios.get(`${BASE_URL}/team/${CLICKUP_TEAM_ID}/webhook`, { headers: headers() });
1405
+ return response.data;
1406
+ }
1407
+ async function createWebhook(params) {
1408
+ if (!params.endpoint)
1409
+ throw new Error('endpoint is required');
1410
+ if (!params.events)
1411
+ throw new Error('events is required');
1412
+ const body = {
1413
+ endpoint: params.endpoint,
1414
+ events: params.events,
1415
+ };
1416
+ if (params.spaceId)
1417
+ body.space_id = params.spaceId;
1418
+ if (params.folderId)
1419
+ body.folder_id = params.folderId;
1420
+ if (params.listId)
1421
+ body.list_id = params.listId;
1422
+ if (params.taskId)
1423
+ body.task_id = params.taskId;
1424
+ const response = await axios.post(`${BASE_URL}/team/${CLICKUP_TEAM_ID}/webhook`, body, { headers: headers() });
1425
+ return response.data;
1426
+ }
1427
+ async function updateWebhook(params) {
1428
+ if (!params.webhookId)
1429
+ throw new Error('webhookId is required');
1430
+ const body = {};
1431
+ if (params.endpoint)
1432
+ body.endpoint = params.endpoint;
1433
+ if (params.events)
1434
+ body.events = params.events;
1435
+ if (params.status)
1436
+ body.status = params.status;
1437
+ const response = await axios.put(`${BASE_URL}/webhook/${params.webhookId}`, body, { headers: headers() });
1438
+ return response.data;
1439
+ }
1440
+ async function deleteWebhook(params) {
1441
+ if (!params.webhookId)
1442
+ throw new Error('webhookId is required');
1443
+ const response = await axios.delete(`${BASE_URL}/webhook/${params.webhookId}`, { headers: headers() });
1444
+ return response.data;
1445
+ }
1446
+ // ===================
1447
+ // BACKEND EXPORT
1448
+ // ===================
1449
+ export const clickupBackend = {
1450
+ name: 'clickup',
1451
+ description: 'ClickUp project management: tasks, lists, folders, spaces, goals, time tracking, checklists, custom fields, and webhooks. Comprehensive API for full ClickUp automation.',
1452
+ actions,
1453
+ async execute(action, params) {
1454
+ switch (action) {
1455
+ // Workspace
1456
+ case 'get_workspace_hierarchy': return getWorkspaceHierarchy();
1457
+ case 'get_workspace_members': return getWorkspaceMembers();
1458
+ case 'find_member_by_name': return findMemberByName(params);
1459
+ // Spaces
1460
+ case 'get_spaces': return getSpaces(params);
1461
+ case 'get_space': return getSpace(params);
1462
+ case 'create_space': return createSpace(params);
1463
+ case 'update_space': return updateSpace(params);
1464
+ case 'delete_space': return deleteSpace(params);
1465
+ // Folders
1466
+ case 'create_folder': return createFolder(params);
1467
+ case 'get_folder': return getFolder(params);
1468
+ case 'update_folder': return updateFolder(params);
1469
+ case 'delete_folder': return deleteFolder(params);
1470
+ // Lists
1471
+ case 'create_list': return createList(params);
1472
+ case 'get_list': return getList(params);
1473
+ case 'update_list': return updateList(params);
1474
+ case 'delete_list': return deleteList(params);
1475
+ // Tasks
1476
+ case 'list_tasks': return listTasks(params);
1477
+ case 'search_tasks': return searchTasks(params);
1478
+ case 'get_my_tasks': return getMyTasks(params);
1479
+ case 'create_task': return createTask(params);
1480
+ case 'get_task': return getTask(params);
1481
+ case 'update_task': return updateTask(params);
1482
+ case 'delete_task': return deleteTask(params);
1483
+ // Comments
1484
+ case 'get_task_comments': return getTaskComments(params);
1485
+ case 'create_task_comment': return createTaskComment(params);
1486
+ case 'update_comment': return updateComment(params);
1487
+ case 'delete_comment': return deleteComment(params);
1488
+ // Checklists
1489
+ case 'create_checklist': return createChecklist(params);
1490
+ case 'update_checklist': return updateChecklist(params);
1491
+ case 'delete_checklist': return deleteChecklist(params);
1492
+ case 'create_checklist_item': return createChecklistItem(params);
1493
+ case 'update_checklist_item': return updateChecklistItem(params);
1494
+ case 'delete_checklist_item': return deleteChecklistItem(params);
1495
+ // Time Tracking
1496
+ case 'get_task_time_entries': return getTaskTimeEntries(params);
1497
+ case 'create_time_entry': return createTimeEntry(params);
1498
+ case 'start_time_entry': return startTimeEntry(params);
1499
+ case 'stop_time_entry': return stopTimeEntry();
1500
+ case 'get_running_time_entry': return getRunningTimeEntry();
1501
+ case 'delete_time_entry': return deleteTimeEntry(params);
1502
+ // Dependencies
1503
+ case 'add_task_dependency': return addTaskDependency(params);
1504
+ case 'delete_task_dependency': return deleteTaskDependency(params);
1505
+ case 'add_task_link': return addTaskLink(params);
1506
+ case 'delete_task_link': return deleteTaskLink(params);
1507
+ // Tags
1508
+ case 'get_space_tags': return getSpaceTags(params);
1509
+ case 'create_tag': return createTag(params);
1510
+ case 'update_tag': return updateTag(params);
1511
+ case 'delete_tag': return deleteTag(params);
1512
+ case 'add_tag_to_task': return addTagToTask(params);
1513
+ case 'remove_tag_from_task': return removeTagFromTask(params);
1514
+ // Custom Fields
1515
+ case 'get_custom_fields': return getCustomFields(params);
1516
+ case 'set_custom_field_value': return setCustomFieldValue(params);
1517
+ case 'remove_custom_field_value': return removeCustomFieldValue(params);
1518
+ // Goals
1519
+ case 'get_goals': return getGoals(params);
1520
+ case 'get_goal': return getGoal(params);
1521
+ case 'create_goal': return createGoal(params);
1522
+ case 'update_goal': return updateGoal(params);
1523
+ case 'delete_goal': return deleteGoal(params);
1524
+ case 'create_key_result': return createKeyResult(params);
1525
+ case 'update_key_result': return updateKeyResult(params);
1526
+ case 'delete_key_result': return deleteKeyResult(params);
1527
+ // Webhooks
1528
+ case 'get_webhooks': return getWebhooks();
1529
+ case 'create_webhook': return createWebhook(params);
1530
+ case 'update_webhook': return updateWebhook(params);
1531
+ case 'delete_webhook': return deleteWebhook(params);
1532
+ default:
1533
+ throw new Error(`Unknown action: ${action}`);
1534
+ }
1535
+ },
1536
+ async healthCheck() {
1537
+ if (!CLICKUP_API_KEY || !CLICKUP_TEAM_ID) {
1538
+ return { status: 'unavailable', latency_ms: 0, error: 'ClickUp credentials not configured' };
1539
+ }
1540
+ try {
1541
+ const start = Date.now();
1542
+ await axios.get(`${BASE_URL}/team/${CLICKUP_TEAM_ID}`, { headers: headers() });
1543
+ return { status: 'healthy', latency_ms: Date.now() - start };
1544
+ }
1545
+ catch (error) {
1546
+ return { status: 'unavailable', latency_ms: 0, error: error instanceof Error ? error.message : String(error) };
1547
+ }
1548
+ },
1549
+ };
1550
+ //# sourceMappingURL=clickup.js.map