Spaces:
Running
Running
| """ | |
| 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") |