rag_search
Search your personal document corpus to find relevant information from notes, files, and web content for developer operational tasks.
Instructions
Поиск по личному корпусу документов
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Поисковый запрос | |
| limit | No | Максимальное количество результатов |
Implementation Reference
- src/rag/rag-service.ts:17-37 (handler)Primary handler for rag_search tool: orchestrates the search using SQLiteClient.search with query and limit parameters.async search(query: string, limit: number = 5): Promise<SearchResult[]> { try { console.log(`🔍 Поиск: "${query}" (лимит: ${limit})`); // Получаем SQLiteClient из пула соединений const sqliteClient = await this.connectionPool.getSQLiteClient(); // Выполняем поиск через SQLite const results = await sqliteClient.search(query, { limit }); if (results.isErr()) { throw new Error(`Ошибка поиска: ${results.error.message}`); } console.log(`✅ Найдено результатов: ${results.value.length}`); return results.value; } catch (error) { console.error('Ошибка поиска:', error); throw new Error(`Ошибка поиска: ${error}`); } }
- src/rag/sqlite-client.ts:485-531 (handler)Core RAG search implementation using SQLite FTS5 full-text search with keyword fallback, snippets, and highlights.async search(query: string, options: SearchOptions = {}): Promise<Result<SearchResult[], SQLiteError>> { const { limit = 10, offset = 0, includeSnippets = true, highlightTerms = true, minScore = 0.1 } = options; try { // Try FTS search first let results = await this.performFTSSearch(query, limit, offset); if (results.length === 0) { // Fallback to simple search results = await this.performSimpleSearch(query, limit, offset); } // Filter by minimum score const filteredResults = results.filter(r => r.score >= minScore); // Add snippets and highlights if requested if (includeSnippets || highlightTerms) { filteredResults.forEach(result => { if (includeSnippets) { result.snippet = this.generateSnippet(result.text, query, 200); } if (highlightTerms) { result.highlights = this.extractHighlights(result.text, query); } }); } this.metrics.recordOperation('search'); this.logger.info('Search completed', { query, resultsCount: filteredResults.length }); return ok(filteredResults); } catch (error) { this.metrics.recordError('search'); return err(new SQLiteError( `Search failed: ${error instanceof Error ? error.message : String(error)}`, 'SEARCH_ERROR', undefined, error instanceof Error ? error : undefined )); } }
- src/server.ts:187-190 (handler)MCP server tool call dispatcher: handles 'rag_search' by invoking RAGService.search.case 'rag_search': return { content: await this.ragService.search(args.query as string, (args.limit as number) || 5) };
- src/server.ts:44-60 (schema)Input schema definition for rag_search tool in MCP ListTools response.name: 'rag_search', description: 'Поиск по личному корпусу документов', inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Поисковый запрос', }, limit: { type: 'number', description: 'Максимальное количество результатов', default: 5, }, }, required: ['query'], },
- src/server.ts:178-227 (registration)Registration of CallToolRequestSchema handler including rag_search case in main MCP server.this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; if (!args) { throw new Error('Аргументы не предоставлены'); } try { switch (name) { case 'rag_search': return { content: await this.ragService.search(args.query as string, (args.limit as number) || 5) }; case 'rag_add_document': await this.ragService.addDocument(args.uri as string, args.content as string, args.title as string); return { content: 'Документ добавлен' }; case 'file_read': return { content: await this.fileService.readFile(args.path as string) }; case 'file_write': await this.fileService.writeFile(args.path as string, args.content as string); return { content: 'Файл записан' }; case 'web_fetch': return { content: await this.webService.fetchPage(args.url as string) }; case 'task_create': return { content: await this.taskService.createTask(args.title as string, args.project as string, args.due as string) }; case 'task_list': return { content: await this.taskService.listTasks(args.project as string, args.status as string) }; default: throw new Error(`Неизвестный инструмент: ${name}`); } } catch (error) { console.error(`Ошибка выполнения инструмента ${name}:`, error); throw error; } });