mcp/MIGRATION.md
This document describes the migration from the custom MCP implementation to the official go-sdk.
Added the official MCP SDK:
go get github.com/modelcontextprotocol/[email protected]
All types are now re-exported from the official SDK:
Tool → sdkmcp.ToolCallToolRequest → sdkmcp.CallToolRequestCallToolResult → sdkmcp.CallToolResultTextContent, ImageContent, etc.)Prompt, Resource, Server, ServerSessionThe McpServer interface has been simplified:
type McpServer interface {
Start()
Stop()
Server() *sdkmcp.Server // Returns underlying SDK server
}
Important: The AddTool, AddPrompt, and AddResource methods have been removed. Use the SDK directly:
// Old (no longer supported)
server.AddTool(tool, handler)
// New (use SDK directly)
sdkmcp.AddTool(server.Server(), tool, handler)
Updated configuration structure:
ProtocolVersion, BaseUrl (SDK manages these)UseStreamable (choose between SSE and Streamable HTTP transport)mcp:
name: my-server
version: 1.0.0
useStreamable: false # false = SSE (2024-11-05), true = Streamable HTTP (2025-03-26)
sseEndpoint: /sse
messageEndpoint: /message
sseTimeout: 24h
messageTimeout: 30s
cors:
- http://localhost:3000
The SDK uses Go generics for type-safe tool registration:
import sdkmcp "github.com/modelcontextprotocol/go-sdk/mcp"
type MyArgs struct {
Value string `json:"value" jsonschema:"description=Input value"`
}
tool := &mcp.Tool{
Name: "my_tool",
Description: "Description",
}
handler := func(ctx context.Context, req *mcp.CallToolRequest, args MyArgs) (*mcp.CallToolResult, any, error) {
return &mcp.CallToolResult{
Content: []mcp.Content{
&mcp.TextContent{Text: "Result"},
},
}, nil, nil
}
// Register with explicit type parameters
sdkmcp.AddTool(server.Server(), tool, handler)
The SDK automatically generates JSON schemas from struct tags.
Two transports are supported:
SSE (Server-Sent Events): 2024-11-05 MCP spec
UseStreamable: false)/sse (configurable)/messageStreamable HTTP: 2025-03-26 MCP spec
UseStreamable: true)/sse (configurable)Before:
server := mcp.NewMcpServer(c)
tool := &mcp.Tool{Name: "greet", Description: "Greet"}
handler := func(ctx context.Context, req *mcp.CallToolRequest, args GreetArgs) (*mcp.CallToolResult, any, error) {
return &mcp.CallToolResult{
Content: []mcp.Content{&mcp.TextContent{Text: "Hello"}},
}, nil, nil
}
if err := server.AddTool(tool, handler); err != nil {
log.Fatal(err)
}
After:
import sdkmcp "github.com/modelcontextprotocol/go-sdk/mcp"
server := mcp.NewMcpServer(c)
tool := &mcp.Tool{Name: "greet", Description: "Greet"}
handler := func(ctx context.Context, req *mcp.CallToolRequest, args GreetArgs) (*mcp.CallToolResult, any, error) {
return &mcp.CallToolResult{
Content: []mcp.Content{&mcp.TextContent{Text: "Hello"}},
}, nil, nil
}
// Use SDK directly - no error return
sdkmcp.AddTool(server.Server(), tool, handler)
server.AddTool() removed → use sdkmcp.AddTool(server.Server(), ...)server.AddPrompt() removed (SDK v1.2.0 limitation)server.AddResource() removed (SDK v1.2.0 limitation)ProtocolVersion and BaseUrl removedsdkmcp "github.com/modelcontextprotocol/go-sdk/mcp"server.AddTool() with sdkmcp.AddTool(server.Server(), ...)ProtocolVersion and BaseUrl, add UseStreamable