search_conversations
Search Claude Code conversation history to find past solutions, track file changes, and learn from previous work.
Instructions
Search through Claude Code conversation history with smart insights
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Search query to find relevant conversations | |
| project | No | Optional project name to filter results | |
| timeframe | No | Time range filter (today, week, month) | |
| limit | No | Maximum number of results (default: 10) | |
| detail_level | No | Response detail: summary (default), detailed, raw | summary |
Implementation Reference
- src/index.ts:265-282 (handler)MCP CallTool handler for 'search_conversations' that invokes universalEngine.searchConversations and formats the result using BeautifulFormatter
case 'search_conversations': { const universalResult = await this.universalEngine.searchConversations( args?.query as string, args?.project as string, args?.timeframe as string, (args?.limit as number) || 10 ); const detailLevel = (args?.detail_level as string) || 'summary'; const formattedResult = this.formatter.formatSearchConversations( universalResult.results, detailLevel ); return { content: [{ type: 'text', text: formattedResult }], }; } - src/index.ts:47-75 (schema)Input schema definition for the search_conversations tool, defining parameters like query, project, timeframe, limit, and detail_level
inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Search query to find relevant conversations', }, project: { type: 'string', description: 'Optional project name to filter results', }, timeframe: { type: 'string', description: 'Time range filter (today, week, month)', }, limit: { type: 'number', description: 'Maximum number of results (default: 10)', default: 10, }, detail_level: { type: 'string', description: 'Response detail: summary (default), detailed, raw', enum: ['summary', 'detailed', 'raw'], default: 'summary', }, }, required: ['query'], }, - src/index.ts:45-76 (registration)Tool registration in ListTools response, including name and description
name: 'search_conversations', description: 'Search through Claude Code conversation history with smart insights', inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Search query to find relevant conversations', }, project: { type: 'string', description: 'Optional project name to filter results', }, timeframe: { type: 'string', description: 'Time range filter (today, week, month)', }, limit: { type: 'number', description: 'Maximum number of results (default: 10)', default: 10, }, detail_level: { type: 'string', description: 'Response detail: summary (default), detailed, raw', enum: ['summary', 'detailed', 'raw'], default: 'summary', }, }, required: ['query'], }, }, - src/universal-engine.ts:69-104 (handler)Core implementation of searchConversations in UniversalHistorySearchEngine, combining results from Claude Code (primary) and Claude Desktop (if available, currently disabled)
async searchConversations( query: string, project?: string, timeframe?: string, limit?: number ): Promise<UniversalSearchResult> { await this.initialize(); const claudeCodeResults = await this.claudeCodeEngine.searchConversations( query, project, timeframe, limit ); if (!this.claudeDesktopAvailable) { return { source: 'claude-code', results: claudeCodeResults, enhanced: false, }; } const desktopMessages = await this.searchClaudeDesktopConversations(query, timeframe, limit); const combinedResults = this.combineSearchResults(claudeCodeResults, desktopMessages); // Only mark as enhanced if we actually found Desktop data const hasDesktopData = desktopMessages.length > 0; return { source: hasDesktopData ? 'claude-desktop' : 'claude-code', results: combinedResults, enhanced: hasDesktopData, }; } - src/formatter.ts:274-296 (helper)Helper function to format search results into a structured JSON response with ranking and deduplication for maximum information density
formatSearchConversations(result: SearchResult, _detailLevel: string = 'summary'): string { const header = `${robots.search} "${result.searchQuery}" | ${result.messages.length} results`; if (result.messages.length === 0) { return `${header}\n\n{"results":[]}`; } const rankedMessages = this.rankAndDeduplicateMessages(result.messages); const topMessages = rankedMessages.slice(0, 8); const structured = { results: topMessages.map((msg) => ({ type: msg.type, ts: this.formatTimestamp(msg.timestamp), content: msg.content, project: msg.projectPath?.split('/').pop() || null, score: msg.relevanceScore || msg.score || null, ctx: msg.context || null, })), }; return `${header}\n\n${JSON.stringify(structured, null, 2)}`; }