create_work_item
Create new work items like tasks, bugs, or user stories in Azure DevOps projects by specifying type, title, and optional details such as description, assignee, and priority.
Instructions
Create a new work item
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | No | The ID or name of the project (Default: MyProject) | |
| organizationId | No | The ID or name of the organization (Default: mycompany) | |
| workItemType | Yes | The type of work item to create (e.g., "Task", "Bug", "User Story") | |
| title | Yes | The title of the work item | |
| description | No | Work item description in HTML format. Multi-line text fields (i.e., System.History, AcceptanceCriteria, etc.) must use HTML format. Do not use CDATA tags. | |
| assignedTo | No | The email or name of the user to assign the work item to | |
| areaPath | No | The area path for the work item | |
| iterationPath | No | The iteration path for the work item | |
| priority | No | The priority of the work item | |
| parentId | No | The ID of the parent work item to create a relationship with | |
| additionalFields | No | Additional fields to set on the work item. Multi-line text fields (i.e., System.History, AcceptanceCriteria, etc.) must use HTML format. Do not use CDATA tags. |
Implementation Reference
- Core handler function that implements the logic to create a work item in Azure DevOps using the WorkItemTrackingApi.export async function createWorkItem( connection: WebApi, projectId: string, workItemType: string, options: CreateWorkItemOptions, ): Promise<WorkItem> { try { if (!options.title) { throw new Error('Title is required'); } const witApi = await connection.getWorkItemTrackingApi(); // Create the JSON patch document const document = []; // Add required fields document.push({ op: 'add', path: '/fields/System.Title', value: options.title, }); // Add optional fields if provided if (options.description) { document.push({ op: 'add', path: '/fields/System.Description', value: options.description, }); } if (options.assignedTo) { document.push({ op: 'add', path: '/fields/System.AssignedTo', value: options.assignedTo, }); } if (options.areaPath) { document.push({ op: 'add', path: '/fields/System.AreaPath', value: options.areaPath, }); } if (options.iterationPath) { document.push({ op: 'add', path: '/fields/System.IterationPath', value: options.iterationPath, }); } if (options.priority !== undefined) { document.push({ op: 'add', path: '/fields/Microsoft.VSTS.Common.Priority', value: options.priority, }); } // Add parent relationship if parentId is provided if (options.parentId) { document.push({ op: 'add', path: '/relations/-', value: { rel: 'System.LinkTypes.Hierarchy-Reverse', url: `${connection.serverUrl}/_apis/wit/workItems/${options.parentId}`, }, }); } // Add any additional fields if (options.additionalFields) { for (const [key, value] of Object.entries(options.additionalFields)) { document.push({ op: 'add', path: `/fields/${key}`, value: value, }); } } // Create the work item const workItem = await witApi.createWorkItem( null, document, projectId, workItemType, ); if (!workItem) { throw new Error('Failed to create work item'); } return workItem; } catch (error) { if (error instanceof AzureDevOpsError) { throw error; } throw new Error( `Failed to create work item: ${error instanceof Error ? error.message : String(error)}`, ); } }
- src/features/work-items/index.ts:90-109 (handler)MCP tool request handler that validates input with schema, maps arguments, calls the core createWorkItem function, and formats the response.case 'create_work_item': { const args = CreateWorkItemSchema.parse(request.params.arguments); const result = await createWorkItem( connection, args.projectId ?? defaultProject, args.workItemType, { title: args.title, description: args.description, assignedTo: args.assignedTo, areaPath: args.areaPath, iterationPath: args.iterationPath, priority: args.priority, parentId: args.parentId, additionalFields: args.additionalFields, }, ); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }], };
- Zod schema defining the input parameters and validation for the create_work_item tool.export const CreateWorkItemSchema = z.object({ projectId: z .string() .optional() .describe(`The ID or name of the project (Default: ${defaultProject})`), organizationId: z .string() .optional() .describe(`The ID or name of the organization (Default: ${defaultOrg})`), workItemType: z .string() .describe( 'The type of work item to create (e.g., "Task", "Bug", "User Story")', ), title: z.string().describe('The title of the work item'), description: z .string() .optional() .describe( 'Work item description in HTML format. Multi-line text fields (i.e., System.History, AcceptanceCriteria, etc.) must use HTML format. Do not use CDATA tags.', ), assignedTo: z .string() .optional() .describe('The email or name of the user to assign the work item to'), areaPath: z.string().optional().describe('The area path for the work item'), iterationPath: z .string() .optional() .describe('The iteration path for the work item'), priority: z.number().optional().describe('The priority of the work item'), parentId: z .number() .optional() .describe('The ID of the parent work item to create a relationship with'), additionalFields: z .record(z.string(), z.any()) .optional() .describe( 'Additional fields to set on the work item. Multi-line text fields (i.e., System.History, AcceptanceCriteria, etc.) must use HTML format. Do not use CDATA tags.', ), });
- src/features/work-items/tool-definitions.ts:25-29 (registration)Registration of the create_work_item tool in the workItemsTools array, including name, description, and input schema.{ name: 'create_work_item', description: 'Create a new work item', inputSchema: zodToJsonSchema(CreateWorkItemSchema), },
- TypeScript interface matching the options used by the createWorkItem handler function.export interface CreateWorkItemOptions { title: string; description?: string; assignedTo?: string; areaPath?: string; iterationPath?: string; priority?: number; parentId?: number; additionalFields?: Record<string, string | number | boolean | null>; }