fix(mcp): support "streamable-http" transport for remote MCP servers#57
Merged
Conversation
createTransport only handled "stdio" and "sse", so a server configured with transport "streamable-http" was rejected up front with "unsupported transport type 'streamable-http'" and the agent silently proceeded without the tool. The "sse" branch was already returning the SDK's StreamableClientTransport (the modern Streamable HTTP client), not the legacy HTTP+SSE transport — so "sse" and "streamable-http" are the same wire protocol, only the label differed. Route both labels to that transport and rename the misleading NewSSETransport -> NewStreamableHTTPTransport so the code matches reality. "sse" stays as a back-compat alias; existing deployments are unaffected. Adds an end-to-end test that stands up an in-process Streamable HTTP MCP server and asserts both labels connect and list tools.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A production AI-SRE session (
sess_L4nRADByqKyGoqtUjH9MxU) failed to call a remote MCP server configured withtransport: "streamable-http". The runner rejected it up front:The agent then silently proceeded without the tool.
Root cause
createTransport(mcp/client.go) only switched on"stdio"and"sse";"streamable-http"fell through to thedefaulterror branch.The twist: the
"sse"branch was already returning the SDK'sStreamableClientTransport— i.e. the modern Streamable HTTP client, not the legacy HTTP+SSE transport. So"sse"and"streamable-http"are the same wire protocol; only the config label differed. Existing servers kept working because they happened to be labeled"sse"; a server honestly labeled"streamable-http"hit the gap.Meanwhile fc-safari treats both
sseandstreamable-httpas valid remote transports and passes the label through to the runner verbatim (types/workspace.go,logic/environment/remote.go), so the mismatch was purely on the runner side.Fix
"streamable-http"and"sse"to the Streamable HTTP client."sse"is kept as a back-compat alias — existing deployments are byte-for-byte unaffected.NewSSETransport→NewStreamableHTTPTransport(it always returnedStreamableClientTransport) so the code matches reality and nobody re-introduces this gap.MCPServerConfig.Transportdoc comment to list all three labels.Tests
TestListToolsConnectsOverStreamableHTTP— stands up an in-process Streamable HTTP MCP server and asserts both"streamable-http"and"sse"connect and list tools end-to-end. Fails onmainwith the exact production error; passes here.TestCreateTransport— pins the dispatch:stdio→*CommandTransport, both HTTP labels →*StreamableClientTransport, unknown → error.go test ./...andgo build ./...green;go vet ./...clean.Follow-up (out of scope)
headerTransportshort-circuits the standalone SSE GET with a synthetic 405 to avoid a connect hang. The SDK now exposesStreamableClientTransport.DisableStandaloneSSEwhich expresses this intent cleanly; worth replacing the interceptor in a separate change.