ClickUp MCP Server
by windalfin
Verified
/**
* ClickUp List Service
*
* Handles all operations related to lists in ClickUp, including:
* - Creating lists
* - Retrieving lists
* - Updating lists
* - Deleting lists
* - Finding lists by name
*/
import { AxiosError } from 'axios';
import { BaseClickUpService, ErrorCode, ClickUpServiceError, ServiceResponse } from './base.js';
import {
ClickUpList,
ClickUpTask,
CreateListData
} from './types.js';
import { WorkspaceService } from './workspace.js';
export class ListService extends BaseClickUpService {
private workspaceService: WorkspaceService | null = null;
constructor(apiKey: string, teamId: string, baseUrl?: string, workspaceService?: WorkspaceService) {
super(apiKey, teamId, baseUrl);
this.workspaceService = workspaceService || null;
}
/**
* Helper method to handle errors consistently
* @param error The error that occurred
* @param message Optional custom error message
* @returns A ClickUpServiceError
*/
private handleError(error: any, message?: string): ClickUpServiceError {
if (error instanceof ClickUpServiceError) {
return error;
}
return new ClickUpServiceError(
message || `List service error: ${error.message}`,
ErrorCode.UNKNOWN,
error
);
}
/**
* Create a new list in a space
* @param spaceId The ID of the space to create the list in
* @param listData The data for the new list
* @returns The created list
*/
async createList(spaceId: string, listData: CreateListData): Promise<ClickUpList> {
this.logOperation('createList', { spaceId, ...listData });
try {
return await this.makeRequest(async () => {
const response = await this.client.post<ClickUpList>(
`/space/${spaceId}/list`,
listData
);
return response.data;
});
} catch (error) {
throw this.handleError(error, `Failed to create list in space ${spaceId}`);
}
}
/**
* Create a new list in a folder
* @param folderId The ID of the folder to create the list in
* @param listData The data for the new list
* @returns The created list
*/
async createListInFolder(folderId: string, listData: CreateListData): Promise<ClickUpList> {
this.logOperation('createListInFolder', { folderId, ...listData });
try {
return await this.makeRequest(async () => {
const response = await this.client.post<ClickUpList>(
`/folder/${folderId}/list`,
listData
);
return response.data;
});
} catch (error) {
throw this.handleError(error, `Failed to create list in folder ${folderId}`);
}
}
/**
* Get a list by ID
* @param listId The ID of the list to retrieve
* @returns The requested list
*/
async getList(listId: string): Promise<ClickUpList> {
this.logOperation('getList', { listId });
try {
return await this.makeRequest(async () => {
const response = await this.client.get<ClickUpList>(`/list/${listId}`);
return response.data;
});
} catch (error) {
throw this.handleError(error, `Failed to get list ${listId}`);
}
}
/**
* Update an existing list
* @param listId The ID of the list to update
* @param updateData The data to update on the list
* @returns The updated list
*/
async updateList(listId: string, updateData: Partial<CreateListData>): Promise<ClickUpList> {
this.logOperation('updateList', { listId, ...updateData });
try {
return await this.makeRequest(async () => {
const response = await this.client.put<ClickUpList>(
`/list/${listId}`,
updateData
);
return response.data;
});
} catch (error) {
throw this.handleError(error, `Failed to update list ${listId}`);
}
}
/**
* Delete a list
* @param listId The ID of the list to delete
* @returns Success indicator
*/
async deleteList(listId: string): Promise<ServiceResponse<void>> {
this.logOperation('deleteList', { listId });
try {
await this.makeRequest(async () => {
await this.client.delete(`/list/${listId}`);
});
return {
success: true
};
} catch (error) {
throw this.handleError(error, `Failed to delete list ${listId}`);
}
}
/**
* Get all lists in a space
* @param spaceId The ID of the space to get lists from
* @returns Array of lists in the space
*/
async getListsInSpace(spaceId: string): Promise<ClickUpList[]> {
this.logOperation('getListsInSpace', { spaceId });
try {
return await this.makeRequest(async () => {
const response = await this.client.get<{ lists: ClickUpList[] }>(
`/space/${spaceId}/list`
);
return response.data.lists;
});
} catch (error) {
throw this.handleError(error, `Failed to get lists in space ${spaceId}`);
}
}
/**
* Get all lists in a folder
* @param folderId The ID of the folder to get lists from
* @returns Array of lists in the folder
*/
async getListsInFolder(folderId: string): Promise<ClickUpList[]> {
this.logOperation('getListsInFolder', { folderId });
try {
return await this.makeRequest(async () => {
const response = await this.client.get<{ lists: ClickUpList[] }>(
`/folder/${folderId}/list`
);
return response.data.lists;
});
} catch (error) {
throw this.handleError(error, `Failed to get lists in folder ${folderId}`);
}
}
/**
* Find a list by its name in a space
* @param spaceId The ID of the space to search in
* @param listName The name of the list to find
* @returns The list if found, otherwise null
*/
async findListByNameInSpace(spaceId: string, listName: string): Promise<ClickUpList | null> {
this.logOperation('findListByNameInSpace', { spaceId, listName });
try {
const lists = await this.getListsInSpace(spaceId);
const matchingList = lists.find(list =>
list.name.toLowerCase() === listName.toLowerCase()
);
return matchingList || null;
} catch (error) {
throw this.handleError(error, `Failed to find list by name in space ${spaceId}`);
}
}
/**
* Find a list by its name in a folder
* @param folderId The ID of the folder to search in
* @param listName The name of the list to find
* @returns The list if found, otherwise null
*/
async findListByNameInFolder(folderId: string, listName: string): Promise<ClickUpList | null> {
this.logOperation('findListByNameInFolder', { folderId, listName });
try {
const lists = await this.getListsInFolder(folderId);
const matchingList = lists.find(list =>
list.name.toLowerCase() === listName.toLowerCase()
);
return matchingList || null;
} catch (error) {
throw this.handleError(error, `Failed to find list by name in folder ${folderId}`);
}
}
}