find_tool_patterns
Analyzes successful tool usage patterns within Claude Historian's conversation history to optimize workflows and improve decision-making.
Instructions
Find patterns of successful tool usage
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of patterns (default: 20) | |
| tool_name | No | Optional specific tool name to analyze |
Implementation Reference
- src/index.ts:420-447 (handler)MCP CallTool handler for 'find_tool_patterns': delegates to UniversalHistorySearchEngine.getToolPatterns, formats with BeautifulFormatter.formatToolPatterns, adds header.case 'find_tool_patterns': { const universalResult = await this.universalEngine.getToolPatterns( args?.tool_name as string, (args?.limit as number) || 12 ); const patternType = (args?.pattern_type as string) || 'tools'; const formattedResult = this.formatter.formatToolPatterns(universalResult.results as any, args?.tool_name as string, patternType); // Create enhanced 3-line header with tool pattern context const lines = formattedResult.split('\n'); const sourceInfo = universalResult.enhanced ? '[⌐⎚_⎚] Searching: Claude Code + Desktop' : '[⌐⎚_⎚] Searching: Claude Code'; const actionInfo = `Tool: "${args?.tool_name || 'all'}" | Action: Pattern analysis | Type: ${patternType}`; lines[0] = sourceInfo; lines[1] = actionInfo; return { content: [ { type: 'text', text: lines.join('\n'), }, ], }; }
- src/index.ts:207-229 (schema)Input schema and metadata for 'find_tool_patterns' tool in ListTools response.name: 'find_tool_patterns', description: 'Analyze tool usage patterns, workflows, and successful practices', inputSchema: { type: 'object', properties: { tool_name: { type: 'string', description: 'Optional specific tool name to analyze', }, pattern_type: { type: 'string', description: 'Type of patterns: tools, workflows, or solutions', enum: ['tools', 'workflows', 'solutions'], default: 'tools', }, limit: { type: 'number', description: 'Maximum number of patterns (default: 12)', default: 12, }, }, }, },
- src/search.ts:937-1131 (handler)Core implementation in HistorySearchEngine.getToolPatterns: scans conversations in parallel, extracts individual tool usages and multi-step workflows (e.g., 'Edit → Read → findtoolpatterns'), aggregates frequencies, deduplicates, returns ranked ToolPattern objects.async getToolPatterns(toolName?: string, limit: number = 20): Promise<ToolPattern[]> { const toolMap = new Map<string, CompactMessage[]>(); const workflowMap = new Map<string, CompactMessage[]>(); try { const projectDirs = await findProjectDirectories(); const limitedDirs = projectDirs.slice(0, 15); // Focus on core Claude Code tools that GLOBAL would recognize const coreTools = new Set(['Edit', 'Read', 'Bash', 'Grep', 'Glob', 'Write', 'Task', 'MultiEdit', 'Notebook']); // PARALLEL PROCESSING: Process all projects concurrently const projectResults = await Promise.allSettled( limitedDirs.map(async (projectDir) => { const jsonlFiles = await findJsonlFiles(projectDir); const limitedFiles = jsonlFiles.slice(0, 8); const projectToolMap = new Map<string, CompactMessage[]>(); const projectWorkflowMap = new Map<string, CompactMessage[]>(); // PARALLEL: Process files within project simultaneously const fileResults = await Promise.allSettled( limitedFiles.map(async (file) => { const messages = await this.parser.parseJsonlFile(projectDir, file); // Extract individual tool usage patterns for (const msg of messages) { if (msg.context?.toolsUsed?.length) { for (const tool of msg.context.toolsUsed) { // Only track core tools to match GLOBAL's focus if (coreTools.has(tool) || !toolName || tool === toolName) { if (!projectToolMap.has(tool)) { projectToolMap.set(tool, []); } projectToolMap.get(tool)!.push(msg); } } } } // Extract workflow patterns (tool sequences) for (let i = 0; i < messages.length - 1; i++) { const current = messages[i]; const next = messages[i + 1]; if (current.context?.toolsUsed?.length && next.context?.toolsUsed?.length) { // Create focused workflow patterns like GLOBAL: "Edit → Read" for (const currentTool of current.context.toolsUsed) { for (const nextTool of next.context.toolsUsed) { // Only create workflows with core tools if ((coreTools.has(currentTool) || !toolName || currentTool === toolName) && (coreTools.has(nextTool) || !toolName || nextTool === toolName)) { const workflowKey = `${currentTool} → ${nextTool}`; if (!projectWorkflowMap.has(workflowKey)) { projectWorkflowMap.set(workflowKey, []); } projectWorkflowMap.get(workflowKey)!.push(current, next); } } } } } // Also create longer sequences for complex workflows for (let i = 0; i < messages.length - 2; i++) { const first = messages[i]; const second = messages[i + 1]; const third = messages[i + 2]; if (first.context?.toolsUsed?.length && second.context?.toolsUsed?.length && third.context?.toolsUsed?.length) { for (const firstTool of first.context.toolsUsed) { for (const secondTool of second.context.toolsUsed) { for (const thirdTool of third.context.toolsUsed) { // Create 3-step workflows like "Edit → Read → findtoolpatterns" if (coreTools.has(firstTool) && coreTools.has(secondTool)) { const workflowKey = `${firstTool} → ${secondTool} → ${thirdTool}`; if (!projectWorkflowMap.has(workflowKey)) { projectWorkflowMap.set(workflowKey, []); } projectWorkflowMap.get(workflowKey)!.push(first, second, third); } } } } } } }) ); return { tools: projectToolMap, workflows: projectWorkflowMap }; }) ); // Aggregate results from parallel processing for (const result of projectResults) { if (result.status === 'fulfilled') { // Aggregate individual tools for (const [tool, messages] of result.value.tools.entries()) { if (!toolMap.has(tool)) { toolMap.set(tool, []); } toolMap.get(tool)!.push(...messages); } // Aggregate workflows for (const [workflow, messages] of result.value.workflows.entries()) { if (!workflowMap.has(workflow)) { workflowMap.set(workflow, []); } workflowMap.get(workflow)!.push(...messages); } } } const patterns: ToolPattern[] = []; // ENHANCED: Create diverse patterns like GLOBAL showing related tools with workflows const toolFrequency = new Map<string, number>(); // First pass: Calculate tool frequencies for prioritization for (const [tool, messages] of toolMap.entries()) { toolFrequency.set(tool, messages.length); } // Add diverse individual tool patterns (different tools, not just highest frequency) const usedTools = new Set<string>(); for (const [tool, messages] of Array.from(toolMap.entries()).sort((a, b) => b[1].length - a[1].length)) { if (messages.length >= 1 && !usedTools.has(tool) && patterns.length < limit) { const uniqueMessages = SearchHelpers.deduplicateByContent(messages); patterns.push({ toolName: tool, successfulUsages: uniqueMessages.slice(0, 10), commonPatterns: [`${tool} usage pattern`], bestPractices: [`${tool} used ${uniqueMessages.length}x successfully`], }); usedTools.add(tool); } } // Add related workflow patterns for each tool (like GLOBAL's approach) for (const tool of usedTools) { // Find workflows involving this tool for (const [workflow, messages] of workflowMap.entries()) { if (workflow.includes(tool) && workflow.includes('→') && messages.length >= 1) { const uniqueMessages = SearchHelpers.deduplicateByContent(messages); // Only add if not already added and we have space if (!patterns.some(p => p.toolName === workflow) && patterns.length < limit) { patterns.push({ toolName: workflow, successfulUsages: uniqueMessages.slice(0, 10), commonPatterns: [workflow], bestPractices: [`${workflow} workflow (${uniqueMessages.length}x successful)`], }); } } } } // If we still have space, add any remaining high-frequency workflows for (const [workflow, messages] of Array.from(workflowMap.entries()).sort((a, b) => b[1].length - a[1].length)) { if (workflow.includes('→') && messages.length >= 1 && patterns.length < limit) { if (!patterns.some(p => p.toolName === workflow)) { const uniqueMessages = SearchHelpers.deduplicateByContent(messages); patterns.push({ toolName: workflow, successfulUsages: uniqueMessages.slice(0, 10), commonPatterns: [workflow], bestPractices: [`${workflow} workflow (${uniqueMessages.length}x successful)`], }); } } } // Sort to prioritize individual tools, then their related workflows return patterns .sort((a, b) => { const aIsWorkflow = a.toolName.includes('→'); const bIsWorkflow = b.toolName.includes('→'); // Individual tools first, then workflows, then by usage frequency if (aIsWorkflow !== bIsWorkflow) { return aIsWorkflow ? 1 : -1; } return b.successfulUsages.length - a.successfulUsages.length; }) .slice(0, limit); } catch (error) { console.error('Tool pattern search error:', error); return []; } }
- src/formatter.ts:590-626 (helper)BeautifulFormatter.formatToolPatterns: formats ToolPattern results with rankings, success rates, best practices, and workflow intelligence for the tool response.formatToolPatterns(patterns: ToolPattern[], toolName?: string, _patternType: string = 'tools'): string { const toolFilter = toolName ? ` for "${toolName}"` : ''; let output = `Tool usage patterns${toolFilter}\n\n`; if (patterns.length === 0) { return output + 'No tool patterns found.\n'; } // REVOLUTIONARY: Usage frequency ranking and workflow intelligence const rankedPatterns = this.rankToolPatternsByValue(patterns); const topPatterns = rankedPatterns.slice(0, Math.min(patterns.length, 8)); output += `Found ${patterns.length} patterns, showing ${topPatterns.length} highest-value (${Math.round((topPatterns.length/patterns.length)*100)}% success rate):\n\n`; topPatterns.forEach((pattern, index) => { const successRate = pattern.successfulUsages.length; const efficiency = this.calculateToolEfficiency(pattern); output += `${index + 1}. ${pattern.toolName} (${successRate} uses, ${efficiency}% efficiency)\n`; // Extract most valuable pattern if (pattern.commonPatterns.length > 0) { const bestPattern = this.selectBestPattern(pattern.commonPatterns); output += ` Pattern: ${bestPattern}\n`; } // Extract most actionable practice if (pattern.bestPractices.length > 0) { const bestPractice = this.selectBestPractice(pattern.bestPractices); output += ` Best Practice: ${bestPractice}\n`; } output += '\n'; }); return output.trim(); }
- src/universal-engine.ts:1390-1410 (helper)Delegation layer in UniversalHistorySearchEngine.getToolPatterns: calls HistorySearchEngine impl, adds desktop enhancement flag.async getToolPatterns(toolName?: string, limit?: number): Promise<UniversalSearchResult> { await this.initialize(); const claudeCodePatterns = await this.claudeCodeEngine.getToolPatterns(toolName, limit || 12); if (!this.claudeDesktopAvailable) { return { source: 'claude-code', results: claudeCodePatterns as any, enhanced: false }; } // For tool patterns, Desktop doesn't have tool usage data, so we focus on Code // But we mark as enhanced if Desktop is available for future Desktop tool analysis return { source: 'claude-code', results: claudeCodePatterns as any, enhanced: this.claudeDesktopAvailable }; }