UNPKG

mongodb-memory-bank-mcp-v2

Version:

MongoDB-powered Memory Bank MCP server with hybrid search capabilities for AI assistants

398 lines (344 loc) 10.7 kB
import { join, basename } from 'path'; import { existsSync, mkdirSync, writeFileSync } from 'fs'; import { InitToolSchema } from '../types/memory.js'; import { getMemoryCollection } from '../db/connection.js'; import { logger } from '../utils/logger.js'; import { createHash } from 'crypto'; import { initializeContextEngineeringTemplates } from '../services/context-engineering.js'; const MEMORY_BANK_DIR = '.memory-bank'; const CONFIG_FILE = 'config.json'; const INITIAL_MEMORY_TEMPLATES = { 'projectbrief.md': `# Project Brief ## Project Name [Project name here] ## Overview [One sentence: What does this project do?] ## Problem & Solution - **Problem**: [Specific problem we're solving] - **Solution**: [How we're solving it] - **Why Now**: [Why is this the right time?] ## Goals - **Primary**: [Main objective - be specific] - **Metrics**: [How we measure success] - **Timeline**: [Key milestones] ## Scope ### In Scope - [Core feature 1] - [Core feature 2] - [Technical requirement] ### Out of Scope - [Future feature] - [Not needed now] ## Success Criteria - **Technical**: [e.g., 95% test coverage, <100ms response] - **User**: [e.g., Solves X problem for Y users] - **Business**: [e.g., Reduces Z by N%] ## AI Context Guide **When coding this project, remember:** - Start with [this component/feature] - Use [specific patterns/libraries] - Avoid [anti-patterns] - See systemPatterns.md for architecture `, 'productContext.md': `# Product Context ## Problem Statement **The Problem**: [Specific problem in 1-2 sentences] **Current Solutions**: [What exists today and why it's not enough] **Our Approach**: [How we're different/better] ## Target Users ### Primary User - **Who**: [Specific user type] - **Needs**: [What they're trying to accomplish] - **Pain Points**: [Current frustrations] ### User Journey 1. [Step 1: Discovery] 2. [Step 2: First use] 3. [Step 3: Regular use] ## Key Features - **Feature 1**: [What it does] [User benefit] - **Feature 2**: [What it does] [User benefit] ## Competitive Analysis - **Alternative 1**: [Pros/Cons] - **Alternative 2**: [Pros/Cons] - **Our Advantage**: [Why choose us] ## Success Metrics - **Adoption**: [Target metrics] - **Engagement**: [Usage patterns] - **Satisfaction**: [Quality measures] `, 'activeContext.md': `# Active Context ## Current Sprint/Phase **Goal**: [What we're trying to achieve this sprint] **Deadline**: [When it needs to be done] ## Active Tasks ### In Progress - [ ] [Current task with context] - Status: [Where we are] - Blockers: [Any issues] - Next: [Immediate next step] ### Up Next - [ ] [Next priority] - [ ] [Following task] ## Recent Changes - **[Date]**: [What changed and why] - **[Date]**: [Important update] ## Working Directory Structure \`\`\` src/ ├── [Key directories with purpose] └── [Current focus area] \`\`\` ## Key Commands \`\`\`bash # Development npm run dev # [What this does] npm test # [Test command] # Project-specific [Important commands] \`\`\` ## Open Questions - [ ] [Technical decision needed] - [ ] [Design choice to make] ## AI Coding Notes - Currently working in: [file/module] - Watch out for: [gotchas] - Related files: [see techContext.md for stack] `, 'systemPatterns.md': `# System Patterns ## Architecture Overview \`\`\` [ASCII diagram or component layout] \`\`\` ## Core Design Principles 1. **[Principle]**: [Why it matters here] 2. **[Principle]**: [How we implement it] ## Key Components ### [Component Name] - **Purpose**: [What it does] - **Interface**: [How to use it] - **Location**: \`src/path/to/component\` - **Example**: \`\`\`typescript // Quick usage example \`\`\` ## Design Patterns ### [Pattern Name] - **Where**: [Which components use this] - **Why**: [Problem it solves] - **Implementation**: \`\`\`typescript // Code example \`\`\` ## Data Flow 1. **Input**: [How data enters] 2. **Processing**: [Key transformations] 3. **Storage**: [Where/how stored] 4. **Output**: [How data exits] ## Error Handling Strategy - **Validation**: [Input validation approach] - **Error Types**: [Common errors and handling] - **User Feedback**: [How errors are communicated] ## Performance Considerations - **Bottlenecks**: [Known slow points] - **Optimizations**: [What we've optimized] - **Monitoring**: [How to measure] ## AI Implementation Guide - **Entry Points**: Start with [these files] - **Core Logic**: Located in [these modules] - **Extension Points**: Add features at [these interfaces] - **Testing**: Run [these tests] when changing [this] `, 'techContext.md': `# Technical Context ## Technology Stack ### Core - **Language**: [Language + version] - **Runtime**: [Node.js/Python/etc + version] - **Framework**: [Framework + why chosen] - **Database**: MongoDB Atlas (Vector Search enabled) ### Key Dependencies \`\`\`json { "critical": { "[package]": "[version] - [why essential]" } } \`\`\` ## Development Environment ### Prerequisites - [Requirement 1 with version] - [Requirement 2 with install command] ### Setup Steps \`\`\`bash # 1. Clone and install git clone [repo] npm install # 2. Environment variables cp .env.example .env.local # Edit: [Which vars to set] # 3. Run development npm run dev \`\`\` ## Architecture Decisions ### [Decision 1] - **Choice**: [What we chose] - **Alternatives**: [What we didn't choose] - **Rationale**: [Why this was best] ## API/Interface Design ### [Main API/Interface] \`\`\`typescript // Interface example interface Example { // Key method signatures } \`\`\` ## Performance Profile - **Load Time**: [Target metrics] - **Memory Usage**: [Constraints] - **Scalability**: [Considerations] ## Security Considerations - **Authentication**: [Approach] - **Data Protection**: [Methods] - **Input Validation**: [Strategy] ## Testing Strategy - **Unit Tests**: [Framework, coverage target] - **Integration**: [Key test scenarios] - **E2E**: [Critical paths] ## Deployment - **Environment**: [Where it runs] - **CI/CD**: [Pipeline details] - **Monitoring**: [What we track] `, 'progress.md': `# Progress ## Project Timeline - **Started**: [Date] - **Target**: [Date] - **Phase**: [Current phase] ## Completed ✅ ### [Week/Sprint] - [x] [Achievement with impact] - Result: [What this enabled] - Learning: [Key insight] ## In Progress 🚧 ### [Current Task] - [ ] [Subtask 1] - [% complete] - [ ] [Subtask 2] - [Status] ## Upcoming 📋 ### Next Sprint - [ ] [Priority 1] - [ ] [Priority 2] ## Issues & Solutions 🔧 ### [Issue Name] - **Problem**: [What went wrong] - **Solution**: [How we fixed it] - **Prevention**: [Avoiding in future] ## Metrics 📊 - **Coverage**: [Test %] - **Performance**: [Key metric] - **Progress**: [% to goal] ## Lessons Learned 💡 1. **[Topic]**: [Insight] 2. **[Pattern]**: [What worked] ## AI Notes - **Effective**: [Patterns that worked] - **Avoid**: [What slowed us down] - **Remember**: [Key context for AI] `, }; function generateProjectId(projectPath) { // Create deterministic project ID from path const hash = createHash('sha256').update(projectPath).digest('hex'); return `${hash.substring(0, 8)}-${hash.substring(8, 12)}-${hash.substring(12, 16)}-${hash.substring(16, 20)}-${hash.substring(20, 32)}`; } export async function initTool(args) { try { const params = InitToolSchema.parse(args); const projectPath = params.projectPath || process.cwd(); const projectName = params.projectName || basename(projectPath); // Create .memory-bank directory const memoryBankPath = join(projectPath, MEMORY_BANK_DIR); if (!existsSync(memoryBankPath)) { mkdirSync(memoryBankPath, { recursive: true }); } // Check if already initialized const configPath = join(memoryBankPath, CONFIG_FILE); if (existsSync(configPath)) { return { content: [ { type: 'text', text: 'Memory bank already initialized for this project. Use memory_bank/read to access existing memories.', }, ], }; } // Generate project ID (deterministic from path) const projectId = generateProjectId(projectPath); // Create project config const config = { projectId, projectPath, name: projectName, createdAt: new Date().toISOString(), }; // Save config writeFileSync(configPath, JSON.stringify(config, null, 2)); // Create initial memory files in MongoDB const collection = getMemoryCollection(); const now = new Date(); const memoryDocuments = Object.entries(INITIAL_MEMORY_TEMPLATES).map(([fileName, content]) => ({ projectId, fileName, content, metadata: { lastUpdated: now, version: 1, type: fileName.replace('.md', ''), fileSize: Buffer.byteLength(content, 'utf-8'), }, references: [], createdAt: now, updatedAt: now, })); await collection.insertMany(memoryDocuments); // Initialize Context Engineering templates logger.info('Initializing Context Engineering templates...'); await initializeContextEngineeringTemplates(); // Create regular indexes if they don't exist try { await collection.createIndex({ projectId: 1, fileName: 1 }, { unique: true }); } catch (e) { logger.debug('Index already exists:', e); } try { await collection.createIndex({ projectId: 1, 'metadata.type': 1 }); } catch (e) { logger.debug('Index already exists:', e); } // Note: Text search now uses Atlas Search index created during sync logger.info(`Initialized memory bank for project: ${projectName} (${projectId})`); return { content: [ { type: 'text', text: `Memory bank initialized successfully! Project: ${projectName} ID: ${projectId} Path: ${projectPath} Created files: ${Object.keys(INITIAL_MEMORY_TEMPLATES).map((f) => `- ${f}`).join('\n')} Next steps: 1. Update memory files with project-specific information 2. Use memory_bank/sync to generate embeddings 3. Use memory_bank/search to query your memories`, }, ], }; } catch (error) { logger.error('Init tool error:', error); throw error; } } //# sourceMappingURL=init.js.map