Skip to main content
Glama

Cursor DB MCP Server

by TaylorChen
chat-parser.ts5 kB
import { ChatConversation, ChatMessage, CodeBlock, FileChange } from '../types/cursor-data.js'; export class ChatParser { static parseConversations(chatData: any): ChatConversation[] { if (!chatData || !Array.isArray(chatData.conversations)) { return []; } return chatData.conversations.map((conv: any) => ({ id: conv.id || this.generateId(), title: conv.title || 'Untitled Conversation', messages: this.parseMessages(conv.messages || []), createdAt: conv.createdAt || new Date().toISOString(), updatedAt: conv.updatedAt || new Date().toISOString(), workspaceFolder: conv.workspaceFolder })); } static fromRoleMessages(roleMessages: any[]): ChatConversation[] { if (!Array.isArray(roleMessages)) return []; const messages: ChatMessage[] = roleMessages .filter((m: any) => typeof m === 'object' && m) .map((m: any, idx: number) => ({ id: m.id || `msg-${idx}`, type: (m.role === 'user' ? 'user' : 'assistant'), text: m.content || m.text || '', createdAt: new Date(m.unixMs || Date.now()).toISOString(), bubbleId: m.bubbleId, contextFiles: this.parseContextFiles(m.contextFiles), codeBlocks: this.extractCodeBlocks(m.content || m.text || '') })); const now = new Date().toISOString(); return [{ id: `conv-${Math.random().toString(36).slice(2)}`, title: 'Imported Conversation', createdAt: now, updatedAt: now, messages }]; } static parseMessages(messagesData: any[]): ChatMessage[] { return messagesData.map((msg: any) => ({ id: msg.id || this.generateId(), type: msg.type === 'user' ? 'user' : 'assistant', text: msg.text || '', createdAt: msg.createdAt || new Date().toISOString(), bubbleId: msg.bubbleId, contextFiles: this.parseContextFiles(msg.contextFiles), codeBlocks: this.extractCodeBlocks(msg.text || '') })); } static parseContextFiles(contextFiles: any[]): any[] { if (!Array.isArray(contextFiles)) return []; return contextFiles.map((file: any) => ({ path: file.path || '', content: file.content || '', language: file.language || 'text' })); } static extractCodeBlocks(text: string): CodeBlock[] { const codeBlockRegex = /```(\w+)?\n([\s\S]*?)```/g; const blocks: CodeBlock[] = []; let match: RegExpExecArray | null; while ((match = codeBlockRegex.exec(text)) !== null) { blocks.push({ language: match[1] || 'text', code: match[2].trim(), filename: this.extractFilename(match[2]) }); } return blocks; } static extractFilename(code: string): string | undefined { const lines = code.split('\n'); const firstLine = lines[0]?.trim(); if (firstLine && /^\/\*.*\*\/$/.test(firstLine)) { return firstLine.replace(/^\/\*\s*|\s*\*\/$/g, ''); } if (firstLine && /\.(js|ts|py|java|cpp|html|css|json)$/.test(firstLine)) { return firstLine; } return undefined; } static analyzeCodeChanges(messages: ChatMessage[]): { totalLinesAdded: number; totalLinesModified: number; totalLinesDeleted: number; fileChanges: FileChange[]; } { let totalLinesAdded = 0; let totalLinesModified = 0; let totalLinesDeleted = 0; const fileChanges: FileChange[] = []; for (let i = 0; i < messages.length - 1; i++) { const userMsg = messages[i]; const assistantMsg = messages[i + 1]; if (userMsg.type === 'user' && assistantMsg.type === 'assistant') { const userBlocks = userMsg.codeBlocks || []; const assistantBlocks = assistantMsg.codeBlocks || []; assistantBlocks.forEach(block => { const lines = block.code.split('\n').length; const filename = block.filename || `unnamed.${block.language}`; const userBlock = userBlocks.find(ub => ub.language === block.language || ub.filename === block.filename); if (userBlock) { const userLines = userBlock.code.split('\n').length; const diff = lines - userLines; if (diff > 0) { totalLinesAdded += diff; } else { totalLinesModified += Math.abs(diff); } fileChanges.push({ file: filename, type: 'modify', additions: Math.max(0, diff), deletions: Math.max(0, -diff) }); } else { totalLinesAdded += lines; fileChanges.push({ file: filename, type: 'create', additions: lines, deletions: 0, content: block.code }); } }); } } return { totalLinesAdded, totalLinesModified, totalLinesDeleted, fileChanges }; } private static generateId(): string { return Math.random().toString(36).substr(2, 9); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/TaylorChen/cursor-db-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server