store-codebase-insight
Store code analysis insights like architectural decisions, performance bottlenecks, security concerns, and refactoring opportunities for repositories to support development workflows.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| repositoryUrl | Yes | ||
| insightType | Yes | ||
| insightContent | Yes | ||
| relatedFiles | No | ||
| tags | No |
Implementation Reference
- src/features/memory/index.ts:31-61 (handler)The core execution logic of the tool: categorizes the insight using categorizeInsight, stores it using storeMemory, and returns a success or error message.async ({ repositoryUrl, insightType, insightContent, relatedFiles, tags }) => { try { // Categorize and store the insight const category = await categorizeInsight(insightContent, insightType); const memoryId = await storeMemory({ repositoryUrl, insightType, category, insightContent, relatedFiles: relatedFiles || [], tags: tags || [], timestamp: new Date().toISOString() }); return { content: [{ type: "text", text: `Successfully stored insight with ID: ${memoryId}` }] }; } catch (error) { return { content: [{ type: "text", text: `Error storing insight: ${(error as Error).message}` }], isError: true }; } } );
- src/features/memory/index.ts:17-30 (schema)Zod schema defining the input parameters for the tool: repositoryUrl, insightType (enum), insightContent, optional relatedFiles and tags.{ repositoryUrl: z.string(), insightType: z.enum([ "architectural-decision", "performance-bottleneck", "security-concern", "code-pattern", "refactoring-opportunity", "other" ]), insightContent: z.string(), relatedFiles: z.array(z.string()).optional(), tags: z.array(z.string()).optional() },
- src/features/memory/index.ts:16-61 (registration)Registration of the 'store-codebase-insight' tool on the MCP server, specifying name, input schema, and handler function."store-codebase-insight", { repositoryUrl: z.string(), insightType: z.enum([ "architectural-decision", "performance-bottleneck", "security-concern", "code-pattern", "refactoring-opportunity", "other" ]), insightContent: z.string(), relatedFiles: z.array(z.string()).optional(), tags: z.array(z.string()).optional() }, async ({ repositoryUrl, insightType, insightContent, relatedFiles, tags }) => { try { // Categorize and store the insight const category = await categorizeInsight(insightContent, insightType); const memoryId = await storeMemory({ repositoryUrl, insightType, category, insightContent, relatedFiles: relatedFiles || [], tags: tags || [], timestamp: new Date().toISOString() }); return { content: [{ type: "text", text: `Successfully stored insight with ID: ${memoryId}` }] }; } catch (error) { return { content: [{ type: "text", text: `Error storing insight: ${(error as Error).message}` }], isError: true }; } } );
- Helper function to store the insight in SQLite database, handling related files and tags with transactions.export async function storeMemory(insight: Insight): Promise<number> { // Initialize the database if it hasn't been initialized if (!db) { db = await createDatabase("memory"); } const { repositoryUrl, insightType, category, insightContent, relatedFiles, tags, timestamp } = insight; if (!db) { throw new Error("Database not initialized"); } // Start transaction await db.exec('BEGIN TRANSACTION'); try { // Insert the insight const insightResult = await db.run( `INSERT INTO insights (repositoryUrl, insightType, category, insightContent, timestamp) VALUES (?, ?, ?, ?, ?)`, [repositoryUrl, insightType, category, insightContent, timestamp] ); const insightId = insightResult.lastID ?? 0; // Use default value if undefined if (insightId === 0) { throw new Error("Failed to insert insight - no ID returned"); } // Insert related files if (relatedFiles && relatedFiles.length > 0) { for (const filePath of relatedFiles) { await db.run( `INSERT INTO relatedFiles (insightId, filePath) VALUES (?, ?)`, [insightId, filePath] ); } } // Insert tags if (tags && tags.length > 0) { for (const tag of tags) { await db.run( `INSERT INTO tags (insightId, tag) VALUES (?, ?)`, [insightId, tag] ); } } // Commit transaction await db.exec('COMMIT'); return insightId; } catch (error) { // Rollback transaction on error await db.exec('ROLLBACK'); throw error; } }
- Helper function to categorize the insight into priority levels based on type and keyword heuristics.export async function categorizeInsight( insightContent: string, insightType: InsightType ): Promise<InsightCategory> { // Simple heuristic for categorization - would be replaced with actual ML/NLP // Security concerns are usually high priority if (insightType === "security-concern") { return "high-priority"; } // Check for urgent keywords const urgentKeywords = ["critical", "urgent", "immediate", "severe", "vulnerability"]; if (urgentKeywords.some(keyword => insightContent.toLowerCase().includes(keyword))) { return "high-priority"; } // Performance bottlenecks might be medium priority if (insightType === "performance-bottleneck") { return "medium-priority"; } // Check for medium-priority keywords const mediumKeywords = ["important", "should", "improve", "refactor"]; if (mediumKeywords.some(keyword => insightContent.toLowerCase().includes(keyword))) { return "medium-priority"; } // Refactoring opportunities might be low priority if (insightType === "refactoring-opportunity" || insightType === "code-pattern") { return "low-priority"; } // Default to information if no specific category is determined return "information"; }