feat(mcp): add WorldQuant authentication recovery tools
Deploy production / deploy (push) Successful in 52s

This commit is contained in:
yuxuanhui
2026-09-10 10:26:44 +08:00
parent d4c33d0124
commit f67b4d99b7
6 changed files with 142 additions and 4 deletions
+77 -1
View File
@@ -162,7 +162,7 @@ async def test_official_sdk_client_and_error_contract(mcp_app):
async with ClientSession(streams[0], streams[1]) as client:
await client.initialize()
listed = await client.list_tools()
assert len(listed.tools) == 13
assert len(listed.tools) == 15
caps = await client.call_tool("get_research_capabilities", {})
assert caps.structured_content["max_candidates"] == 100
result = await client.call_tool("submit_backtests", submission())
@@ -383,3 +383,79 @@ async def test_self_correlation_read_only_scope_and_invalid_inputs(mcp_app):
assert missing.is_error and missing.structured_content["error"]["code"] == "NOT_FOUND"
async with mcp_app.state.sessions() as db:
assert await db.scalar(select(func.count()).select_from(Job)) == 0
async def test_worldquant_authentication_queue_and_recovery(mcp_app):
from app.models import Account, Job
principal, _ = await credentials(mcp_app)
runner = mcp_app.state.runner
runner.client.disconnect()
async with mcp_app.state.sessions.begin() as db:
account = await db.get(Account, 1)
account.connection_status = "disconnected"
before = await invoke(mcp_app, principal, "get_worldquant_connection")
assert before["credentials_configured"] and not before["session_authenticated"]
runner.wake.clear()
started = await invoke(mcp_app, principal, "authenticate_worldquant")
assert started["status"] == "queued" and runner.wake.is_set()
again = await invoke(mcp_app, principal, "authenticate_worldquant")
assert again["job_id"] == started["job_id"]
await runner.execute(started["job_id"])
done = await invoke(mcp_app, principal, "get_worldquant_connection", {"job_id": started["job_id"]})
assert done["job"]["status"] == "completed"
assert done["connection_status"] == "connected" and done["session_authenticated"]
async with mcp_app.state.sessions() as db:
assert await db.scalar(select(func.count()).select_from(Job)) == 1
audit = await db.scalar(select(MCPAudit).where(MCPAudit.tool == "authenticate_worldquant"))
assert audit.business_id == started["job_id"]
assert "synthetic-platform-secret" not in str(done)
assert "password" not in str(done) and "verification_url" not in str(done)
async def test_worldquant_authentication_permissions_and_challenge(mcp_app):
from fastapi import HTTPException
from app.models import Account, Job
from app.worldquant import VerificationRequired
readonly, _ = await credentials(mcp_app, {"research:read"})
await invoke(mcp_app, readonly, "get_worldquant_connection")
with pytest.raises(HTTPException) as denied:
await mcp_app.state.mcp.invoke(readonly, "authenticate_worldquant", {})
assert denied.value.status_code == 403
principal, _ = await credentials(mcp_app)
invalid = await mcp_app.state.mcp.invoke(principal, "authenticate_worldquant", {"password": "untrusted"})
assert invalid.is_error and invalid.structured_content["error"]["code"] == "INVALID_INPUT"
runner = mcp_app.state.runner
original = runner.client.authenticate
async def challenge(*args, **kwargs):
runner.client.verification_url = "https://api.worldquantbrain.com/authentication/test-challenge"
raise VerificationRequired(runner.client.verification_url)
runner.client.authenticate = challenge
started = await invoke(mcp_app, principal, "authenticate_worldquant")
await runner.execute(started["job_id"])
waiting = await invoke(mcp_app, principal, "get_worldquant_connection", {"job_id": started["job_id"]})
assert waiting["requires_human_verification"] and waiting["job"]["status"] == "waiting_auth"
blocked = await mcp_app.state.mcp.invoke(principal, "authenticate_worldquant", {})
assert blocked.structured_content["error"]["code"] == "VERIFICATION_REQUIRED"
runner.client.authenticate = original
# Simulate completion of the human challenge; keep normal profile/identity verification.
async def verified():
runner.client.verification_url = None
await original("synthetic@example.com", "synthetic-platform-secret", force=True)
runner.client.verify = verified
resumed = await invoke(mcp_app, principal, "authenticate_worldquant", {"action": "verify"})
await runner.execute(resumed["job_id"])
done = await invoke(mcp_app, principal, "get_worldquant_connection", {"job_id": resumed["job_id"]})
assert done["connection_status"] == "connected" and done["job"]["status"] == "completed"
async with mcp_app.state.sessions.begin() as db:
account = await db.get(Account, 1)
account.password_encrypted = None
db.add(Job(id="unrelated", kind="pnl_refresh"))
missing = await mcp_app.state.mcp.invoke(principal, "authenticate_worldquant", {})
assert missing.structured_content["error"]["code"] == "CREDENTIALS_NOT_CONFIGURED"
wrong = await mcp_app.state.mcp.invoke(principal, "get_worldquant_connection", {"job_id": "unrelated"})
assert wrong.structured_content["error"]["code"] == "NOT_FOUND"