From c5221173d5658cfff7b36c66c3efaf806126e61d Mon Sep 17 00:00:00 2001 From: Esteban-Rod Date: Wed, 29 Apr 2026 10:43:00 -0500 Subject: [PATCH 1/2] Fix create_list_from_template URL path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The two methods `createListFromTemplateInFolder` and `createListFromTemplateInSpace` in `src/clickup-client/lists.ts` were calling `/folder/{id}/list/template/{templateId}` and `/space/{id}/list/template/{templateId}`, which return HTTP 404. The ClickUp REST API actually expects `/list_template/{templateId}` (underscore) per the official endpoints: - https://developer.clickup.com/reference/createlistfromtemplate - https://developer.clickup.com/reference/createlistfromtemplateinspace Replacing `list/template` with `list_template` makes the two MCP tools work as documented. Verified locally against a real workspace by building and invoking the server in stdio mode — the list is now created with the template's statuses, custom fields, milestones and sub-tasks intact. --- CHANGELOG.md | 1 + src/clickup-client/lists.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca1ced4..cbdb29b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed ### Fixed +- Fixed `create_list_from_template_in_folder` and `create_list_from_template_in_space` returning HTTP 404. The URL path used `/list/template/{templateId}` (with a slash) instead of `/list_template/{templateId}` (with an underscore), which is what the ClickUp API expects per the [createListFromTemplate](https://developer.clickup.com/reference/createlistfromtemplate) and [createListFromTemplateInSpace](https://developer.clickup.com/reference/createlistfromtemplateinspace) endpoints. ## [1.12.0] - 2025-04-14 diff --git a/src/clickup-client/lists.ts b/src/clickup-client/lists.ts index 46537b5..ef23599 100644 --- a/src/clickup-client/lists.ts +++ b/src/clickup-client/lists.ts @@ -123,7 +123,7 @@ export class ListsClient { * @returns The created list */ async createListFromTemplateInFolder(folderId: string, templateId: string, params: CreateListParams): Promise { - return this.client.post(`/folder/${folderId}/list/template/${templateId}`, params); + return this.client.post(`/folder/${folderId}/list_template/${templateId}`, params); } /** @@ -134,7 +134,7 @@ export class ListsClient { * @returns The created list */ async createListFromTemplateInSpace(spaceId: string, templateId: string, params: CreateListParams): Promise { - return this.client.post(`/space/${spaceId}/list/template/${templateId}`, params); + return this.client.post(`/space/${spaceId}/list_template/${templateId}`, params); } } From 9db3cec07115a47127193f51452fc40937f4ba4c Mon Sep 17 00:00:00 2001 From: Esteban-Rod Date: Wed, 29 Apr 2026 16:33:19 -0500 Subject: [PATCH 2/2] fix(create_list_from_template): refetch to drop spurious deleted:true MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ClickUp's POST /folder/{id}/list_template/{tid} (and the space variant) returns the freshly created list with deleted:true — an artefact of how the API serializes the just-spawned record. A refetch via getList shows deleted:false. Rather than expose this footgun to callers, the client now refetches the list immediately after creation and falls back to the raw response only if the refetch fails. --- src/clickup-client/lists.ts | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/clickup-client/lists.ts b/src/clickup-client/lists.ts index ef23599..7bd703a 100644 --- a/src/clickup-client/lists.ts +++ b/src/clickup-client/lists.ts @@ -116,25 +116,45 @@ export class ListsClient { } /** - * Create a new list from a template in a folder + * Create a new list from a template in a folder. + * The POST response from ClickUp returns `deleted: true` as an artefact — + * we refetch the list immediately to return its real state. * @param folderId The ID of the folder to create the list in * @param templateId The ID of the template to use * @param params The list parameters - * @returns The created list + * @returns The created list with real (post-creation) state */ async createListFromTemplateInFolder(folderId: string, templateId: string, params: CreateListParams): Promise { - return this.client.post(`/folder/${folderId}/list_template/${templateId}`, params); + const created = await this.client.post(`/folder/${folderId}/list_template/${templateId}`, params); + if (created?.id) { + try { + return await this.getList(created.id); + } catch { + return created; + } + } + return created; } /** - * Create a new list from a template in a space + * Create a new list from a template in a space. + * The POST response from ClickUp returns `deleted: true` as an artefact — + * we refetch the list immediately to return its real state. * @param spaceId The ID of the space to create the list in * @param templateId The ID of the template to use * @param params The list parameters - * @returns The created list + * @returns The created list with real (post-creation) state */ async createListFromTemplateInSpace(spaceId: string, templateId: string, params: CreateListParams): Promise { - return this.client.post(`/space/${spaceId}/list_template/${templateId}`, params); + const created = await this.client.post(`/space/${spaceId}/list_template/${templateId}`, params); + if (created?.id) { + try { + return await this.getList(created.id); + } catch { + return created; + } + } + return created; } }