Skip to content

feat(coderd/x/chatd/mcpclient): migrate external MCP client to official Go SDK - #28058

Draft
ibetitsmike wants to merge 1 commit into
mike/mcp-go-sdk/cli-stdio-serverfrom
mike/mcp-go-sdk/chatd-client
Draft

feat(coderd/x/chatd/mcpclient): migrate external MCP client to official Go SDK#28058
ibetitsmike wants to merge 1 commit into
mike/mcp-go-sdk/cli-stdio-serverfrom
mike/mcp-go-sdk/chatd-client

Conversation

@ibetitsmike

@ibetitsmike ibetitsmike commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Stack Context

PR 3 of 6 in a stack that migrates every Coder MCP surface from the archived github.com/mark3labs/mcp-go library to the official github.com/modelcontextprotocol/go-sdk v1.7.0.

Stack: #28056 -> #28057 -> #28058 -> #28059 -> #28060 -> #28061

Why

The chatd external MCP client (admin-configured MCP servers used by Agent chat) now holds *mcp.ClientSession connections created via mcp.NewClient and Client.Connect, with StreamableClientTransport or SSEClientTransport per server config.

  • Auth and identity headers are injected through a custom http.RoundTripper because the official SDK has no per-header transport options.
  • Tool input schemas are extracted from the SDK's map[string]any decoding.
  • Content conversion handles the official pointer content types; the SDK decodes blob resources into raw bytes, so binary content is handled without an extra base64 round trip.
  • Test fixtures are official stateless Streamable HTTP servers.

Mux created this PR on Mike's behalf.

…al Go SDK

Replace the mark3labs client with the official SDK client for chatd's
external MCP server connections. All four auth modes (oauth2,
api_key, custom_headers, user_oidc) now inject headers through an
http.RoundTripper on the transport's HTTPClient instead of per-header
transport options; header keys still pass through http.Header.Set so
case-insensitive collisions stay deterministic.

The SDK negotiates the protocol version internally (2026-07-28 down
to 2024-11-05), so older external servers keep working. Tool name
prefixing, allow/deny filtering, model-intent wrapping, and content
conversion are behavior-identical; the SDK decodes base64 image,
audio, and blob payloads during unmarshal, so the manual decode
paths are gone.
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