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
TableJSON 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 BeautifulFormattercase '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_levelinputSchema: { 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 descriptionname: '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 densityformatSearchConversations(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)}`; }