mirror of
https://github.com/hanzoai/python-sdk.git
synced 2026-10-27 04:20:09 +00:00
5.5 KiB
5.5 KiB
Modular Plugin Architecture for Hanzo-MCP Memory System
Overview
This document outlines a modular plugin architecture for the Hanzo-MCP memory system that allows users to enable specific backends and capabilities as needed, without requiring heavy dependencies by default.
Current Architecture
hanzo-mcp: Main MCP serverhanzo-tools-memory: Memory tools package with unified interfacehanzo-memory: Full memory backend implementation with multiple backends
Proposed Plugin Architecture
1. Plugin Interface
Define a standard interface for memory backends that can be loaded dynamically:
from abc import ABC, abstractmethod
from typing import Protocol, Optional, List, Dict, Any
class MemoryBackendPlugin(Protocol):
"""Interface for memory backend plugins."""
@property
def name(self) -> str:
"""Unique name of the backend."""
...
@property
def capabilities(self) -> List[str]:
"""List of capabilities provided by this backend."""
...
async def initialize(self) -> None:
"""Initialize the backend."""
...
async def shutdown(self) -> None:
"""Shutdown the backend."""
...
async def store_memory(self, content: str, metadata: Dict[str, Any]) -> str:
"""Store a memory and return its ID."""
...
async def retrieve_memory(self, query: str, limit: int = 10) -> List[Dict[str, Any]]:
"""Retrieve memories based on query."""
...
2. Plugin Registry
A central registry to manage available plugins:
class PluginRegistry:
"""Registry for memory backend plugins."""
def __init__(self):
self._plugins: Dict[str, MemoryBackendPlugin] = {}
self._active_plugins: List[str] = []
def register_plugin(self, plugin: MemoryBackendPlugin):
"""Register a new plugin."""
self._plugins[plugin.name] = plugin
def enable_plugin(self, name: str) -> bool:
"""Enable a registered plugin."""
if name in self._plugins and name not in self._active_plugins:
self._active_plugins.append(name)
return True
return False
def get_active_plugins(self) -> List[MemoryBackendPlugin]:
"""Get all active plugins."""
return [self._plugins[name] for name in self._active_plugins]
3. Configuration-Based Loading
Allow users to configure which backends to load via configuration:
# config.py
from pydantic import BaseModel
from typing import List
class PluginConfig(BaseModel):
enabled_backends: List[str] = ["sqlite"] # Default to lightweight SQLite
backend_configs: Dict[str, Dict[str, Any]] = {
"sqlite": {"path": "~/.hanzo/memory.db"},
"lancedb": {"path": "./data/lancedb"},
"redis": {"url": "redis://localhost:6379"}
}
4. Lazy Loading
Only load plugins when they are actually needed:
class MemoryService:
"""Memory service that uses plugins."""
def __init__(self, config: PluginConfig):
self.config = config
self.registry = PluginRegistry()
self._initialized = False
async def initialize(self):
"""Initialize the service and load configured plugins."""
if self._initialized:
return
# Register all available plugins
self._register_available_plugins()
# Enable configured plugins
for backend_name in self.config.enabled_backends:
self.registry.enable_plugin(backend_name)
# Initialize active plugins
for plugin in self.registry.get_active_plugins():
await plugin.initialize()
self._initialized = True
def _register_available_plugins(self):
"""Register all available backend plugins."""
# Register SQLite plugin
from .backends.sqlite_plugin import SQLiteBackendPlugin
self.registry.register_plugin(SQLiteBackendPlugin())
# Conditionally register other plugins if dependencies are available
try:
from .backends.lancedb_plugin import LanceDBBackendPlugin
self.registry.register_plugin(LanceDBBackendPlugin())
except ImportError:
pass # Skip if dependencies not available
try:
from .backends.redis_plugin import RedisBackendPlugin
self.registry.register_plugin(RedisBackendPlugin())
except ImportError:
pass
5. User Experience
Users can enable backends as needed:
# Default installation - only lightweight SQLite
pip install hanzo-mcp
# With full memory capabilities
pip install hanzo-mcp[memory]
# With specific backends
pip install hanzo-mcp[memory,lancedb,redis]
# Or configure via config file
echo '{"enabled_backends": ["sqlite", "lancedb"]}' > hanzo_config.json
Benefits
- Modularity: Users only install what they need
- Flexibility: Easy to add new backends
- Performance: Only load necessary components
- Scalability: Different backends for different use cases
- Maintainability: Clear separation of concerns
Implementation Steps
- Define the plugin interface
- Create the registry system
- Implement the lazy loading mechanism
- Create adapter classes for existing backends
- Update configuration system
- Update documentation and examples
This architecture would allow users to have a lightweight MCP server by default, but enable advanced memory capabilities when needed, without having to rebuild or restart the entire system.