Skip to main content
Glama

MCP Memory Service

multi-client-architecture.md16.1 kB
# Multi-Client Architecture Documentation This document provides technical details about the multi-client architecture implementation in the MCP Memory Service, specifically focusing on the integrated setup functionality added to `install.py`. ## Overview The multi-client architecture enables multiple MCP applications to safely share the same memory database concurrently. The latest implementation integrates this setup directly into the main installation process, making it universally accessible to any MCP-compatible application. ## Architecture Components ### 1. Client Detection System #### Detection Strategy The system uses a multi-pronged approach to detect MCP clients: ```python def detect_mcp_clients(): """Detect installed MCP-compatible applications.""" clients = {} # Pattern-based detection for known applications detection_patterns = { 'claude_desktop': [ Path.home() / "AppData" / "Roaming" / "Claude" / "claude_desktop_config.json", # Windows Path.home() / "Library" / "Application Support" / "Claude" / "claude_desktop_config.json", # macOS Path.home() / ".config" / "Claude" / "claude_desktop_config.json" # Linux ], 'vscode_mcp': [ # VS Code settings.json locations with MCP extension detection ], 'continue': [ # Continue IDE configuration locations ], 'generic_mcp': [ # Generic MCP configuration file locations ] } ``` #### Detection Logic 1. **File-based Detection**: Checks for configuration files in standard locations 2. **Content Analysis**: Examines configuration files for MCP-related settings 3. **CLI Detection**: Tests for command-line tools (e.g., Claude Code) 4. **Extension Detection**: Identifies IDE extensions that support MCP ### 2. Configuration Management #### Configuration Abstraction Each client type has a dedicated configuration handler: ```python class MCPClientConfigurator: """Base class for MCP client configuration.""" def detect(self) -> bool: """Detect if this client is installed.""" raise NotImplementedError def configure(self, config: MCPConfig) -> bool: """Configure the client for multi-client access.""" raise NotImplementedError def validate(self) -> bool: """Validate the configuration.""" raise NotImplementedError class ClaudeDesktopConfigurator(MCPClientConfigurator): """Configure Claude Desktop for multi-client access.""" def configure(self, config: MCPConfig) -> bool: # Update claude_desktop_config.json pass class ContinueIDEConfigurator(MCPClientConfigurator): """Configure Continue IDE for multi-client access.""" def configure(self, config: MCPConfig) -> bool: # Update Continue configuration files pass ``` #### Configuration Template System Universal configuration templates ensure consistency: ```python class MCPConfig: """Standard MCP configuration structure.""" def __init__(self, repo_path: str): self.repo_path = repo_path self.base_config = { "command": "uv", "args": ["--directory", repo_path, "run", "memory"], "env": { "MCP_MEMORY_STORAGE_BACKEND": "sqlite_vec", "MCP_MEMORY_SQLITE_PRAGMAS": "busy_timeout=15000,cache_size=20000", "LOG_LEVEL": "INFO" } } def for_client(self, client_type: str) -> dict: """Generate client-specific configuration.""" config = self.base_config.copy() if client_type == "claude_desktop": # Claude Desktop specific adjustments pass elif client_type == "continue": # Continue IDE specific adjustments pass return config ``` ### 3. WAL Mode Coordination #### SQLite WAL Implementation Write-Ahead Logging mode enables safe concurrent access: ```python async def test_wal_mode_coordination(): """Test WAL mode storage coordination for multi-client access.""" # Create test database with WAL mode storage = SqliteVecMemoryStorage(test_db_path) await storage.initialize() # WAL mode pragmas are applied in storage initialization: # PRAGMA journal_mode=WAL; # PRAGMA busy_timeout=15000; # PRAGMA cache_size=20000; # PRAGMA synchronous=NORMAL; # Test concurrent access patterns storage2 = SqliteVecMemoryStorage(test_db_path) await storage2.initialize() # Verify both can read/write safely success = await test_concurrent_operations(storage, storage2) return success ``` #### Concurrency Model - **Multiple Readers**: Any number of clients can read simultaneously - **Single Writer**: One client writes at a time, with automatic queuing - **Retry Logic**: Exponential backoff for lock conflicts - **Timeout Handling**: 15-second timeout prevents deadlocks ### 4. Integration Flow #### Installation Integration Points The multi-client setup integrates at specific points in the installation flow: ```python def main(): """Main installation function with multi-client integration.""" # 1. System detection and backend selection system_info = detect_system() final_backend = determine_backend(args, system_info) # 2. Core installation (dependencies, package, paths) install_success = install_package(args) configure_paths(args) verify_installation() # 3. Multi-client integration point if should_offer_multi_client_setup(args, final_backend): if prompt_user_for_multi_client() or args.setup_multi_client: setup_universal_multi_client_access(system_info, args) # 4. Final configuration and completion complete_installation() ``` #### Decision Logic Multi-client setup is offered based on: ```python def should_offer_multi_client_setup(args, final_backend): """Intelligent decision logic for multi-client offering.""" # Required: SQLite-vec backend (only backend supporting multi-client) if final_backend != "sqlite_vec": return False # Skip in automated/server environments if args.server_mode or args.skip_multi_client_prompt: return False # Always beneficial for development environments return True ``` ### 5. Error Handling and Fallbacks #### Layered Error Handling The system implements multiple fallback layers: ```python def setup_universal_multi_client_access(system_info, args): """Configure multi-client access with comprehensive error handling.""" try: # Layer 1: WAL mode validation if not test_wal_mode_coordination(): raise MCPSetupError("WAL mode coordination test failed") # Layer 2: Client detection and configuration clients = detect_mcp_clients() success_count = configure_detected_clients(clients, system_info) # Layer 3: Environment setup setup_shared_environment() # Layer 4: Generic configuration (always succeeds) provide_generic_configuration() return True except MCPSetupError as e: # Graceful degradation: provide manual instructions print_error(f"Automated setup failed: {e}") provide_manual_setup_instructions() return False ``` #### Fallback Mechanisms 1. **Automated → Manual**: If automated setup fails, provide manual instructions 2. **Specific → Generic**: If client-specific config fails, use generic templates 3. **Integrated → Standalone**: Direct users to standalone setup script 4. **Setup → Documentation**: Always provide comprehensive documentation ### 6. Extensibility Framework #### Adding New Client Support The architecture is designed for easy extension: ```python # 1. Add detection pattern def detect_new_client(): """Detect NewClient MCP application.""" config_paths = [ # Platform-specific configuration file locations ] for path in config_paths: if path.exists() and is_mcp_configured(path): return path return None # 2. Add configuration handler def configure_new_client_multi_client(config_path): """Configure NewClient for multi-client access.""" try: # Read existing configuration config = read_client_config(config_path) # Apply multi-client settings config.update(generate_mcp_config()) # Write updated configuration write_client_config(config_path, config) print_info(" [OK] NewClient: Updated configuration") return True except Exception as e: print_warning(f" -> NewClient configuration failed: {e}") return False # 3. Register in detection system def detect_mcp_clients(): clients = {} # ... existing detection logic ... # Add new client detection new_client_path = detect_new_client() if new_client_path: clients['new_client'] = new_client_path return clients ``` #### Plugin Architecture Potential The current implementation could evolve into a plugin system: ```python class MCPClientPlugin: """Base class for MCP client plugins.""" name: str priority: int def detect(self) -> Optional[Path]: """Detect client installation.""" pass def configure(self, config: MCPConfig, config_path: Path) -> bool: """Configure client for multi-client access.""" pass def validate(self, config_path: Path) -> bool: """Validate client configuration.""" pass # Plugin registration system REGISTERED_PLUGINS = [ ClaudeDesktopPlugin(), ContinueIDEPlugin(), VSCodeMCPPlugin(), CursorIDEPlugin(), GenericMCPPlugin(), # Fallback plugin ] ``` ## Technical Decisions ### Why SQLite-vec Only? Multi-client support is limited to SQLite-vec backend because: 1. **WAL Mode Support**: SQLite's WAL mode provides robust concurrent access 2. **File-based Storage**: Single database file simplifies sharing 3. **Performance**: SQLite is optimized for multi-reader scenarios 4. **Reliability**: Well-tested concurrency mechanisms 5. **Simplicity**: No network coordination required ### Why Integrated Setup? Integration into the main installer provides: 1. **Discoverability**: Users learn about multi-client capabilities during installation 2. **Convenience**: One-step setup for all MCP applications 3. **Consistency**: Uniform configuration across all clients 4. **Future-proofing**: Automatic support for new MCP applications ### Configuration Strategy Direct configuration file modification was chosen over: - **Environment variables only**: Would require manual client restart - **Network-based coordination**: Adds complexity and failure points - **Copy-paste instructions**: Reduces user experience and increases errors ## Performance Considerations ### Database Performance - **WAL Mode**: Allows concurrent readers without blocking - **Cache Size**: 20MB cache improves multi-client performance - **Busy Timeout**: 15-second timeout prevents deadlocks - **Synchronous Mode**: NORMAL mode balances safety and performance ### Memory Usage - **Shared Database**: Single database reduces total memory usage - **Connection Pooling**: Each client maintains its own connection pool - **Cache Coordination**: WAL mode provides implicit cache coordination ### Startup Performance - **Lazy Initialization**: Clients initialize storage on first use - **Fast Detection**: Configuration file checking is optimized - **Minimal Overhead**: Setup adds <1 second to installation time ## Security Considerations ### File System Security - **Path Validation**: All configuration paths are validated before modification - **Backup Creation**: Original configurations are backed up before changes - **Permission Checks**: Write permissions verified before attempting changes ### Configuration Security - **Template Validation**: All configuration templates are validated - **Injection Prevention**: No user input is directly inserted into configurations - **Safe Defaults**: Conservative defaults used for security-sensitive settings ## Testing Strategy ### Unit Testing ```python def test_client_detection(): """Test MCP client detection functionality.""" # Mock configuration files with mock_config_files(): clients = detect_mcp_clients() assert 'claude_desktop' in clients assert 'continue' in clients def test_configuration_generation(): """Test MCP configuration generation.""" config = MCPConfig("/test/repo") claude_config = config.for_client("claude_desktop") assert claude_config["env"]["MCP_MEMORY_STORAGE_BACKEND"] == "sqlite_vec" assert "busy_timeout" in claude_config["env"]["MCP_MEMORY_SQLITE_PRAGMAS"] ``` ### Integration Testing ```python async def test_multi_client_coordination(): """Test actual multi-client database coordination.""" # Create test database db_path = create_test_database() # Initialize multiple storage instances storage1 = SqliteVecMemoryStorage(db_path) storage2 = SqliteVecMemoryStorage(db_path) await storage1.initialize() await storage2.initialize() # Test concurrent operations success = await test_concurrent_read_write(storage1, storage2) assert success ``` ### End-to-End Testing ```python def test_full_installation_flow(): """Test complete installation with multi-client setup.""" with temporary_environment(): # Run installer with multi-client setup result = run_installer(["--setup-multi-client", "--storage-backend", "sqlite_vec"]) assert result.success assert result.multi_client_configured assert validate_client_configurations() ``` ## Monitoring and Observability ### Logging Framework ```python # Multi-client specific logging logger = logging.getLogger("mcp.multi_client") def setup_universal_multi_client_access(system_info, args): logger.info("Starting universal multi-client setup") clients = detect_mcp_clients() logger.info(f"Detected {len(clients)} MCP clients: {list(clients.keys())}") for client_type, config_path in clients.items(): try: success = configure_client(client_type, config_path) logger.info(f"Client {client_type} configuration: {'success' if success else 'failed'}") except Exception as e: logger.error(f"Client {client_type} configuration error: {e}") ``` ### Metrics Collection ```python # Installation metrics class InstallationMetrics: def __init__(self): self.clients_detected = 0 self.clients_configured = 0 self.configuration_errors = [] self.setup_duration = 0 def record_client_detection(self, client_type: str): self.clients_detected += 1 def record_configuration_success(self, client_type: str): self.clients_configured += 1 def record_configuration_error(self, client_type: str, error: str): self.configuration_errors.append((client_type, error)) ``` ## Future Enhancements ### Planned Improvements 1. **HTTP Coordination**: Advanced coordination for 3+ clients 2. **Configuration Validation**: Real-time validation of client configurations 3. **Auto-Updates**: Automatic configuration updates for new MCP versions 4. **Cloud Sync**: Multi-device memory synchronization 5. **Plugin System**: Formal plugin architecture for client support ### Research Areas 1. **Conflict Resolution**: Advanced merge strategies for concurrent edits 2. **Performance Optimization**: Database sharding for large-scale deployments 3. **Security Enhancements**: Encrypted inter-client communication 4. **Mobile Support**: Extension to mobile MCP applications This architecture provides a robust, extensible foundation for universal multi-client support in the MCP Memory Service ecosystem.

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/doobidoo/mcp-memory-service'

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