Skip to main content
Glama

Command-Line MCP Server

by andresthor
test_server.py8.49 kB
"""Tests for the command-line MCP server. NOTE: These tests need to be updated for the latest MCP library version. The API for accessing tools and executing them has changed significantly. """ import pytest from cmd_line_mcp.server import CommandLineMCP from cmd_line_mcp.security import validate_command @pytest.fixture def server(): """Create a CommandLineMCP instance for testing.""" return CommandLineMCP() def test_validate_command(): """Test the command validation function.""" # Setup default command lists for testing read_commands = ["ls", "cat", "grep", "sort", "head", "tail", "find", "wc"] write_commands = ["mkdir", "touch", "rm", "cp", "mv"] system_commands = ["ps", "top", "ping", "netstat"] blocked_commands = ["sudo", "bash", "sh", "zsh", "eval", "exec"] dangerous_patterns = [r"rm\s+-rf\s+/", r">\s+/etc/", r"\$\(", r"`"] # Valid read command result = validate_command( "ls -la", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns ) assert result["is_valid"] is True assert result["command_type"] == "read" assert result["error"] is None # Valid write command result = validate_command( "mkdir test_dir", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns ) assert result["is_valid"] is True assert result["command_type"] == "write" assert result["error"] is None # Valid system command result = validate_command( "ps aux", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns ) assert result["is_valid"] is True assert result["command_type"] == "system" assert result["error"] is None # Blocked command result = validate_command( "sudo rm -rf /", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns ) assert result["is_valid"] is False assert result["command_type"] is None assert result["error"] is not None # Dangerous pattern result = validate_command( "rm -rf /", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns ) assert result["is_valid"] is False assert result["command_type"] is None assert result["error"] is not None # Unsupported command result = validate_command( "nonsense_command", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns ) assert result["is_valid"] is False assert result["command_type"] is None assert result["error"] is not None @pytest.mark.asyncio async def test_command_categories(server): """Test that command categories are correctly defined.""" # Test that the command categories are loaded from config assert isinstance(server.read_commands, list) assert isinstance(server.write_commands, list) assert isinstance(server.system_commands, list) assert isinstance(server.blocked_commands, list) # Test the list_available_commands tool result = await server._list_available_commands_func() assert "read_commands" in result assert "write_commands" in result assert "system_commands" in result assert "blocked_commands" in result @pytest.mark.asyncio async def test_execute_read_command(server): """Test executing a read command.""" # We need to patch the validation process and subprocess execution # Create a special version of the execute_read_command function for testing original_func = server._execute_read_command_func # Create a mock version that bypasses the actual implementation async def mock_read_command_func(command): if command == "ls -la": return { "success": True, "output": "test output", "error": "", "command_type": "read", } elif command == "invalid_command": return {"success": False, "output": "", "error": "Invalid command"} elif command == "mkdir test_dir": return { "success": False, "output": "", "error": "This tool only supports read commands. Use execute_command for other command types.", } else: return {"success": False, "error": "Unexpected command in test"} # Temporarily replace the method server._execute_read_command_func = mock_read_command_func try: # Test with a valid read command result = await server._execute_read_command_func("ls -la") assert result["success"] == True assert "output" in result assert result["output"] == "test output" assert "command_type" in result assert result["command_type"] == "read" # Test with an invalid command result = await server._execute_read_command_func("invalid_command") assert result["success"] == False assert "error" in result # Test with a write command (should be rejected) result = await server._execute_read_command_func("mkdir test_dir") assert result["success"] == False assert "error" in result assert "only supports read commands" in result["error"] finally: # Restore the original function server._execute_read_command_func = original_func @pytest.mark.asyncio async def test_session_management(server): """Test session management and approval flow.""" # Create a session ID for testing session_id = "test-session-123" # Use a simple write command - using touch which is safer for testing mock_write_command = "touch test_file.tmp" # Test executing a write command without approval (should require approval) result = await server._execute_command( mock_write_command, session_id=session_id ) # Check if auto-approval is enabled (would depend on config) if "requires_approval" in result and result["requires_approval"]: # If approval is required, we should see that in the response assert result["success"] == False assert result["requires_approval"] == True assert result["command_type"] == "write" assert result["session_id"] == session_id # Now approve the command type approval_result = await server._approve_command_type_func( "write", session_id, True ) assert approval_result["success"] == True # Retry the command, it should work now result = await server._execute_command( mock_write_command, session_id=session_id ) assert "command_type" in result assert result["command_type"] == "write" else: # If auto-approval is enabled (e.g., for Claude Desktop compatibility), # the command should be processed without requiring explicit approval # Check only that the command was categorized correctly, not that it succeeded # (since it might fail if the server doesn't have permission to create the file) # The key test is that the security approval mechanism is working assert "output" in result assert "error" in result # Test the session manager directly # Add a command type approval server.session_manager.approve_command_type(session_id, "write") # Check that the approval is stored assert server.session_manager.has_command_type_approval( session_id, "write" ) # Store original session content original_session = server.session_manager.sessions[session_id].copy() # Set the last_active time to be way in the past to ensure it gets cleaned up server.session_manager.sessions[session_id]["last_active"] = 0 # Test session timeout server.session_manager.clean_old_sessions(10) # Force session cleanup with 10 sec timeout assert session_id not in server.session_manager.sessions # Restore the session for other tests that might depend on it server.session_manager.sessions[session_id] = original_session # Clean up test file if it was created await server._execute_command("rm -f test_file.tmp", session_id=session_id)

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/andresthor/cmd-line-mcp'

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