Skip to main content
Glama

MCP Memory Service

#!/usr/bin/env python3 """ Windows Service installer for MCP Memory Service. Installs the service using Python's Windows service capabilities. """ import os import sys import json import argparse import subprocess from pathlib import Path # Add parent directory to path for imports sys.path.insert(0, str(Path(__file__).parent.parent)) try: from scripts.service_utils import ( get_project_root, get_service_paths, get_service_environment, generate_api_key, save_service_config, load_service_config, check_dependencies, get_service_command, print_service_info, require_admin ) except ImportError as e: print(f"Error importing service utilities: {e}") print("Please ensure you're running this from the project directory") sys.exit(1) SERVICE_NAME = "MCPMemoryService" SERVICE_DISPLAY_NAME = "MCP Memory Service" SERVICE_DESCRIPTION = "Semantic memory and persistent storage service for Claude Desktop" def create_windows_service_script(): """Create the Windows service wrapper script.""" paths = get_service_paths() service_script = paths['scripts_dir'] / 'mcp_memory_windows_service.py' script_content = '''#!/usr/bin/env python3 """ Windows Service wrapper for MCP Memory Service. This script runs as a Windows service and manages the MCP Memory server process. """ import os import sys import time import subprocess import win32serviceutil import win32service import win32event import servicemanager import socket import json from pathlib import Path class MCPMemoryService(win32serviceutil.ServiceFramework): _svc_name_ = "MCPMemoryService" _svc_display_name_ = "MCP Memory Service" _svc_description_ = "Semantic memory and persistent storage service for Claude Desktop" def __init__(self, args): win32serviceutil.ServiceFramework.__init__(self, args) self.hWaitStop = win32event.CreateEvent(None, 0, 0, None) socket.setdefaulttimeout(60) self.is_running = True self.process = None def SvcStop(self): self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) win32event.SetEvent(self.hWaitStop) self.is_running = False # Stop the subprocess if self.process: self.process.terminate() try: self.process.wait(timeout=10) except subprocess.TimeoutExpired: self.process.kill() def SvcDoRun(self): servicemanager.LogMsg( servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTED, (self._svc_name_, '') ) self.main() def main(self): # Load service configuration config_dir = Path.home() / '.mcp_memory_service' config_file = config_dir / 'service_config.json' if not config_file.exists(): servicemanager.LogErrorMsg("Service configuration not found") return with open(config_file, 'r') as f: config = json.load(f) # Set up environment env = os.environ.copy() env.update(config['environment']) # Start the service process try: self.process = subprocess.Popen( config['command'], env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True ) servicemanager.LogMsg( servicemanager.EVENTLOG_INFORMATION_TYPE, 0, "MCP Memory Service process started" ) # Monitor the process while self.is_running: if self.process.poll() is not None: # Process died, log error and restart stdout, stderr = self.process.communicate() servicemanager.LogErrorMsg( f"Service process died unexpectedly. stderr: {stderr}" ) # Wait a bit before restarting time.sleep(5) # Restart the process self.process = subprocess.Popen( config['command'], env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True ) # Check if we should stop if win32event.WaitForSingleObject(self.hWaitStop, 1000) == win32event.WAIT_OBJECT_0: break except Exception as e: servicemanager.LogErrorMsg(f"Error in service: {str(e)}") if __name__ == '__main__': if len(sys.argv) == 1: servicemanager.Initialize() servicemanager.PrepareToHostSingle(MCPMemoryService) servicemanager.StartServiceCtrlDispatcher() else: win32serviceutil.HandleCommandLine(MCPMemoryService) ''' with open(service_script, 'w') as f: f.write(script_content) return service_script def create_batch_scripts(): """Create convenient batch scripts for service management.""" paths = get_service_paths() scripts_dir = paths['scripts_dir'] / 'windows' scripts_dir.mkdir(exist_ok=True) # Start service batch file start_script = scripts_dir / 'start_service.bat' with open(start_script, 'w') as f: f.write(f'''@echo off echo Starting {SERVICE_DISPLAY_NAME}... net start {SERVICE_NAME} if %ERRORLEVEL% == 0 ( echo Service started successfully! ) else ( echo Failed to start service. Run as Administrator if needed. ) pause ''') # Stop service batch file stop_script = scripts_dir / 'stop_service.bat' with open(stop_script, 'w') as f: f.write(f'''@echo off echo Stopping {SERVICE_DISPLAY_NAME}... net stop {SERVICE_NAME} if %ERRORLEVEL% == 0 ( echo Service stopped successfully! ) else ( echo Failed to stop service. Run as Administrator if needed. ) pause ''') # Status batch file status_script = scripts_dir / 'service_status.bat' with open(status_script, 'w') as f: f.write(f'''@echo off echo Checking {SERVICE_DISPLAY_NAME} status... sc query {SERVICE_NAME} pause ''') # Uninstall batch file uninstall_script = scripts_dir / 'uninstall_service.bat' with open(uninstall_script, 'w') as f: f.write(f'''@echo off echo This will uninstall {SERVICE_DISPLAY_NAME}. echo. set /p confirm="Are you sure? (Y/N): " if /i "%confirm%" neq "Y" exit /b echo Stopping service... net stop {SERVICE_NAME} 2>nul echo Uninstalling service... python "{paths['scripts_dir'] / 'install_windows_service.py'}" --uninstall pause ''') return scripts_dir def install_service(): """Install the Windows service.""" # Check if pywin32 is installed try: import win32serviceutil import win32service except ImportError: print("\n❌ ERROR: pywin32 is required for Windows service installation") print("Please install it with: pip install pywin32") sys.exit(1) # Require administrator privileges require_admin("Administrator privileges are required to install Windows services") print("\n🔍 Checking dependencies...") deps_ok, deps_msg = check_dependencies() if not deps_ok: print(f"❌ {deps_msg}") sys.exit(1) print(f"✅ {deps_msg}") # Generate API key api_key = generate_api_key() print(f"\n🔑 Generated API key: {api_key}") # Create service configuration config = { 'service_name': SERVICE_NAME, 'api_key': api_key, 'command': get_service_command(), 'environment': get_service_environment() } config['environment']['MCP_API_KEY'] = api_key # Save configuration config_file = save_service_config(config) print(f"💾 Saved configuration to: {config_file}") # Create service wrapper script print("\n📝 Creating service wrapper...") service_script = create_windows_service_script() # Install the service using the wrapper print(f"\n🚀 Installing {SERVICE_DISPLAY_NAME}...") try: # First, try to stop and remove existing service subprocess.run([ sys.executable, str(service_script), 'stop' ], capture_output=True) subprocess.run([ sys.executable, str(service_script), 'remove' ], capture_output=True) # Install the service result = subprocess.run([ sys.executable, str(service_script), 'install' ], capture_output=True, text=True) if result.returncode != 0: print(f"❌ Failed to install service: {result.stderr}") sys.exit(1) # Configure service for automatic startup subprocess.run([ 'sc', 'config', SERVICE_NAME, 'start=', 'auto' ], capture_output=True) # Set service description subprocess.run([ 'sc', 'description', SERVICE_NAME, SERVICE_DESCRIPTION ], capture_output=True) print(f"✅ Service installed successfully!") except Exception as e: print(f"❌ Error installing service: {e}") sys.exit(1) # Create batch scripts scripts_dir = create_batch_scripts() print(f"\n📁 Created management scripts in: {scripts_dir}") # Print service information platform_info = { 'Start Service': f'net start {SERVICE_NAME}', 'Stop Service': f'net stop {SERVICE_NAME}', 'Service Status': f'sc query {SERVICE_NAME}', 'Uninstall': f'python "{Path(__file__)}" --uninstall' } print_service_info(api_key, platform_info) return True def uninstall_service(): """Uninstall the Windows service.""" require_admin("Administrator privileges are required to uninstall Windows services") print(f"\n🗑️ Uninstalling {SERVICE_DISPLAY_NAME}...") paths = get_service_paths() service_script = paths['scripts_dir'] / 'mcp_memory_windows_service.py' if not service_script.exists(): # Try using sc command directly result = subprocess.run([ 'sc', 'delete', SERVICE_NAME ], capture_output=True, text=True) if result.returncode == 0: print("✅ Service uninstalled successfully!") else: print(f"❌ Failed to uninstall service: {result.stderr}") else: # Stop the service first subprocess.run([ sys.executable, str(service_script), 'stop' ], capture_output=True) # Remove the service result = subprocess.run([ sys.executable, str(service_script), 'remove' ], capture_output=True, text=True) if result.returncode == 0: print("✅ Service uninstalled successfully!") else: print(f"❌ Failed to uninstall service: {result.stderr}") def start_service(): """Start the Windows service.""" print(f"\n▶️ Starting {SERVICE_DISPLAY_NAME}...") result = subprocess.run([ 'net', 'start', SERVICE_NAME ], capture_output=True, text=True) if result.returncode == 0: print("✅ Service started successfully!") else: if "already been started" in result.stderr: print("ℹ️ Service is already running") else: print(f"❌ Failed to start service: {result.stderr}") print("\n💡 Try running as Administrator if you see access denied errors") def stop_service(): """Stop the Windows service.""" print(f"\n⏹️ Stopping {SERVICE_DISPLAY_NAME}...") result = subprocess.run([ 'net', 'stop', SERVICE_NAME ], capture_output=True, text=True) if result.returncode == 0: print("✅ Service stopped successfully!") else: if "is not started" in result.stderr: print("ℹ️ Service is not running") else: print(f"❌ Failed to stop service: {result.stderr}") def service_status(): """Check the Windows service status.""" print(f"\n📊 {SERVICE_DISPLAY_NAME} Status:") print("-" * 40) result = subprocess.run([ 'sc', 'query', SERVICE_NAME ], capture_output=True, text=True) if result.returncode == 0: # Parse the output for line in result.stdout.splitlines(): if "STATE" in line: if "RUNNING" in line: print("✅ Service is RUNNING") elif "STOPPED" in line: print("⏹️ Service is STOPPED") else: print(f"ℹ️ {line.strip()}") elif "SERVICE_NAME:" in line: print(f"Service Name: {SERVICE_NAME}") else: print("❌ Service is not installed") # Show configuration if available config = load_service_config() if config: print(f"\n📋 Configuration:") print(f" API Key: {config.get('api_key', 'Not set')}") print(f" Config File: {get_service_paths()['config_dir'] / 'service_config.json'}") def main(): """Main entry point.""" parser = argparse.ArgumentParser( description="Windows Service installer for MCP Memory Service" ) parser.add_argument('--uninstall', action='store_true', help='Uninstall the service') parser.add_argument('--start', action='store_true', help='Start the service') parser.add_argument('--stop', action='store_true', help='Stop the service') parser.add_argument('--status', action='store_true', help='Check service status') parser.add_argument('--restart', action='store_true', help='Restart the service') args = parser.parse_args() if args.uninstall: uninstall_service() elif args.start: start_service() elif args.stop: stop_service() elif args.status: service_status() elif args.restart: stop_service() start_service() else: # Default action is to install install_service() if __name__ == '__main__': main()

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