search_context
Find relevant code snippets in your project using natural language queries. This tool automatically indexes your codebase and returns semantically related results with file paths and line numbers.
Instructions
Search for relevant code context based on a query within a specific project. This tool automatically performs incremental indexing before searching, ensuring results are always up-to-date. Returns formatted text snippets from the codebase that are semantically related to your query. Supports cross-platform paths including Windows WSL.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| project_root_path | Yes | Absolute path to the project root directory. Supports cross-platform paths: Windows (C:/Users/...), WSL UNC (\\wsl$\Ubuntu\home\...), Unix (/home/...), WSL-to-Windows (/mnt/c/...). Paths are automatically normalized. | |
| query | Yes | Natural language search query to find relevant code context. This tool performs semantic search and returns code snippets that match your query. Examples: 'logging configuration setup initialization logger' (finds logging setup code), 'user authentication login' (finds auth-related code), 'database connection pool' (finds DB connection code), 'error handling exception' (finds error handling patterns), 'API endpoint routes' (finds API route definitions). The tool returns formatted text snippets with file paths and line numbers showing where the relevant code is located. |
Implementation Reference
- src/tools/searchContext.ts:29-70 (handler)The main handler function searchContextTool that implements the tool logic: validates inputs, normalizes project path, creates IndexManager instance, calls searchContext method, and returns formatted ToolResult.export async function searchContextTool(arguments_: SearchContextArgs): Promise<ToolResult> { try { const projectRootPath = arguments_.project_root_path; const query = arguments_.query; if (!projectRootPath) { return { type: 'text', text: 'Error: project_root_path is required' }; } if (!query) { return { type: 'text', text: 'Error: query is required' }; } // 规范化路径,支持 WSL 和跨平台兼容性 let normalizedPath: string; try { normalizedPath = normalizeProjectPath(projectRootPath); } catch (error: any) { return { type: 'text', text: `Error: Invalid project path - ${error.message}` }; } logger.info(`Tool invoked: search_context for project ${normalizedPath} with query: ${query}`); const config = getConfig(); const indexManager = new IndexManager( config.indexStoragePath, config.baseUrl, config.token, config.textExtensions, config.batchSize, config.maxLinesPerBlob, config.excludePatterns ); const result = await indexManager.searchContext(normalizedPath, query); return { type: 'text', text: result }; } catch (error: any) { logger.exception('Error in search_context_tool', error); return { type: 'text', text: `Error: ${error.message}` }; } }
- src/index.ts:68-83 (schema)MCP JSON input schema for the search_context tool, defining properties for project_root_path and query with detailed descriptions.inputSchema: { type: 'object', properties: { project_root_path: { type: 'string', description: 'Absolute path to the project root directory. Supports cross-platform paths: Windows (C:/Users/...), WSL UNC (\\\\wsl$\\Ubuntu\\home\\...), Unix (/home/...), WSL-to-Windows (/mnt/c/...). Paths are automatically normalized.', }, query: { type: 'string', description: "Natural language search query to find relevant code context. This tool performs semantic search and returns code snippets that match your query. Examples: 'logging configuration setup initialization logger' (finds logging setup code), 'user authentication login' (finds auth-related code), 'database connection pool' (finds DB connection code), 'error handling exception' (finds error handling patterns), 'API endpoint routes' (finds API route definitions). The tool returns formatted text snippets with file paths and line numbers showing where the relevant code is located.", }, }, required: ['project_root_path', 'query'], },
- src/index.ts:62-88 (registration)MCP server registration of search_context tool via ListToolsRequestHandler, providing name, description, and input schema.server.setRequestHandler(ListToolsRequestSchema, async () => { const tools: Tool[] = [ { name: 'search_context', description: 'Search for relevant code context based on a query within a specific project. This tool automatically performs incremental indexing before searching, ensuring results are always up-to-date. Returns formatted text snippets from the codebase that are semantically related to your query. Supports cross-platform paths including Windows WSL.', inputSchema: { type: 'object', properties: { project_root_path: { type: 'string', description: 'Absolute path to the project root directory. Supports cross-platform paths: Windows (C:/Users/...), WSL UNC (\\\\wsl$\\Ubuntu\\home\\...), Unix (/home/...), WSL-to-Windows (/mnt/c/...). Paths are automatically normalized.', }, query: { type: 'string', description: "Natural language search query to find relevant code context. This tool performs semantic search and returns code snippets that match your query. Examples: 'logging configuration setup initialization logger' (finds logging setup code), 'user authentication login' (finds auth-related code), 'database connection pool' (finds DB connection code), 'error handling exception' (finds error handling patterns), 'API endpoint routes' (finds API route definitions). The tool returns formatted text snippets with file paths and line numbers showing where the relevant code is located.", }, }, required: ['project_root_path', 'query'], }, }, ]; return { tools }; });
- src/index.ts:98-107 (registration)Dispatch logic in CallToolRequestHandler that invokes searchContextTool when name === 'search_context'.if (name === 'search_context') { const result = await searchContextTool(args as any); return { content: [ { type: 'text', text: result.text, }, ], };
- src/index/manager.ts:617-693 (helper)Core helper method in IndexManager that performs automatic incremental indexing, loads indexed blobs, and executes semantic search via remote API, returning formatted retrieval results.async searchContext(projectRootPath: string, query: string): Promise<string> { const normalizedPath = this.normalizePath(projectRootPath); logger.info(`Searching context in project ${normalizedPath} with query: ${query}`); try { // 步骤 1: 自动索引 logger.info(`Auto-indexing project ${normalizedPath} before search...`); const indexResult = await this.indexProject(projectRootPath); if (indexResult.status === 'error') { return `Error: Failed to index project before search. ${indexResult.message}`; } // 记录索引统计信息 if (indexResult.stats) { logger.info( `Auto-indexing completed: total=${indexResult.stats.total_blobs}, existing=${indexResult.stats.existing_blobs}, new=${indexResult.stats.new_blobs}` ); } // 步骤 2: 加载已索引的 blob 名称 const projects = this.loadProjects(); const blobNames = projects[normalizedPath] || []; if (blobNames.length === 0) { return `Error: No blobs found for project ${normalizedPath} after indexing.`; } // 步骤 3: 执行搜索 logger.info(`Performing search with ${blobNames.length} blobs...`); const payload = { information_request: query, blobs: { checkpoint_id: null, added_blobs: blobNames, deleted_blobs: [], }, dialog: [], max_output_length: 0, disable_codebase_retrieval: false, enable_commit_retrieval: false, }; const searchRequest = async () => { // 使用 httpClient 确保配置一致性 const response = await this.httpClient.post( `${this.baseUrl}/agents/codebase-retrieval`, payload, { timeout: 60000, // 搜索请求使用更长的超时时间 } ); return response.data; }; let result: any; try { result = await this.retryRequest(searchRequest, 3, 2000); } catch (error: any) { logger.error(`Search request failed after retries: ${error.message}`); return `Error: Search request failed after 3 retries. ${error.message}`; } const formattedRetrieval = result.formatted_retrieval || ''; if (!formattedRetrieval) { logger.warning(`Search returned empty result for project ${normalizedPath}`); return 'No relevant code context found for your query.'; } logger.info(`Search completed for project ${normalizedPath}`); return formattedRetrieval; } catch (error: any) { logger.error(`Failed to search context in project ${normalizedPath}: ${error.message}`); return `Error: ${error.message}`; } }