Skip to content

[go-fan] Go Module Review: modelcontextprotocol/go-sdkΒ #5996

@github-actions

Description

@github-actions

🐹 Go Fan Report: modelcontextprotocol/go-sdk

Module Overview

The official Go SDK for the Model Context Protocol (MCP) β€” the central dependency that makes this project tick. It provides:

  • Client and server implementations over JSON-RPC 2.0
  • The 2025-03-26 Streamable HTTP transport (sdk.NewStreamableHTTPHandler)
  • Type-safe Go structs for tools, resources, prompts, and all content types
  • In-memory transports for fast unit testing

This is arguably the most important direct dependency in the project: virtually every user-facing feature routes through the SDK.

Current Usage in gh-aw-mcpg

Version: v1.5.0
Files: 34 files (10 production, 24 test/integration)
Distinct SDK symbols used: 42

Key APIs Used

Symbol Usage
sdk.NewServer / sdk.NewStreamableHTTPHandler Frontend HTTP server (routed + unified modes)
sdk.NewClient + ClientOptions{KeepAlive} Backend connection management
sdk.ErrSessionMissing Session expiry detection (v1.5.0 feature, correctly using errors.Is)
sdk.NewInMemoryTransports() Fast in-memory test harness in mcptest package
sdk.CommandTransport, sdk.SSEClientTransport, sdk.StreamableClientTransport Three backend transport types
sdk.TextContent, sdk.ImageContent, sdk.AudioContent, sdk.EmbeddedResource Full content type support
sdk.CallToolParamsRaw Test-only raw parameter access

Notable Pattern: Bypass-Validation Tool Registration

The project uses server.AddTool (the instance method on *sdk.Server) instead of the package-level sdk.AddTool function to bypass JSON Schema validation for third-party tool input schemas. This is correctly documented in tool_registry.go:

// NOTE: ... must be re-verified on every SDK upgrade.
// Verified correct for go-sdk v1.5.0 (see server.go:Server.AddTool vs AddTool[In,Out]).
func registerToolWithoutValidation(server *sdk.Server, tool *sdk.Tool, handler ...) {
    server.AddTool(tool, ...)  // instance method β€” no arg validation
}

This is a silent contract with the SDK internals that could break silently on upgrade.

Research Findings

Version Status

  • In use: v1.5.0
  • Latest available: v1.6.0 (detected; content filtered by integrity policy)
  • The project is 1 minor version behind and should investigate v1.6.0 changes

Recent Updates (v1.5.0 features already adopted βœ…)

  • sdk.ErrSessionMissing typed sentinel β€” already used correctly with errors.Is
  • sdk.StreamableHTTPOptions.SessionTimeout β€” already configured in both routed and unified modes
  • sdk.ClientOptions.KeepAlive β€” already enabled for HTTP backend connections

Best Practices Observed βœ…

  • Proper errors.Is wrapping for ErrSessionMissing
  • slog logger bridge (logger.NewSlogLoggerWithHandler) connecting project's debug logger to SDK
  • sdk.NewInMemoryTransports() in test harness β€” idiomatic testing approach
  • sdk.StreamableHTTPOptions{Stateless: false} β€” correct for session-aware gateway

Improvement Opportunities

πŸƒ Quick Wins

  1. Remove the plain JSON-RPC transport fallback β€” There's an explicit TODO(tech-debt) at internal/mcp/http_transport.go:88:

    // TODO(tech-debt): remove this string-matching fallback once the plain JSON-RPC
    // transport (HTTPTransportPlainJSON) is retired.

    This is dead weight if all production backends now support 2024-11-05 MCP spec. Assess if HTTPTransportPlainJSON is still needed and schedule removal.

  2. Unify duplicate session-not-found detection β€” isSessionNotFoundHTTPResponse and isSessionNotFoundError both detect "session not found" conditions with duplicated string-matching logic. Extract a shared sessionNotFoundMessage constant or helper.

✨ Feature Opportunities

  1. Upgrade to v1.6.0 β€” The project is 1 minor version behind. Review the v1.6.0 changelog/release notes at https://github.com/modelcontextprotocol/go-sdk/releases for new features, performance improvements, or deprecations that could benefit this project.

  2. Use typed sdk.AddTool[In, Out] for first-party tools β€” The sys tools (DIFC-related) are implemented directly in this project and have known schemas. These could benefit from the compile-time type safety of sdk.AddTool[In, Out] rather than the bypass-validation pattern.

πŸ“ Best Practice Alignment

  1. Add a regression test for the bypass-validation pattern β€” The comment in tool_registry.go says the behavior "must be re-verified on every SDK upgrade." Add an automated test that asserts server.AddTool does NOT validate tool arguments against the input schema. This prevents a silent regression if the SDK changes this behavior.

    func TestRegisterToolWithoutValidation_SkipsArgValidation(t *testing.T) {
        // Register a tool with a strict schema requiring "name: string"
        // Then call it with missing args β€” should NOT return a schema validation error
    }
  2. Consider a CI alert for SDK releases β€” Given how central this dependency is, it's worth adding a Dependabot entry or a release-watch workflow to get notified of new go-sdk releases promptly.

πŸ”§ General Improvements

  1. Verify sdk.Shutdown is wired into graceful shutdown β€” sdk.Shutdown appears in the codebase, but it's worth auditing that all connection types (stdio, SSE, streamable HTTP) go through the SDK's shutdown path during gateway shutdown.

Recommendations (Prioritized)

Priority Action Effort
πŸ”΄ High Upgrade to v1.6.0 and review changelog Low
πŸ”΄ High Add regression test for bypass-validation pattern Low
🟑 Medium Assess and remove HTTPTransportPlainJSON fallback Medium
🟑 Medium Unify duplicate session-not-found detection Low
🟒 Low Switch sys tools to typed sdk.AddTool[In, Out] Medium
🟒 Low Add Dependabot/release watch for go-sdk Low

Next Steps

  • Run go get github.com/modelcontextprotocol/go-sdk@latest and review the diff
  • Audit HTTPTransportPlainJSON usage in production to determine if it can be retired
  • Add regression test for registerToolWithoutValidation behavior
  • Verify graceful shutdown path covers all SDK transport types

Generated by Go Fan 🐹
Module analysis: specs/mods/go-sdk.md (workspace read-only; saved to session artifacts)
Run: Β§26084942494

Note

πŸ”’ Integrity filter blocked 7 items

The following items were blocked because they don't meet the GitHub integrity level.

To allow these resources, lower min-integrity in your GitHub frontmatter:

tools:
  github:
    min-integrity: approved  # merged | approved | unapproved | none

Generated by Go Fan Β· ● 1.6M Β· β—·

  • expires on May 26, 2026, 8:21 AM UTC

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions