From 98aba8bf83a1bb908d5553f5e30963f6b24252b1 Mon Sep 17 00:00:00 2001 From: Alfonso Alongi Date: Fri, 10 Oct 2025 14:02:41 +0200 Subject: [PATCH] Add STDIO fallback support for MCP hosts without HTTP transport --- hexstrike_mcp.py | 65 ++++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 27 deletions(-) diff --git a/hexstrike_mcp.py b/hexstrike_mcp.py index 23b083b47..bf87ae435 100644 --- a/hexstrike_mcp.py +++ b/hexstrike_mcp.py @@ -160,34 +160,36 @@ def __init__(self, server_url: str, timeout: int = DEFAULT_REQUEST_TIMEOUT): self.session = requests.Session() # Try to connect to server with retries - connected = False - for i in range(MAX_RETRIES): - try: - logger.info(f"๐Ÿ”— Attempting to connect to HexStrike AI API at {server_url} (attempt {i+1}/{MAX_RETRIES})") - # First try a direct connection test before using the health endpoint + # If running under an MCP host (stdio not attached to a TTY), skip HTTP health checks to avoid bootstrap delays. + if sys.stdin.isatty() or sys.stdout.isatty(): + connected = False + for i in range(MAX_RETRIES): try: - test_response = self.session.get(f"{self.server_url}/health", timeout=5) - test_response.raise_for_status() - health_check = test_response.json() - connected = True - logger.info(f"๐ŸŽฏ Successfully connected to HexStrike AI API Server at {server_url}") - logger.info(f"๐Ÿฅ Server health status: {health_check.get('status', 'unknown')}") - logger.info(f"๐Ÿ“Š Server version: {health_check.get('version', 'unknown')}") - break - except requests.exceptions.ConnectionError: - logger.warning(f"๐Ÿ”Œ Connection refused to {server_url}. Make sure the HexStrike AI server is running.") - time.sleep(2) # Wait before retrying + logger.info(f"๐Ÿ”— Attempting to connect to HexStrike AI API at {server_url} (attempt {i+1}/{MAX_RETRIES})") + try: + test_response = self.session.get(f"{self.server_url}/health", timeout=5) + test_response.raise_for_status() + health_check = test_response.json() + connected = True + logger.info(f"๐ŸŽฏ Successfully connected to HexStrike AI API Server at {server_url}") + logger.info(f"๐Ÿฅ Server health status: {health_check.get('status', 'unknown')}") + logger.info(f"๐Ÿ“Š Server version: {health_check.get('version', 'unknown')}") + break + except requests.exceptions.ConnectionError: + logger.warning(f"๐Ÿ”Œ Connection refused to {server_url}. Make sure the HexStrike AI server is running.") + time.sleep(2) + except Exception as e: + logger.warning(f"โš ๏ธ Connection test failed: {str(e)}") + time.sleep(2) except Exception as e: - logger.warning(f"โš ๏ธ Connection test failed: {str(e)}") - time.sleep(2) # Wait before retrying - except Exception as e: - logger.warning(f"โŒ Connection attempt {i+1} failed: {str(e)}") - time.sleep(2) # Wait before retrying - - if not connected: - error_msg = f"Failed to establish connection to HexStrike AI API Server at {server_url} after {MAX_RETRIES} attempts" - logger.error(error_msg) - # We'll continue anyway to allow the MCP server to start, but tools will likely fail + logger.warning(f"โŒ Connection attempt {i+1} failed: {str(e)}") + time.sleep(2) + if not connected: + error_msg = f"Failed to establish connection to HexStrike AI API Server at {server_url} after {MAX_RETRIES} attempts" + logger.error(error_msg) + # continue anyway; MCP stdio server will still start + else: + logger.info("๐Ÿงช Stdio host detected (non-TTY). Skipping HTTP health checks and starting MCP stdio immediately.") def safe_get(self, endpoint: str, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]: """ @@ -5459,7 +5461,16 @@ def main(): mcp = setup_mcp_server(hexstrike_client) logger.info("๐Ÿš€ Starting HexStrike AI MCP server") logger.info("๐Ÿค– Ready to serve AI agents with enhanced cybersecurity capabilities") - mcp.run() + # Minimal stdio fallback for MCP clients that require stdio transport. + try: + mcp.run() + except AttributeError: + # Older/newer FastMCP variants expose an async stdio runner. + import asyncio + if hasattr(mcp, "run_stdio"): + asyncio.run(mcp.run_stdio()) + else: + raise except Exception as e: logger.error(f"๐Ÿ’ฅ Error starting MCP server: {str(e)}") import traceback