Commit 815ebb4
fix: add httpx_client_factory support to SseConnectionParams
Merge #4842
### Link to Issue or Description of Change
**1. Link to an existing issue**
Closes #4841
**2. Changes**
This change aligns SSE transport behavior with Streamable HTTP transport for MCP tools, enabling users to customize the httpx.AsyncClient for SSE-based MCP connections (e.g., proxy, auth, TLS config).
- Update `SseConnectionParams` model to include httpx_client_factory parameter (matching StreamableHTTPConnectionParams pattern)
- Pass `httpx_client_factory` from `SseConnectionParams` to underlying `sse_client()` call
- Add `model_config` to `SseConnectionParams` to allow arbitrary types for the factory function
- Update docstrings to document the new `httpx_client_factory attribute`
- Add unit test for new senarios
### Testing Plan
**Unit Tests:**
- [x] I have added or updated unit tests for my change.
- `tests/unittests/tools/mcp_tool/test_mcp_session_manager.py`
- [x] All unit tests pass locally.
- All test cases have passed the test.
**Manual End-to-End (E2E) Tests:**
1. Set custom httpx_client_factory parameter for SseConnectionParams
```Python
from typing import Any
import httpx
from google.adk.agents.llm_agent import Agent
from google.adk.models import LiteLlm
from google.adk.tools.mcp_tool import SseConnectionParams, McpToolset
# Cutom httpx client factory for MCP SSE transport
def custom_httpx_client_factory(
headers: dict[str, str] | None = None,
timeout: httpx.Timeout | None = None,
auth: httpx.Auth | None = None,
) -> httpx.AsyncClient:
# Print message for debugging
print(' === Custom httpx_client_factory running! ===')
kwargs: dict[str, Any] = {
"follow_redirects": True,
}
if timeout is None:
kwargs["timeout"] = httpx.Timeout(30, read=300)
else:
kwargs["timeout"] = timeout
if headers is not None:
kwargs["headers"] = headers
if auth is not None:
kwargs["auth"] = auth
return httpx.AsyncClient(**kwargs)
connection_params = SseConnectionParams(
url='http://127.0.0.1:9000/sse',
httpx_client_factory=custom_httpx_client_factory, # Custom httpx client factory
)
tool = McpToolset(connection_params=connection_params)
root_agent = Agent(
model=LiteLlm(model="ollama_chat/qwen3.5:35b-a3b-q4_K_M"),
name='root_agent',
description='A helpful assistant for user questions.',
instruction='Answer user questions to the best of your knowledge',
tools=[tool],
)
```
2. Run the Agent, and display the debug log in console
```
2026-03-15 23:54:14,304 - INFO - agent_loader.py:130 - Found root_agent in my_agent.agent
INFO: 127.0.0.1:55642 - "POST /run_sse HTTP/1.1" 200 OK
=== Custom httpx_client_factory running! ===
2026-03-15 23:54:14,345 - INFO - _client.py:1740 - HTTP Request: GET http://127.0.0.1:9000/sse "HTTP/1.1 200 OK"
2026-03-15 23:54:14,349 - INFO - _client.py:1740 - HTTP Request: POST http://127.0.0.1:9000/messages/?session_id=b5750c6e214048c28110dff11c412ecb "HTTP/1.1 202 Accepted"
```
### Checklist
- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [x] I have commented my code, particularly in hard-to-understand areas.
- [x] I have added tests that prove my fix is effective or that my feature works.
- [x] New and existing unit tests pass locally with my changes.
- [x] I have manually tested my changes end-to-end.
- [x] Any dependent changes have been merged and published in downstream modules.
### Additional context
Co-authored-by: Kathy Wu <wukathy@google.com>
COPYBARA_INTEGRATE_REVIEW=#4842 from ushelp:main e3125fb
PiperOrigin-RevId: 8907086941 parent 3f3ed0f commit 815ebb4
File tree
2 files changed
+49
-0
lines changed- src/google/adk/tools/mcp_tool
- tests/unittests/tools/mcp_tool
2 files changed
+49
-0
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
99 | 99 | | |
100 | 100 | | |
101 | 101 | | |
| 102 | + | |
| 103 | + | |
102 | 104 | | |
103 | 105 | | |
| 106 | + | |
| 107 | + | |
104 | 108 | | |
105 | 109 | | |
106 | 110 | | |
107 | 111 | | |
| 112 | + | |
108 | 113 | | |
109 | 114 | | |
110 | 115 | | |
| |||
398 | 403 | | |
399 | 404 | | |
400 | 405 | | |
| 406 | + | |
401 | 407 | | |
402 | 408 | | |
403 | 409 | | |
| |||
Lines changed: 43 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
134 | 134 | | |
135 | 135 | | |
136 | 136 | | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
137 | 180 | | |
138 | 181 | | |
139 | 182 | | |
| |||
0 commit comments