Hmbown/CodeWhale · error · anyhow::Error
Unsupported MCP transport '{transport}'. Supported values: s
Error message
Unsupported MCP transport '{transport}'. Supported values: sse What it means
validate_mcp_transport accepts exactly one non-empty transport value - `sse`, compared after trim and ASCII case-insensitively - or no transport at all (crates/tui/src/mcp.rs:1353-1361). Any other value (stdio, http, streamable-http, websocket, typos) is rejected when a server is added via the mcp add path (add_server_config, mcp.rs:4024) or validated through runtime_api. Note what the field actually selects: a url server without transport uses the streamable HTTP transport, `sse` selects the legacy SSE client, and command-based servers are stdio with no transport field.
Source
Thrown at crates/tui/src/mcp.rs:1360
}
}
fn is_legacy_sse_transport(config: &McpServerConfig) -> bool {
config
.transport
.as_deref()
.map(|transport| transport.trim().eq_ignore_ascii_case("sse"))
.unwrap_or(false)
}
pub fn validate_mcp_transport(transport: Option<&str>) -> Result<()> {
let Some(transport) = transport else {
return Ok(());
};
if transport.trim().eq_ignore_ascii_case("sse") {
return Ok(());
}
anyhow::bail!("Unsupported MCP transport '{transport}'. Supported values: sse");
}
fn response_id_matches(id: Option<&serde_json::Value>, expected_id: &str) -> bool {
let Some(id) = id else {
return false;
};
if id.as_str() == Some(expected_id) {
return true;
}
id.as_u64()
.map(|id| id.to_string() == expected_id)
.unwrap_or(false)
}
// === McpConnection - Async Connection Management ===
/// Manages a single async connection to an MCP server
pub struct McpConnection {View on GitHub (pinned to 8880682c63)
Solutions
- Remove the transport field entirely: command servers are stdio automatically and url servers use streamable HTTP by default.
- Keep "transport": "sse" only for legacy HTTP+SSE servers that require the SSE client.
- If sse was intended, check spelling, case and surrounding whitespace - it must equal sse after trimming.
Example fix
// before
"my-server": { "url": "https://mcp.example.com", "transport": "http" }
// after: omit transport for the streamable HTTP client
"my-server": { "url": "https://mcp.example.com" }
// (legacy SSE only: "transport": "sse") Defensive patterns
Strategy: validation
Validate before calling
fn transport_valid(transport: Option<&str>) -> bool {
transport.is_none_or(|t| t.trim().eq_ignore_ascii_case("sse"))
}
assert!(transport_valid(None));
assert!(transport_valid(Some(" SSE ")));
assert!(!transport_valid(Some("stdio"))); Prevention
- Omit the transport field unless you specifically need the legacy SSE client.
- Remember: command => stdio, url (no transport) => streamable HTTP, url + "sse" => legacy SSE.
- Validate config snippets ported from other MCP clients before writing them.
When it happens
Trigger: Adding a server with --transport stdio or writing "transport": "http" / "streamable-http" / "websocket" into the MCP config; porting snippets from other MCP clients whose vocabularies use those names.
Common situations: Configs copied from Claude Desktop / Cursor style JSON that uses "type": "stdio"; users trying to explicitly force the streamable HTTP client.
Related errors
- MCP config path cannot be empty
- MCP config path cannot contain '..' components
- invalid environment placeholder in MCP config value
- MCP server '{name}' config must have either 'command' or 'ur
- Provide either a command or URL for MCP server '{name}'.
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/a93d0af07ab52bf2.
Report an issue: GitHub.