Timeout Configurations for SSE and Streamable HTTP Transports in the Dify MCP Plugin
Both SSE and Streamable HTTP transports support a general timeout parameter, but only the SSE transport includes an additional sse_read_timeout to control how long the client waits for incoming Server-Sent Events after the connection is established.
The junjiem/dify-plugin-tools-mcp_sse repository implements two transport mechanisms for Model Context Protocol (MCP) servers: Server-Sent Events (SSE) and Streamable HTTP. Understanding the timeout configurations for SSE and Streamable HTTP transports is critical for preventing connection drops during long-running operations while maintaining responsive error handling.
Available Timeout Settings
The plugin exposes two distinct timeout parameters in the server configuration JSON:
timeout– A general request timeout that applies to both transport types. It controls the maximum duration for the entire HTTP request/response cycle, including connection establishment, writing, and reading. The default value is 50 seconds.sse_read_timeout– A specialized read timeout that applies only to SSE transports. It determines how long the client waits for the next Server-Sent Event after the connection is already established. The default value is 50 seconds.
Key Differences Between SSE and Streamable HTTP Timeouts
The fundamental distinction lies in how httpx timeout objects are constructed for each transport in utils/mcp_client.py.
SSE Transport Implementation
For SSE connections, the client creates an httpx.Client using a composite timeout that separates the general timeout from the read-specific value:
# Lines 84-89 in utils/mcp_client.py
httpx.Client(
timeout=httpx.Timeout(
timeout, # General timeout (connect + write + read)
read=sse_read_timeout # Specific to SSE event reading
)
)
The same values are passed to httpx_sse.connect_sse at lines 112-114 to ensure the SSE-specific read timeout is respected during event streaming.
Streamable HTTP Transport Implementation
For Streamable HTTP connections, the client uses a simpler timeout configuration without a separate read parameter:
# Lines 132-136 in utils/mcp_client.py
httpx.Client(
timeout=httpx.Timeout(timeout) # Single timeout for entire request
)
This means Streamable HTTP does not support sse_read_timeout and relies solely on the general timeout value for all timing constraints.
Configuration Examples
JSON Configuration
According to the README (lines 33-36), configure your servers with the appropriate timeout fields:
{
"my_sse_server": {
"transport": "sse",
"url": "http://localhost:8000/sse",
"headers": {},
"timeout": 30,
"sse_read_timeout": 10
},
"my_stream_server": {
"transport": "streamable_http",
"url": "http://localhost:8001/mcp",
"headers": {},
"timeout": 30
}
}
Python Instantiation
When using the McpClients class directly in utils/mcp_client.py, the configuration dictionary maps directly to the constructor parameters:
from utils.mcp_client import McpClients
servers_config = {
"sse_backend": {
"transport": "sse",
"url": "http://localhost:8000/sse",
"timeout": 50,
"sse_read_timeout": 50,
},
"http_backend": {
"transport": "streamable_http",
"url": "http://localhost:8001/mcp",
"timeout": 50,
},
}
clients = McpClients(servers_config)
The McpSseClient receives both timeout and sse_read_timeout arguments, while McpStreamableHttpClient receives only the generic timeout value.
Summary
- Both transports use the
timeoutparameter (default 50s) to limit the total duration of HTTP requests. - Only SSE transport supports
sse_read_timeout(default 50s) to independently control how long the client waits for the next event after connection establishment. - Implementation location:
utils/mcp_client.pylines 84-89 (SSE timeout setup), 112-114 (SSE streaming), and 132-136 (Streamable HTTP setup). - Configuration: Define timeouts in the server JSON configuration; omit
sse_read_timeoutfor Streamable HTTP servers.
Frequently Asked Questions
What happens if sse_read_timeout is shorter than timeout?
If sse_read_timeout is shorter than the general timeout, the SSE client will disconnect when no events arrive within the sse_read_timeout window, even though the total request duration has not yet exceeded the general timeout. This allows fine-grained control over idle connection detection without affecting the overall request lifecycle.
Can I use sse_read_timeout with Streamable HTTP transport?
No, the sse_read_timeout parameter is ignored for Streamable HTTP connections. According to the implementation in utils/mcp_client.py lines 132-136, the Streamable HTTP client only accepts the general timeout parameter and creates an httpx.Timeout object without a separate read component.
What are the default timeout values if I don't specify them in the configuration?
Both timeout and sse_read_timeout default to 50 seconds when not explicitly defined in the server configuration. This is hardcoded in the McpClients instantiation logic where config.get("timeout", 50) and config.get("sse_read_timeout", 50) are used for SSE servers, while Streamable HTTP servers only use the former.
How do these timeouts affect long-running MCP tool executions?
The general timeout acts as a hard ceiling on the entire HTTP request, which may terminate long-running tool calls regardless of transport type. However, the sse_read_timeout specifically affects SSE connections by determining how long the client tolerates silence between events; for long-running operations that send periodic keep-alive events via SSE, you should set sse_read_timeout higher than the expected interval between events to prevent premature reconnection.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →