Skip to content

Add MCP registry builder for Copilot MCP servers#216

Merged
2-Coatl merged 3 commits intodevelopfrom
feature/implement-mcp-server-installation-and-configuration-05-50-55
Nov 18, 2025
Merged

Add MCP registry builder for Copilot MCP servers#216
2-Coatl merged 3 commits intodevelopfrom
feature/implement-mcp-server-installation-and-configuration-05-50-55

Conversation

@2-Coatl
Copy link
Copy Markdown
Collaborator

@2-Coatl 2-Coatl commented Nov 16, 2025

Summary

  • add an ai.mcp registry module that captures the blackbird, GitHub, and Playwright MCP configurations as dataclasses and exposes a serializable CLI config
  • add unit tests that validate the remote entries, Playwright CLI args, and registry serialization helpers

Testing

  • pytest scripts/coding/tests/ai/mcp/test_registry.py -q

Codex Task

Copilot AI review requested due to automatic review settings November 16, 2025 05:51
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.py with 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__.py for 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

Comment thread scripts/coding/ai/mcp/registry.py Outdated
"metadata": {
"allowed_origins": list(self.allowed_origins),
"output_dir": self.output_dir,
"viewport_size": self.viewport_size,
Copy link

Copilot AI Nov 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

  1. Storing viewport_size as a list [1280, 720] for JSON compatibility
  2. 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.

Suggested change
"viewport_size": self.viewport_size,
"viewport_size": list(self.viewport_size),

Copilot uses AI. Check for mistakes.
from __future__ import annotations

from dataclasses import dataclass, field
from typing import Dict, Mapping, Tuple
Copy link

Copilot AI Nov 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[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] with dict[str, object]
  • Replace Dict[str, Dict[str, object]] with dict[str, dict[str, object]]
  • Replace Mapping[str, str] with collections.abc.Mapping[str, str] or just dict[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).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment on lines +35 to +66
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"
Copy link

Copilot AI Nov 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test suite lacks coverage for edge cases such as:

  1. Empty registries (no remote or local servers)
  2. Servers with custom headers or environment variables
  3. 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"

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

name="playwright",
command="npx",
args=(
"@playwright/mcp@0.0.40",
Copy link

Copilot AI Nov 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The hardcoded version @playwright/mcp@0.0.40 should be verified to exist. Consider:

  1. Adding a comment explaining why this specific version is pinned (e.g., "// Version 0.0.40 matches the Copilot CLI reference log")
  2. 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-DD

This makes version management more maintainable and traceable.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

2-Coatl and others added 2 commits November 16, 2025 00:04
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented Nov 16, 2025

@2-Coatl I've opened a new pull request, #217, to work on those changes. Once the pull request is ready, I'll request review from you.

Copy link
Copy Markdown
Contributor

Copilot AI commented Nov 16, 2025

@2-Coatl I've opened a new pull request, #218, to work on those changes. Once the pull request is ready, I'll request review from you.

Copy link
Copy Markdown
Contributor

Copilot AI commented Nov 16, 2025

@2-Coatl I've opened a new pull request, #219, to work on those changes. Once the pull request is ready, I'll request review from you.

@2-Coatl 2-Coatl merged commit 16e67a1 into develop Nov 18, 2025
5 of 27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants