@sebastienheyd/clickup-mcp 1.7.2 → 1.7.3

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.
@@ -1,7 +1,8 @@
1
1
  import Fuse from 'fuse.js';
2
2
  /**
3
3
  * Checks if a string looks like a valid ClickUp task ID
4
- * Valid task IDs are 6-9 characters long and contain only alphanumeric characters
4
+ * Valid task IDs are at least 6 characters long and contain only alphanumeric characters.
5
+ * No upper bound: ClickUp now issues IDs of 10+ characters (e.g. "wdrv93ebwx").
5
6
  */
6
7
  export declare function isTaskId(str: string): boolean;
7
8
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/shared/utils.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,SAAS,CAAC;AAI3B;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAG7C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAiB3E;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ/D;AAKD;;;GAGG;AACH,wBAAsB,cAAc,iBA6BnC;AAGD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAIpD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CA8C/D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,GAAG,GAAG,MAAM,CA+CpD;AAID;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CA0B7D;AAKD;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,CAAC,EAAE,MAAM,EAAE,EACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,EACnB,SAAS,CAAC,EAAE,MAAM,EAAE,EACpB,cAAc,CAAC,EAAE,OAAO,EACxB,QAAQ,CAAC,EAAE,OAAO,GACjB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAiC3B;AA2ED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAK1E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,MAAM,CA4ElG;AAKD;;;GAGG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CA+CrE;AAKD;;GAEG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IAAC,OAAO,EAAE,GAAG,EAAE,CAAC;IAAC,SAAS,EAAE,GAAG,EAAE,CAAA;CAAE,CAAC,CAgFlH;AAKD;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CA+C3D;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,CAAC,EAC5C,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,EACpB,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,CAAC,EAAE,CAAC,CA8Dd"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/shared/utils.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,SAAS,CAAC;AAI3B;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAG7C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAiB3E;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ/D;AAKD;;;GAGG;AACH,wBAAsB,cAAc,iBA6BnC;AAGD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAIpD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CA8C/D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,GAAG,GAAG,MAAM,CA+CpD;AAID;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CA0B7D;AAKD;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,CAAC,EAAE,MAAM,EAAE,EACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,EACnB,SAAS,CAAC,EAAE,MAAM,EAAE,EACpB,cAAc,CAAC,EAAE,OAAO,EACxB,QAAQ,CAAC,EAAE,OAAO,GACjB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAiC3B;AA2ED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAK1E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,MAAM,CA4ElG;AAKD;;;GAGG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CA+CrE;AAKD;;GAEG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IAAC,OAAO,EAAE,GAAG,EAAE,CAAC;IAAC,SAAS,EAAE,GAAG,EAAE,CAAA;CAAE,CAAC,CAgFlH;AAKD;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CA+C3D;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,CAAC,EAC5C,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,EACpB,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,CAAC,EAAE,CAAC,CA8Dd"}
@@ -28,11 +28,12 @@ const fuse_js_1 = __importDefault(require("fuse.js"));
28
28
  const GLOBAL_REFRESH_INTERVAL = 60000; // 60 seconds - that is the rate limit time frame
29
29
  /**
30
30
  * Checks if a string looks like a valid ClickUp task ID
31
- * Valid task IDs are 6-9 characters long and contain only alphanumeric characters
31
+ * Valid task IDs are at least 6 characters long and contain only alphanumeric characters.
32
+ * No upper bound: ClickUp now issues IDs of 10+ characters (e.g. "wdrv93ebwx").
32
33
  */
33
34
  function isTaskId(str) {
34
- // Task IDs are 6-9 characters long and contain only alphanumeric characters
35
- return /^[a-z0-9]{6,9}$/i.test(str);
35
+ // Task IDs are 6+ characters long and contain only alphanumeric characters
36
+ return /^[a-z0-9]{6,}$/i.test(str);
36
37
  }
37
38
  /**
38
39
  * Checks if a string looks like a ClickUp custom task ID (e.g. "SOI-4422", "PQP-123")
@@ -67,7 +68,7 @@ async function resolveTaskId(id) {
67
68
  if (isCustomTaskId(id)) {
68
69
  return resolveCustomTaskId(id);
69
70
  }
70
- throw new Error(`Invalid task ID format: "${id}". Expected an internal ID (6-9 alphanumeric characters) or a custom ID (e.g. "SOI-4422").`);
71
+ throw new Error(`Invalid task ID format: "${id}". Expected an internal ID (6+ alphanumeric characters) or a custom ID (e.g. "SOI-4422").`);
71
72
  }
72
73
  // Cache for current user info to avoid repeated API calls and race conditions
73
74
  let cachedUserPromise = null;
@@ -20,9 +20,9 @@ function registerTaskToolsRead(server, userData) {
20
20
  .string()
21
21
  .min(1)
22
22
  .refine(val => (0, utils_1.isTaskId)(val) || (0, utils_1.isCustomTaskId)(val), {
23
- message: "Must be an internal task ID (6-9 alphanumeric characters) or a custom task ID (e.g. SOI-4422)"
23
+ message: "Must be an internal task ID (6+ alphanumeric characters) or a custom task ID (e.g. SOI-4422)"
24
24
  })
25
- .describe(`The task ID: either an internal ID (6-9 alphanumeric characters like "869c4za0g") or a custom task ID (e.g. "SOI-4422"). Do not include prefixes like "#", "CU-" or URLs.`),
25
+ .describe(`The task ID: either an internal ID (6+ alphanumeric characters like "869c4za0g") or a custom task ID (e.g. "SOI-4422"). Do not include prefixes like "#", "CU-" or URLs.`),
26
26
  }, {
27
27
  readOnlyHint: true
28
28
  }, async ({ id }) => {
@@ -32,7 +32,7 @@ function registerTaskToolsWrite(server, userData) {
32
32
  return descriptionBase.join("\n");
33
33
  })(), {
34
34
  task_id: zod_1.z.string().min(1).refine(val => (0, utils_1.isTaskId)(val) || (0, utils_1.isCustomTaskId)(val), {
35
- message: "Must be an internal task ID (6-9 alphanumeric characters) or a custom task ID (e.g. SOI-4422)"
35
+ message: "Must be an internal task ID (6+ alphanumeric characters) or a custom task ID (e.g. SOI-4422)"
36
36
  }).describe("The task ID to comment on: internal ID (e.g. \"869c4za0g\") or custom ID (e.g. \"SOI-4422\")"),
37
37
  comment: zod_1.z.string().min(1).describe("The comment text to add to the task"),
38
38
  }, {
@@ -108,7 +108,7 @@ function registerTaskToolsWrite(server, userData) {
108
108
  return descriptionBase.join("\n");
109
109
  })(), {
110
110
  task_id: zod_1.z.string().min(1).refine(val => (0, utils_1.isTaskId)(val) || (0, utils_1.isCustomTaskId)(val), {
111
- message: "Must be an internal task ID (6-9 alphanumeric characters) or a custom task ID (e.g. SOI-4422)"
111
+ message: "Must be an internal task ID (6+ alphanumeric characters) or a custom task ID (e.g. SOI-4422)"
112
112
  }).describe("The task ID to update: internal ID (e.g. \"869c4za0g\") or custom ID (e.g. \"SOI-4422\")"),
113
113
  name: taskNameSchema.optional(),
114
114
  append_description: zod_1.z.string().optional().describe("Optional markdown content to APPEND to existing task description (preserves existing content for safety)"),
@@ -1 +1 @@
1
- {"version":3,"file":"time-tools.d.ts","sourceRoot":"","sources":["../../src/tools/time-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAyDpE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,QAmFtD;AAyLD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,QA2FvD"}
1
+ {"version":3,"file":"time-tools.d.ts","sourceRoot":"","sources":["../../src/tools/time-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAyDpE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,QAqFtD;AAyLD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,QAgGvD"}
@@ -54,7 +54,9 @@ function registerTimeToolsRead(server) {
54
54
  // Workaround: SDK 1.27+ dual Zod v3/v4 type causes TS2589 on server.tool() generics
55
55
  const tool = server.tool.bind(server);
56
56
  tool("getTimeEntries", "Gets time entries for a specific task or all user's time entries. Returns last 30 days by default if no dates specified.", {
57
- task_id: zod_1.z.string().min(6).max(9).optional().describe("Optional 6-9 character task ID to filter entries. If not provided, returns all user's time entries."),
57
+ task_id: zod_1.z.string().min(1).refine(val => (0, utils_1.isTaskId)(val) || (0, utils_1.isCustomTaskId)(val), {
58
+ message: "Must be an internal task ID (6+ alphanumeric characters) or a custom task ID (e.g. SOI-4422)"
59
+ }).optional().describe("Optional task ID to filter entries: internal ID (e.g. \"869c4za0g\") or custom ID (e.g. \"SOI-4422\"). If not provided, returns all user's time entries."),
58
60
  start_date: zod_1.z.string().optional().describe("Optional start date filter as ISO date string (e.g., '2024-10-06T00:00:00+02:00'). Defaults to 30 days ago."),
59
61
  end_date: zod_1.z.string().optional().describe("Optional end date filter as ISO date string (e.g., '2024-10-06T23:59:59+02:00'). Defaults to current date."),
60
62
  list_id: zod_1.z.string().optional().describe("Optional single list ID to filter time entries by a specific list"),
@@ -67,7 +69,7 @@ function registerTimeToolsRead(server) {
67
69
  // Build query parameters
68
70
  const params = new URLSearchParams();
69
71
  if (task_id) {
70
- params.append('task_id', task_id);
72
+ params.append('task_id', await (0, utils_1.resolveTaskId)(task_id));
71
73
  }
72
74
  if (start_date) {
73
75
  params.append('start_date', isoToTimestamp(start_date).toString());
@@ -271,7 +273,9 @@ function registerTimeToolsWrite(server) {
271
273
  "IMPORTANT: Before booking time, check the task's status - booking time on tasks in 'backlog', 'closed', or similar inactive states usually doesn't make sense.",
272
274
  "Suggest moving the task to an active status like 'in progress' first."
273
275
  ].join("\n"), {
274
- task_id: zod_1.z.string().min(6).max(9).describe("The 6-9 character task ID to book time against"),
276
+ task_id: zod_1.z.string().min(1).refine(val => (0, utils_1.isTaskId)(val) || (0, utils_1.isCustomTaskId)(val), {
277
+ message: "Must be an internal task ID (6+ alphanumeric characters) or a custom task ID (e.g. SOI-4422)"
278
+ }).describe("The task ID to book time against: internal ID (e.g. \"869c4za0g\") or custom ID (e.g. \"SOI-4422\")"),
275
279
  hours: zod_1.z.number().min(0.01).max(24).describe("Hours to book (decimal format, e.g., 0.25 = 15min, 1.5 = 1h 30min)"),
276
280
  description: zod_1.z.string().optional().describe("Optional description for the time entry"),
277
281
  start_time: zod_1.z.string().optional().describe("Optional start time as ISO date string (e.g., '2024-10-06T09:00:00+02:00', defaults to current time)")
@@ -285,8 +289,10 @@ function registerTimeToolsWrite(server) {
285
289
  const durationMs = Math.round(hours * 60 * 60 * 1000);
286
290
  // Convert ISO date to timestamp if provided, otherwise use current time
287
291
  const startTimeMs = start_time ? isoToTimestamp(start_time) : Date.now();
292
+ // Resolve custom task IDs (e.g. "SOI-4422") to internal IDs before booking
293
+ const resolved_task_id = await (0, utils_1.resolveTaskId)(task_id);
288
294
  const requestBody = {
289
- tid: task_id,
295
+ tid: resolved_task_id,
290
296
  start: startTimeMs,
291
297
  duration: durationMs,
292
298
  ...(description && { description })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sebastienheyd/clickup-mcp",
3
- "version": "1.7.2",
3
+ "version": "1.7.3",
4
4
  "description": "Search, create, and retrieve tasks, add comments, and track time through natural language commands.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -58,7 +58,7 @@
58
58
  "undici": "^7.16.0"
59
59
  },
60
60
  "engines": {
61
- "node": ">=16.0.0"
61
+ "node": ">=20.0.0"
62
62
  },
63
63
  "repository": {
64
64
  "type": "git",