search_code
Search for patterns in code within a specified directory. Use a query or regex, optionally filter by file pattern like *.py or *.js. Ideal for locating specific code snippets across projects.
Instructions
Search for patterns in code
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Search query or regex | |
| path | Yes | Directory to search in | |
| file_pattern | No | File pattern (e.g., *.py, *.js) | |
| regex | No | Use regex search |
Implementation Reference
- src/services/AnalysisService.ts:66-85 (handler)Main handler function for the 'search_code' tool. Accepts SearchCodeArgs (query, path, file_pattern, regex), resolves the search path via WorkspaceService, then recursively searches directories for matching patterns. Returns results as JSON string.
async searchCode(args: SearchCodeArgs): Promise<ToolResult> { const { query, path: searchPath, file_pattern, regex = false } = args; ValidationUtils.validateRequired({ query, path: searchPath }, ['query', 'path']); const fullPath = this.workspaceService.resolvePath(searchPath); const results: SearchResult[] = []; try { await this.searchInDirectory(fullPath, query, file_pattern, regex, results); return { content: [{ type: 'text', text: JSON.stringify(results, null, 2), }], }; } catch (error) { throw new Error(`Failed to search code: ${error instanceof Error ? error.message : 'Unknown error'}`); } } - src/services/AnalysisService.ts:213-248 (handler)Helper that recursively walks directories, skips hidden files, applies file_pattern filter, restricts to known text/code file extensions, and calls searchInFile on each matching file.
private async searchInDirectory( dirPath: string, query: string, filePattern?: string, regex: boolean = false, results: SearchResult[] = [] ): Promise<void> { try { const entries = await fs.readdir(dirPath, { withFileTypes: true }); for (const entry of entries) { if (entry.name.startsWith('.')) continue; // Skip hidden files const fullPath = path.join(dirPath, entry.name); if (entry.isDirectory()) { await this.searchInDirectory(fullPath, query, filePattern, regex, results); } else if (entry.isFile()) { // Check file pattern if specified if (filePattern && !entry.name.match(new RegExp(filePattern))) { continue; } // Only search in text files const ext = path.extname(entry.name).toLowerCase(); if (!['.js', '.jsx', '.ts', '.tsx', '.py', '.java', '.c', '.cpp', '.txt', '.md'].includes(ext)) { continue; } await this.searchInFile(fullPath, query, regex, results); } } } catch (error) { // Skip directories we can't read } } - src/services/AnalysisService.ts:253-291 (handler)Helper that reads a single file, splits into lines, matches against the query (plain text or regex), and pushes SearchResult objects with file, line, column, content, and match text.
private async searchInFile(filePath: string, query: string, regex: boolean, results: SearchResult[]): Promise<void> { try { const content = await fs.readFile(filePath, 'utf8'); const lines = content.split('\n'); const searchPattern = regex ? new RegExp(query, 'gi') : query.toLowerCase(); lines.forEach((line, index) => { let match = false; let matchText = ''; if (regex && searchPattern instanceof RegExp) { const regexMatch = line.match(searchPattern); if (regexMatch) { match = true; matchText = regexMatch[0]; } } else { const lowerLine = line.toLowerCase(); if (lowerLine.includes(searchPattern as string)) { match = true; matchText = query; } } if (match) { results.push({ file: filePath, line: index + 1, column: line.indexOf(matchText) + 1, content: line.trim(), match: matchText }); } }); } catch (error) { // Skip files we can't read } } - TypeScript interface defining the input arguments for search_code: query (string, required), path (string, required), file_pattern (optional), regex (optional boolean).
export interface SearchCodeArgs { query: string; path: string; file_pattern?: string; regex?: boolean; } - src/index.ts:231-232 (registration)Dispatch in the main server's executeToolCommand switch-case that routes 'search_code' to this.analysisService.searchCode(args as SearchCodeArgs).
case 'search_code': return await this.analysisService.searchCode(args as SearchCodeArgs); - src/toolDefinitions.ts:336-349 (registration)Tool definition/schema registration for 'search_code' including its description and inputSchema (query, path, file_pattern, regex properties).
{ name: 'search_code', description: 'Search for patterns in code', inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Search query or regex' }, path: { type: 'string', description: 'Directory to search in' }, file_pattern: { type: 'string', description: 'File pattern (e.g., *.py, *.js)' }, regex: { type: 'boolean', description: 'Use regex search' }, }, required: ['query', 'path'], }, },