Skip to content

Commit 59fe808

Browse files
committed
add timeout for client connection to prevent infinite hang
1 parent 48087db commit 59fe808

File tree

1 file changed

+24
-1
lines changed

1 file changed

+24
-1
lines changed

packages/agents/src/mcp/client-connection.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,13 @@ export type MCPTransportOptions = (
7474
) & {
7575
authProvider?: AgentsOAuthProvider;
7676
type?: TransportType;
77+
/**
78+
* Connection timeout in milliseconds. Default: 15000 (15 seconds).
79+
* If the connection doesn't complete within this time, it will fail.
80+
* Timeouts are often caused by proxies (like Cloudflare WARP) that strip
81+
* SSE newline terminators, causing the EventSource parser to hang.
82+
*/
83+
connectionTimeoutMs?: number;
7784
};
7885

7986
export type MCPClientConnectionResult = {
@@ -616,6 +623,8 @@ export class MCPClientConnection {
616623
): Promise<MCPClientConnectionResult> {
617624
const transports: BaseTransportType[] =
618625
transportType === "auto" ? ["streamable-http", "sse"] : [transportType];
626+
const connectionTimeoutMs =
627+
this.options.transport?.connectionTimeoutMs ?? 15000;
619628

620629
for (const currentTransportType of transports) {
621630
const isLastTransport =
@@ -628,7 +637,21 @@ export class MCPClientConnection {
628637
const transport = this.getTransport(currentTransportType);
629638

630639
try {
631-
await this.client.connect(transport);
640+
// Timeouts are often caused by proxies (like Cloudflare WARP) that strip
641+
// SSE newline terminators (\n\n), causing the EventSource parser to hang
642+
// waiting for message boundaries that never arrive.
643+
await Promise.race([
644+
this.client.connect(transport),
645+
new Promise<never>((_, reject) =>
646+
setTimeout(
647+
() =>
648+
reject(
649+
new Error(`Connection timeout after ${connectionTimeoutMs}ms`)
650+
),
651+
connectionTimeoutMs
652+
)
653+
)
654+
]);
632655

633656
return {
634657
state: MCPConnectionState.CONNECTED,

0 commit comments

Comments
 (0)