-
Notifications
You must be signed in to change notification settings - Fork 3k
feat(sdk-python): enable mcp_servers support via initialize control request #6463
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -110,6 +110,8 @@ async def _ensure_started(self) -> None: | |
| async def _initialize(self) -> None: | ||
| try: | ||
| payload: dict[str, Any] = {"hooks": None} | ||
| if self._options.mcp_servers: | ||
| payload["mcpServers"] = self._options.mcp_servers | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Suggestion] The 2 new production lines that wire A regression here (typo in key name, wrong variable reference) would silently break MCP server support with no test catching it. Consider adding a test in @pytest.mark.asyncio
async def test_initialize_includes_mcp_servers_in_payload() -> None:
transport = FakeTransport()
servers = {"my-server": {"command": "node", "args": []}}
query = Query(
transport=transport,
options=QueryOptions(mcp_servers=servers, timeout=TimeoutOptions(...)),
prompt="hello",
session_id=VALID_UUID,
)
await query._ensure_started()
init_request = await _wait_for_request(transport, "initialize")
assert init_request["request"]["mcpServers"] == servers
await query.close()Also worth testing the negative case: when — qwen3.7-max via Qwen Code /review |
||
| await self._send_control_request("initialize", payload) | ||
| except Exception as exc: | ||
| await self._finish_with_error(exc) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -64,12 +64,6 @@ def validate_query_options(options: QueryOptions) -> None: | |
| ): | ||
| raise ValidationError("path_to_qwen_executable cannot be empty") | ||
|
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Suggestion] The PR removes the reject-all validation for Malformed configs will pass through silently and be dropped by the CLI's Consider adding minimal validation: if options.mcp_servers:
for name, cfg in options.mcp_servers.items():
if not isinstance(cfg, dict):
raise ValidationError(f"mcp_servers['{name}'] must be a dict")
if not any(k in cfg for k in ("command", "url", "httpUrl", "tcp")):
raise ValidationError(
f"mcp_servers['{name}'] must include at least one of: "
"command, url, httpUrl, tcp"
)— qwen3.7-max via Qwen Code /review |
||
| if options.mcp_servers: | ||
| raise ValidationError( | ||
| "mcp_servers is not supported in Python SDK v1. " | ||
| "Remove the mcp_servers option or use the TypeScript SDK." | ||
| ) | ||
|
|
||
|
|
||
| def _validate_optional_callable( | ||
| value: object, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Critical] The 2 new lines adding
mcpServersto the initialize payload have no test coverage. The existingtest_accepts_mcp_serversonly verifies that validation doesn't raise — it doesn't assert the wire payload. A regression that drops or renames the key would go undetected.Add a unit test in
test_query_core.pythat constructs aQuerywithmcp_serversset and asserts the captured initialize request payload contains"mcpServers":— qwen3.7-max via Qwen Code /review