Skip to content

feat(transport): add Unix domain socket client for streamable HTTP#749

Open
wpfleger96 wants to merge 2 commits intomodelcontextprotocol:mainfrom
wpfleger96:main
Open

feat(transport): add Unix domain socket client for streamable HTTP#749
wpfleger96 wants to merge 2 commits intomodelcontextprotocol:mainfrom
wpfleger96:main

Conversation

@wpfleger96
Copy link

Adds UnixSocketHttpClient, a new StreamableHttpClient implementation that routes MCP HTTP traffic through a Unix domain socket using hyper + tokio::net::UnixStream, gated behind the transport-streamable-http-client-unix-socket feature.

MCP hosts running in Kubernetes environments with Envoy sidecars can't use TCP/DNS because outbound traffic must go through the sidecar proxy, which exposes an abstract Unix socket (e.g., @egress.sock). This unblocks any rmcp-based MCP host from connecting through a service mesh sidecar by setting the socket path at transport construction time. The goose equivalent lives in block/goose#7631 and will be replaced with this once merged.

  • Adds UnixSocketHttpClient with new(socket_path, uri) constructor and from_unix_socket / from_unix_socket_with_config convenience constructors on StreamableHttpClientTransport
  • Supports Linux abstract sockets (@name\0name) via spawn_blocking + std::os::unix::net since tokio::net::UnixStream lacks connect_addr; filesystem sockets work on all Unix targets
  • Extracts RESERVED_HEADERS, validate_custom_header, and extract_scope_from_header from reqwest/streamable_http_client.rs into common/http_header.rs so both HTTP client implementations share a single source of truth for header policy
  • Integration tests bind an axum MCP server to a real UnixListener and exercise handshake, custom header forwarding, and the convenience constructor

MCP hosts in Kubernetes environments with Envoy sidecars need to route
HTTP through Unix domain sockets because DNS-based URIs only resolve
via the proxy. Adds UnixSocketHttpClient implementing StreamableHttpClient
using hyper over tokio::net::UnixStream, gated behind the
transport-streamable-http-client-unix-socket feature.

Also extracts RESERVED_HEADERS, extract_scope_from_header, and
validate_custom_header into common/http_header.rs to share header
validation logic between the reqwest and unix socket implementations.
@github-actions github-actions bot added T-dependencies Dependencies related changes T-test Testing related changes T-config Configuration file changes T-core Core library changes T-transport Transport layer changes labels Mar 12, 2026
- Document one-connection-per-request behavior on UnixSocketHttpClient
- Reject empty socket paths and bare '@' in constructor with assert
- Add explicit dep:http to unix-socket feature for self-documenting deps
- Document MCP-Protocol-Version exception on RESERVED_HEADERS constant
- Fix test catch-all to echo request id instead of hardcoding 1
- Remove leftover sleep(100ms) in test_unix_socket_custom_headers
- Add blank line before macro comment in Cargo.toml
wpfleger96 added a commit to block/goose that referenced this pull request Mar 13, 2026
Replace goose local UnixSocketHttpClient with the upstream implementation
from rmcp transport-streamable-http-client-unix-socket feature
(modelcontextprotocol/rust-sdk#749). Deletes ~420 lines of local transport
code and delegates to rmcp for the Unix socket client, socket path
resolution, Host header derivation, and custom header validation.

Temporarily points rmcp at the wpfleger96/rust-sdk fork for testing.
Will switch back to crates.io once the upstream PR is merged and released.
@wpfleger96 wpfleger96 marked this pull request as ready for review March 13, 2026 15:30
@wpfleger96 wpfleger96 requested a review from a team as a code owner March 13, 2026 15:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-config Configuration file changes T-core Core library changes T-dependencies Dependencies related changes T-test Testing related changes T-transport Transport layer changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant