mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-24 21:55:25 -04:00
5ce2056521
Part of #3629 (the `admin_tools.py` bullet). Moves the config/integration admin tools off the legacy elif dispatch chain in tool_implementations.py onto the agent_tools registry: manage_endpoints, manage_mcp, manage_webhooks, manage_tokens, manage_settings The do_* implementations (and manage_mcp's command-allowlist / RCE guard: _validate_mcp_command, _mcp_allowed_commands, and the _MCP_* constants) move verbatim into the new src/agent_tools/admin_tools.py. They register through a single ADMIN_TOOL_HANDLERS map that TOOL_HANDLERS.update()s, and the five elif branches plus their imports are dropped from tool_execution.py, so these tools now flow through _direct_fallback like the other migrated clusters. The names are re-exported from src.agent_tools for back-compat. Dedup: - _parse_tool_args was duplicated in tool_implementations.py and document_tools.py. It now lives once in src.tool_utils (which imports nothing from the project beyond src.constants, so this introduces no cycle) and both call sites import it from there. The orphaned `import json` in document_tools is removed with it. - The five tools share one _owner_adapter(fn) factory that threads ctx["owner"] into the owner-taking do_* signature, instead of five near-identical wrappers. Tests: new tests/test_admin_tools_registry.py pins the registration, the re-export back-compat, the owner-threading adapter, and the single-source _parse_tool_args (across admin_tools and document_tools). Existing MCP / settings / webhook suites are repointed at the new module.
47 lines
1.5 KiB
Python
47 lines
1.5 KiB
Python
"""Verify that MCP reconnect via the agent tool passes full server metadata."""
|
|
|
|
import asyncio
|
|
import json
|
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|
from types import SimpleNamespace
|
|
|
|
|
|
def test_reconnect_passes_full_server_config():
|
|
"""do_manage_mcp reconnect must pass name/transport/command/args/env/url."""
|
|
from src.agent_tools.admin_tools import do_manage_mcp
|
|
|
|
fake_mcp = MagicMock()
|
|
fake_mcp.disconnect_server = AsyncMock()
|
|
fake_mcp.connect_server = AsyncMock(return_value=True)
|
|
fake_mcp.get_server_status = MagicMock(return_value={"tool_count": 3})
|
|
|
|
fake_srv = SimpleNamespace(
|
|
id="srv-123",
|
|
name="test-server",
|
|
transport="stdio",
|
|
command="/usr/bin/test",
|
|
args=json.dumps(["--flag"]),
|
|
env=json.dumps({"KEY": "val"}),
|
|
url=None,
|
|
)
|
|
|
|
fake_db = MagicMock()
|
|
fake_db.query.return_value.filter.return_value.first.return_value = fake_srv
|
|
|
|
with patch("src.agent_tools.admin_tools.get_mcp_manager", return_value=fake_mcp), \
|
|
patch("core.database.SessionLocal", return_value=fake_db):
|
|
result = asyncio.run(do_manage_mcp(
|
|
json.dumps({"action": "reconnect", "server_id": "srv-123"})
|
|
))
|
|
|
|
assert result["exit_code"] == 0
|
|
fake_mcp.connect_server.assert_called_once_with(
|
|
server_id="srv-123",
|
|
name="test-server",
|
|
transport="stdio",
|
|
command="/usr/bin/test",
|
|
args=["--flag"],
|
|
env={"KEY": "val"},
|
|
url=None,
|
|
)
|