Search Vectors
search-vectorsFind files and code snippets using natural language queries in your project directory with semantic vector search.
Instructions
Search for files and code snippets using natural language queries
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Natural language search query | |
| path | No | Project path to search (defaults to current directory) | |
| provider | No | Embedding provider to use (defaults to configured provider) | |
| limit | No | Maximum number of results | |
| similarityThreshold | No | Minimum similarity score (0-1) | |
| filesOnly | No | Return only file paths without chunks |
Implementation Reference
- src/handlers/vector.ts:86-149 (handler)The main handler function that executes the 'search-vectors' tool logic. It validates input, checks for indexed vectors, gets embedding provider, and calls either getRelatedFiles or searchVectors based on filesOnly flag, then formats the results.
export async function handleSearchVectors(args: SearchVectorsInput): Promise<string> { const configManager = new ConfigManager(); logger.log('Searching vectors...'); try { // Check if project is indexed const vectorCount = await getVectorCount(args.path); if (vectorCount === 0) { return 'No vectors found. Please run index-vectors first.'; } // Get embedding provider let provider: EmbeddingProvider; if (args.provider) { provider = new EmbeddingProvider({ provider: args.provider }, configManager); } else { provider = await getDefaultEmbeddingProvider(configManager); } if (args.filesOnly) { // Get related files only const files = await getRelatedFiles({ projectPath: args.path, query: args.query, provider, limit: args.limit, similarityThreshold: args.similarityThreshold, }); if (files.length === 0) { return 'No matching files found.'; } return `Found ${files.length} related files:\n\n${files.map(f => `- ${f}`).join('\n')}`; } else { // Get full search results with chunks const results = await searchVectors({ projectPath: args.path, query: args.query, provider, limit: args.limit, similarityThreshold: args.similarityThreshold, }); if (results.length === 0) { return 'No matching results found.'; } const formatted = results.map((result, index) => { const preview = result.chunk.slice(0, 200).replace(/\n/g, ' '); return `${index + 1}. ${result.relpath} Similarity: ${(result.similarity * 100).toFixed(1)}% Chunk ID: ${result.chunkId} Preview: ${preview}${result.chunk.length > 200 ? '...' : ''}`; }).join('\n\n'); return `Found ${results.length} matches:\n\n${formatted}`; } } catch (error) { logger.error('Vector search failed:', error); throw new Error(`Search failed: ${error instanceof Error ? error.message : String(error)}`); } } - src/handlers/vector.ts:17-25 (schema)Zod schema defining the input parameters for the search-vectors tool, used for validation.
// Input schema for search-vectors tool export const SearchVectorsSchema = z.object({ query: z.string(), path: z.string().default(process.cwd()), provider: z.enum(['openai', 'azure', 'gemini']).optional(), limit: z.number().min(1).max(50).default(10), similarityThreshold: z.number().min(0).max(1).default(0.7), filesOnly: z.boolean().default(false), }); - src/server.ts:467-489 (registration)Registration of the 'search-vectors' tool on the MCP server, dynamically importing and calling the handler function.
server.registerTool("search-vectors", { title: "Search Vectors", description: "Search for files and code snippets using natural language queries", inputSchema: SearchVectorsSchema.shape, }, async (args) => { const { handleSearchVectors } = await import("./handlers/vector"); const result = await handleSearchVectors({ query: args.query, path: args.path || process.cwd(), provider: args.provider, limit: args.limit || 10, similarityThreshold: args.similarityThreshold || 0.7, filesOnly: args.filesOnly || false, }); return { content: [ { type: "text", text: result } ] }; });