Automatically submitted on behalf of the user by an AI agent.
Summary
With Executor v1.6.8 self-host and OpenCode v2.0.3, the MCP connection can complete initialization and tool discovery, but the standalone Streamable HTTP GET /mcp remains open and sends no bytes. After roughly 356–360 seconds, Bun's native fetch reports a TimeoutError; OpenCode then retries the GET and eventually reports the MCP server as unavailable.
The local daemon and authentication are otherwise healthy: /api/health responds quickly, valid POST /mcp requests complete, and invalid authentication is rejected quickly.
Environment
- Executor v1.6.8 self-host
- Windows x64
- OpenCode v2.0.3 using the Streamable HTTP MCP client
@modelcontextprotocol/sdk 1.29.0 in the OpenCode v2.0.3 source
- Local MCP endpoint on loopback
- OAuth disabled; the configured bearer credential is intentionally omitted
Reproduction
- Configure OpenCode as a remote MCP client for the Executor
/mcp endpoint.
- Complete
initialize and notifications/initialized.
- Observe the client's follow-up GET with
Accept: text/event-stream and the negotiated session ID.
- Leave the GET stream idle. It returns HTTP 200 with
Content-Type: text/event-stream, but no SSE data or comment is sent.
- After approximately six minutes, the OpenCode log records a native
TimeoutError for the GET request. The client starts another GET and repeats the cycle.
A direct authenticated probe shows the same shape: the response headers arrive promptly, but the stream produces no bytes during a short observation window. initialize, notifications/initialized, and tools/list all work before this happens.
Expected behavior
A quiet standalone SSE stream should remain usable for Bun-based clients, or the server should clearly opt out of standalone SSE. The MCP transport specification permits a server to return 405 Method Not Allowed for GET when it does not offer a server-to-client SSE stream.
Possible fixes
- Send an SSE comment heartbeat such as
: ping at a configurable interval comfortably below common client idle limits (for example, 30–60 seconds); or
- provide a configuration option for the endpoint to return
405 for standalone GET when server-initiated messages are not needed.
Please add a regression test using a Bun client that keeps the GET open long enough to cross the native idle limit. This is separate from #1716, which fixes cancellation of response bodies for Executor's outbound remote-MCP connections.
Impact
The initial handshake looks successful, so this is easy to misdiagnose as an authentication or tool-discovery failure. It causes repeated reconnects and can surface to the user as an MCP request-timeout error even though normal POST requests to the daemon are responsive.
Automatically submitted on behalf of the user by an AI agent.
Summary
With Executor v1.6.8 self-host and OpenCode v2.0.3, the MCP connection can complete initialization and tool discovery, but the standalone Streamable HTTP
GET /mcpremains open and sends no bytes. After roughly 356–360 seconds, Bun's native fetch reports aTimeoutError; OpenCode then retries the GET and eventually reports the MCP server as unavailable.The local daemon and authentication are otherwise healthy:
/api/healthresponds quickly, validPOST /mcprequests complete, and invalid authentication is rejected quickly.Environment
@modelcontextprotocol/sdk1.29.0 in the OpenCode v2.0.3 sourceReproduction
/mcpendpoint.initializeandnotifications/initialized.Accept: text/event-streamand the negotiated session ID.Content-Type: text/event-stream, but no SSE data or comment is sent.TimeoutErrorfor the GET request. The client starts another GET and repeats the cycle.A direct authenticated probe shows the same shape: the response headers arrive promptly, but the stream produces no bytes during a short observation window.
initialize,notifications/initialized, andtools/listall work before this happens.Expected behavior
A quiet standalone SSE stream should remain usable for Bun-based clients, or the server should clearly opt out of standalone SSE. The MCP transport specification permits a server to return
405 Method Not Allowedfor GET when it does not offer a server-to-client SSE stream.Possible fixes
: pingat a configurable interval comfortably below common client idle limits (for example, 30–60 seconds); or405for standalone GET when server-initiated messages are not needed.Please add a regression test using a Bun client that keeps the GET open long enough to cross the native idle limit. This is separate from #1716, which fixes cancellation of response bodies for Executor's outbound remote-MCP connections.
Impact
The initial handshake looks successful, so this is easy to misdiagnose as an authentication or tool-discovery failure. It causes repeated reconnects and can surface to the user as an MCP request-timeout error even though normal POST requests to the daemon are responsive.