Build Smarter Applications, Connect Powerful Models Easily integrate large language model capabilities with MCP Go SDK
MCP Go SDK is a Go implementation of the Model Context Protocol, fully supporting the latest MCP 2025-06-18 specification, while maintaining backward compatibility with MCP 2025-03-26 and MCP 2024-11-05.
- Fully MCP Compliant - Supports latest MCP 2025-06-18 spec, backward compatible with 2025-03-26, 2024-11-05
- Elegant Architecture - Client/Server + Session pattern, high cohesion and low coupling
- Server SDK - Quickly build MCP servers with tools, resources, and prompt templates
- Client SDK - Complete client implementation for connecting to any MCP-compatible server
- Multiple Transport Protocols - STDIO (recommended), Streamable HTTP (latest), SSE (backward compatible)
- Multi-Session Support - Both Server and Client can manage multiple concurrent connections
- High Performance - Concurrency-safe with optimized message processing
- Security Protection - Built-in input validation, path traversal protection, resource limits
This SDK tracks and supports the latest developments in the MCP protocol, ensuring compatibility with the ecosystem:
| Version | Release Date | Key Features | Support Status |
|---|---|---|---|
| 2025-06-18 | June 2025 | Structured tool output, tool annotations, Elicitation user interaction, Sampling LLM inference | Fully Supported |
| 2025-03-26 | March 2025 | OAuth 2.1 authorization, Streamable HTTP, JSON-RPC batching | Fully Supported |
| 2024-11-05 | November 2024 | HTTP+SSE transport, basic tools and resources | Fully Supported |
- Structured Tool Output: Tools can return typed JSON data for programmatic processing
- Tool Annotations: Describe tool behavior characteristics (read-only, destructive, caching strategy, etc.)
- User Interaction Requests: Tools can proactively request user input or confirmation
- Resource Links: Support for associations and references between resources
- Protocol Version Header: HTTP transport requires
MCP-Protocol-Versionheader - Extended Metadata (_meta): Add custom metadata to tools, resources, and prompts
2025-03-26 → 2025-06-18:
- Added structured tool output support
- Enhanced tool annotation system
- Added user interaction request mechanism
- Support for resource linking functionality
- Added
_metafield for extended metadata
2024-11-05 → 2025-03-26:
- Introduced OAuth 2.1 authorization framework
- Replaced HTTP+SSE with Streamable HTTP
- Added JSON-RPC batching support
- Added audio content type support
go get github.com/voocel/mcp-sdk-goThe simplest way is to use STDIO transport, suitable for command-line tools and Claude Desktop integration:
package main import ( "context" "fmt" "log" "github.com/voocel/mcp-sdk-go/protocol" "github.com/voocel/mcp-sdk-go/server" "github.com/voocel/mcp-sdk-go/transport/stdio" ) func main() { ctx := context.Background() // Create MCP server mcpServer := server.NewServer(&protocol.ServerInfo{ Name: "Quick Start Server", Version: "1.0.0", }, nil) // Register a simple greeting tool mcpServer.AddTool( &protocol.Tool{ Name: "greet", Description: "Greet the user", InputSchema: map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ "name": map[string]interface{}{ "type": "string", "description": "User name", }, }, "required": []string{"name"}, }, }, func(ctx context.Context, req *server.CallToolRequest) (*protocol.CallToolResult, error) { name := req.Params.Arguments["name"].(string) greeting := fmt.Sprintf("Hello, %s! Welcome to MCP Go SDK!", name) return protocol.NewToolResultText(greeting), nil }, ) // Run server with STDIO transport if err := mcpServer.Run(ctx, &stdio.StdioTransport{}); err != nil { log.Fatal(err) } }Build web services using Streamable HTTP transport:
package main import ( "context" "log" "net/http" "github.com/voocel/mcp-sdk-go/protocol" "github.com/voocel/mcp-sdk-go/server" "github.com/voocel/mcp-sdk-go/transport/streamable" ) func main() { // Create MCP server mcpServer := server.NewServer(&protocol.ServerInfo{ Name: "HTTP Server", Version: "1.0.0", }, nil) // Register tools... mcpServer.AddTool(...) // Create HTTP handler handler := streamable.NewHTTPHandler(func(*http.Request) *server.Server { return mcpServer }) // Start HTTP server log.Println("Server started at http://localhost:8081") if err := http.ListenAndServe(":8081", handler); err != nil { log.Fatal(err) } }package main import ( "context" "fmt" "log" "os/exec" "github.com/voocel/mcp-sdk-go/client" "github.com/voocel/mcp-sdk-go/protocol" ) func main() { ctx := context.Background() // Create client mcpClient := client.NewClient(&client.ClientInfo{ Name: "Demo Client", Version: "1.0.0", }, nil) // Connect to server via STDIO (launch subprocess) transport := client.NewCommandTransport(exec.Command("./server")) session, err := mcpClient.Connect(ctx, transport, nil) if err != nil { log.Fatalf("Connection failed: %v", err) } defer session.Close() fmt.Printf("Connected successfully! Server: %s v%s\n", session.ServerInfo().Name, session.ServerInfo().Version) // List available tools tools, err := session.ListTools(ctx, nil) if err != nil { log.Fatalf("Failed to list tools: %v", err) } for _, tool := range tools.Tools { fmt.Printf("Tool: %s - %s\n", tool.Name, tool.Description) } // Call tool result, err := session.CallTool(ctx, &protocol.CallToolParams{ Name: "greet", Arguments: map[string]interface{}{ "name": "Go Developer", }, }) if err != nil { log.Fatalf("Failed to call tool: %v", err) } if len(result.Content) > 0 { if textContent, ok := result.Content[0].(protocol.TextContent); ok { fmt.Printf("Result: %s\n", textContent.Text) } } // Read resource resource, err := session.ReadResource(ctx, &protocol.ReadResourceParams{ URI: "info://server", }) if err != nil { log.Fatalf("Failed to read resource: %v", err) } if len(resource.Contents) > 0 { fmt.Printf("Server info: %s\n", resource.Contents[0].Text) } }| Example | Description | Transport | Features |
|---|---|---|---|
| Basic | Complete comprehensive example | STDIO | All core features + client |
| Calculator | Math calculator service | STDIO | Tools, resources |
| SSE Demo | SSE transport demo | SSE | SSE transport |
| Chatbot | Chatbot service | SSE | Conversational interaction |
| File Server | File operation service | SSE | File operations |
| Streamable Demo | Streamable HTTP demo | Streamable HTTP | Streaming transport |
Recommended to start with Basic example: Complete demonstration of all core features, including server and client implementations.
How to run:
# Server cd examples/basic && go run main.go # Client cd examples/basic/client && go run main.go// Create MCP server mcpServer := server.NewServer(&protocol.ServerInfo{ Name: "My Server", Version: "1.0.0", }, nil) // Register tool mcpServer.AddTool( &protocol.Tool{ Name: "greet", Description: "Greet the user", InputSchema: map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ "name": map[string]interface{}{ "type": "string", "description": "User name", }, }, "required": []string{"name"}, }, }, func(ctx context.Context, req *server.CallToolRequest) (*protocol.CallToolResult, error) { name := req.Params.Arguments["name"].(string) return protocol.NewToolResultText(fmt.Sprintf("Hello, %s!", name)), nil }, ) // Register resource mcpServer.AddResource( &protocol.Resource{ URI: "info://server", Name: "Server Info", Description: "Get basic server information", MimeType: "text/plain", }, func(ctx context.Context, req *server.ReadResourceRequest) (*protocol.ReadResourceResult, error) { contents := protocol.NewTextResourceContents("info://server", "Server information content") return protocol.NewReadResourceResult(contents), nil }, ) // Register resource template mcpServer.AddResourceTemplate( &protocol.ResourceTemplate{ URITemplate: "log://app/{date}", Name: "Application Logs", Description: "Get application logs for a specific date", MimeType: "text/plain", }, func(ctx context.Context, req *server.ReadResourceRequest) (*protocol.ReadResourceResult, error) { // Extract parameters from URI date := extractDateFromURI(req.Params.URI) contents := protocol.NewTextResourceContents(req.Params.URI, fmt.Sprintf("Log content: %s", date)) return protocol.NewReadResourceResult(contents), nil }, ) // Register prompt template mcpServer.AddPrompt( &protocol.Prompt{ Name: "code_review", Description: "Code review prompt", Arguments: []protocol.PromptArgument{ {Name: "language", Description: "Programming language", Required: true}, {Name: "code", Description: "Code content", Required: true}, }, }, func(ctx context.Context, req *server.GetPromptRequest) (*protocol.GetPromptResult, error) { language := req.Params.Arguments["language"] code := req.Params.Arguments["code"] messages := []protocol.PromptMessage{ protocol.NewPromptMessage(protocol.RoleUser, protocol.NewTextContent(fmt.Sprintf("Please review this %s code:\n%s", language, code))), } return protocol.NewGetPromptResult("Code Review", messages...), nil }, ) // Run server (STDIO) if err := mcpServer.Run(ctx, &stdio.StdioTransport{}); err != nil { log.Fatal(err) } // Or use HTTP transport handler := streamable.NewHTTPHandler(func(r *http.Request) *server.Server { return mcpServer }) http.ListenAndServe(":8081", handler)// Create client mcpClient := client.NewClient(&client.ClientInfo{ Name: "My Client", Version: "1.0.0", }, nil) // Connect via STDIO (launch subprocess) transport := client.NewCommandTransport(exec.Command("./server")) session, err := mcpClient.Connect(ctx, transport, nil) if err != nil { log.Fatal(err) } defer session.Close() // List tools tools, err := session.ListTools(ctx, nil) for _, tool := range tools.Tools { fmt.Printf("Tool: %s\n", tool.Name) } // Call tool result, err := session.CallTool(ctx, &protocol.CallToolParams{ Name: "greet", Arguments: map[string]interface{}{"name": "World"}, }) // List resources resources, err := session.ListResources(ctx, nil) for _, res := range resources.Resources { fmt.Printf("Resource: %s\n", res.URI) } // Read resource resource, err := session.ReadResource(ctx, &protocol.ReadResourceParams{ URI: "info://server", }) // Get prompt prompt, err := session.GetPrompt(ctx, &protocol.GetPromptParams{ Name: "code_review", Arguments: map[string]string{ "language": "Go", "code": "func main() { ... }", }, })// Server side: register resource template mcpServer.AddResourceTemplate( &protocol.ResourceTemplate{ URITemplate: "log://app/{date}", Name: "Application Logs", Description: "Get application logs for a specific date", }, func(ctx context.Context, req *server.ReadResourceRequest) (*protocol.ReadResourceResult, error) { // Handle dynamic resource request return protocol.NewReadResourceResult(contents), nil }, ) // Client side: list resource templates templates, err := session.ListResourceTemplates(ctx, nil) for _, tpl := range templates.ResourceTemplates { fmt.Printf("Template: %s\n", tpl.URITemplate) } // Read specific resource resource, err := session.ReadResource(ctx, &protocol.ReadResourceParams{ URI: "log://app/2025-01-15", })// Client side: set roots mcpClient := client.NewClient(&client.ClientInfo{ Name: "Client", Version: "1.0.0", }, &client.ClientOptions{ Roots: []*protocol.Root{ protocol.NewRoot("file:///home/user/projects", "Projects Directory"), protocol.NewRoot("file:///home/user/documents", "Documents Directory"), }, }) // Server side: request client roots list // Note: Must be called within ServerSession rootsList, err := session.ListRoots(ctx) for _, root := range rootsList.Roots { fmt.Printf("Root: %s - %s\n", root.URI, root.Name) }// Client side: set Sampling handler mcpClient := client.NewClient(&client.ClientInfo{ Name: "Client", Version: "1.0.0", }, &client.ClientOptions{ SamplingHandler: func(ctx context.Context, req *protocol.CreateMessageRequest) (*protocol.CreateMessageResult, error) { // Call actual LLM API response := callLLMAPI(req.Messages) return protocol.NewCreateMessageResult( protocol.RoleAssistant, protocol.NewTextContent(response), "gpt-4", protocol.StopReasonEndTurn, ), nil }, }) // Server side: initiate Sampling request // Note: Must be called within ServerSession result, err := session.CreateMessage(ctx, &protocol.CreateMessageRequest{ Messages: []protocol.SamplingMessage{ {Role: protocol.RoleUser, Content: protocol.NewTextContent("Calculate 2+2")}, }, MaxTokens: 100, })Fully compliant with MCP 2025-06-18 specification, backward compatible with MCP 2025-03-26, 2024-11-05
| Protocol | Use Case | Official Support | Protocol Version |
|---|---|---|---|
| STDIO | Subprocess communication | Official standard | 2024-11-05+ |
| SSE | Web applications | Official standard | 2024-11-05+ |
| Streamable HTTP | Modern web applications | Official standard | 2025-06-18 |
| Unofficial | - | ||
| Unofficial | - |
// Server side mcpServer.Run(ctx, &stdio.StdioTransport{}) // Client side (launch subprocess) transport := client.NewCommandTransport(exec.Command("./server")) session, err := mcpClient.Connect(ctx, transport, nil)// Server side handler := streamable.NewHTTPHandler(func(r *http.Request) *server.Server { return mcpServer }) http.ListenAndServe(":8081", handler) // Client side transport, err := streamable.NewStreamableTransport("http://localhost:8081/mcp") session, err := mcpClient.Connect(ctx, transport, nil)// Server side handler := sse.NewHTTPHandler(func(r *http.Request) *server.Server { return mcpServer }) http.ListenAndServe(":8080", handler) // Client side transport, err := sse.NewSSETransport("http://localhost:8080") session, err := mcpClient.Connect(ctx, transport, nil)- Quick Start → Understand basic concepts
- Basic Example → Complete feature demonstration
- Streamable Demo → HTTP transport
- Client Example → Client development
We welcome all forms of contributions!
- Report Bugs - Submit issues describing problems
- Feature Suggestions - Propose new feature ideas
- Improve Documentation - Enhance documentation and examples
- Code Contributions - Submit Pull Requests
Please see Contributing Guide for details.
MIT License - See LICENSE file for details
Core Architecture:
- Client/Server + Session Pattern
- Transport Abstraction Layer - Unified Transport/Connection interface
- Multi-Session Support - Both Server and Client support multiple concurrent connections
Transport Protocols:
- STDIO Transport - Standard input/output, suitable for CLI and Claude Desktop
- Streamable HTTP Transport - Latest HTTP transport protocol (MCP 2025-06-18)
- SSE Transport - Backward compatible with legacy HTTP+SSE (MCP 2024-11-05)
MCP 2025-06-18 Features:
- Tools - Complete tool registration and invocation
- Resources - Resource management and subscription
- Resource Templates - Dynamic resource URI templates
- Prompts - Prompt template management
- Roots - Client roots management
- Sampling - LLM inference request support
- Progress Tracking - Progress feedback for long-running operations
- Logging - Structured log messages
- Request Cancellation - Cancel long-running operations
- CLI Tool - Command-line tool for developing, testing, and debugging MCP servers
- OAuth 2.1 Authorization - Enterprise-grade security authentication (MCP 2025-03-26)
- Middleware System - Request/response interception and processing
- More Examples - More example code for real-world scenarios
- MCP Official Specification - Protocol specification definition
- MCP Python SDK - Python implementation
- MCP TypeScript SDK - TypeScript implementation