Skip to content

Commit 8e980f4

Browse files
JohnUiterwykKludex
andauthored
Add headers, timeout, and sse_read_timeout to MCPServerHTTP (#1218)
Co-authored-by: John Uiterwyk <[email protected]> Co-authored-by: Marcelo Trylesinski <[email protected]>
1 parent ec08992 commit 8e980f4

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

pydantic_ai_slim/pydantic_ai/mcp.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,11 +188,35 @@ async def main():
188188
For example for a server running locally, this might be `http://localhost:3001/sse`.
189189
"""
190190

191+
headers: dict[str, Any] | None = None
192+
"""Optional HTTP headers to be sent with each request to the SSE endpoint.
193+
194+
These headers will be passed directly to the underlying `httpx.AsyncClient`.
195+
Useful for authentication, custom headers, or other HTTP-specific configurations.
196+
"""
197+
198+
timeout: float = 5
199+
"""Initial connection timeout in seconds for establishing the SSE connection.
200+
201+
This timeout applies to the initial connection setup and handshake.
202+
If the connection cannot be established within this time, the operation will fail.
203+
"""
204+
205+
sse_read_timeout: float = 60 * 5
206+
"""Maximum time in seconds to wait for new SSE messages before timing out.
207+
208+
This timeout applies to the long-lived SSE connection after it's established.
209+
If no new messages are received within this time, the connection will be considered stale
210+
and may be closed. Defaults to 5 minutes (300 seconds).
211+
"""
212+
191213
@asynccontextmanager
192214
async def client_streams(
193215
self,
194216
) -> AsyncIterator[
195217
tuple[MemoryObjectReceiveStream[JSONRPCMessage | Exception], MemoryObjectSendStream[JSONRPCMessage]]
196218
]: # pragma: no cover
197-
async with sse_client(url=self.url) as (read_stream, write_stream):
219+
async with sse_client(
220+
url=self.url, headers=self.headers, timeout=self.timeout, sse_read_timeout=self.sse_read_timeout
221+
) as (read_stream, write_stream):
198222
yield read_stream, write_stream

tests/test_mcp.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,19 @@ def test_sse_server():
4343
assert sse_server.url == 'http://localhost:8000/sse'
4444

4545

46+
def test_sse_server_with_header_and_timeout():
47+
sse_server = MCPServerHTTP(
48+
url='http://localhost:8000/sse',
49+
headers={'my-custom-header': 'my-header-value'},
50+
timeout=10,
51+
sse_read_timeout=100,
52+
)
53+
assert sse_server.url == 'http://localhost:8000/sse'
54+
assert sse_server.headers is not None and sse_server.headers['my-custom-header'] == 'my-header-value'
55+
assert sse_server.timeout == 10
56+
assert sse_server.sse_read_timeout == 100
57+
58+
4659
async def test_agent_with_stdio_server(allow_model_requests: None, openai_api_key: str):
4760
server = MCPServerStdio('python', ['-m', 'tests.mcp_server'])
4861
model = OpenAIModel('gpt-4o', provider=OpenAIProvider(api_key=openai_api_key))

0 commit comments

Comments
 (0)