Hmbown/CodeWhale · error
MCP SSE server sent a message before declaring its endpoint
Error message
MCP SSE server sent a message before declaring its endpoint
What it means
Per the MCP SSE protocol the server's first event must be endpoint; this error fires when a message event arrives before any endpoint was declared. The transport refuses to continue because it has no URL to POST requests to — a server-side protocol violation.
Source
Thrown at crates/tui/src/mcp/sse.rs:231
let msg = tokio::select! {
_ = cancel_token.cancelled() => {
anyhow::bail!("SSE transport cancelled before endpoint was discovered");
}
_ = &mut timeout => {
anyhow::bail!(
"SSE endpoint not received within {}ms",
endpoint_timeout.as_millis()
);
}
msg = self.receiver.recv() => {
msg.context("SSE transport closed before endpoint was discovered")?
}
};
match msg {
SseInbound::Endpoint(endpoint) => self.store_endpoint(&endpoint),
SseInbound::Message(_) => {
anyhow::bail!("MCP SSE server sent a message before declaring its endpoint");
}
}
}
fn store_endpoint(&mut self, endpoint: &str) -> Result<()> {
self.endpoint_url = Some(Self::resolve_endpoint_url(&self.base_url, endpoint)?);
Ok(())
}
fn resolve_endpoint_url(base_url: &str, endpoint_url: &str) -> Result<String> {
let base = reqwest::Url::parse(base_url)?;
let resolved =
if endpoint_url.starts_with("http://") || endpoint_url.starts_with("https://") {
reqwest::Url::parse(endpoint_url)?
} else {
base.join(endpoint_url)?
};
// Security: the server-supplied `endpoint` event must stay same-originView on GitHub (pinned to 8880682c63)
Solutions
- Fix the server to send `event: endpoint` (POST URL in data) as its first event after connect
- Update the server to a spec-compliant MCP SDK version
- If the server only speaks streamable HTTP, switch the client to transport=http instead of sse
Defensive patterns
Strategy: fallback
Validate before calling
```rust
// Reuse the endpoint probe and additionally assert the FIRST event is `endpoint`:
async fn first_event_is_endpoint(client: &reqwest::Client, url: &str) -> bool {
// read the first complete event block; return true only if it starts with `event: endpoint`
// (same shape as announces_endpoint, but return false on any `event: message` seen first)
announces_endpoint_no_messages_first(client, url).await
}
``` Try / catch
On this protocol violation, mark the server non-conforming and fall back to streamable-http transport or a compliant server version; retrying the same SSE connect cannot succeed.
Prevention
- Only attach transport=sse to MCP SDK servers that implement the endpoint-first handshake
- Smoke-test new or upgraded servers with curl -N: the first event must be `endpoint`
When it happens
Trigger: The server pushes a JSON-RPC message or notification immediately on connect without first sending `event: endpoint` with the POST URL.
Common situations: Home-grown or outdated MCP servers that skip the handshake; servers migrated to streamable-http that still accept SSE GETs; test stubs emitting canned messages first.
Related errors
- Antigravity cloud-code SSE shape is unproven; failing closed
- MCP error in '{method}': {error}
- MCP error in '{}': {}
- MCP SSE connect cancelled before authentication completed
- MCP SSE connect cancelled before the request completed
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/2a8edb1034650d34.
Report an issue: GitHub.