feat: migrate legacy mcp config
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
|
||||
from typer.testing import CliRunner
|
||||
|
||||
from wf_cli.app import app
|
||||
|
||||
|
||||
def test_wf_config_migrate_mcp_prints_neutral_config(tmp_path) -> None:
|
||||
legacy_path = tmp_path / "wf_mcp.config.json"
|
||||
legacy_path.write_text(
|
||||
"""
|
||||
{
|
||||
"store_root": ".wf_mcp_store",
|
||||
"connections": [
|
||||
{
|
||||
"id": "everything.default",
|
||||
"server": "everything",
|
||||
"account": "default",
|
||||
"metadata": {
|
||||
"transport": "stdio",
|
||||
"command": "uvx",
|
||||
"args": ["mcp-server-everything"]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
result = CliRunner().invoke(app, ["config", "migrate-mcp", str(legacy_path)])
|
||||
|
||||
assert result.exit_code == 0, result.output
|
||||
payload = json.loads(result.output)
|
||||
assert payload["server"]["store"] == {
|
||||
"kind": "filesystem",
|
||||
"root": ".wf_mcp_store",
|
||||
}
|
||||
source = payload["server"]["sources"][0]
|
||||
assert source["kind"] == "mcp"
|
||||
assert source["id"] == "everything.default"
|
||||
assert source["transport"]["kind"] == "stdio"
|
||||
assert source["transport"]["command"] == "uvx"
|
||||
|
||||
|
||||
def test_wf_config_migrate_mcp_writes_output_file(tmp_path) -> None:
|
||||
legacy_path = tmp_path / "wf_mcp.config.json"
|
||||
output_path = tmp_path / "wf.json"
|
||||
legacy_path.write_text(
|
||||
"""
|
||||
{
|
||||
"store_root": "store",
|
||||
"connections": [
|
||||
{
|
||||
"id": "context7.default",
|
||||
"server": "context7",
|
||||
"account": "default",
|
||||
"metadata": {
|
||||
"transport": "streamable_http",
|
||||
"url": "http://127.0.0.1:3000/mcp"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
result = CliRunner().invoke(
|
||||
app,
|
||||
["config", "migrate-mcp", str(legacy_path), "--output", str(output_path)],
|
||||
)
|
||||
|
||||
assert result.exit_code == 0, result.output
|
||||
status = json.loads(result.output)
|
||||
assert status["status"] == "written"
|
||||
payload = json.loads(output_path.read_text(encoding="utf-8"))
|
||||
assert payload["server"]["sources"][0]["transport"]["kind"] == "http"
|
||||
@@ -45,15 +45,44 @@ def test_broker_config_from_workflow_config_converts_mcp_sources(tmp_path) -> No
|
||||
assert connection.source_config_ownership == "seed"
|
||||
assert connection.metadata["profile"] == "dev"
|
||||
assert connection.metadata["auth_ref"] == "auth.everything.default"
|
||||
assert connection.metadata["transport"] == {
|
||||
"kind": "stdio",
|
||||
"command": "uvx",
|
||||
"args": ["mcp-server-everything"],
|
||||
"env": {"DEBUG": "1"},
|
||||
}
|
||||
assert connection.metadata["transport"] == "stdio"
|
||||
assert connection.metadata["command"] == "uvx"
|
||||
assert connection.metadata["args"] == ["mcp-server-everything"]
|
||||
assert connection.metadata["env"] == {"DEBUG": "1"}
|
||||
assert connection.metadata["description"] == "Everything test server"
|
||||
|
||||
|
||||
def test_broker_config_from_workflow_config_converts_mcp_http_source(tmp_path) -> None:
|
||||
workflow_config = WorkflowConfigFile.model_validate(
|
||||
{
|
||||
"version": 1,
|
||||
"server": {
|
||||
"store": {"kind": "filesystem", "root": str(tmp_path / "store")},
|
||||
"sources": [
|
||||
{
|
||||
"kind": "mcp",
|
||||
"id": "context7.default",
|
||||
"provider": "context7",
|
||||
"account": "default",
|
||||
"transport": {
|
||||
"kind": "http",
|
||||
"url": "http://127.0.0.1:3000/mcp",
|
||||
"headers": {"X-Test": "yes"},
|
||||
},
|
||||
}
|
||||
],
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
broker_config = broker_config_from_workflow_config(workflow_config)
|
||||
|
||||
connection = broker_config.connections[0]
|
||||
assert connection.metadata["transport"] == "streamable_http"
|
||||
assert connection.metadata["url"] == "http://127.0.0.1:3000/mcp"
|
||||
assert connection.metadata["headers"] == {"X-Test": "yes"}
|
||||
|
||||
|
||||
def test_broker_config_from_workflow_config_ignores_non_mcp_sources(tmp_path) -> None:
|
||||
workflow_config = WorkflowConfigFile.model_validate(
|
||||
{
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from wf_config.models import McpSourceConfig
|
||||
from wf_mcp.broker.config import migrate_broker_config_file
|
||||
|
||||
|
||||
def test_migrate_broker_config_file_converts_stdio_connection(tmp_path: Path) -> None:
|
||||
legacy_path = tmp_path / "wf_mcp.config.json"
|
||||
legacy_path.write_text(
|
||||
"""
|
||||
{
|
||||
"store_root": ".wf_mcp_store",
|
||||
"connections": [
|
||||
{
|
||||
"id": "everything.default",
|
||||
"server": "everything",
|
||||
"account": "default",
|
||||
"enabled": true,
|
||||
"source_config_ownership": "seed",
|
||||
"metadata": {
|
||||
"transport": "stdio",
|
||||
"command": "uvx",
|
||||
"args": ["mcp-server-everything"],
|
||||
"env": {"DEBUG": "1"},
|
||||
"profile": "dev",
|
||||
"auth_ref": "auth.everything.default",
|
||||
"description": "Everything test server"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
config = migrate_broker_config_file(legacy_path)
|
||||
|
||||
assert config.server.store.kind == "filesystem"
|
||||
assert config.server.store.root == Path(".wf_mcp_store")
|
||||
assert len(config.server.sources) == 1
|
||||
source = config.server.sources[0]
|
||||
assert isinstance(source, McpSourceConfig)
|
||||
assert source.kind == "mcp"
|
||||
assert source.id == "everything.default"
|
||||
assert source.provider == "everything"
|
||||
assert source.account == "default"
|
||||
assert source.enabled is True
|
||||
assert source.ownership == "seed"
|
||||
assert source.profile == "dev"
|
||||
assert source.auth_ref == "auth.everything.default"
|
||||
assert source.transport.kind == "stdio"
|
||||
assert source.transport.command == "uvx"
|
||||
assert source.transport.args == ("mcp-server-everything",)
|
||||
assert source.transport.env == {"DEBUG": "1"}
|
||||
assert source.metadata["description"] == "Everything test server"
|
||||
|
||||
|
||||
def test_migrate_broker_config_file_converts_streamable_http_connection(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
legacy_path = tmp_path / "wf_mcp.config.json"
|
||||
legacy_path.write_text(
|
||||
"""
|
||||
{
|
||||
"store_root": "store",
|
||||
"connections": [
|
||||
{
|
||||
"id": "context7.default",
|
||||
"server": "context7",
|
||||
"account": "default",
|
||||
"metadata": {
|
||||
"transport": "streamable-http",
|
||||
"url": "http://127.0.0.1:3000/mcp",
|
||||
"headers": {"X-Test": "yes"},
|
||||
"description": "HTTP server"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
config = migrate_broker_config_file(legacy_path)
|
||||
|
||||
source = config.server.sources[0]
|
||||
assert isinstance(source, McpSourceConfig)
|
||||
assert source.kind == "mcp"
|
||||
assert source.transport.kind == "http"
|
||||
assert str(source.transport.url) == "http://127.0.0.1:3000/mcp"
|
||||
assert source.transport.headers == {"X-Test": "yes"}
|
||||
assert source.metadata["description"] == "HTTP server"
|
||||
assert source.metadata["legacy_transport"] == "streamable-http"
|
||||
|
||||
|
||||
def test_migrate_broker_config_file_converts_sse_connection(tmp_path: Path) -> None:
|
||||
legacy_path = tmp_path / "wf_mcp.config.json"
|
||||
legacy_path.write_text(
|
||||
"""
|
||||
{
|
||||
"store_root": "store",
|
||||
"connections": [
|
||||
{
|
||||
"id": "legacy.default",
|
||||
"server": "legacy",
|
||||
"account": "default",
|
||||
"metadata": {
|
||||
"transport": "sse",
|
||||
"url": "http://127.0.0.1:3000/sse"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
config = migrate_broker_config_file(legacy_path)
|
||||
|
||||
source = config.server.sources[0]
|
||||
assert isinstance(source, McpSourceConfig)
|
||||
assert source.transport.kind == "http"
|
||||
assert str(source.transport.url) == "http://127.0.0.1:3000/sse"
|
||||
assert source.metadata["legacy_transport"] == "sse"
|
||||
Reference in New Issue
Block a user