search_work_items
Search for work items across Azure DevOps projects using filters, sorting, and faceting for precise results.
Instructions
Search for work items across projects in Azure DevOps
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| filters | No | Optional filters to narrow search results | |
| includeFacets | No | Whether to include faceting in results (default: true) | |
| orderBy | No | Options for sorting search results | |
| projectId | Yes | The ID or name of the project to search in | |
| searchText | Yes | The text to search for in work items | |
| skip | No | Number of results to skip for pagination (default: 0) | |
| top | No | Number of results to return (default: 100, max: 1000) |
Implementation Reference
- The core handler function that executes the search_work_items tool logic, performing an API call to Azure DevOps search endpoint for work items.export async function searchWorkItems( connection: WebApi, options: SearchWorkItemsOptions, ): Promise<WorkItemSearchResponse> { try { // Prepare the search request const searchRequest: WorkItemSearchRequest = { searchText: options.searchText, $skip: options.skip, $top: options.top, filters: { ...(options.projectId ? { 'System.TeamProject': [options.projectId] } : {}), ...options.filters, }, includeFacets: options.includeFacets, $orderBy: options.orderBy, }; // Get the authorization header from the connection const authHeader = await getAuthorizationHeader(); // Extract organization and project from the connection URL const { organization, project } = extractOrgAndProject( connection, options.projectId, ); // Make the search API request // If projectId is provided, include it in the URL, otherwise perform organization-wide search const searchUrl = options.projectId ? `https://almsearch.dev.azure.com/${organization}/${project}/_apis/search/workitemsearchresults?api-version=7.1` : `https://almsearch.dev.azure.com/${organization}/_apis/search/workitemsearchresults?api-version=7.1`; const searchResponse = await axios.post<WorkItemSearchResponse>( searchUrl, searchRequest, { headers: { Authorization: authHeader, 'Content-Type': 'application/json', }, }, ); return searchResponse.data; } catch (error) { // If it's already an AzureDevOpsError, rethrow it if (error instanceof AzureDevOpsError) { throw error; } // Handle axios errors if (axios.isAxiosError(error)) { const status = error.response?.status; const message = error.response?.data?.message || error.message; if (status === 404) { throw new AzureDevOpsResourceNotFoundError( `Resource not found: ${message}`, ); } else if (status === 400) { throw new AzureDevOpsValidationError( `Invalid request: ${message}`, error.response?.data, ); } else if (status === 401 || status === 403) { throw new AzureDevOpsPermissionError(`Permission denied: ${message}`); } else { // For other axios errors, wrap in a generic AzureDevOpsError throw new AzureDevOpsError(`Azure DevOps API error: ${message}`); } // This code is unreachable but TypeScript doesn't know that } // Otherwise, wrap it in a generic error throw new AzureDevOpsError( `Failed to search work items: ${error instanceof Error ? error.message : String(error)}`, ); } }
- Zod schema defining the input parameters and validation for the search_work_items tool.export const SearchWorkItemsSchema = z.object({ searchText: z.string().describe('The text to search for in work items'), organizationId: z .string() .optional() .describe(`The ID or name of the organization (Default: ${defaultOrg})`), projectId: z .string() .optional() .describe( `The ID or name of the project to search in (Default: ${defaultProject}). If not provided, the default project will be used.`, ), filters: z .object({ 'System.TeamProject': z .array(z.string()) .optional() .describe('Filter by project names'), 'System.WorkItemType': z .array(z.string()) .optional() .describe('Filter by work item types (Bug, Task, User Story, etc.)'), 'System.State': z .array(z.string()) .optional() .describe('Filter by work item states (New, Active, Closed, etc.)'), 'System.AssignedTo': z .array(z.string()) .optional() .describe('Filter by assigned users'), 'System.AreaPath': z .array(z.string()) .optional() .describe('Filter by area paths'), }) .optional() .describe('Optional filters to narrow search results'), top: z .number() .int() .min(1) .max(1000) .default(100) .describe('Number of results to return (default: 100, max: 1000)'), skip: z .number() .int() .min(0) .default(0) .describe('Number of results to skip for pagination (default: 0)'), includeFacets: z .boolean() .default(true) .describe('Whether to include faceting in results (default: true)'), orderBy: z .array( z.object({ field: z.string().describe('Field to sort by'), sortOrder: z.enum(['ASC', 'DESC']).describe('Sort order (ASC/DESC)'), }), ) .optional() .describe('Options for sorting search results'), });
- src/features/search/tool-definitions.ts:23-27 (registration)Tool registration entry including name, description, and input schema for search_work_items.{ name: 'search_work_items', description: 'Search for work items across projects in Azure DevOps', inputSchema: zodToJsonSchema(SearchWorkItemsSchema), },
- src/features/search/index.ts:58-64 (handler)Dispatcher case in the request handler that invokes the searchWorkItems function for MCP tool calls.case 'search_work_items': { const args = SearchWorkItemsSchema.parse(request.params.arguments); const result = await searchWorkItems(connection, args); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }], }; }
- src/features/search/types.ts:358-426 (helper)TypeScript interface defining the options for the searchWorkItems function.export interface SearchWorkItemsOptions { /** * The text to search for within work items */ searchText: string; /** * The ID or name of the project to search in * If not provided, search will be performed across the entire organization */ projectId?: string; /** * Optional filters to narrow search results */ filters?: { /** * Filter by project names. Useful for cross-project searches. */ 'System.TeamProject'?: string[]; /** * Filter by work item types (Bug, Task, User Story, etc.) */ 'System.WorkItemType'?: string[]; /** * Filter by work item states (New, Active, Closed, etc.) */ 'System.State'?: string[]; /** * Filter by assigned users */ 'System.AssignedTo'?: string[]; /** * Filter by area paths */ 'System.AreaPath'?: string[]; }; /** * Number of results to return * @default 100 * @minimum 1 * @maximum 1000 */ top?: number; /** * Number of results to skip for pagination * @default 0 * @minimum 0 */ skip?: number; /** * Whether to include faceting in results * @default true */ includeFacets?: boolean; /** * Options for sorting search results * If null, results are sorted by relevance */ orderBy?: SortOption[]; }