Skip to content

Send periodic SSE keep-alive comments to survive proxy timeouts #118

Description

@bst1n

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions