diff --git a/.changeset/mcp-discovery-timeout-30s.md b/.changeset/mcp-discovery-timeout-30s.md new file mode 100644 index 0000000000..f0013936a2 --- /dev/null +++ b/.changeset/mcp-discovery-timeout-30s.md @@ -0,0 +1,5 @@ +--- +"executor": patch +--- + +Wait up to 30 seconds, instead of 15, for an MCP server to connect and list its tools. Servers that cold-start or build a large tool catalog no longer show as degraded with `MCP discovery timed out after 15000ms`. diff --git a/packages/plugins/mcp/src/sdk/discover.ts b/packages/plugins/mcp/src/sdk/discover.ts index d3c672361d..24f58df89a 100644 --- a/packages/plugins/mcp/src/sdk/discover.ts +++ b/packages/plugins/mcp/src/sdk/discover.ts @@ -25,11 +25,12 @@ const MAX_LIST_TOOLS_PAGES = 100; // carries a deadline of its own against a server that never answers (a // closed/half-open loopback socket, a server wedged mid-handshake), so // without a bound here a single unresponsive endpoint hangs the calling -// fiber forever. Mirrors the shape-probe fallback's default -// (`probeMcpEndpointShape`'s `timeoutMs = 8_000`) at a slightly longer -// bound since a real handshake + listTools round-trip is heavier than the -// shape probe's single unauth POST. -const DEFAULT_DISCOVER_TIMEOUT = Duration.seconds(15); +// fiber forever. Longer than the shape-probe fallback's default +// (`probeMcpEndpointShape`'s `timeoutMs = 8_000`) since a real handshake + +// listTools round-trip is heavier than the shape probe's single unauth POST, +// and generous enough for servers that cold-start or build a large tool +// catalog on first connect. +const DEFAULT_DISCOVER_TIMEOUT = Duration.seconds(30); // Teardown is best-effort and paid for by the request that performed discovery. // A remote transport may accept close and then never settle, so use the same