Repository navigation
[RFC] Standardize timeouts between servers and clients - #1492
myaroshefsky wants to merge 6 commits into
Conversation
|
In order to be accepted, this proposal would need an SEP. (I have not dug into the specifics of this proposal; I am merely pointing out a formality. 😄) |
Thank you! Working on that now in Discord. |
|
A few thoughts:
|
|
Thanks @simonrussell ! I appreciate the ideas.
I originally started thinking that way way, but I realized that a requester setting a specific deadline isn't going to make a responder go faster. It'll just guarantee a failure. Keeping in the spirit of declaring capabilities that MCP already embraces, I propose that "time required" is also a capability to be declared. Treating it as such is likely to result in increased reliability and interoperability of the spec.
Keep in mind that this proposal continues to allow the requester to cancel the request at any time for any reason. There's no obligation of servers to wait the specified amount of time. So I don't believe there's obvious benefit from adding an explicit timeout to the request itself (unless others have cases where the responder would actually do something differently based on that?). On the other hand, there's obvious benefit from having the requester be aware of approximately how long the responder would consider "reasonable." I haven't yet found a downside to letting the responder declare that information, which the requester can then use:
I definitely need to read more about that, but is that going to move away from the initialization and capability negotiation paradigm that this uses? |
I can definitely see where you're coming from, and perhaps the request deadline might not solve the particular problem you have. It just maybe feels like a lot of extra stuff to add for something that's probably going to be boilerplate for 99% of servers. And I still don't really know whether a client will wait for longer for something like Long running tool calls are another question, but then the progress notification already exists as a "keepalive". I think some of the wording you've got here around how that should work is good. Could your main problem just be fixed by the spec saying "timeouts for X should be Y", and removing the negotiation?
It removes |
|
Closing this SEP as dormant - it has not received sponsorship and hasn't seen recent updates. We can re-open in the future if there is a desire to resume work on it. |

This RFC proposes adding standardized bi-directional timeout handling to the Model Context Protocol to address widespread interoperability issues where mismatched timeout configurations between clients and servers break the protocol's core promise of universal compatibility.
Treating timing as a capability to be negotiated
Following MCP's spirit of capability declaration and negotiation to improve universal interoperability, this proposal uses responder-recommended timeouts declared during initialization. It specifically retains full and complete timing control by the requesters, which may use these recommendations to negotiate among the requesters' ideal timeouts, requesters' maximum safe timeouts, and the responders' recommended timeouts.
Leveraging existing lifecycle events (initialization, cancellation)
The implementation includes per-method timeout declarations in capabilities, protocol-wide default timeouts for each method, and support for timeout-triggered cancellations with a dedicated timeout field in cancellation notifications to enable better monitoring and debugging of timeout-related issues.
Incremental improvement
While the community continues exploring comprehensive solutions for long-running tools and async operations (see referenced issues below), this targeted timeout standardization addresses immediate interoperability issues and can be implemented without waiting for those broader architectural decisions. Standardizing timeout handling now will improve protocol reliability and enable more production deployments, which benefits the protocol and community.
Motivation and Context
Without standardized timeout coordination directed at improving reliability, the current MCP specification creates interoperability challenges that affect deployment reliability and limit production adoption.
Observed issues
tools/listbut a 60-second timeout for other/listoperations, which has led to flakiness. After my team raised a bug report, the Anthropic team has asked us to help define what timeout duration would work best for a product like ours (an enterprise MCP gateway that fans out to various MCPs), suggesting that a universal protocol-default timeout may not be appropriate and should be explicitly negotiated between clients and servers.Online evidence in support of improving timeout behavior
Here's a fuller list of community problems caused by the lack of explicit timeout handling in the protocol
TypeScript SDK #245: 13+ reactions asking for longer timeouts
Inspector #142: 21+ reactions requesting configurable timeouts
Continue #5325: "Please add longer mcp_timeout"
Continue #7509 "We have advanced MCP tools that want to use via continue, but we are facing a timeout problem"
LM Studio #727 "The Model Context Protocol (MCP) client in the chat interface has a fixed, non-configurable request timeout. This prevents the use of MCP tools that require more than the default time to complete."
Claude Code #424 "Would greatly appreciate a config option / env var for MCP tool call timeout"
Cline #1306 SDK hard-coded timeout prevents Cline users from extending timeouts
Cline #2296 SDK fails to respect timeout. This was rolled into Cline #4391 Fix MCP System Issues and Compatibility Problems
Codex #2346 Make MCP Request timeout configurable
Gemini CLI #3130 MCP Server times out on windows
N8N Community Requesting configurable MCP timeouts (up to 15 minutes or more)
N8N PR #15886 feat(MCP Client Tool Node): Add Timeout config for the MCP Client tool
Blender #50 Error : MCP error -32001: Request Timed out
Desktop Commander MCP #19 Error: MCP error -32001: Request timed out
Smithery CLI #137 32001 Request timed out error during the initialize phase
Dify #23546 feat: improved MCP timeout
Other protocols
Other successful protocols have tackled the timeout question in various ways, with various levels of acceptance:
Unlike HTTP/gRPC, MCP already has a rich initialization phase where servers declare their capabilities. Adding timeout expectations fits naturally into this existing pattern. Servers already say "I support tools X, Y, Z with these schemas" so adding "and I typically need N seconds" is consistent.
Why not requester-defined timeouts?
Having the requester define a timeout is not likely to reduce the rate of failures. It would just make them more explicit.
MCP's initialization phase gives it a unique advantage over other protocols. While most protocols must rely on requester-defined timeouts, MCP can treat response times as negotiable capabilities during its existing capability exchange. This allows servers to communicate realistic expectations upfront, improving the interoperability that the initialization step was designed to provide.
Clients retain their existing ultimate control and can impose stricter limits when needed, ensuring that server timeout declarations serve as guidance rather than binding requirements.
Goals
The main goals of this change include:
Philosophy of Change
Unlike requester-declared timeouts (as is typical with other protocols, like gRPC), this change aims to improve the rate of successes by providing useful information to the requester that it can use to decide on an appropriate timeout.
Having the requester demand a specific timeout typically will not make the response come faster; it will just ensure a failure. On the other hand, this approach continues to give requesters ultimate control over what timeout they can set, but it gives them information that may influence how they select that timeout.
While 60 seconds is a very reasonable default, this gives the requester the option to decide whether 60 seconds is the true "maximum" timeout or whether they would actually be willing to wait a bit longer.
A UI may wish to enforce a stricter timeout. Meanwhile, autonomous agents may prefer to adopt more flexible timing to decrease the rate of timing failures from over-strict timeouts.
This proposal seeks to yield a net benefit in success rates by enabling discovery of the true upper timing bound on a request rather than requesters making unnecessarily conservative guesses about timing.
This addresses the current information asymmetry where clients must set timeouts without knowledge of server requirements. This need for server timing information is already evident, for instance, when platform providers contact server authors directly to determine appropriate timeout values (see Anthropic example above), indicating that timeout negotiation is happening out-of-band. This proposal formalizes that essential information exchange within the protocol specification, enabling informed timeout decisions based on actual server capabilities rather than external coordination or speculation.
How Has This Been Tested?
These changes have not yet been tested. However, they seem reasonably trivial to implement and test, assuming there is community support for this kind of a change to be explored.
Breaking Changes
This change aims to provide backwards compatibility such that:
The main risk of breaking changes would be for implementations that reject the additional properties in certain existing messages, such as:
timeout?:number field toCancelledNotificationparamsTypes of changes
Checklist
Additional context
Other considerations & open discussion
Finer-grained timeouts
It was considered whether to provide finer-grained timeout expectations, such as on a per-tool basis as part of the tool metadata. For example, perhaps one specific tool requires 240 seconds to complete while the rest generally would complete in under 10 seconds.
For now, it was decided that this complexity likely isn't warranted. Instead, the proposal is just to have the responder define the timeout for each method as the longest time it expects to require for any single invocation. According to the specification, either party may still cancel a request for any reason at any time, leaving flexibility for enforcing different timeouts in practice.
Per-request vs. per-method
While it originally seemed logical to consider HTTP-style per-request timeouts made by the requester, the implementer of the operation knows how long it typically takes, and may be in a better position to declare the timeouts.
However, the downside of this approach is that requesters can't adjust for urgent vs. non-urgent requests nor specify tighter timeouts smartly based on specifics (see the comment above about finer-grained timeouts on a per-tool basis).
This proposal currently adopts the "responder declares" approach because it treats timeouts as a property of the operation and prevents an "impedance mismatch" between what the requester expects and what's realistic. It also aligns with the protocol's philosophy of capability declaration during initialization.
Negotiation of timeouts
It was considered whether timeouts should be declared unilaterally by the responder or negotiated somehow between both parties. For example, perhaps responder requests a 60-second timeout but a requester would like there to be a 30-second timeout. This results in unusual conflicts, as the responder may not be able to honor that shorter timeout, resulting in failures.
It was decided for now that the best path may be to let the responders provide information they have about the timeouts they need, allowing the requester to either honor that (if they can be flexible) or use a different behavior (acknowledging the risks). Nothing in the changes requires a requester to respect the responder's declared timeout, as they may still cancel at any time for any reason. However, at least this implementation avoids ambiguity about how long the responder expects to need, leaving timing entirely to protocol defaults or implementer-specific decisions.
In the case of the enterprise gateway that composes various MCP servers into one logical composite server, a gateway may be able to provide an estimate of the duration it requires to perform the fan-out for a
tools/listoperation based on the number (or type) of servers it expects to need responses from during that call.Cancellation vs. Error
It was considered whether timeouts should be considered errors or whether to use the cancellation framework. Since timeouts represent the requester deciding "I'm done waiting," cancellation seems to capture this semantic better.
In addition, the timeout field in cancellations makes it trivial to distinguish timeout-triggered cancellations from user-initiated ones, enabling better observability without overloading error semantics.
Timeout extension
It was considered whether the protocol should define more explicit behavior around progress notifications extending the timeout. This leads to potentially ambiguous behaviors that need further explicitness (e.g. whether a declared timeout is for the entire duration or just the expected duration between progress updates).
It was decided for now to avoid that complexity and stay closer to the existing behavior, which specified that the requester may choose to extend the timeout upon progress. Nonetheless, clarity is provided that the declared timeouts should be the timeout expected for the entire method to complete.
Open questions
References for work related to lengthy operations
[#982] [notes] Long running tools/ async tools/ resumability
[#1391 SEP-1391: Asynchronous Tool Execution
[#418] [Specification] Client should send cancellation notification when request timeout
The steering committee is already looking at how to handle long-running tools, async tools, and resumability. While it is worthwhile to consider those conversations in the context of this change, it may be expedient to develop a baseline timeout behavior as an important nearer-term goal in order to improve overall protocol reliability and encourage greater production adoption. Waiting to resolve this together with these other proposals may delay the much-needed clarity around basic timeouts that are currently interfering with even simple cases of enterprise production adoption.