Skip to content

fix(mcp): support "streamable-http" transport for remote MCP servers#57

Merged
ysyneu merged 1 commit into
mainfrom
feat/mcp-streamable-http-transport
Jun 8, 2026
Merged

fix(mcp): support "streamable-http" transport for remote MCP servers#57
ysyneu merged 1 commit into
mainfrom
feat/mcp-streamable-http-transport

Conversation

@ysyneu

@ysyneu ysyneu commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

Problem

A production AI-SRE session (sess_L4nRADByqKyGoqtUjH9MxU) failed to call a remote MCP server configured with transport: "streamable-http". The runner rejected it up front:

MCP server "dsl-test-flashduty-mcp" is unavailable: remote mcp_list_tools operation failed:
unsupported transport type 'streamable-http' — proceed without this tool

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 the default error branch.

The twist: the "sse" branch was already returning the SDK's StreamableClientTransport — 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 sse and streamable-http as 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

  • Route both "streamable-http" and "sse" to the Streamable HTTP client. "sse" is kept as a back-compat alias — existing deployments are byte-for-byte unaffected.
  • Rename the misleading NewSSETransportNewStreamableHTTPTransport (it always returned StreamableClientTransport) so the code matches reality and nobody re-introduces this gap.
  • Update the MCPServerConfig.Transport doc 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 on main with the exact production error; passes here.
  • TestCreateTransport — pins the dispatch: stdio*CommandTransport, both HTTP labels → *StreamableClientTransport, unknown → error.

go test ./... and go build ./... green; go vet ./... clean.

Follow-up (out of scope)

headerTransport short-circuits the standalone SSE GET with a synthetic 405 to avoid a connect hang. The SDK now exposes StreamableClientTransport.DisableStandaloneSSE which expresses this intent cleanly; worth replacing the interceptor in a separate change.

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.
@ysyneu ysyneu merged commit b1d0b3a into main Jun 8, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant