-
Notifications
You must be signed in to change notification settings - Fork 19
[go-fan] Go Module Review: modelcontextprotocol/go-sdk #3054
Description
🐹 Go Fan Report: modelcontextprotocol/go-sdk
Module Overview
github.com/modelcontextprotocol/go-sdk is the official Go SDK for the Model Context Protocol (MCP). It provides production-ready client and server implementations covering the full MCP spec, including stdio, SSE, and Streamable HTTP transports. For gh-aw-mcpg, this is the foundational dependency — the entire gateway is built on top of it.
- Version in use:
v1.4.1 - Repository: https://github.com/modelcontextprotocol/go-sdk
Current Usage in gh-aw
The SDK is used pervasively across 12 production files and 9 test/utility files.
- Files (production):
internal/mcp/connection.go,internal/mcp/tool_result.go,internal/mcp/http_transport.go,internal/server/unified.go,internal/server/routed.go,internal/server/transport.go,internal/server/tool_registry.go,internal/middleware/jqschema.go - Files (test utils):
internal/testutil/mcptest/(5 files),internal/server/*_test.go,internal/middleware/*_test.go,test/integration/ - Import alias:
sdk "github.com/modelcontextprotocol/go-sdk/mcp"(consistent across all files ✅)
Key APIs Used
| API | Where | Purpose |
|---|---|---|
sdk.NewServer |
unified.go, routed.go, mcptest/server.go |
Create MCP server instances |
sdk.NewClient |
http_transport.go, mcptest/validator.go |
Create backend client connections |
sdk.Server.AddTool |
tool_registry.go, routed.go |
Register tools (method form, bypasses schema validation) |
sdk.NewStreamableHTTPHandler |
transport.go, routed.go |
HTTP handler for Streamable HTTP transport |
sdk.StreamableHTTPOptions |
transport.go, routed.go |
Configure stateful sessions, logger, 2h timeout |
sdk.CommandTransport |
connection.go, mcptest/driver.go |
Stdio transport for Docker containers |
sdk.StreamableClientTransport |
connection.go, http_transport.go |
HTTP client transport to backends |
sdk.SSEClientTransport |
connection.go, http_transport.go |
SSE transport to legacy backends |
sdk.NewInMemoryTransports |
mcptest/driver.go |
In-memory transport for tests |
sdk.CallToolRequest/Result |
tool_registry.go, unified.go, middleware/ |
Tool invocation types |
sdk.Content, sdk.TextContent, etc. |
tool_result.go, unified.go, middleware/ |
MCP content types |
sdk.ToolAnnotations |
tool_registry.go, unified.go |
Tool metadata passthrough |
Notable Usage Patterns
-
Server-side (gateway):
sdk.NewServercreates the unified aggregator; backends' tools are registered with prefixed names (serverID___toolName) viaserver.AddTool— the method form (not thesdk.AddToolfunction) to bypass JSON Schema validation and support draft-07 schemas from backends. -
Client-side (backend connections):
sdk.NewClient+sdk.ClientSessionconnect to backend MCP servers over stdio, Streamable HTTP, or SSE. -
Routed mode filtered servers: A custom
filteredServerCachemaintains per-session*sdk.Serverinstances with a TTL, allowing guard-filtered tool sets per session. -
SDK logging integration:
logger.NewSlogLoggerWithHandler(log)is passed assdk.StreamableHTTPOptions.Logger— correctly bridges SDK's slog-based logging into the project's structured logger. -
In-memory testing:
sdk.NewInMemoryTransports()is used inmcptest/driver.gofor fast, deterministic unit testing without real Docker containers.
Research Findings
Key Features Available in the SDK
- Dual role: Same SDK handles both the server (gateway) and client (backend connection) sides
- Transport abstraction:
CommandTransport,StreamableClientTransport,SSEClientTransport,InMemoryTransport— all used by the project - Schema validation control:
sdk.AddToolvalidates schemas;server.AddTooldoes not — project exploits this intentionally - Stateful session management:
StreamableHTTPOptions.Stateless=false+SessionTimeoutproperly support long-running agentic sessions - Pagination:
ClientSession.ListTools,ListResources,ListPromptsall support cursor-based pagination — project uses these viapaginateAll
Recent Updates (observed from SDK versioning)
- SDK is in rapid iteration (v1.4.1) alongside the MCP specification evolution
- Streamable HTTP transport is the primary recommended transport (spec 2025-03-26+)
Improvement Opportunities
🏃 Quick Wins
-
Centralize the
server.AddToolbypass pattern: The workaround is duplicated intool_registry.goandrouted.gowith a long comment explaining why. Extract a helperregisterToolWithoutValidation(server, tool, handler)to reduce comment duplication and make the intent clearer. -
ParseToolArgumentsconsistency:mcptest/server.gore-implementsjson.Unmarshal(req.Params.Arguments, &args)inline (not usingmcp.ParseToolArguments). Standardize on the helper to keep argument parsing consistent. -
Error result constructor:
newErrorCallToolResult(err)exists inunified.gobut isn't exported. Ifmcptestor other packages need to create error results, they duplicate the pattern. Consider exporting it from themcppackage.
✨ Feature Opportunities
-
Expand in-memory transport usage in integration tests:
sdk.NewInMemoryTransports()is already inmcptest/driver.gobut the more complex integration tests inserver/*_integration_test.gospin up real servers. More test coverage with in-memory transports would be faster and wouldn't require Docker. -
SDK resources/prompts via the gateway: The project uses
ClientSession.ListResources,ListPrompts,ReadResource, andGetPrompton the client side (to query backends) but doesn't expose these through the gateway's MCP server. As the SDK matures and resources/prompts become more prominent in MCP workflows, consider proxying them through the gateway. -
Session context enrichment: The SDK passes context through all handlers. If future SDK versions add session metadata to context (e.g., client capabilities, initialization params), the project could leverage this to simplify
us.getSessionID(ctx)and related patterns.
📐 Best Practice Alignment
-
Schema validation bypass is well-documented ✅ — Comments explain the
server.AddToolvssdk.AddToolchoice. Monitor SDK releases for configurable validation that natively handles draft-07 schemas from backends. -
SessionTimeout: 2*time.Hour— Good choice for long-running agentic workflows. This should ideally be a configurable value (via config file or environment variable) rather than a hard-coded constant. AddingMCP_GATEWAY_SESSION_TIMEOUTsupport would give operators control. -
Slog logger integration ✅ —
logger.NewSlogLoggerWithHandlerpassed toStreamableHTTPOptions.Loggeris the correct idiomatic pattern. -
Transport selection ✅ — The project correctly negotiates transport type (Streamable HTTP preferred → SSE fallback → plain JSON) per the MCP spec evolution.
🔧 General Improvements
-
filteredServerCacheTTL: The per-session*sdk.Servercache in routed mode uses lazy eviction. This is correct but could grow unbounded if many unique sessions are created in quick succession. Consider adding a background sweeper goroutine or a max-size limit. -
ConvertToCallToolResultcomplexity: The function inmcp/tool_result.gohas 4 distinct parsing paths (array, empty-content-field, missing-content-field, standard). This complexity exists to handle diverse backend behaviors. Adding table-driven unit tests for all paths would improve confidence during SDK upgrades.
Recommendations
- [Low effort] Extract
registerToolWithoutValidationhelper to deduplicate theserver.AddToolbypass pattern and its comment (appears in 2 files). - [Low effort] Use
mcp.ParseToolArgumentsinmcptest/server.goinstead of inlinejson.Unmarshal. - [Medium effort] Make
SessionTimeoutconfigurable via env var (MCP_GATEWAY_SESSION_TIMEOUT) with the current 2h as default. - [Medium effort] Add more in-memory transport tests to reduce Docker dependency in integration test suite.
- [Medium effort] Add a max-size or background sweeper to
filteredServerCacheinrouted.go. - [Future] Watch SDK releases for native draft-07 schema support to remove the
server.AddToolbypass. - [Future] Evaluate proxying MCP resources and prompts through the gateway as SDK/spec support matures.
Next Steps
- Track SDK releases at https://github.com/modelcontextprotocol/go-sdk/releases
- Consider subscribing to the MCP spec changelog for transport/protocol changes
- Review items 1-2 (quick wins) can be addressed in a single small PR
Generated by Go Fan 🐹
Module summary: specs/mods/go-sdk.md (directory creation restricted in this workflow run)
Run: §23889513585
References:
- §23889513585
- https://github.com/modelcontextprotocol/go-sdk
- https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp
Note
🔒 Integrity filter blocked 15 items
The following items were blocked because they don't meet the GitHub integrity level.
- https://github.com/BurntSushi/toml/releases/tag/v1.6.0
get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/wazero/wazero/releases/tag/v1.11.0
get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/stretchr/testify/releases/tag/v1.11.1
get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/itchyny/gojq/releases/tag/v0.12.19
get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/santhosh-tekuri/jsonschema/releases/tag/v6.0.2
get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/spf13/cobra/releases/tag/v1.10.2
get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/modelcontextprotocol/go-sdk/releases/tag/v1.4.1
get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - BurntSushi/toml@8685fba
list_commits: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - itchyny/gojq@b7ebffb
list_commits: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - santhosh-tekuri/jsonschema@180cde3
list_commits: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - stretchr/testify@5f80e4a
list_commits: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - modelcontextprotocol/go-sdk@76d5a54
list_commits: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - spf13/cobra@61968e8
list_commits: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - wazero/wazero@929e400
list_commits: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - get_file_contents
get_file_contents: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".
To allow these resources, lower min-integrity in your GitHub frontmatter:
tools:
github:
min-integrity: approved # merged | approved | unapproved | none
- expires on Apr 9, 2026, 7:41 AM UTC