mirror of
https://github.com/HKUDS/OpenSpace.git
synced 2026-09-06 08:16:07 +00:00
132 lines
No EOL
5.1 KiB
Python
132 lines
No EOL
5.1 KiB
Python
"""
|
|
Configuration loader for MCP session.
|
|
|
|
This module provides functionality to load MCP configuration from JSON files.
|
|
"""
|
|
|
|
from typing import Any, Optional
|
|
|
|
from openspace.grounding.core.types import SandboxOptions
|
|
from openspace.config.utils import get_config_value
|
|
from .transport.connectors import (
|
|
MCPBaseConnector,
|
|
HttpConnector,
|
|
SandboxConnector,
|
|
StdioConnector,
|
|
WebSocketConnector,
|
|
)
|
|
from .transport.connectors.utils import is_stdio_server
|
|
from .installer import MCPInstallerManager
|
|
|
|
# Import E2BSandbox
|
|
try:
|
|
from openspace.grounding.core.security import E2BSandbox
|
|
E2B_AVAILABLE = True
|
|
except ImportError:
|
|
E2BSandbox = None
|
|
E2B_AVAILABLE = False
|
|
|
|
async def create_connector_from_config(
|
|
server_config: dict[str, Any],
|
|
server_name: str = "unknown",
|
|
sandbox: bool = False,
|
|
sandbox_options: SandboxOptions | None = None,
|
|
timeout: float = 30.0,
|
|
sse_read_timeout: float = 300.0,
|
|
installer: Optional[MCPInstallerManager] = None,
|
|
check_dependencies: bool = True,
|
|
tool_call_max_retries: int = 3,
|
|
tool_call_retry_delay: float = 1.0,
|
|
) -> MCPBaseConnector:
|
|
"""Create a connector based on server configuration.
|
|
|
|
Args:
|
|
server_config: The server configuration section
|
|
server_name: Name of the MCP server (for display purposes)
|
|
sandbox: Whether to use sandboxed execution mode for running MCP servers.
|
|
sandbox_options: Optional sandbox configuration options.
|
|
timeout: Timeout for operations in seconds (default: 30.0)
|
|
sse_read_timeout: SSE read timeout in seconds (default: 300.0)
|
|
installer: Optional installer manager for dependency installation
|
|
check_dependencies: Whether to check and install dependencies (default: True)
|
|
tool_call_max_retries: Maximum number of retries for tool calls (default: 3)
|
|
tool_call_retry_delay: Initial delay between retries in seconds (default: 1.0)
|
|
|
|
Returns:
|
|
A configured connector instance
|
|
|
|
Raises:
|
|
RuntimeError: If dependencies are not installed and user declines installation
|
|
"""
|
|
|
|
# Get original command and args from config
|
|
original_command = get_config_value(server_config, "command")
|
|
original_args = get_config_value(server_config, "args", [])
|
|
|
|
# Check and install dependencies if needed (only for stdio servers)
|
|
if is_stdio_server(server_config) and check_dependencies:
|
|
# Use provided installer or get global instance
|
|
if installer is None:
|
|
from .installer import get_global_installer
|
|
installer = get_global_installer()
|
|
|
|
# Ensure dependencies are installed (using original command/args)
|
|
await installer.ensure_dependencies(server_name, original_command, original_args)
|
|
|
|
# Stdio connector (command-based)
|
|
if is_stdio_server(server_config) and not sandbox:
|
|
return StdioConnector(
|
|
command=get_config_value(server_config, "command"),
|
|
args=get_config_value(server_config, "args"),
|
|
env=get_config_value(server_config, "env", None),
|
|
)
|
|
|
|
# Sandboxed connector
|
|
elif is_stdio_server(server_config) and sandbox:
|
|
if not E2B_AVAILABLE:
|
|
raise ImportError(
|
|
"E2B sandbox support not available. Please install e2b-code-interpreter: "
|
|
"'pip install e2b-code-interpreter'"
|
|
)
|
|
|
|
# Create E2B sandbox instance
|
|
_sandbox_options = sandbox_options or {}
|
|
e2b_sandbox = E2BSandbox(_sandbox_options)
|
|
|
|
# Extract timeout values from sandbox_options or use defaults
|
|
connector_timeout = _sandbox_options.get("timeout", timeout)
|
|
connector_sse_timeout = _sandbox_options.get("sse_read_timeout", sse_read_timeout)
|
|
|
|
# Create and return sandbox connector
|
|
return SandboxConnector(
|
|
sandbox=e2b_sandbox,
|
|
command=get_config_value(server_config, "command"),
|
|
args=get_config_value(server_config, "args"),
|
|
env=get_config_value(server_config, "env", None),
|
|
supergateway_command=_sandbox_options.get("supergateway_command", "npx -y supergateway"),
|
|
port=_sandbox_options.get("port", 3000),
|
|
timeout=connector_timeout,
|
|
sse_read_timeout=connector_sse_timeout,
|
|
)
|
|
|
|
# HTTP connector
|
|
elif "url" in server_config:
|
|
return HttpConnector(
|
|
base_url=get_config_value(server_config, "url"),
|
|
headers=get_config_value(server_config, "headers", None),
|
|
auth_token=get_config_value(server_config, "auth_token", None),
|
|
timeout=timeout,
|
|
sse_read_timeout=sse_read_timeout,
|
|
tool_call_max_retries=tool_call_max_retries,
|
|
tool_call_retry_delay=tool_call_retry_delay,
|
|
)
|
|
|
|
# WebSocket connector
|
|
elif "ws_url" in server_config:
|
|
return WebSocketConnector(
|
|
url=get_config_value(server_config, "ws_url"),
|
|
headers=get_config_value(server_config, "headers", None),
|
|
auth_token=get_config_value(server_config, "auth_token", None),
|
|
)
|
|
|
|
raise ValueError("Cannot determine connector type from config") |