MCP: fix in-process tool calls and keep caller token in batch calls

- httpx.ASGITransport is async-only; the sync client made every
  tools/call fail with "'ASGITransport' object has no attribute
  '__enter__'". Run the in-process request on the API loop from the
  tool worker thread instead.
- http_json_many fanned out on a plain thread pool without the caller's
  context, so batch requests fell back to the server MCP token file.
  Copy the context per request so RBAC uses the caller's token.
- Real-TCP regression: tools/call getTopologyTree must reach the API.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
oliver 2026-10-16 22:09:28 +08:00
parent 52679a7cfc
commit 92bfad3e34
3 changed files with 89 additions and 33 deletions

View file

@ -187,3 +187,28 @@ def test_mcp_tcp_httpx_initialize(live_mcp_port: int):
assert r.status_code == 200, (r.status_code, r.text[:300])
data = r.json()
assert data["result"]["serverInfo"]["name"] == "netx"
def test_mcp_tcp_tool_call_reaches_api(live_mcp_port: int):
"""tools/call must run the in-process API request (not just list tools)."""
body = {
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {"name": "getTopologyTree", "arguments": {}},
}
r = httpx.post(
f"http://127.0.0.1:{live_mcp_port}/mcp",
json=body,
headers={
"Accept": "application/json, text/event-stream",
"MCP-Protocol-Version": "2024-11-05",
},
timeout=60.0,
trust_env=False,
)
assert r.status_code == 200, (r.status_code, r.text[:300])
result = r.json()["result"]
text = result["content"][0]["text"]
assert "netx_request_failed" not in text, text[:300]
assert not result.get("isError"), text[:300]