fix: non-blocking health checks and wait defaults

- docker_health now runs HTTP call in thread executor instead of
  blocking the async event loop (prevents MCP server freeze during polls)
- docker_auto_start defaults to wait=False so tool returns immediately
  (clients should call docker_wait separately if needed)
This commit is contained in:
Ryan Malloy 2026-02-02 14:25:07 -07:00
parent 77ce01d313
commit 48ccc2aff3

View File

@ -815,21 +815,15 @@ class DockerMixin(MCPMixin):
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
return {"error": f"Build failed: {e.stderr or e.stdout}"} return {"error": f"Build failed: {e.stderr or e.stdout}"}
@mcp_tool( def _sync_health_check(self, port: int, timeout: float) -> Dict[str, Any]:
name="docker_health", """Synchronous health check (runs in thread to avoid blocking event loop).
description="Check if a GhydraMCP container's API is responding",
)
async def docker_health(
self, port: int = 8192, timeout: float = 5.0, ctx: Optional[Context] = None
) -> Dict[str, Any]:
"""Check if a GhydraMCP container's API is healthy.
Args: Args:
port: API port to check (default: 8192) port: API port to check
timeout: Request timeout in seconds timeout: Request timeout in seconds
Returns: Returns:
Health status and API info if available Health status dict
""" """
import json as json_module import json as json_module
import urllib.error import urllib.error
@ -862,6 +856,27 @@ class DockerMixin(MCPMixin):
"error": str(e), "error": str(e),
} }
@mcp_tool(
name="docker_health",
description="Check if a GhydraMCP container's API is responding",
)
async def docker_health(
self, port: int = 8192, timeout: float = 5.0, ctx: Optional[Context] = None
) -> Dict[str, Any]:
"""Check if a GhydraMCP container's API is healthy.
Args:
port: API port to check (default: 8192)
timeout: Request timeout in seconds
Returns:
Health status and API info if available
"""
loop = asyncio.get_event_loop()
return await loop.run_in_executor(
None, self._sync_health_check, port, timeout
)
@mcp_tool( @mcp_tool(
name="docker_wait", name="docker_wait",
description="Wait for a GhydraMCP container to become healthy", description="Wait for a GhydraMCP container to become healthy",
@ -910,7 +925,7 @@ class DockerMixin(MCPMixin):
async def docker_auto_start( async def docker_auto_start(
self, self,
binary_path: str, binary_path: str,
wait: bool = True, wait: bool = False,
timeout: float = 300.0, timeout: float = 300.0,
ctx: Optional[Context] = None, ctx: Optional[Context] = None,
) -> Dict[str, Any]: ) -> Dict[str, Any]:
@ -927,7 +942,7 @@ class DockerMixin(MCPMixin):
Args: Args:
binary_path: Path to the binary to analyze binary_path: Path to the binary to analyze
wait: Wait for container to be ready (default: True) wait: Wait for container to be ready (default: False, use docker_wait separately)
timeout: Max wait time in seconds (default: 300) timeout: Max wait time in seconds (default: 300)
Returns: Returns: