You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
Server-side (gateway): sdk.NewServer creates the unified aggregator; backends' tools are registered with prefixed names (serverID___toolName) via server.AddTool — the method form (not the sdk.AddTool function) to bypass JSON Schema validation and support draft-07 schemas from backends.
Client-side (backend connections): sdk.NewClient + sdk.ClientSession connect to backend MCP servers over stdio, Streamable HTTP, or SSE.
Routed mode filtered servers: A custom filteredServerCache maintains per-session *sdk.Server instances with a TTL, allowing guard-filtered tool sets per session.
SDK logging integration: logger.NewSlogLoggerWithHandler(log) is passed as sdk.StreamableHTTPOptions.Logger — correctly bridges SDK's slog-based logging into the project's structured logger.
In-memory testing: sdk.NewInMemoryTransports() is used in mcptest/driver.go for 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.AddTool validates schemas; server.AddTool does not — project exploits this intentionally
Pagination: ClientSession.ListTools, ListResources, ListPrompts all support cursor-based pagination — project uses these via paginateAll
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.AddTool bypass pattern: The workaround is duplicated in tool_registry.go and routed.go with a long comment explaining why. Extract a helper registerToolWithoutValidation(server, tool, handler) to reduce comment duplication and make the intent clearer.
ParseToolArguments consistency: mcptest/server.go re-implements json.Unmarshal(req.Params.Arguments, &args) inline (not using mcp.ParseToolArguments). Standardize on the helper to keep argument parsing consistent.
Error result constructor: newErrorCallToolResult(err) exists in unified.go but isn't exported. If mcptest or other packages need to create error results, they duplicate the pattern. Consider exporting it from the mcp package.
✨ Feature Opportunities
Expand in-memory transport usage in integration tests: sdk.NewInMemoryTransports() is already in mcptest/driver.go but the more complex integration tests in server/*_integration_test.go spin 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, and GetPrompt on 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.AddTool vs sdk.AddTool choice. 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. Adding MCP_GATEWAY_SESSION_TIMEOUT support would give operators control.
Slog logger integration ✅ — logger.NewSlogLoggerWithHandler passed to StreamableHTTPOptions.Logger is 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
filteredServerCache TTL: The per-session *sdk.Server cache 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.
ConvertToCallToolResult complexity: The function in mcp/tool_result.go has 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 registerToolWithoutValidation helper to deduplicate the server.AddTool bypass pattern and its comment (appears in 2 files).
[Low effort] Use mcp.ParseToolArguments in mcptest/server.go instead of inline json.Unmarshal.
[Medium effort] Make SessionTimeout configurable 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 filteredServerCache in routed.go.
[Future] Watch SDK releases for native draft-07 schema support to remove the server.AddTool bypass.
[Future] Evaluate proxying MCP resources and prompts through the gateway as SDK/spec support matures.
BurntSushi/toml@8685fbalist_commits: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".
itchyny/gojq@b7ebffblist_commits: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".
santhosh-tekuri/jsonschema@180cde3list_commits: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".
stretchr/testify@5f80e4alist_commits: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".
modelcontextprotocol/go-sdk@76d5a54list_commits: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".
spf13/cobra@61968e8list_commits: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".
wazero/wazero@929e400list_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:
🐹 Go Fan Report: modelcontextprotocol/go-sdk
Module Overview
github.com/modelcontextprotocol/go-sdkis 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.v1.4.1Current Usage in gh-aw
The SDK is used pervasively across 12 production files and 9 test/utility files.
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.gointernal/testutil/mcptest/(5 files),internal/server/*_test.go,internal/middleware/*_test.go,test/integration/sdk "github.com/modelcontextprotocol/go-sdk/mcp"(consistent across all files ✅)Key APIs Used
sdk.NewServerunified.go,routed.go,mcptest/server.gosdk.NewClienthttp_transport.go,mcptest/validator.gosdk.Server.AddTooltool_registry.go,routed.gosdk.NewStreamableHTTPHandlertransport.go,routed.gosdk.StreamableHTTPOptionstransport.go,routed.gosdk.CommandTransportconnection.go,mcptest/driver.gosdk.StreamableClientTransportconnection.go,http_transport.gosdk.SSEClientTransportconnection.go,http_transport.gosdk.NewInMemoryTransportsmcptest/driver.gosdk.CallToolRequest/Resulttool_registry.go,unified.go,middleware/sdk.Content,sdk.TextContent, etc.tool_result.go,unified.go,middleware/sdk.ToolAnnotationstool_registry.go,unified.goNotable 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
CommandTransport,StreamableClientTransport,SSEClientTransport,InMemoryTransport— all used by the projectsdk.AddToolvalidates schemas;server.AddTooldoes not — project exploits this intentionallyStreamableHTTPOptions.Stateless=false+SessionTimeoutproperly support long-running agentic sessionsClientSession.ListTools,ListResources,ListPromptsall support cursor-based pagination — project uses these viapaginateAllRecent Updates (observed from SDK versioning)
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
registerToolWithoutValidationhelper to deduplicate theserver.AddToolbypass pattern and its comment (appears in 2 files).mcp.ParseToolArgumentsinmcptest/server.goinstead of inlinejson.Unmarshal.SessionTimeoutconfigurable via env var (MCP_GATEWAY_SESSION_TIMEOUT) with the current 2h as default.filteredServerCacheinrouted.go.server.AddToolbypass.Next Steps
Generated by Go Fan 🐹
Module summary:
specs/mods/go-sdk.md(directory creation restricted in this workflow run)Run: §23889513585
References:
Note
🔒 Integrity filter blocked 15 items
The following items were blocked because they don't meet the GitHub integrity level.
get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".list_commits: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".list_commits: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".list_commits: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".list_commits: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".list_commits: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".list_commits: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".list_commits: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".get_file_contents: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".To allow these resources, lower
min-integrityin your GitHub frontmatter: