UNPKG

claude-code-conversation-search-mcp

Version:

Never lose your Claude Code conversations again. Search across all projects, find old chats, and resume where you left off.

158 lines (136 loc) 5.59 kB
export class ConversationSearchError extends Error { constructor( public readonly code: string, message: string, public readonly userMessage: string, public readonly cause?: Error ) { super(message); this.name = 'ConversationSearchError'; } } export class DatabaseError extends ConversationSearchError { constructor(message: string, cause?: Error) { const userMessage = 'Database operation failed. Try refreshing the index or check if the database file is accessible.'; super('DATABASE_ERROR', message, userMessage, cause); } } export class FileAccessError extends ConversationSearchError { constructor(filePath: string, cause?: Error) { const userMessage = `Cannot access conversation file. Please check if Claude Code has proper file permissions and the file exists.`; super('FILE_ACCESS_ERROR', `Failed to access file: ${filePath}`, userMessage, cause); } } export class ParsingError extends ConversationSearchError { constructor(filePath: string, lineNumber?: number, cause?: Error) { const locationInfo = lineNumber ? ` at line ${lineNumber}` : ''; const userMessage = `Conversation file format is invalid${locationInfo}. This file may be corrupted or not a valid Claude conversation.`; super('PARSING_ERROR', `Failed to parse conversation file: ${filePath}${locationInfo}`, userMessage, cause); } } export class ConfigurationError extends ConversationSearchError { constructor(setting: string, cause?: Error) { const userMessage = `Configuration issue with ${setting}. Please check your environment variables or MCP server configuration.`; super('CONFIG_ERROR', `Configuration error: ${setting}`, userMessage, cause); } } export class SearchError extends ConversationSearchError { constructor(query: string, cause?: Error) { const userMessage = 'Search failed. Try simplifying your query or check if the database is properly indexed.'; super('SEARCH_ERROR', `Search failed for query: ${query}`, userMessage, cause); } } export class IndexingError extends ConversationSearchError { constructor(message: string, cause?: Error) { const userMessage = 'Failed to index conversations. Check if Claude Code projects directory exists and contains valid conversation files.'; super('INDEXING_ERROR', message, userMessage, cause); } } export function createUserFriendlyError(error: unknown, fallbackMessage: string = 'An unexpected error occurred'): ConversationSearchError { if (error instanceof ConversationSearchError) { return error; } if (error instanceof Error) { // Try to identify common error patterns and create appropriate user-friendly errors if (error.message.includes('ENOENT') || error.message.includes('no such file')) { return new FileAccessError(error.message, error); } if (error.message.includes('EACCES') || error.message.includes('permission denied')) { return new ConfigurationError('file permissions', error); } if (error.message.includes('database') || error.message.includes('SQL')) { return new DatabaseError(error.message, error); } if (error.message.includes('JSON') || error.message.includes('parse')) { return new ParsingError('unknown file', undefined, error); } } return new ConversationSearchError('UNKNOWN_ERROR', String(error), fallbackMessage); } export function getErrorResponse(error: unknown, context: string): { isError: true; content: [{ type: 'text'; text: string }] } { const searchError = createUserFriendlyError(error); const errorText = [ `❌ ${context} failed`, '', `**Error:** ${searchError.userMessage}`, '', '**Troubleshooting tips:**' ]; switch (searchError.code) { case 'FILE_ACCESS_ERROR': errorText.push( '• Check if ~/.claude/projects directory exists', '• Verify Claude Code has read permissions', '• Ensure conversation files are not corrupted' ); break; case 'DATABASE_ERROR': errorText.push( '• Try running refresh_index() to rebuild the database', '• Check if database file is not locked by another process', '• Verify disk space is available' ); break; case 'PARSING_ERROR': errorText.push( '• Some conversation files may be corrupted', '• Try restarting Claude Code to regenerate files', '• Check if specific files can be manually opened' ); break; case 'CONFIG_ERROR': errorText.push( '• Check MCP server configuration in claude_desktop_config.json', '• Verify environment variables are set correctly', '• Ensure proper file paths and permissions' ); break; case 'SEARCH_ERROR': errorText.push( '• Try a simpler search query', '• Check if database is indexed (run refresh_index())', '• Verify search terms are not empty' ); break; case 'INDEXING_ERROR': errorText.push( '• Check if ~/.claude/projects contains conversation files', '• Verify Claude Code is creating conversation files', '• Try restarting the MCP server' ); break; default: errorText.push( '• Try restarting the MCP server', '• Check the console for detailed error logs', '• Verify Claude Code is working properly' ); } return { isError: true, content: [{ type: 'text', text: errorText.join('\n') }] }; }