linear_searchIssues
Search Linear issues by text, team, assignee, project, or status to find specific project management tasks quickly.
Instructions
Search for issues with various filters
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Text to search for in issue title or description | |
| teamId | No | Filter issues by team ID | |
| assigneeId | No | Filter issues by assignee ID | |
| projectId | No | Filter issues by project ID | |
| states | No | Filter issues by state name (e.g., 'Todo', 'In Progress', 'Done') | |
| limit | No | Maximum number of issues to return (default: 10) |
Implementation Reference
- Core handler function for the 'linear_searchIssues' tool. Validates input arguments using the type guard and delegates the search logic to LinearService.searchIssues.export function handleSearchIssues(linearService: LinearService) { return async (args: unknown) => { try { console.log('searchIssues args:', JSON.stringify(args, null, 2)); if (!isSearchIssuesArgs(args)) { console.error('Invalid arguments for searchIssues'); throw new Error('Invalid arguments for searchIssues'); } console.log('Arguments validated successfully'); return await linearService.searchIssues(args); } catch (error) { logError('Error searching issues', error); throw error; } }; }
- Schema definition for the linear_searchIssues tool, including input parameters (query, teamId, assigneeId, etc.) and output structure.export const searchIssuesToolDefinition: MCPToolDefinition = { name: 'linear_searchIssues', description: 'Search for issues with various filters', input_schema: { type: 'object', properties: { query: { type: 'string', description: 'Text to search for in issue title or description', }, teamId: { type: 'string', description: 'Filter issues by team ID', }, assigneeId: { type: 'string', description: 'Filter issues by assignee ID', }, projectId: { type: 'string', description: 'Filter issues by project ID', }, states: { type: 'array', items: { type: 'string' }, description: "Filter issues by state name (e.g., 'Todo', 'In Progress', 'Done')", }, limit: { type: 'number', description: 'Maximum number of issues to return (default: 10)', }, }, required: [], }, output_schema: { type: 'array', items: { type: 'object', properties: { id: { type: 'string' }, identifier: { type: 'string' }, title: { type: 'string' }, description: { type: 'string' }, state: { type: 'string' }, priority: { type: 'number' }, estimate: { type: 'number' }, dueDate: { type: 'string' }, team: { type: 'object' }, assignee: { type: 'object' }, project: { type: 'object' }, cycle: { type: 'object' }, parent: { type: 'object' }, labels: { type: 'array', items: { type: 'object', properties: { id: { type: 'string' }, name: { type: 'string' }, color: { type: 'string' }, }, }, }, sortOrder: { type: 'number' }, createdAt: { type: 'string' }, updatedAt: { type: 'string' }, url: { type: 'string' }, }, }, }, };
- src/tools/handlers/index.ts:64-126 (registration)Registration of the linear_searchIssues handler within the registerToolHandlers function, mapping the tool name to handleSearchIssues(linearService). Note: excerpt abbreviated for brevity.export function registerToolHandlers(linearService: LinearService) { return { // User tools linear_getViewer: handleGetViewer(linearService), linear_getOrganization: handleGetOrganization(linearService), linear_getUsers: handleGetUsers(linearService), linear_getLabels: handleGetLabels(linearService), // Team tools linear_getTeams: handleGetTeams(linearService), linear_getWorkflowStates: handleGetWorkflowStates(linearService), // Project tools linear_getProjects: handleGetProjects(linearService), linear_createProject: handleCreateProject(linearService), // Project Management tools linear_updateProject: handleUpdateProject(linearService), linear_addIssueToProject: handleAddIssueToProject(linearService), linear_getProjectIssues: handleGetProjectIssues(linearService), // Cycle Management tools linear_getCycles: handleGetCycles(linearService), linear_getActiveCycle: handleGetActiveCycle(linearService), linear_addIssueToCycle: handleAddIssueToCycle(linearService), // Initiative Management tools linear_getInitiatives: getInitiativesHandler(linearService), linear_getInitiativeById: getInitiativeByIdHandler(linearService), linear_createInitiative: createInitiativeHandler(linearService), linear_updateInitiative: updateInitiativeHandler(linearService), linear_archiveInitiative: archiveInitiativeHandler(linearService), linear_unarchiveInitiative: unarchiveInitiativeHandler(linearService), linear_deleteInitiative: deleteInitiativeHandler(linearService), linear_getInitiativeProjects: getInitiativeProjectsHandler(linearService), linear_addProjectToInitiative: addProjectToInitiativeHandler(linearService), linear_removeProjectFromInitiative: removeProjectFromInitiativeHandler(linearService), // Issue tools linear_getIssues: handleGetIssues(linearService), linear_getIssueById: handleGetIssueById(linearService), linear_searchIssues: handleSearchIssues(linearService), linear_createIssue: handleCreateIssue(linearService), linear_updateIssue: handleUpdateIssue(linearService), linear_createComment: handleCreateComment(linearService), linear_addIssueLabel: handleAddIssueLabel(linearService), linear_removeIssueLabel: handleRemoveIssueLabel(linearService), // New Issue Management tools linear_assignIssue: handleAssignIssue(linearService), linear_subscribeToIssue: handleSubscribeToIssue(linearService), linear_convertIssueToSubtask: handleConvertIssueToSubtask(linearService), linear_createIssueRelation: handleCreateIssueRelation(linearService), linear_archiveIssue: handleArchiveIssue(linearService), linear_setIssuePriority: handleSetIssuePriority(linearService), linear_transferIssue: handleTransferIssue(linearService), linear_duplicateIssue: handleDuplicateIssue(linearService), linear_getIssueHistory: handleGetIssueHistory(linearService), // Comment Management tools linear_getComments: handleGetComments(linearService), }; }
- src/tools/type-guards.ts:24-89 (helper)Type guard isSearchIssuesArgs for validating the input arguments of the linear_searchIssues tool./** * Type guard for linear_searchIssues tool arguments */ export function isSearchIssuesArgs(args: unknown): args is { query?: string; teamId?: string; assigneeId?: string; projectId?: string; states?: string[]; limit?: number; } { // Check if args is an object if (typeof args !== 'object' || args === null) { console.error('searchIssues args is not an object or is null'); return false; } // Check query if ('query' in args && typeof (args as { query: unknown }).query !== 'string') { console.error('searchIssues query is not a string'); return false; } // Check teamId if ('teamId' in args && typeof (args as { teamId: unknown }).teamId !== 'string') { console.error('searchIssues teamId is not a string'); return false; } // Check assigneeId if ('assigneeId' in args && typeof (args as { assigneeId: unknown }).assigneeId !== 'string') { console.error('searchIssues assigneeId is not a string'); return false; } // Check projectId if ('projectId' in args && typeof (args as { projectId: unknown }).projectId !== 'string') { console.error('searchIssues projectId is not a string'); return false; } // Check states if ('states' in args) { const states = (args as { states: unknown }).states; if (!Array.isArray(states)) { console.error('searchIssues states is not an array'); return false; } // Check that all elements in the array are strings for (let i = 0; i < states.length; i++) { if (typeof states[i] !== 'string') { console.error(`searchIssues states[${i}] is not a string`); return false; } } } // Check limit if ('limit' in args && typeof (args as { limit: unknown }).limit !== 'number') { console.error('searchIssues limit is not a number'); return false; } return true; }