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 (v1.4.1) is the official Go SDK for the Model Context Protocol. It provides the complete MCP server and client implementation β the core of how gh-aw-mcpg exposes MCP endpoints and connects to backend MCP servers. This is the most strategically important dependency in the project.
Current Usage in gh-aw
The SDK is used pervasively across the codebase, aliased everywhere as sdk "github.com/modelcontextprotocol/go-sdk/mcp".
Files: 26 files (12 production, 14 test)
Key APIs Used:
API
Purpose
sdk.NewServer
Creates MCP server for unified and routed endpoints
sdk.NewClient + client.Connect
Connects to backend MCP servers
sdk.NewStreamableHTTPHandler
HTTP transport handler for /mcp and /mcp/{server} routes
Periodic pings to keep HTTP backend sessions alive
sdk.StreamableHTTPOptions
Session timeout and statefulness configuration
Research Findings
Architecture: How the SDK is layered
The project uses the SDK at two distinct levels:
Inbound (gateway β client): sdk.NewServer + sdk.NewStreamableHTTPHandler creates the MCP endpoint that agents connect to. Session callbacks in the handler authenticate incoming requests and route them to the right backend.
Outbound (gateway β backend): sdk.NewClient + transport connectors connect the gateway to backend MCP servers. The project implements transport auto-negotiation (Streamable HTTP β SSE β plain JSON-RPC) which is custom-coded on top of the SDK's transport interfaces.
Notable Project-Specific Patterns
Custom handler signature: All tool handlers use a three-argument form:
The SDK's native form is two-argument. The extra state interface{} (always nil at the call site) and interface{} return value exist to support the jq middleware pipeline and DIFC write-sink logging. This is a deliberate internal convention.
registerToolWithoutValidation: Uses server.AddToolmethod (bypasses JSON Schema validation) rather than the sdk.AddToolfunction (validates input schema). This is required because backends may return draft-07 schemas that fail the SDK's validator. The distinction relies on internal SDK behavior and should be re-evaluated with each SDK upgrade.
NormalizeInputSchema: Custom pre-processor ensures backend schemas have "type": "object" and "properties": {} before registration. This defensively handles backends that omit these fields.
paginateAll generic helper: Custom Go-generics abstraction over the SDK's cursor-based list pagination for tools, resources, and prompts.
headerInjectingRoundTripper: Custom http.RoundTripper that injects auth headers into SDK-managed transports (StreamableClientTransport, SSEClientTransport), which don't expose a per-request header API.
A v1.5.0-pre.1 is available. Specific release notes were not accessible in this run (external data filtered by integrity policy), but the pre-release status warrants monitoring for:
Schema validation configuration options
Transport header injection APIs
Pagination helper utilities
Improvement Opportunities
π Quick Wins
1. Add a page limit guard to paginateAll
The paginateAll helper in internal/mcp/connection.go iterates cursor pages with no bound. A misbehaving or adversarial backend returning infinite pages would consume unbounded memory and time. A configurable max-pages parameter (e.g., default 100) would add resilience:
internal/testutil/mcptest/server.go uses sdk.ServerOptions{} without a logger. Adding a no-op or test-level slog logger would surface SDK-level protocol issues during integration test failures.
β¨ Feature Opportunities
1. Monitor go-sdk v1.5.0 for schema bypass option
The registerToolWithoutValidation workaround relies on the distinction between sdk.AddTool (validates) and server.AddTool method (skips validation). If v1.5.0 adds an explicit SkipSchemaValidation option on sdk.Tool or sdk.ServerOptions, this workaround can be removed and the handler signature can be simplified back to the SDK native form.
2. Monitor for native header injection in transport structs
The headerInjectingRoundTripper exists because StreamableClientTransport and SSEClientTransport don't expose a headers field. If a future SDK release adds Headers map[string]string to these structs, the custom RoundTripper can be removed.
3. Monitor for SDK pagination helper
The custom generic paginateAll is clean code, but if the SDK adds a CollectAll or similar utility for its paginated list APIs, the custom implementation can be removed.
π Best Practice Alignment
1. Re-evaluate registerToolWithoutValidation on each SDK upgrade
The server.AddTool method (as opposed to the sdk.AddTool function) is being used to bypass schema validation. This relies on an internal SDK implementation detail. It should be explicitly re-checked whenever the SDK is upgraded to ensure the behavior hasn't changed.
2. Document the three-argument handler convention
The custom func(ctx, req, state interface{}) (*CallToolResult, interface{}, error) handler type is used throughout the codebase but is an internal convention not documented at the package level. A package-level godoc comment or ARCHITECTURE.md note explaining why this differs from the SDK native signature would help future contributors.
π§ General Improvements
1. Simplify ConvertToCallToolResult with a decision table
The function in internal/mcp/tool_result.go handles 5 branches with comments explaining each case. The logic is correct and well-tested, but restructuring it with named predicates (isRawArray, hasContentField, etc.) would make the control flow easier to scan:
This could benefit from a configurable value, especially for slow-starting backends.
Recommendations
[Low risk, high value] Add maxPages guard to paginateAll β protects against runaway backends
[Low risk, medium value] Add godoc for the custom three-argument handler convention
[Monitoring] Track go-sdk v1.5.0 release for schema validation options, transport header support, and pagination helpers β each could remove significant custom workaround code
[Process] Add a checklist item to upgrade PRs: re-verify registerToolWithoutValidation behavior on each SDK version bump
Next Steps
Watch go-sdk releases for v1.5.0 stable
Consider filing an upstream issue on modelcontextprotocol/go-sdk requesting: (a) explicit schema validation bypass option, (b) headers field on transport structs
Generated by Go Fan πΉ β Run Β§24023435150 Module summary saved to: specs/mods/go-sdk.md (session artifact)
Note
π Integrity filter blocked 77 items
The following items were blocked because they don't meet the GitHub integrity level.
spf13/cobra@61968e8list_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".
stretchr/testify@5f80e4alist_commits: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".
modelcontextprotocol/go-sdk@862d78alist_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".
... and 61 more items
To allow these resources, lower min-integrity in your GitHub frontmatter:
πΉ Go Fan Report: modelcontextprotocol/go-sdk
Module Overview
github.com/modelcontextprotocol/go-sdk(v1.4.1) is the official Go SDK for the Model Context Protocol. It provides the complete MCP server and client implementation β the core of howgh-aw-mcpgexposes MCP endpoints and connects to backend MCP servers. This is the most strategically important dependency in the project.Current Usage in gh-aw
The SDK is used pervasively across the codebase, aliased everywhere as
sdk "github.com/modelcontextprotocol/go-sdk/mcp".sdk.NewServersdk.NewClient+client.Connectsdk.NewStreamableHTTPHandler/mcpand/mcp/{server}routessdk.CommandTransportsdk.StreamableClientTransportsdk.SSEClientTransportsdk.Tool,sdk.CallToolRequest/Resultsdk.TextContent,sdk.ImageContent,sdk.AudioContent,sdk.EmbeddedResourcesdk.ClientOptions.KeepAlivesdk.StreamableHTTPOptionsResearch Findings
Architecture: How the SDK is layered
The project uses the SDK at two distinct levels:
Inbound (gateway β client):
sdk.NewServer+sdk.NewStreamableHTTPHandlercreates the MCP endpoint that agents connect to. Session callbacks in the handler authenticate incoming requests and route them to the right backend.Outbound (gateway β backend):
sdk.NewClient+ transport connectors connect the gateway to backend MCP servers. The project implements transport auto-negotiation (Streamable HTTP β SSE β plain JSON-RPC) which is custom-coded on top of the SDK's transport interfaces.Notable Project-Specific Patterns
Custom handler signature: All tool handlers use a three-argument form:
The SDK's native form is two-argument. The extra
state interface{}(alwaysnilat the call site) andinterface{}return value exist to support the jq middleware pipeline and DIFC write-sink logging. This is a deliberate internal convention.registerToolWithoutValidation: Usesserver.AddToolmethod (bypasses JSON Schema validation) rather than thesdk.AddToolfunction (validates input schema). This is required because backends may return draft-07 schemas that fail the SDK's validator. The distinction relies on internal SDK behavior and should be re-evaluated with each SDK upgrade.NormalizeInputSchema: Custom pre-processor ensures backend schemas have"type": "object"and"properties": {}before registration. This defensively handles backends that omit these fields.paginateAllgeneric helper: Custom Go-generics abstraction over the SDK's cursor-based list pagination for tools, resources, and prompts.headerInjectingRoundTripper: Customhttp.RoundTripperthat injects auth headers into SDK-managed transports (StreamableClientTransport,SSEClientTransport), which don't expose a per-request header API.ConvertToCallToolResult: Custom converter that handles 5 distinct backend response shapes (raw array, object with content field, no-content object, parse failures, empty content arrays).Recent Updates
A v1.5.0-pre.1 is available. Specific release notes were not accessible in this run (external data filtered by integrity policy), but the pre-release status warrants monitoring for:
Improvement Opportunities
π Quick Wins
1. Add a page limit guard to
paginateAllThe
paginateAllhelper ininternal/mcp/connection.goiterates cursor pages with no bound. A misbehaving or adversarial backend returning infinite pages would consume unbounded memory and time. A configurable max-pages parameter (e.g., default 100) would add resilience:2. Add logger to test server
internal/testutil/mcptest/server.gousessdk.ServerOptions{}without a logger. Adding a no-op or test-level slog logger would surface SDK-level protocol issues during integration test failures.β¨ Feature Opportunities
1. Monitor go-sdk v1.5.0 for schema bypass option
The
registerToolWithoutValidationworkaround relies on the distinction betweensdk.AddTool(validates) andserver.AddToolmethod (skips validation). If v1.5.0 adds an explicitSkipSchemaValidationoption onsdk.Toolorsdk.ServerOptions, this workaround can be removed and the handler signature can be simplified back to the SDK native form.2. Monitor for native header injection in transport structs
The
headerInjectingRoundTripperexists becauseStreamableClientTransportandSSEClientTransportdon't expose a headers field. If a future SDK release addsHeaders map[string]stringto these structs, the custom RoundTripper can be removed.3. Monitor for SDK pagination helper
The custom generic
paginateAllis clean code, but if the SDK adds aCollectAllor similar utility for its paginated list APIs, the custom implementation can be removed.π Best Practice Alignment
1. Re-evaluate
registerToolWithoutValidationon each SDK upgradeThe
server.AddToolmethod (as opposed to thesdk.AddToolfunction) is being used to bypass schema validation. This relies on an internal SDK implementation detail. It should be explicitly re-checked whenever the SDK is upgraded to ensure the behavior hasn't changed.2. Document the three-argument handler convention
The custom
func(ctx, req, state interface{}) (*CallToolResult, interface{}, error)handler type is used throughout the codebase but is an internal convention not documented at the package level. A package-level godoc comment orARCHITECTURE.mdnote explaining why this differs from the SDK native signature would help future contributors.π§ General Improvements
1. Simplify
ConvertToCallToolResultwith a decision tableThe function in
internal/mcp/tool_result.gohandles 5 branches with comments explaining each case. The logic is correct and well-tested, but restructuring it with named predicates (isRawArray,hasContentField, etc.) would make the control flow easier to scan:2. Make transport negotiation timeouts configurable
In
internal/mcp/http_transport.go, the reconnect timeout is hardcoded at 10 seconds:This could benefit from a configurable value, especially for slow-starting backends.
Recommendations
maxPagesguard topaginateAllβ protects against runaway backendsregisterToolWithoutValidationbehavior on each SDK version bumpNext Steps
modelcontextprotocol/go-sdkrequesting: (a) explicit schema validation bypass option, (b) headers field on transport structsGenerated by Go Fan πΉ β Run Β§24023435150
Module summary saved to: specs/mods/go-sdk.md (session artifact)
Note
π Integrity filter blocked 77 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".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".list_commits: 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: