Skip to content

Commit 77684ca

Browse files
HanSur94claude
andcommitted
fix(ci): poll /mcp endpoint instead of /health for server readiness
The /health route is registered via @mcp.custom_route() which may not be accessible via direct HTTP in all FastMCP transport modes. Poll the MCP endpoint with a JSON-RPC initialize request instead — this is always available when the server is ready. Also increased timeout to 20s and removed continue-on-error now that the root cause is fixed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent d5ba1af commit 77684ca

2 files changed

Lines changed: 15 additions & 5 deletions

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ jobs:
102102
integration-test:
103103
needs: lint
104104
runs-on: ubuntu-latest
105-
continue-on-error: true # Server subprocess startup is timing-sensitive in CI
105+
# Polls /mcp endpoint for readiness (not /health which may not be routed)
106106
steps:
107107
- uses: actions/checkout@v4
108108
- uses: actions/setup-python@v5

tests/test_mcp_integration.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,8 @@
2929
_SERVER_HOST = "127.0.0.1"
3030
_SERVER_PORT = 8765
3131
_AUTH_TOKEN = "test-token-for-ci"
32-
_HEALTH_URL = f"http://{_SERVER_HOST}:{_SERVER_PORT}/health"
3332
_MCP_URL = f"http://{_SERVER_HOST}:{_SERVER_PORT}/mcp"
34-
_STARTUP_TIMEOUT_S = 15.0
33+
_STARTUP_TIMEOUT_S = 20.0
3534
_POLL_INTERVAL_S = 0.5
3635
_TEARDOWN_TIMEOUT_S = 5.0
3736

@@ -77,12 +76,23 @@ def mcp_server_process() -> Any:
7776
stderr=subprocess.PIPE,
7877
)
7978

80-
# Poll /health until server is ready or timeout expires
79+
# Poll /mcp until server is ready or timeout expires.
80+
# We POST a minimal JSON-RPC initialize to the MCP endpoint since /health
81+
# may not be routed through the same ASGI app on all transport modes.
8182
deadline = time.monotonic() + _STARTUP_TIMEOUT_S
8283
ready = False
84+
headers = {"Authorization": f"Bearer {_AUTH_TOKEN}"}
8385
while time.monotonic() < deadline:
8486
try:
85-
response = httpx.get(_HEALTH_URL, timeout=2.0)
87+
response = httpx.post(
88+
_MCP_URL,
89+
json={"jsonrpc": "2.0", "method": "initialize", "id": 0,
90+
"params": {"protocolVersion": "2024-11-05",
91+
"capabilities": {},
92+
"clientInfo": {"name": "test", "version": "0.1"}}},
93+
headers=headers,
94+
timeout=2.0,
95+
)
8696
if response.status_code < 500:
8797
ready = True
8898
break

0 commit comments

Comments
 (0)