refactor(tools): Audit and cleanup mcp_client.py and shell_runner.py
This commit is contained in:
+10
-2
@@ -999,10 +999,13 @@ class StdioMCPServer:
|
|||||||
return str(result)
|
return str(result)
|
||||||
|
|
||||||
class ExternalMCPManager:
|
class ExternalMCPManager:
|
||||||
|
"""Manages external MCP servers using the StdioMCPServer class."""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
"""Initialize the manager with an empty server registry."""
|
||||||
self.servers = {}
|
self.servers = {}
|
||||||
|
|
||||||
async def add_server(self, config: models.MCPServerConfig):
|
async def add_server(self, config: models.MCPServerConfig):
|
||||||
|
"""Add and start a new MCP server from a configuration object."""
|
||||||
if config.url:
|
if config.url:
|
||||||
# RemoteMCPServer placeholder
|
# RemoteMCPServer placeholder
|
||||||
return
|
return
|
||||||
@@ -1011,11 +1014,13 @@ class ExternalMCPManager:
|
|||||||
self.servers[config.name] = server
|
self.servers[config.name] = server
|
||||||
|
|
||||||
async def stop_all(self):
|
async def stop_all(self):
|
||||||
|
"""Stop all managed MCP servers and clear the registry."""
|
||||||
for server in self.servers.values():
|
for server in self.servers.values():
|
||||||
await server.stop()
|
await server.stop()
|
||||||
self.servers = {}
|
self.servers = {}
|
||||||
|
|
||||||
def get_all_tools(self) -> dict:
|
def get_all_tools(self) -> dict:
|
||||||
|
"""Retrieve a dictionary of all tools available across all managed servers."""
|
||||||
all_tools = {}
|
all_tools = {}
|
||||||
for sname, server in self.servers.items():
|
for sname, server in self.servers.items():
|
||||||
for tname, tool in server.tools.items():
|
for tname, tool in server.tools.items():
|
||||||
@@ -1023,9 +1028,11 @@ class ExternalMCPManager:
|
|||||||
return all_tools
|
return all_tools
|
||||||
|
|
||||||
def get_servers_status(self) -> dict[str, str]:
|
def get_servers_status(self) -> dict[str, str]:
|
||||||
|
"""Get the current operational status of all managed servers."""
|
||||||
return {name: server.status for name, server in self.servers.items()}
|
return {name: server.status for name, server in self.servers.items()}
|
||||||
|
|
||||||
async def async_dispatch(self, tool_name: str, tool_input: dict) -> str:
|
async def async_dispatch(self, tool_name: str, tool_input: dict) -> str:
|
||||||
|
"""Dispatch a tool call to the appropriate external MCP server asynchronously."""
|
||||||
for server in self.servers.values():
|
for server in self.servers.values():
|
||||||
if tool_name in server.tools:
|
if tool_name in server.tools:
|
||||||
return await server.call_tool(tool_name, tool_input)
|
return await server.call_tool(tool_name, tool_input)
|
||||||
@@ -1034,11 +1041,10 @@ class ExternalMCPManager:
|
|||||||
_external_mcp_manager = ExternalMCPManager()
|
_external_mcp_manager = ExternalMCPManager()
|
||||||
|
|
||||||
def get_external_mcp_manager() -> ExternalMCPManager:
|
def get_external_mcp_manager() -> ExternalMCPManager:
|
||||||
|
"""Retrieve the global ExternalMCPManager instance."""
|
||||||
global _external_mcp_manager
|
global _external_mcp_manager
|
||||||
return _external_mcp_manager
|
return _external_mcp_manager
|
||||||
|
|
||||||
TOOL_NAMES: set[str] = {"read_file", "list_directory", "search_files", "get_file_summary", "py_get_skeleton", "py_get_code_outline", "py_get_definition", "get_git_diff", "web_search", "fetch_url", "get_ui_performance", "get_file_slice", "set_file_slice", "edit_file", "py_update_definition", "py_get_signature", "py_set_signature", "py_get_class_summary", "py_get_var_declaration", "py_set_var_declaration", "py_find_usages", "py_get_imports", "py_check_syntax", "py_get_hierarchy", "py_get_docstring", "get_tree"}
|
|
||||||
|
|
||||||
def dispatch(tool_name: str, tool_input: dict[str, Any]) -> str:
|
def dispatch(tool_name: str, tool_input: dict[str, Any]) -> str:
|
||||||
"""
|
"""
|
||||||
Dispatch an MCP tool call by name. Returns the result as a string.
|
Dispatch an MCP tool call by name. Returns the result as a string.
|
||||||
@@ -1598,6 +1604,8 @@ MCP_TOOL_SPECS: list[dict[str, Any]] = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
TOOL_NAMES: set[str] = {t['name'] for t in MCP_TOOL_SPECS}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+9
-2
@@ -1,4 +1,11 @@
|
|||||||
# shell_runner.py
|
# shell_runner.py
|
||||||
|
"""
|
||||||
|
Shell Runner - Execution engine for PowerShell scripts.
|
||||||
|
|
||||||
|
This module provides utilities to run PowerShell scripts in a subprocess,
|
||||||
|
configuring the environment via mcp_env.toml. It handles timeouts,
|
||||||
|
logging, and optional QA/patch callbacks for error recovery.
|
||||||
|
"""
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import shutil
|
import shutil
|
||||||
@@ -14,7 +21,7 @@ TIMEOUT_SECONDS: int = 60
|
|||||||
_ENV_CONFIG: dict = {}
|
_ENV_CONFIG: dict = {}
|
||||||
|
|
||||||
def _load_env_config() -> dict:
|
def _load_env_config() -> dict:
|
||||||
"""Load mcp_env.toml from project root (sibling of this file or parent dir)."""
|
"""Load mcp_env.toml from project root or environment variable."""
|
||||||
env_path = os.environ.get("SLOP_MCP_ENV")
|
env_path = os.environ.get("SLOP_MCP_ENV")
|
||||||
if env_path and Path(env_path).exists():
|
if env_path and Path(env_path).exists():
|
||||||
with open(env_path, "rb") as f:
|
with open(env_path, "rb") as f:
|
||||||
@@ -30,7 +37,7 @@ def _load_env_config() -> dict:
|
|||||||
return {}
|
return {}
|
||||||
|
|
||||||
def _build_subprocess_env() -> dict[str, str]:
|
def _build_subprocess_env() -> dict[str, str]:
|
||||||
"""Build env dict for subprocess: current env + mcp_env.toml overrides."""
|
"""Build environment dictionary for subprocess with overrides from mcp_env.toml."""
|
||||||
global _ENV_CONFIG
|
global _ENV_CONFIG
|
||||||
if not _ENV_CONFIG:
|
if not _ENV_CONFIG:
|
||||||
_ENV_CONFIG = _load_env_config()
|
_ENV_CONFIG = _load_env_config()
|
||||||
|
|||||||
Reference in New Issue
Block a user