getProjectPerson
Retrieve detailed records of individuals associated with a specific project, filtering by user type, role, or activity, to manage team participation effectively.
Instructions
Returns one or more people on a project. Retrieve a person(s) record.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| companyIds | No | company ids | |
| excludeContacts | No | exclude contact types, returning only account and collaborator. | |
| excludeIds | No | exclude certain user ids | |
| excludeProjectIds | No | exclude people assigned to certain project id | |
| fieldsCompanies | No | Query parameter: fields[companies] | |
| fieldsPeople | No | Query parameter: fields[people] | |
| fieldsPerson | No | Query parameter: fields[person] | |
| fieldsProjectPermissions | No | Query parameter: fields[ProjectPermissions] | |
| fieldsTeams | No | Query parameter: fields[teams] | |
| filterByNoCostRate | No | Returns users who are missing cost rates(OCA only) | |
| ids | No | filter by user ids | |
| include | No | include (not used when generating reports) | |
| includeClients | No | include clients | |
| includeCollaborators | No | exclude collaborators types, returning only account and contact. | |
| includePlaceholders | No | include placeholder users | |
| includeServiceAccounts | No | include service accounts | |
| inclusiveFilter | No | make the filter inclusive for user ids, teamIds, companyIds | |
| lastLoginAfter | No | Query parameter: lastLoginAfter | |
| onlyOwnerCompany | No | return people only from the owner company. This will replace any provided company ID. | |
| onlySiteOwner | No | Query parameter: onlySiteOwner | |
| orderBy | No | order by | |
| orderMode | No | order mode | |
| orderPrioritiseCurrentUser | No | Force to have the current/session user in the response | |
| page | No | page number (not used when generating reports) | |
| pageSize | No | number of items in a page (not used when generating reports) | |
| personId | Yes | Path parameter: personId | |
| projectId | Yes | Path parameter: projectId | |
| projectIds | No | filter by project ids | |
| searchTerm | No | filter by comment content | |
| searchUserJobRole | No | Include user job role in search | |
| showDeleted | No | include deleted items | |
| skipCounts | No | SkipCounts allows you to skip doing counts on a list API endpoint for performance reasons. | |
| teamIds | No | team ids | |
| updatedAfter | No | date time | |
| userType | No | user type |
Implementation Reference
- The handler function that executes the tool logic. It maps input fields, calls the getProjectPersonService, and formats the response as MCP content.export async function handleGetProjectPerson(input: any) { logger.info("Calling getProjectPersonService()"); const apiInput: Record<string, any> = { ...input }; const fieldMappings: Record<string, string> = { fieldsTeams: "fields[teams]", fieldsPerson: "fields[person]", fieldsPeople: "fields[people]", fieldsCompanies: "fields[companies]", fieldsProjectPermissions: "fields[ProjectPermissions]", }; for (const [camelCaseKey, apiKey] of Object.entries(fieldMappings)) { if (apiInput[camelCaseKey] !== undefined) { apiInput[apiKey] = apiInput[camelCaseKey]; delete apiInput[camelCaseKey]; } } try { const response = await getProjectPersonService({ projectId: apiInput.projectId, personId: apiInput.personId, ...apiInput }); logger.info("getProjectPersonService response received"); return { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] }; } catch (error: any) { logger.error(`Error in handleGetProjectPerson: ${error.message}`); return { content: [{ type: "text", text: `Error retrieving project person: ${error.message}` }] }; } }
- The tool schema definition, including inputSchema with all parameters, required fields, and annotations for the getProjectPerson tool.export const getProjectPersonDefinition = { name: "getProjectPerson", description: "Returns one or more people on a project. Retrieve a person(s) record.", inputSchema: { type: 'object', properties: { projectId: { type: 'integer', description: 'Path parameter: projectId' }, personId: { type: 'integer', description: 'Path parameter: personId' }, userType: { type: 'string', description: 'user type', enum: [ 'account', 'collaborator', 'contact' ] }, updatedAfter: { type: 'string', description: 'date time' }, searchTerm: { type: 'string', description: 'filter by comment content' }, orderMode: { type: 'string', description: 'order mode', enum: [ 'asc', 'desc' ] }, orderBy: { type: 'string', description: 'order by', enum: [ 'name', 'namecaseinsensitive', 'company' ] }, lastLoginAfter: { type: 'string', description: 'Query parameter: lastLoginAfter' }, 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)' }, skipCounts: { type: 'boolean', description: 'SkipCounts allows you to skip doing counts on a list API endpoint for performance reasons.' }, showDeleted: { type: 'boolean', description: 'include deleted items' }, searchUserJobRole: { type: 'boolean', description: 'Include user job role in search' }, orderPrioritiseCurrentUser: { type: 'boolean', description: 'Force to have the current/session user in the response' }, onlySiteOwner: { type: 'boolean', description: 'Query parameter: onlySiteOwner' }, onlyOwnerCompany: { type: 'boolean', description: 'return people only from the owner company. This will replace any provided company ID.' }, inclusiveFilter: { type: 'boolean', description: 'make the filter inclusive for user ids, teamIds, companyIds' }, includeServiceAccounts: { type: 'boolean', description: 'include service accounts' }, includePlaceholders: { type: 'boolean', description: 'include placeholder users' }, includeCollaborators: { type: 'boolean', description: 'exclude collaborators types, returning only account and contact.' }, includeClients: { type: 'boolean', description: 'include clients' }, filterByNoCostRate: { type: 'boolean', description: 'Returns users who are missing cost rates(OCA only)' }, excludeContacts: { type: 'boolean', description: 'exclude contact types, returning only account and collaborator.' }, teamIds: { type: 'array', items: { type: 'integer' }, description: 'team ids' }, projectIds: { type: 'array', items: { type: 'integer' }, description: 'filter by project ids' }, include: { type: 'array', items: { type: 'string' }, description: 'include (not used when generating reports)' }, ids: { type: 'array', items: { type: 'integer' }, description: 'filter by user ids' }, fieldsTeams: { type: 'array', description: 'Query parameter: fields[teams]', items: { type: 'string', enum: [ "id", "name", "teamLogo", "teamLogoIcon", "teamLogoColor" ] } }, fieldsPerson: { type: 'array', description: 'Query parameter: fields[person]', items: { type: 'string', enum: [ "id", "firstName", "lastName", "title", "email", "companyId", "company", "isAdmin", "isClientUser", "isServiceAccount", "type", "deleted", "avatarUrl", "lengthOfDay", "workingHoursId", "workingHour", "userRate", "userCost", "canAddProjects" ] } }, fieldsPeople: { type: 'array', description: 'Query parameter: fields[people]', items: { type: 'string', enum: [ "id", "firstName", "lastName", "title", "email", "companyId", "company", "isAdmin", "isClientUser", "isServiceAccount", "type", "deleted", "avatarUrl", "lengthOfDay", "workingHoursId", "workingHour", "userRate", "userCost", "canAddProjects" ] } }, fieldsCompanies: { type: 'array', description: 'Query parameter: fields[companies]', items: { type: 'string', enum: [ "id", "name", "logoUploadedToServer", "logoImage" ] } }, fieldsProjectPermissions: { type: 'array', description: 'Query parameter: fields[ProjectPermissions]', items: { type: 'string', enum: [ "viewMessagesAndFiles", "viewTasksAndMilestones", "viewTime", "viewNotebooks", "viewRiskRegister", "viewEstimatedTime", "viewInvoices", "addTasks", "addRisks", "manageCustomFields", "addExpenses", "editAllTasks", "addMilestones", "addTaskLists", "addMessages", "addFiles", "addTime", "addNotebooks", "viewLinks", "addLinks", "canViewForms", "addForms", "viewAllTimeLogs", "setPrivacy", "projectAdministrator", "viewProjectUpdate", "addProjectUpdate", "canViewProjectMembers", "canViewProjectBudget", "canManageProjectBudget", "canViewRates", "canManageRates", "canViewSchedule", "canManageSchedule", "receiveEmailNotifications", "isObserving", "isArchived", "active", "canAccess", "inOwnerCompany", "canManagePeople", "canViewProjectTemplates", "canManageProjectTemplates" ] } }, excludeProjectIds: { type: 'array', items: { type: 'integer' }, description: 'exclude people assigned to certain project id' }, excludeIds: { type: 'array', items: { type: 'integer' }, description: 'exclude certain user ids' }, companyIds: { type: 'array', items: { type: 'integer' }, description: 'company ids' } }, required: [ 'projectId', 'personId' ] }, annotations: { title: "Get a Person(s) on a Project", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false } };
- src/tools/index.ts:47-146 (registration)Registration of the getProjectPerson tool: import, inclusion in toolPairs array, and re-export of the handler.import { getProjectPersonDefinition as getProjectPerson, handleGetProjectPerson } from './people/getProjectPerson.js'; import { getProjectsReportingUserTaskCompletionDefinition as getProjectsReportingUserTaskCompletion, handleGetProjectsReportingUserTaskCompletion } from './reporting/getUserTaskCompletion.js'; import { getProjectsReportingUtilizationDefinition as getProjectsReportingUtilization, handleGetProjectsReportingUtilization } from './people/getUtilization.js'; // Time-related imports import { getTimeDefinition as getTime, handleGetTime } from './time/getTime.js'; import { getProjectsAllocationsTimeDefinition as getAllocationTime, handleGetProjectsAllocationsTime } from './time/getAllocationTime.js'; // Core import { getTimezonesDefinition as getTimezones, handleGetTimezones } from './core/getTimezones.js'; // Define a structure that pairs tool definitions with their handlers interface ToolPair { definition: any; handler: Function; } // 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 } ]; // Extract just the definitions for the toolDefinitions array export const toolDefinitions = toolPairs.map(pair => pair.definition); // Create a map of tool names to their handler functions export const toolHandlersMap: Record<string, Function> = toolPairs.reduce((map, pair) => { map[pair.definition.name] = pair.handler; return map; }, {} as Record<string, Function>); // Export all tool handlers export { handleGetProjects } from './projects/getProjects.js'; export { handleGetCurrentProject } from './projects/getCurrentProject.js'; export { handleCreateProject } from './projects/createProject.js'; export { handleGetTasks } from './tasks/getTasks.js'; export { handleGetTasksByProjectId } from './tasks/getTasksByProjectId.js'; export { handleGetTaskListsByProjectId } from './tasks/getTaskListsByProjectId.js'; export { handleGetTaskById } from './tasks/getTaskById.js'; export { handleGetTasksByTaskListId } from './tasks/getTasksByTaskListId.js'; export { handleCreateTask } from './tasks/createTask.js'; export { handleCreateSubTask } from './tasks/createSubTask.js'; export { handleUpdateTask } from './tasks/updateTask.js'; export { handleDeleteTask } from './tasks/deleteTask.js'; export { handleGetTasksMetricsComplete } from './tasks/getTasksMetricsComplete.js'; export { handleGetTasksMetricsLate } from './tasks/getTasksMetricsLate.js'; export { handleGetTaskSubtasks } from './tasks/getTaskSubtasks.js'; export { handleGetTaskComments } from './tasks/getTaskComments.js'; export { handleCreateComment } from './comments/createComment.js'; export { handleGetPeople } from './people/getPeople.js'; export { handleGetPersonById } from './people/getPersonById.js'; export { handleGetProjectPeople } from './people/getProjectPeople.js'; export { handleAddPeopleToProject } from './people/addPeopleToProject.js'; export { handleDeletePerson } from './people/deletePerson.js'; export { handleUpdatePerson } from './people/updatePerson.js'; export { handleCreateCompany } from './companies/createCompany.js'; export { handleUpdateCompany } from './companies/updateCompany.js'; export { handleDeleteCompany } from './companies/deleteCompany.js'; export { handleGetCompanies } from './companies/getCompanies.js'; export { handleGetCompanyById } from './companies/getCompanyById.js'; export { handleGetProjectsPeopleMetricsPerformance } from './people/getPeopleMetricsPerformance.js'; export { handleGetProjectsPeopleUtilization } from './people/getPeopleUtilization.js'; export { handleGetTime } from './time/getTime.js'; export { handleGetProjectsAllocationsTime } from './time/getAllocationTime.js'; export { handleGetProjectPerson } from './people/getProjectPerson.js';
- Supporting service function that performs the actual API call to retrieve the project person data using the Teamwork API.export async function getProjectPerson(params: GetProjectPersonPathParams & QueryParams) { const api = getApiClientForVersion('v3'); const { projectId, personId, ...queryParams } = params; logger.debug(`Making GET request to /projects/${projectId}/people/${personId}.json with params: ${JSON.stringify(queryParams)}`); try { const response = await api.get(`/projects/${projectId}/people/${personId}.json`, { params: queryParams }); return response.data; } catch (error: any) { if (error.response) { logger.error(`Error fetching project person: Status ${error.response.status} - ${JSON.stringify(error.response.data)}`); } else if (error.request) { logger.error(`Error fetching project person: No response received - ${error.request}`); } else { logger.error(`Error fetching project person: ${error.message}`); } throw new Error(`Failed to fetch project person from Teamwork API: ${error.message}`); } } export default getProjectPerson;
- src/services/index.ts:33-54 (registration)Export and registration of the getProjectPerson service in the services index.import getProjectPerson from './people/getProjectPerson.js'; // Company-related exports import createCompany from './companies/createCompany.js'; import updateCompany from './companies/updateCompany.js'; import deleteCompany from './companies/deleteCompany.js'; import getCompanies from './companies/getCompanies.js'; import getCompanyById from './companies/getCompanyById.js'; // Time-related exports import getTime, { GetTimeParams } from './time/getTime.js'; import getTimezones from './core/getTimezones.js'; // Reporting exports import getUserTaskCompletion from './reporting/getUserTaskCompletion.js'; import getUtilizationCsv from './reporting/getUtilizationCsv.js'; // Re-export all functions export { getProjects, getCurrentProject, createProject, CreateProjectData }; export { getTasks, getTasksByProjectId, getTaskListsByProjectId, getTaskById, createTask, createSubTask, updateTask, deleteTask }; export { createComment }; export { getPeople, PeopleQueryParams, getPersonById, getProjectPeople, addPeopleToProject, AddPeopleToProjectPayload, deletePerson, updatePerson, getPeopleMetricsPerformance, getPeopleUtilization, getProjectPerson };