Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR introduces a declarative MCP (Model Context Protocol) registry system that captures configurations for Copilot MCP servers. The implementation includes dataclasses for remote (blackbird, GitHub) and local (Playwright) servers with serialization support for CLI consumption.
Key Changes:
- Added
scripts/coding/ai/mcp/registry.pywith frozen dataclasses for RemoteMCPServer, LocalMCPServer, and MCPRegistry with CLI serialization methods - Created comprehensive unit tests validating server configurations, CLI argument formatting, and registry serialization
- Exposed public API through
__init__.pyfor easy consumption
Reviewed Changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
scripts/coding/ai/mcp/registry.py |
Core registry implementation with dataclasses and build_default_registry() factory function mirroring Copilot CLI configuration |
scripts/coding/tests/ai/mcp/test_registry.py |
Unit tests validating remote server URLs, Playwright CLI arguments, and serialization logic |
scripts/coding/ai/mcp/__init__.py |
Package initialization with public API exports for registry components |
scripts/coding/tests/ai/mcp/__init__.py |
Empty test package marker file |
| "metadata": { | ||
| "allowed_origins": list(self.allowed_origins), | ||
| "output_dir": self.output_dir, | ||
| "viewport_size": self.viewport_size, |
There was a problem hiding this comment.
The viewport_size metadata in the CLI entry is stored as a tuple (1280, 720) while the command-line argument is formatted as a string "1280, 720". This inconsistency could confuse consumers of the serialized config. Consider either:
- Storing
viewport_sizeas a list[1280, 720]for JSON compatibility - Converting the tuple to a list in the serialization:
"viewport_size": list(self.viewport_size)
This makes the serialized format more standard and easier to consume by downstream tools.
| "viewport_size": self.viewport_size, | |
| "viewport_size": list(self.viewport_size), |
| from __future__ import annotations | ||
|
|
||
| from dataclasses import dataclass, field | ||
| from typing import Dict, Mapping, Tuple |
There was a problem hiding this comment.
[nitpick] The Mapping and Dict types used in return annotations don't align with modern Python best practices. Consider using lowercase generic types from typing or the built-in types (Python 3.9+):
- Replace
Dict[str, object]withdict[str, object] - Replace
Dict[str, Dict[str, object]]withdict[str, dict[str, object]] - Replace
Mapping[str, str]withcollections.abc.Mapping[str, str]or justdict[str, str]for the default
This follows PEP 585 and aligns with modern Python type hinting practices (Python 3.11 is in use per the project guidelines).
There was a problem hiding this comment.
@copilot open a new pull request to apply changes based on this feedback
| def test_default_registry_declares_remote_servers(registry_module): | ||
| registry = registry_module.build_default_registry() | ||
|
|
||
| remote_names = [server.name for server in registry.remote_servers] | ||
| assert remote_names == ["blackbird-mcp-server", "github-mcp-server"] | ||
| assert {server.url for server in registry.remote_servers} == { | ||
| "https://api.githubcopilot.com/mcp/readonly" | ||
| } | ||
| assert all(server.mode == "readonly" for server in registry.remote_servers) | ||
|
|
||
|
|
||
| def test_playwright_server_configuration_matches_reference_log(registry_module): | ||
| registry = registry_module.build_default_registry() | ||
| local_servers = {server.name: server for server in registry.local_servers} | ||
| playwright = local_servers["playwright"] | ||
|
|
||
| assert playwright.command == "npx" | ||
| assert playwright.viewport_size == (1280, 720) | ||
| assert playwright.output_dir == "/tmp/playwright-logs" | ||
| assert "@playwright/mcp@0.0.40" in playwright.args | ||
| assert "--allowed-origins" in playwright.args | ||
| assert "localhost;localhost:*;127.0.0.1;127.0.0.1:*" in playwright.args | ||
|
|
||
|
|
||
| def test_registry_cli_config_serializes_servers(registry_module): | ||
| registry = registry_module.build_default_registry() | ||
| cli_config = registry.as_cli_config() | ||
|
|
||
| assert "remote" in cli_config and "local" in cli_config | ||
| assert cli_config["remote"]["github-mcp-server"]["url"].startswith("https://") | ||
| assert cli_config["local"]["playwright"]["command"] == "npx" | ||
| assert cli_config["local"]["playwright"]["args"][0] == "@playwright/mcp@0.0.40" |
There was a problem hiding this comment.
The test suite lacks coverage for edge cases such as:
- Empty registries (no remote or local servers)
- Servers with custom headers or environment variables
- Error handling when serializing invalid data
Consider adding test cases like:
def test_empty_registry_serializes_correctly(registry_module):
empty_registry = registry_module.MCPRegistry(remote_servers=(), local_servers=())
config = empty_registry.as_cli_config()
assert config == {"remote": {}, "local": {}}
def test_remote_server_with_custom_headers(registry_module):
server = registry_module.RemoteMCPServer(
name="test",
url="https://test.com",
headers={"Authorization": "Bearer token"}
)
entry = server.as_cli_entry()
assert "headers" in entry
assert entry["headers"]["Authorization"] == "Bearer token"There was a problem hiding this comment.
@copilot open a new pull request to apply changes based on this feedback
| name="playwright", | ||
| command="npx", | ||
| args=( | ||
| "@playwright/mcp@0.0.40", |
There was a problem hiding this comment.
[nitpick] The hardcoded version @playwright/mcp@0.0.40 should be verified to exist. Consider:
- Adding a comment explaining why this specific version is pinned (e.g., "// Version 0.0.40 matches the Copilot CLI reference log")
- Documenting the version source or adding a constant at the module level for easier updates:
PLAYWRIGHT_MCP_VERSION = "0.0.40" # From Copilot CLI log YYYY-MM-DDThis makes version management more maintainable and traceable.
There was a problem hiding this comment.
@copilot open a new pull request to apply changes based on this feedback
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Summary
Testing
pytest scripts/coding/tests/ai/mcp/test_registry.py -qCodex Task