list_work_items
List work items in an Azure DevOps project using filters like project, organization, team, saved query, or WIQL. Control pagination with top and skip parameters.
Instructions
List work items in a project
Input 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) | |
| teamId | No | The ID of the team | |
| queryId | No | ID of a saved work item query | |
| wiql | No | Work Item Query Language (WIQL) query | |
| top | No | Maximum number of work items to return | |
| skip | No | Number of work items to skip |
Implementation Reference
- The main handler function that executes the list_work_items tool logic. Connects to the Azure DevOps Work Item Tracking API, runs a WIQL query (either from a saved query ID, a custom WIQL string, or a default query), applies pagination, fetches work item details, and returns them.
export async function listWorkItems( connection: WebApi, options: ListWorkItemsOptions, ): Promise<WorkItemType[]> { try { const witApi = await connection.getWorkItemTrackingApi(); const { projectId, teamId, queryId, wiql } = options; let workItemRefs: WorkItemReference[] = []; if (queryId) { const teamContext: TeamContext = { project: projectId, team: teamId, }; const queryResult = await witApi.queryById(queryId, teamContext); workItemRefs = queryResult.workItems || []; } else { const query = wiql || constructDefaultWiql(projectId, teamId); const teamContext: TeamContext = { project: projectId, team: teamId, }; const queryResult = await witApi.queryByWiql({ query }, teamContext); workItemRefs = queryResult.workItems || []; } // Apply pagination in memory const { top = 200, skip } = options; if (skip !== undefined) { workItemRefs = workItemRefs.slice(skip); } if (top !== undefined) { workItemRefs = workItemRefs.slice(0, top); } const workItemIds = workItemRefs .map((ref) => ref.id) .filter((id): id is number => id !== undefined); if (workItemIds.length === 0) { return []; } const fields = [ 'System.Id', 'System.Title', 'System.State', 'System.AssignedTo', ]; const workItems = await witApi.getWorkItems( workItemIds, fields, undefined, undefined, ); if (!workItems) { return []; } return workItems.filter((wi): wi is WorkItem => wi !== undefined); } catch (error) { if (error instanceof AzureDevOpsError) { throw error; } // Check for specific error types and convert to appropriate Azure DevOps errors if (error instanceof Error) { if ( error.message.includes('Authentication') || error.message.includes('Unauthorized') ) { throw new AzureDevOpsAuthenticationError( `Failed to authenticate: ${error.message}`, ); } if ( error.message.includes('not found') || error.message.includes('does not exist') ) { throw new AzureDevOpsResourceNotFoundError( `Resource not found: ${error.message}`, ); } } throw new AzureDevOpsError( `Failed to list work items: ${error instanceof Error ? error.message : String(error)}`, ); } } - Zod input schema for the list_work_items tool, defining the validated parameters: projectId, organizationId, teamId, queryId, wiql, top, and skip.
export const ListWorkItemsSchema = 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})`), teamId: z.string().optional().describe('The ID of the team'), queryId: z.string().optional().describe('ID of a saved work item query'), wiql: z.string().optional().describe('Work Item Query Language (WIQL) query'), top: z.number().optional().describe('Maximum number of work items to return'), skip: z.number().optional().describe('Number of work items to skip'), }); - src/features/work-items/tool-definitions.ts:14-40 (registration)Tool definition registration for list_work_items, mapping the name to its description and input schema (converted to JSON Schema via zodToJsonSchema).
export const workItemsTools: ToolDefinition[] = [ { name: 'list_work_items', description: 'List work items in a project', inputSchema: zodToJsonSchema(ListWorkItemsSchema), }, { name: 'get_work_item', description: 'Get details of a specific work item', inputSchema: zodToJsonSchema(GetWorkItemSchema), }, { name: 'create_work_item', description: 'Create a new work item', inputSchema: zodToJsonSchema(CreateWorkItemSchema), }, { name: 'update_work_item', description: 'Update an existing work item', inputSchema: zodToJsonSchema(UpdateWorkItemSchema), }, { name: 'manage_work_item_link', description: 'Add or remove links between work items', inputSchema: zodToJsonSchema(ManageWorkItemLinkSchema), }, ]; - Helper function that constructs the default WIQL query for listing all work items in a project (optionally filtered by team).
function constructDefaultWiql(projectId: string, teamId?: string): string { let query = `SELECT [System.Id] FROM WorkItems WHERE [System.TeamProject] = '${projectId}'`; if (teamId) { query += ` AND [System.TeamId] = '${teamId}'`; } query += ' ORDER BY [System.Id]'; return query; } - src/features/work-items/index.ts:76-148 (registration)Request handler case clause that parses the incoming list_work_items call using the schema, invokes the handler with defaults, and returns the JSON response.
case 'list_work_items': { const args = ListWorkItemsSchema.parse(request.params.arguments); const result = await listWorkItems(connection, { projectId: args.projectId ?? defaultProject, teamId: args.teamId, queryId: args.queryId, wiql: args.wiql, top: args.top, skip: args.skip, }); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }], }; } 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) }], }; } case 'update_work_item': { const args = UpdateWorkItemSchema.parse(request.params.arguments); const result = await updateWorkItem(connection, args.workItemId, { title: args.title, description: args.description, assignedTo: args.assignedTo, areaPath: args.areaPath, iterationPath: args.iterationPath, priority: args.priority, state: args.state, additionalFields: args.additionalFields, }); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }], }; } case 'manage_work_item_link': { const args = ManageWorkItemLinkSchema.parse(request.params.arguments); const result = await manageWorkItemLink( connection, args.projectId ?? defaultProject, { sourceWorkItemId: args.sourceWorkItemId, targetWorkItemId: args.targetWorkItemId, operation: args.operation, relationType: args.relationType, newRelationType: args.newRelationType, comment: args.comment, }, ); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }], }; } default: throw new Error(`Unknown work items tool: ${request.params.name}`); } };