createProject
Creates a new project in Teamwork. Specify the project name and optional details like description, dates, and status.
Instructions
Create a new project in Teamwork
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | The name of the project (required) | |
| description | No | The description of the project | |
| companyId | No | The ID of the company the project belongs to | |
| categoryId | No | The ID of the category the project belongs to | |
| startDate | No | The start date of the project (format: YYYYMMDD) | |
| endDate | No | The end date of the project (format: YYYYMMDD) | |
| status | No | The status of the project |
Implementation Reference
- Tool handler that extracts input fields, constructs CreateProjectData, and delegates to the teamwork service to create the project.
export async function handleCreateProject(input: any) { logger.info('Calling teamworkService.createProject()'); logger.info(`Project name: ${input?.name}`); try { if (!input?.name) { throw new Error("Project name is required"); } // Prepare project data const projectData: CreateProjectData = { name: input.name }; // Add optional fields if provided if (input.description) projectData.description = input.description; if (input.companyId) projectData.companyId = input.companyId; if (input.categoryId) projectData.categoryId = input.categoryId; if (input.startDate) projectData.startDate = input.startDate; if (input.endDate) projectData.endDate = input.endDate; if (input.status) projectData.status = input.status; // Add any other properties that might be in the input Object.keys(input).forEach(key => { if (!['name', 'description', 'companyId', 'categoryId', 'startDate', 'endDate', 'status'].includes(key)) { projectData[key] = input[key]; } }); // Call the service to create the project const result = await teamworkService.createProject(projectData); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; } catch (error: any) { return createErrorResponse(error, 'Creating project'); } } - MCP tool definition with input schema requiring only 'name', with optional fields for description, companyId, categoryId, startDate, endDate, and status.
export const createProjectDefinition = { name: "createProject", description: "Create a new project in Teamwork", inputSchema: { type: "object", properties: { name: { type: "string", description: "The name of the project (required)" }, description: { type: "string", description: "The description of the project" }, companyId: { type: "integer", description: "The ID of the company the project belongs to" }, categoryId: { type: "integer", description: "The ID of the category the project belongs to" }, startDate: { type: "string", description: "The start date of the project (format: YYYYMMDD)" }, endDate: { type: "string", description: "The end date of the project (format: YYYYMMDD)" }, status: { type: "string", description: "The status of the project" } }, required: ["name"] }, annotations: { title: "Create a Project", readOnlyHint: false, destructiveHint: false, openWorldHint: false } }; - TypeScript interface defining the project creation data shape, with name required and optional fields.
export interface CreateProjectData { name: string; description?: string; companyId?: number; categoryId?: number; startDate?: string; // Format: YYYYMMDD endDate?: string; // Format: YYYYMMDD status?: string; [key: string]: any; // Allow additional properties } - Service-layer function that makes the actual POST request to the Teamwork API v1 /projects.json endpoint, wrapping data in a 'project' object.
export const createProject = async (projectData: CreateProjectData) => { try { logger.info('Creating new project in Teamwork'); if (!projectData.name) { throw new Error('Project name is required'); } // The v1 API endpoint for creating projects is /projects.json const api = getApiClientForVersion('v1'); // The API expects the project data to be wrapped in a 'project' object const requestData = { project: projectData }; logger.info(`Creating project with name: ${projectData.name}`); const response = await api.post('/projects.json', requestData); logger.info(`Successfully created project: ${projectData.name}`); logger.info(`Project ID: ${response.data?.id || 'Unknown'}`); return response.data; } catch (error: any) { logger.error(`Failed to create project: ${error.message}`); throw new Error(`Failed to create project: ${error.message}`); } }; - src/tools/index.ts:108-111 (registration)Registration of createProject into the toolHandlersMap by name, enabling dispatch from createProject to handleCreateProject.
export const toolHandlersMap: Record<string, Function> = toolPairs.reduce((map, pair) => { map[pair.definition.name] = pair.handler; return map; }, {} as Record<string, Function>);