|
| 1 | +# stdlib imports |
| 2 | +from pathlib import Path |
| 3 | + |
| 4 | +# third party imports |
| 5 | +import pytest |
| 6 | + |
| 7 | +# local imports |
| 8 | +from mcp.client.config.mcp_servers_config import MCPServersConfig, StdioServerConfig, StreamableHTTPServerConfig |
| 9 | + |
| 10 | + |
| 11 | +@pytest.fixture |
| 12 | +def mcp_yaml_config_file() -> Path: |
| 13 | + """Return path to the mcp.yaml config file.""" |
| 14 | + return Path(__file__).parent / "mcp.yaml" |
| 15 | + |
| 16 | + |
| 17 | +def test_yaml_extension_auto_detection(mcp_yaml_config_file: Path): |
| 18 | + """Test that .yaml files are automatically parsed with PyYAML.""" |
| 19 | + config = MCPServersConfig.from_file(mcp_yaml_config_file) |
| 20 | + |
| 21 | + # Should successfully load the YAML file with all 9 servers |
| 22 | + assert "stdio_server" in config.servers |
| 23 | + assert "streamable_http_server_with_headers" in config.servers |
| 24 | + assert "sse_server_with_explicit_type" in config.servers |
| 25 | + |
| 26 | + # Verify a specific server |
| 27 | + stdio_server = config.servers["stdio_server"] |
| 28 | + assert isinstance(stdio_server, StdioServerConfig) |
| 29 | + assert stdio_server.command == "python" |
| 30 | + assert stdio_server.args == ["-m", "my_server"] |
| 31 | + assert stdio_server.env == {"DEBUG": "true"} |
| 32 | + |
| 33 | + |
| 34 | +def test_use_pyyaml_parameter_with_json_file(): |
| 35 | + """Test that use_pyyaml=True forces PyYAML parsing even for JSON files.""" |
| 36 | + json_file = Path(__file__).parent / "mcp.json" |
| 37 | + |
| 38 | + # Load with PyYAML explicitly |
| 39 | + config = MCPServersConfig.from_file(json_file, use_pyyaml=True) |
| 40 | + |
| 41 | + # Should work fine - PyYAML can parse JSON |
| 42 | + assert len(config.servers) == 7 |
| 43 | + assert "stdio_server" in config.servers |
| 44 | + |
| 45 | + # Verify it produces the same result as normal JSON parsing |
| 46 | + config_json = MCPServersConfig.from_file(json_file, use_pyyaml=False) |
| 47 | + assert len(config.servers) == len(config_json.servers) |
| 48 | + assert list(config.servers.keys()) == list(config_json.servers.keys()) |
| 49 | + |
| 50 | + |
| 51 | +def test_time_server(mcp_yaml_config_file: Path): |
| 52 | + """Test the time server configuration with uvx command.""" |
| 53 | + config = MCPServersConfig.from_file(mcp_yaml_config_file) |
| 54 | + |
| 55 | + # Should have the time server |
| 56 | + assert "time" in config.servers |
| 57 | + |
| 58 | + # Verify the server configuration |
| 59 | + time_server = config.servers["time"] |
| 60 | + assert isinstance(time_server, StdioServerConfig) |
| 61 | + assert time_server.type == "stdio" # Should be auto-inferred from command field |
| 62 | + assert time_server.command == "uvx mcp-server-time" |
| 63 | + assert time_server.args is None # No explicit args |
| 64 | + assert time_server.env is None # No environment variables |
| 65 | + |
| 66 | + # Test the effective command parsing |
| 67 | + assert time_server.effective_command == "uvx" |
| 68 | + assert time_server.effective_args == ["mcp-server-time"] |
| 69 | + |
| 70 | + |
| 71 | +def test_streamable_http_server(mcp_yaml_config_file: Path): |
| 72 | + """Test the new streamable HTTP server configuration without headers.""" |
| 73 | + config = MCPServersConfig.from_file(mcp_yaml_config_file) |
| 74 | + |
| 75 | + # Should have the new streamable_http_server |
| 76 | + assert "streamable_http_server" in config.servers |
| 77 | + |
| 78 | + # Verify the server configuration |
| 79 | + http_server = config.servers["streamable_http_server"] |
| 80 | + assert isinstance(http_server, StreamableHTTPServerConfig) |
| 81 | + assert http_server.type == "streamable_http" # Should be auto-inferred |
| 82 | + assert http_server.url == "https://api.example.com/mcp" |
| 83 | + assert http_server.headers is None # No headers specified |
0 commit comments