Skip to main content
Glama
test_imap_server_basic.py8.4 kB
"""Basic integration tests for IMAP MCP server. These tests verify the server can start, connect to Gmail via IMAP, and perform operations. Following the project's integration testing framework, all tests are tagged with @pytest.mark.integration and can be run or skipped with the --skip-integration flag. """ import json import os import pytest import subprocess import time import logging import tempfile import argparse import sys from pathlib import Path # Configure logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) # Mark all tests in this file as integration tests pytestmark = pytest.mark.integration # Define paths and variables PROJECT_ROOT = Path.cwd() SERVER_SCRIPT = PROJECT_ROOT / "scripts" / "run_imap_mcp_server.sh" def run_server_command(args=None): """Run the IMAP MCP server with specified arguments and return the result.""" if args is None: args = ["--dev"] server_cmd = str(SERVER_SCRIPT) command = [server_cmd] + args # Create temporary file for server output with tempfile.NamedTemporaryFile(prefix="imap_server_", suffix=".log", delete=False, mode='w') as temp: log_path = temp.name logger.info(f"Server output will be logged to: {log_path}") try: # Run the server process and wait for it to complete logger.info(f"Running command: {' '.join(command)}") with open(log_path, 'w') as log_file: result = subprocess.run( command, stdout=log_file, stderr=log_file, text=True, timeout=30 # Set a reasonable timeout ) # Read the log file with open(log_path, 'r') as f: log_content = f.read() logger.info(f"Command completed with exit code {result.returncode}") logger.info(f"Log output: {log_content}") return result.returncode, log_content finally: # Clean up the log file if os.path.exists(log_path): try: os.unlink(log_path) except Exception as e: logger.warning(f"Failed to delete log file {log_path}: {e}") class TestImapMcpServerBasic: """Basic tests for the IMAP MCP server functionality.""" def test_server_help_command(self): """Test that the server script responds to --help properly.""" returncode, log_content = run_server_command(["--help"]) # Check exit code assert returncode == 0, f"Server exited with non-zero code: {returncode}" # Check for help content in the output assert "usage:" in log_content, "Help output not found" assert "--config CONFIG" in log_content, "Config option not found in help" assert "--dev" in log_content, "Dev option not found in help" def test_server_version_command(self): """Test that the server script responds to --version properly.""" returncode, log_content = run_server_command(["--version"]) # Check exit code assert returncode == 0, f"Server exited with non-zero code: {returncode}" # Check for version information assert "version" in log_content.lower(), "Version information not found" def test_server_connects_to_gmail(self): """Verify that the server can connect to Gmail.""" returncode, log_content = run_server_command(["--dev"]) # Check exit code assert returncode == 0, f"Server exited with non-zero code: {returncode}" # Check for successful connection assert "Connected to IMAP server imap.gmail.com" in log_content, "Failed to connect to Gmail" # Check for successful OAuth2 authentication assert "Using OAuth2 authentication" in log_content, "Not using OAuth2 authentication" assert "Refreshing Gmail access token" in log_content, "Did not refresh Gmail token" # Verify clean disconnection assert "Disconnected from IMAP server" in log_content, "Did not disconnect cleanly" def test_server_starts_in_dev_mode(self): """Verify that the server starts in development mode.""" returncode, log_content = run_server_command(["--dev"]) # Check exit code assert returncode == 0, f"Server exited with non-zero code: {returncode}" # Verify development mode assert "Starting server in development mode" in log_content, "Server not in development mode" def test_server_config_loading(self): """Verify that the server loads its configuration correctly.""" returncode, log_content = run_server_command(["--dev"]) # Check exit code assert returncode == 0, f"Server exited with non-zero code: {returncode}" # Verify config loading assert "Loaded configuration from config.yaml" in log_content, "Failed to load configuration" def find_available_tools(self, log_content): """Extract available tools from the server log.""" tools = [] for line in log_content.splitlines(): if "Registered tool:" in line: tool_name = line.split("Registered tool:")[1].strip() tools.append(tool_name) return tools @pytest.mark.skip("Skip until debug mode is properly configured") def test_list_available_tools(self): """Test that the server reports its available tools in debug mode.""" returncode, log_content = run_server_command(["--dev", "--debug"]) # Check exit code assert returncode == 0, f"Server exited with non-zero code: {returncode}" # Find and extract tools tools = self.find_available_tools(log_content) # Verify that we found some tools assert len(tools) > 0, "No tools were registered in the server" # Log the found tools logger.info(f"Found registered tools: {tools}") # Verify some expected tools are present expected_tools = ["search_emails", "get_email", "draft_reply"] for tool in expected_tools: # Check if any tool name contains the expected tool name tool_exists = any(t for t in tools if tool in t) assert tool_exists, f"Expected tool '{tool}' was not found in registered tools" @pytest.mark.skip("Currently, direct tool execution is not supported via command line") def test_search_unread_emails(self): """Test the search_emails tool for finding unread emails.""" # Parameters for the search_emails tool search_params = { "folder": "INBOX", "criteria": { "seen": False # Search for unread (unseen) emails }, "limit": 10 } # This test is skipped as the server doesn't support direct tool execution via command line # Instead, use the mcp-cli to execute tools as shown in test_mcp_cli_integration.py pass class TestEmailToolsIntegration: """Tests for the email-related tools in the IMAP MCP server.""" @pytest.mark.skip("Currently, direct tool execution is not supported via command line") def test_list_folders(self): """Test the get_folders tool.""" # This test is skipped as the server doesn't support direct tool execution via command line # Instead, use the mcp-cli to execute tools as shown in test_mcp_cli_integration.py pass if __name__ == "__main__": # Allow running a specific test directly if len(sys.argv) > 1: parser = argparse.ArgumentParser(description="Run IMAP MCP server tests") parser.add_argument("--test", choices=["help", "version", "connect", "dev"], help="Test to run") args = parser.parse_args() test = TestImapMcpServerBasic() if args.test == "help": test.test_server_help_command() elif args.test == "version": test.test_server_version_command() elif args.test == "connect": test.test_server_connects_to_gmail() elif args.test == "dev": test.test_server_starts_in_dev_mode() else: print("Use pytest to run the tests")

Latest Blog Posts

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/non-dirty/imap-mcp'

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