Skip to main content
Glama

MCP Memory Service

#!/usr/bin/env python3 """ Integration tests for CLI interfaces to prevent conflicts and ensure compatibility. This module tests the different CLI entry points to ensure they work correctly and that the compatibility layer functions as expected. """ import subprocess import pytest import warnings import sys import os from pathlib import Path # Add src to path current_dir = Path(__file__).parent src_dir = current_dir.parent.parent / "src" sys.path.insert(0, str(src_dir)) from mcp_memory_service.cli.main import memory_server_main, main as cli_main class TestCLIInterfaces: """Test CLI interface compatibility and functionality.""" def test_memory_command_backward_compatibility(self): """Test that 'uv run memory' (without server) starts the MCP server for backward compatibility.""" result = subprocess.run( ["uv", "run", "memory", "--help"], capture_output=True, text=True, timeout=10, cwd=current_dir.parent.parent ) # Should show help text (not start server) when --help is provided assert result.returncode == 0 assert "MCP Memory Service" in result.stdout def test_memory_command_exists(self): """Test that the memory command is available.""" result = subprocess.run( ["uv", "run", "memory", "--help"], capture_output=True, text=True, cwd=current_dir.parent.parent ) assert result.returncode == 0 assert "MCP Memory Service" in result.stdout assert "server" in result.stdout assert "status" in result.stdout def test_memory_server_command_exists(self): """Test that the memory-server command is available.""" result = subprocess.run( ["uv", "run", "memory-server", "--help"], capture_output=True, text=True, cwd=current_dir.parent.parent ) assert result.returncode == 0 assert "MCP Memory Service" in result.stdout # Should show deprecation warning in stderr assert "deprecated" in result.stderr.lower() def test_mcp_memory_server_command_exists(self): """Test that the mcp-memory-server command is available.""" result = subprocess.run( ["uv", "run", "mcp-memory-server", "--help"], capture_output=True, text=True, cwd=current_dir.parent.parent ) # This might have different behavior or missing dependencies # 0 for success, 1 for import error (missing fastmcp), 2 for argument error assert result.returncode in [0, 1, 2] # If it failed due to missing fastmcp dependency, that's expected if result.returncode == 1 and "fastmcp" in result.stderr: pytest.skip("mcp-memory-server requires FastMCP which is not installed") def test_memory_server_version_flag(self): """Test that memory-server --version works and shows deprecation warning.""" result = subprocess.run( ["uv", "run", "memory-server", "--version"], capture_output=True, text=True, cwd=current_dir.parent.parent ) assert result.returncode == 0 assert "6.3.0" in result.stdout assert "deprecated" in result.stderr.lower() def test_memory_server_vs_memory_server_subcommand(self): """Test that both memory-server and memory server provide similar functionality.""" # Test memory-server --help result1 = subprocess.run( ["uv", "run", "memory-server", "--help"], capture_output=True, text=True, cwd=current_dir.parent.parent ) # Test memory server --help result2 = subprocess.run( ["uv", "run", "memory", "server", "--help"], capture_output=True, text=True, cwd=current_dir.parent.parent ) assert result1.returncode == 0 assert result2.returncode == 0 # Both should mention debug and chroma-path options assert "--debug" in result1.stdout assert "--debug" in result2.stdout assert "--chroma-path" in result1.stdout or "chroma-path" in result1.stdout assert "--chroma-path" in result2.stdout or "chroma-path" in result2.stdout def test_compatibility_wrapper_deprecation_warning(self): """Test that the compatibility wrapper issues deprecation warnings.""" # Capture warnings when calling memory_server_main with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") # Ensure all warnings are caught # Mock sys.argv to test argument parsing original_argv = sys.argv try: sys.argv = ["memory-server", "--version"] # This will raise SystemExit due to --version, which is expected with pytest.raises(SystemExit) as exc_info: memory_server_main() assert exc_info.value.code == 0 # Should exit successfully finally: sys.argv = original_argv # Check that deprecation warning was issued deprecation_warnings = [warning for warning in w if issubclass(warning.category, DeprecationWarning)] assert len(deprecation_warnings) > 0 assert "deprecated" in str(deprecation_warnings[0].message).lower() assert "memory server" in str(deprecation_warnings[0].message) def test_argument_compatibility(self): """Test that arguments are properly passed through compatibility wrapper.""" # Test with --debug flag result = subprocess.run( ["uv", "run", "memory-server", "--help"], capture_output=True, text=True, cwd=current_dir.parent.parent ) assert result.returncode == 0 assert "--debug" in result.stdout assert "--chroma-path" in result.stdout assert "--version" in result.stdout def test_no_cli_conflicts_during_import(self): """Test that importing CLI modules doesn't cause conflicts.""" try: # These imports should work without conflicts from mcp_memory_service.cli.main import main, memory_server_main from mcp_memory_service import server # Check that functions exist and are callable assert callable(main) assert callable(memory_server_main) assert callable(server.main) # Should not raise any import errors or conflicts except ImportError as e: pytest.fail(f"CLI import conflict detected: {str(e)}") class TestCLIFunctionality: """Test actual CLI functionality to ensure commands work end-to-end.""" def test_memory_status_command(self): """Test that memory status command works.""" result = subprocess.run( ["uv", "run", "memory", "status"], capture_output=True, text=True, timeout=30, cwd=current_dir.parent.parent ) # Status command might fail if no storage is available, but should not crash # Return code 0 = success, 1 = expected error (e.g., no storage) assert result.returncode in [0, 1] if result.returncode == 0: assert "MCP Memory Service Status" in result.stdout assert "Version: 6.3.0" in result.stdout else: # If it fails, should have a meaningful error message assert len(result.stderr) > 0 or len(result.stdout) > 0 class TestCLIRobustness: """Test CLI robustness and edge cases.""" def test_environment_variable_passing(self): """Test that environment variables are properly set by CLI commands.""" import os import subprocess # Test memory server command with chroma-path env = os.environ.copy() result = subprocess.run( ["uv", "run", "python", "-c", """ import os print(f"MCP_MEMORY_CHROMA_PATH={os.environ.get('MCP_MEMORY_CHROMA_PATH', 'NOT_SET')}") from mcp_memory_service.cli.main import cli import sys sys.argv = ['memory', 'server', '--chroma-path', '/tmp/test-chroma'] # Don't actually run server, just test env var setting from mcp_memory_service.cli.main import server server(debug=False, chroma_path='/tmp/test-chroma', storage_backend='sqlite_vec') """], capture_output=True, text=True, cwd=current_dir.parent.parent, env=env, timeout=10 ) # Should either succeed or fail gracefully (not crash) assert result.returncode in [0, 1] # 0 = success, 1 = expected server start failure def test_cli_error_handling(self): """Test that CLI handles errors gracefully.""" # Test invalid storage backend result = subprocess.run( ["uv", "run", "memory", "server", "--storage-backend", "invalid"], capture_output=True, text=True, cwd=current_dir.parent.parent, timeout=10 ) # Should fail with clear error message assert result.returncode != 0 assert len(result.stderr) > 0 or "invalid" in result.stdout.lower() def test_memory_server_argument_parity(self): """Test that memory-server and memory server support the same core arguments.""" import subprocess # Test memory server arguments result1 = subprocess.run( ["uv", "run", "memory", "server", "--help"], capture_output=True, text=True, cwd=current_dir.parent.parent ) # Test memory-server arguments result2 = subprocess.run( ["uv", "run", "memory-server", "--help"], capture_output=True, text=True, cwd=current_dir.parent.parent ) assert result1.returncode == 0 assert result2.returncode == 0 # Both should support core arguments core_args = ["--debug", "--chroma-path"] for arg in core_args: assert arg in result1.stdout assert arg in result2.stdout def test_entry_point_isolation(self): """Test that different entry points don't interfere with each other.""" # Test that we can import all entry points without conflicts try: # Import main CLI from mcp_memory_service.cli.main import main, memory_server_main # Import server main from mcp_memory_service.server import main as server_main # Verify they're different functions assert main != memory_server_main assert main != server_main assert memory_server_main != server_main # Verify they're all callable assert callable(main) assert callable(memory_server_main) assert callable(server_main) except ImportError as e: pytest.fail(f"Entry point isolation failed: {e}") def test_backward_compatibility_deprecation_warning(self): """Test that using 'memory' without subcommand shows deprecation warning.""" import warnings import sys from mcp_memory_service.cli.main import cli with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") # Mock sys.argv to test backward compatibility original_argv = sys.argv try: # This simulates 'uv run memory' without subcommand sys.argv = ["memory"] with pytest.raises(SystemExit): # Server will try to start and exit cli(standalone_mode=False) except Exception: # Expected - server can't actually start in test environment pass finally: sys.argv = original_argv # Verify backward compatibility deprecation warning deprecation_warnings = [warning for warning in w if issubclass(warning.category, DeprecationWarning)] assert len(deprecation_warnings) > 0 warning_msg = str(deprecation_warnings[0].message) assert "without a subcommand is deprecated" in warning_msg assert "memory server" in warning_msg assert "backward compatibility will be removed" in warning_msg def test_deprecation_warning_format(self): """Test that deprecation warning has proper format and information.""" import warnings import sys from mcp_memory_service.cli.main import memory_server_main with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") # Mock sys.argv for the compatibility wrapper original_argv = sys.argv try: sys.argv = ["memory-server", "--version"] with pytest.raises(SystemExit): # --version causes system exit memory_server_main() finally: sys.argv = original_argv # Verify deprecation warning content deprecation_warnings = [warning for warning in w if issubclass(warning.category, DeprecationWarning)] assert len(deprecation_warnings) > 0 warning_msg = str(deprecation_warnings[0].message) assert "memory-server" in warning_msg.lower() assert "deprecated" in warning_msg.lower() assert "memory server" in warning_msg.lower() assert "removed" in warning_msg.lower() class TestCLIPerformance: """Test CLI performance characteristics.""" def test_cli_startup_time(self): """Test that CLI commands start reasonably quickly.""" import time import subprocess start_time = time.time() result = subprocess.run( ["uv", "run", "memory", "--help"], capture_output=True, text=True, timeout=30, cwd=current_dir.parent.parent ) elapsed = time.time() - start_time assert result.returncode == 0 # CLI help should respond within 30 seconds (generous timeout for CI) assert elapsed < 30 # Log performance for monitoring print(f"CLI startup took {elapsed:.2f} seconds") def test_memory_version_performance(self): """Test that version commands are fast.""" import time import subprocess # Test both version commands commands = [ ["uv", "run", "memory", "--version"], ["uv", "run", "memory-server", "--version"] ] for cmd in commands: start_time = time.time() result = subprocess.run( cmd, capture_output=True, text=True, timeout=15, cwd=current_dir.parent.parent ) elapsed = time.time() - start_time assert result.returncode == 0 assert "6.3.0" in result.stdout # Version should be very fast assert elapsed < 15 print(f"Version command {' '.join(cmd[2:])} took {elapsed:.2f} seconds") if __name__ == "__main__": pytest.main([__file__, "-v"])

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