Context
When deploying ghst mcp http behind a reverse proxy with a short idle timeout (Cloudflare free tier closes idle HTTP streams after ~100s, error 524), the SSE notification stream is killed on a regular cadence even though the MCP session is healthy.
Current behavior
After a successful initialize + tools/list, the client opens the SSE stream for server-to-client notifications. Without traffic on that stream, intermediate proxies (Cloudflare, some load balancers, ingress controllers) close it after their idle timeout. The client logs show:
Error from remote server: StreamableHTTPError: Streamable HTTP error: Failed to open SSE stream:
code: 524
The client (e.g. Claude Desktop via mcp-remote) then reconnects, runs through initialize + tools/list again, and the cycle repeats every ~100s. Tool calls still work (they go over POST), but the logs are noisy and any future server-pushed notification (e.g. notifications/tools/list_changed) risks being dropped during the reconnect window.
Proposed improvement
Have the SSE handler emit a periodic keep-alive — either an SSE comment line (: keepalive\n\n) or a no-op ping event — every 20–30 seconds while the stream is idle. This is enough to reset the idle timeout on virtually every common reverse proxy and is the standard pattern for SSE behind proxies (see e.g. nginx proxy_read_timeout, Cloudflare 100s rule).
Ideally configurable via a flag like --sse-keepalive-interval 30s (or an env var), with a sane default of ~30s.
Why this matters
- Coolify / Dokku / fly.io / Cloudflare Tunnel deployments of
ghst mcp http all hit this.
- Workarounds today require either disabling the proxy entirely or switching to Cloudflare Enterprise — both are heavy-handed for what is a one-line fix server-side.
- It also future-proofs the use of server-push notifications.
Environment
- ghst v0.13.0
- Deployment: Docker on Coolify, behind Cloudflare proxy (free plan)
- Client: Claude Desktop via
mcp-remote 0.1.37
Happy to test a patch if useful.
Context
When deploying
ghst mcp httpbehind a reverse proxy with a short idle timeout (Cloudflare free tier closes idle HTTP streams after ~100s, error 524), the SSE notification stream is killed on a regular cadence even though the MCP session is healthy.Current behavior
After a successful
initialize+tools/list, the client opens the SSE stream for server-to-client notifications. Without traffic on that stream, intermediate proxies (Cloudflare, some load balancers, ingress controllers) close it after their idle timeout. The client logs show:The client (e.g. Claude Desktop via
mcp-remote) then reconnects, runs throughinitialize+tools/listagain, and the cycle repeats every ~100s. Tool calls still work (they go over POST), but the logs are noisy and any future server-pushed notification (e.g.notifications/tools/list_changed) risks being dropped during the reconnect window.Proposed improvement
Have the SSE handler emit a periodic keep-alive — either an SSE comment line (
: keepalive\n\n) or a no-op ping event — every 20–30 seconds while the stream is idle. This is enough to reset the idle timeout on virtually every common reverse proxy and is the standard pattern for SSE behind proxies (see e.g. nginxproxy_read_timeout, Cloudflare 100s rule).Ideally configurable via a flag like
--sse-keepalive-interval 30s(or an env var), with a sane default of ~30s.Why this matters
ghst mcp httpall hit this.Environment
mcp-remote 0.1.37Happy to test a patch if useful.