getProjects
Retrieve and filter Teamwork projects with customizable parameters for reporting, analysis, and project management oversight.
Instructions
Get all projects from Teamwork
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| updatedAfter | No | Filter projects updated after this date-time (format: ISO 8601) | |
| timeMode | No | Profitability time mode | |
| searchTerm | No | Filter by project name | |
| reportType | No | Define the type of the report | |
| reportTimezone | No | Configure the report dates displayed in a timezone | |
| reportFormat | No | Define the format of the report | |
| projectType | No | Filter by project type | |
| orderMode | No | Order mode | |
| orderBy | No | Order by field | |
| notCompletedBefore | No | Filter by projects that have not been completed before the given date (format: YYYY-MM-DD) | |
| minLastActivityDate | No | Filter by min last activity date (format: YYYY-MM-DD) | |
| maxLastActivityDate | No | Filter by max last activity date (format: YYYY-MM-DD) | |
| userId | No | Filter by user id | |
| pageSize | No | Number of items in a page (not used when generating reports) | |
| page | No | Page number (not used when generating reports) | |
| orderByCustomFieldId | No | Order by custom field id when orderBy is equal to customfield | |
| minBudgetCapacityUsedPercent | No | Filter by minimum budget capacity used | |
| maxBudgetCapacityUsedPercent | No | Filter by maximum budget capacity used | |
| includeArchivedProjects | No | Include archived projects | |
| includeCompletedProjects | No | Include completed projects | |
| includeProjectOwner | No | Include project owner | |
| includeProjectCreator | No | Include project creator | |
| includeProjectCompany | No | Include project company | |
| includeProjectCategory | No | Include project category | |
| includeProjectTags | No | Include project tags | |
| includeProjectStatus | No | Include project status | |
| includeProjectHealth | No | Include project health | |
| includeProjectBudget | No | Include project budget | |
| includeProjectProfitability | No | Include project profitability | |
| includeProjectCustomFields | No | Include project custom fields | |
| includeProjectBillingMethod | No | Include project billing method | |
| includeProjectRateCards | No | Include project rate cards | |
| includeProjectRateCardRates | No | Include project rate card rates | |
| includeProjectRateCardCurrencies | No | Include project rate card currencies | |
| includeProjectRateCardUsers | No | Include project rate card users | |
| includeProjectRateCardUserRates | No | Include project rate card user rates | |
| includeProjectRateCardUserCurrencies | No | Include project rate card user currencies | |
| includeProjectRateCardTasks | No | Include project rate card tasks | |
| includeProjectRateCardTaskRates | No | Include project rate card task rates | |
| includeProjectRateCardTaskCurrencies | No | Include project rate card task currencies |
Implementation Reference
- The main handler function for the 'getProjects' MCP tool. It processes input parameters, calls the underlying teamworkService.getProjects(), handles various response formats, stringifies the result for output, and manages errors.// Tool handler export async function handleGetProjects(input: any) { logger.info('=== getProjects tool called ==='); logger.info(`Query parameters: ${JSON.stringify(input || {})}`); try { logger.info('Calling teamworkService.getProjects()'); const projects = await teamworkService.getProjects(input); // Debug the response logger.info(`Projects response type: ${typeof projects}`); if (projects === null || projects === undefined) { logger.warn('Projects response is null or undefined'); return { content: [{ type: "text", text: "No projects found or API returned empty response." }] }; } else if (Array.isArray(projects)) { logger.info(`Projects array length: ${projects.length}`); if (projects.length === 0) { return { content: [{ type: "text", text: "No projects found. The API returned an empty array." }] }; } } else if (typeof projects === 'object') { // Check if it's a paginated response with 'projects' property if (projects.projects && Array.isArray(projects.projects)) { logger.info(`Projects array found in response object. Length: ${projects.projects.length}`); if (projects.projects.length === 0) { return { content: [{ type: "text", text: "No projects found. The API returned an empty projects array." }] }; } } else { logger.info(`Projects response is an object: ${JSON.stringify(projects).substring(0, 200)}...`); } } else { logger.info(`Projects response is not an array or object: ${JSON.stringify(projects).substring(0, 200)}...`); } try { const jsonString = JSON.stringify(projects, null, 2); logger.info(`Successfully stringified projects response`); logger.info('=== getProjects tool completed successfully ==='); return { content: [{ type: "text", text: jsonString }] }; } catch (jsonError: any) { logger.error(`JSON stringify error: ${jsonError.message}`); return { content: [{ type: "text", text: `Error converting response to JSON: ${jsonError.message}` }] }; } } catch (error: any) { return createErrorResponse(error, 'Retrieving projects'); } }
- The schema/definition for the 'getProjects' tool, including name, description, comprehensive inputSchema with numerous filtering, pagination, inclusion, and ordering parameters, and annotations.export const getProjectsDefinition = { name: "getProjects", description: "Get all projects from Teamwork", inputSchema: { type: "object", properties: { // String parameters updatedAfter: { type: "string", description: "Filter projects updated after this date-time (format: ISO 8601)" }, timeMode: { type: "string", enum: ["timelogs", "estimated"], description: "Profitability time mode" }, searchTerm: { type: "string", description: "Filter by project name" }, reportType: { type: "string", enum: ["project", "health"], description: "Define the type of the report" }, reportTimezone: { type: "string", description: "Configure the report dates displayed in a timezone" }, reportFormat: { type: "string", enum: ["csv", "html", "pdf", "xls"], description: "Define the format of the report" }, projectType: { type: "string", description: "Filter by project type" }, orderMode: { type: "string", enum: ["asc", "desc"], description: "Order mode" }, orderBy: { type: "string", enum: ["companyname", "datecreated", "duedate", "lastactivity", "name", "namecaseinsensitive", "ownercompany", "starred", "categoryname"], description: "Order by field" }, notCompletedBefore: { type: "string", description: "Filter by projects that have not been completed before the given date (format: YYYY-MM-DD)" }, minLastActivityDate: { type: "string", description: "Filter by min last activity date (format: YYYY-MM-DD)" }, maxLastActivityDate: { type: "string", description: "Filter by max last activity date (format: YYYY-MM-DD)" }, // Integer parameters userId: { type: "integer", description: "Filter by user id" }, pageSize: { type: "integer", description: "Number of items in a page (not used when generating reports)" }, page: { type: "integer", description: "Page number (not used when generating reports)" }, orderByCustomFieldId: { type: "integer", description: "Order by custom field id when orderBy is equal to customfield" }, minBudgetCapacityUsedPercent: { type: "integer", description: "Filter by minimum budget capacity used" }, maxBudgetCapacityUsedPercent: { type: "integer", description: "Filter by maximum budget capacity used" }, // Boolean parameters includeArchivedProjects: { type: "boolean", description: "Include archived projects" }, includeCompletedProjects: { type: "boolean", description: "Include completed projects" }, includeProjectOwner: { type: "boolean", description: "Include project owner" }, includeProjectCreator: { type: "boolean", description: "Include project creator" }, includeProjectCompany: { type: "boolean", description: "Include project company" }, includeProjectCategory: { type: "boolean", description: "Include project category" }, includeProjectTags: { type: "boolean", description: "Include project tags" }, includeProjectStatus: { type: "boolean", description: "Include project status" }, includeProjectHealth: { type: "boolean", description: "Include project health" }, includeProjectBudget: { type: "boolean", description: "Include project budget" }, includeProjectProfitability: { type: "boolean", description: "Include project profitability" }, includeProjectCustomFields: { type: "boolean", description: "Include project custom fields" }, includeProjectBillingMethod: { type: "boolean", description: "Include project billing method" }, includeProjectRateCards: { type: "boolean", description: "Include project rate cards" }, includeProjectRateCardRates: { type: "boolean", description: "Include project rate card rates" }, includeProjectRateCardCurrencies: { type: "boolean", description: "Include project rate card currencies" }, includeProjectRateCardUsers: { type: "boolean", description: "Include project rate card users" }, includeProjectRateCardUserRates: { type: "boolean", description: "Include project rate card user rates" }, includeProjectRateCardUserCurrencies: { type: "boolean", description: "Include project rate card user currencies" }, includeProjectRateCardTasks: { type: "boolean", description: "Include project rate card tasks" }, includeProjectRateCardTaskRates: { type: "boolean", description: "Include project rate card task rates" }, includeProjectRateCardTaskCurrencies: { type: "boolean", description: "Include project rate card task currencies" } } }, annotations: { title: "Get Projects", readOnlyHint: false, destructiveHint: false, openWorldHint: false } };
- src/tools/index.ts:64-102 (registration)Registration of the getProjects tool in the central toolPairs array, pairing its definition and handler. This array is used to generate toolDefinitions and toolHandlersMap for MCP.// Create an array of tool pairs const toolPairs: ToolPair[] = [ { definition: getProjects, handler: handleGetProjects }, { definition: getCurrentProject, handler: handleGetCurrentProject }, { definition: createProject, handler: handleCreateProject }, { definition: getTasks, handler: handleGetTasks }, { definition: getTasksByProjectId, handler: handleGetTasksByProjectId }, { definition: getTaskListsByProjectId, handler: handleGetTaskListsByProjectId }, { definition: getTasksByTaskListId, handler: handleGetTasksByTaskListId }, { definition: getTaskById, handler: handleGetTaskById }, { definition: createTask, handler: handleCreateTask }, { definition: createSubTask, handler: handleCreateSubTask }, { definition: updateTask, handler: handleUpdateTask }, { definition: deleteTask, handler: handleDeleteTask }, { definition: getTasksMetricsComplete, handler: handleGetTasksMetricsComplete }, { definition: getTasksMetricsLate, handler: handleGetTasksMetricsLate }, { definition: getTaskSubtasks, handler: handleGetTaskSubtasks }, { definition: getTaskComments, handler: handleGetTaskComments }, { definition: createComment, handler: handleCreateComment }, { definition: getPeople, handler: handleGetPeople }, { definition: getPersonById, handler: handleGetPersonById }, { definition: getProjectPeople, handler: handleGetProjectPeople }, { definition: addPeopleToProject, handler: handleAddPeopleToProject }, { definition: deletePerson, handler: handleDeletePerson }, { definition: updatePerson, handler: handleUpdatePerson }, { definition: createCompany, handler: handleCreateCompany }, { definition: updateCompany, handler: handleUpdateCompany }, { definition: deleteCompany, handler: handleDeleteCompany }, { definition: getCompanies, handler: handleGetCompanies }, { definition: getCompanyById, handler: handleGetCompanyById }, { definition: getProjectsPeopleMetricsPerformance, handler: handleGetProjectsPeopleMetricsPerformance }, { definition: getProjectsPeopleUtilization, handler: handleGetProjectsPeopleUtilization }, { definition: getAllocationTime, handler: handleGetProjectsAllocationsTime }, { definition: getTime, handler: handleGetTime }, { definition: getProjectPerson, handler: handleGetProjectPerson }, { definition: getProjectsReportingUserTaskCompletion, handler: handleGetProjectsReportingUserTaskCompletion }, { definition: getProjectsReportingUtilization, handler: handleGetProjectsReportingUtilization }, { definition: getTimezones, handler: handleGetTimezones } ];
- The core service function getProjects that performs the actual API calls to Teamwork (/projects.json) with fallback between v3 and v1 APIs. Called by the tool handler via teamworkService.export const getProjects = async (params?: ProjectQueryParams) => { try { logger.info('Fetching projects from Teamwork API'); try { // Try with v3 API first const api = ensureApiClient(); const response = await api.get('/projects.json', { params }); logger.info('Successfully fetched projects using v3 API'); return response.data; } catch (error: any) { logger.warn(`V3 API request failed: ${error.message}`); // Try the v1 API format as fallback logger.info('Trying v1 API format as fallback'); try { const v1Api = getApiClientForVersion('v1'); const v1Response = await v1Api.get('/projects.json', { params }); logger.info('Successfully fetched projects using v1 API'); return v1Response.data; } catch (v1Error: any) { logger.error(`V1 API request also failed: ${v1Error.message}`); throw error; // Throw the original error } } } catch (error: any) { logger.error(`Teamwork API error: ${error.message}`); throw new Error('Failed to fetch projects from Teamwork API'); } };
- src/tools/index.ts:7-7 (registration)Import of the getProjects tool definition and handler into the central tools index for registration.import { getProjectsDefinition as getProjects, handleGetProjects } from './projects/getProjects.js';