Golang MCP Server SDK logo

Golang MCP Server SDK

by FreePeak

The Model Context Protocol allows applications to provide context for LLMs in a standardized way. This Golang SDK implements the full MCP specification, making it easy to build MCP servers that expose resources and tools.

View on GitHub

Last updated: N/A

Golang MCP Server SDK

Go Report Card

Go Report Card

Go Reference

Go Reference

Build Status

Build Status

Contributors

Contributors

Table of Contents

Overview

The Model Context Protocol allows applications to provide context for LLMs in a standardized way, separating the concerns of providing context from the actual LLM interaction. This Golang SDK implements the full MCP specification, making it easy to:

  • Build MCP servers that expose resources and tools
  • Use standard transports like stdio and Server-Sent Events (SSE)
  • Handle all MCP protocol messages and lifecycle events
  • Follow Go best practices and clean architecture principles

Note: This SDK is always updated to align with the latest MCP specification from spec.modelcontextprotocol.io/latest

Installation

go get github.com/FreePeak/golang-mcp-server-sdk

Quickstart

Let's create a simple MCP server that exposes an echo tool:

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/FreePeak/golang-mcp-server-sdk/pkg/server"
	"github.com/FreePeak/golang-mcp-server-sdk/pkg/tools"
)

func main() {
	// Create the server
	mcpServer := server.NewMCPServer("Echo Server Example", "1.0.0")

	// Create an echo tool
	echoTool := tools.NewTool("echo",
		tools.WithDescription("Echoes back the input message"),
		tools.WithString("message",
			tools.Description("The message to echo back"),
			tools.Required(),
		),
	)

	// Add the tool to the server with a handler
	ctx := context.Background()
	err := mcpServer.AddTool(ctx, echoTool, handleEcho)
	if err != nil {
		log.Fatalf("Error adding tool: %v", err)
	}

	// Start the server
	fmt.Println("Starting Echo Server...")
	fmt.Println("Send JSON-RPC messages via stdin to interact with the server.")
	
	// Serve over stdio
	if err := mcpServer.ServeStdio(); err != nil {
		fmt.Fprintf(os.Stderr, "Error: %v\n", err)
		os.Exit(1)
	}
}

// Echo tool handler
func handleEcho(ctx context.Context, request server.ToolCallRequest) (interface{}, error) {
	// Extract the message parameter
	message, ok := request.Parameters["message"].(string)
	if !ok {
		return nil, fmt.Errorf("missing or invalid 'message' parameter")
	}

	// Return the echo response in the format expected by the MCP protocol
	return map[string]interface{}{
		"content": []map[string]interface{}{
			{
				"type": "text",
				"text": message,
			},
		},
	}, nil
}

What is MCP?

The Model Context Protocol (MCP) is a standardized protocol that allows applications to provide context for LLMs in a secure and efficient manner. It separates the concerns of providing context and tools from the actual LLM interaction. MCP servers can:

  • Expose data through Resources (read-only data endpoints)
  • Provide functionality through Tools (executable functions)
  • Define interaction patterns through Prompts (reusable templates)
  • Support various transport methods (stdio, HTTP/SSE)

Core Concepts

Server

The MCP Server is your core interface to the MCP protocol. It handles connection management, protocol compliance, and message routing:

// Create a new MCP server
mcpServer := server.NewMCPServer("My App", "1.0.0")

Tools

Tools let LLMs take actions through your server. Unlike resources, tools are expected to perform computation and have side effects:

// Define a calculator tool
calculatorTool := tools.NewTool("calculator",
    tools.WithDescription("Performs basic arithmetic"),
    tools.WithString("operation",
        tools.Description("The operation to perform (add, subtract, multiply, divide)"),
        tools.Required(),
    ),
    tools.WithNumber("a", 
        tools.Description("First number"),
        tools.Required(),
    ),
    tools.WithNumber("b",
        tools.Description("Second number"),
        tools.Required(),
    ),
)

// Add tool to server with a handler
mcpServer.AddTool(ctx, calculatorTool, handleCalculator)

Resources

Resources are how you expose data to LLMs. They're similar to GET endpoints in a REST API - they provide data but shouldn't perform significant computation or have side effects:

// Create a resource (Currently using the internal API)
resource := &domain.Resource{
    URI:         "sample://hello-world",
    Name:        "Hello World Resource",
    Description: "A sample resource for demonstration purposes",
    MIMEType:    "text/plain",
}

// Note: Resource support is being updated in the public API

Prompts

Prompts are reusable templates that help LLMs interact with your server effectively:

// Create a prompt (Currently using the internal API)
codeReviewPrompt := &domain.Prompt{
    Name:        "review-code",
    Description: "A prompt for code review",
    Template:    "Please review this code:\n\n{{.code}}",
    Parameters: []domain.PromptParameter{
        {
            Name:        "code",
            Description: "The code to review",
            Type:        "string",
            Required:    true,
        },
    },
}

// Note: Prompt support is being updated in the public API

Running Your Server

MCP servers in Go can be connected to different transports depending on your use case:

stdio

For command-line tools and direct integrations:

// Start a stdio server
if err := mcpServer.ServeStdio(); err != nil {
    fmt.Fprintf(os.Stderr, "Error: %v\n", err)
    os.Exit(1)
}

HTTP with SSE

For web applications, you can use Server-Sent Events (SSE) for real-time communication:

// Configure the HTTP address
mcpServer.SetAddress(":8080")

// Start an HTTP server with SSE support
if err := mcpServer.ServeHTTP(); err != nil {
    log.Fatalf("HTTP server error: %v", err)
}

// For graceful shutdown
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := mcpServer.Shutdown(ctx); err != nil {
    log.Fatalf("Server shutdown error: %v", err)
}

Multi-Protocol

You can also run multiple protocol servers simultaneously:

// Configure server for both HTTP and stdio
mcpServer := server.NewMCPServer("Multi-Protocol Server", "1.0.0")
mcpServer.SetAddress(":8080")
mcpServer.AddTool(ctx, echoTool, handleEcho)

// Start HTTP server in a goroutine
go func() {
    if err := mcpServer.ServeHTTP(); err != nil {
        log.Fatalf("HTTP server error: %v", err)
    }
}()

// Start stdio server in the main thread
if err := mcpServer.ServeStdio(); err != nil {
    log.Fatalf("Stdio server error: %v", err)
}

Testing and Debugging

For testing your MCP server, you can use the MCP Inspector or send JSON-RPC messages directly:

# Test an echo tool with stdio
echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"echo","parameters":{"message":"Hello, World!"}}}' | go run your_server.go

Examples

Check out the examples directory for complete example servers:

Echo Server

A simple echo server example is available in examples/echo_server.go:

# Run the example
go run examples/echo_server.go

Calculator Server

A more advanced calculator example with both HTTP and stdio modes is available in examples/calculator/:

# Run in HTTP mode
go run examples/calculator/main.go --mode http

# Run in stdio mode
go run examples/calculator/main.go --mode stdio

Package Structure

The SDK is organized following clean architecture principles:

golang-mcp-server-sdk/
├── pkg/                    # Public API (exposed to users)
│   ├── builder/            # Public builder pattern for server construction
│   ├── server/             # Public server implementation
│   ├── tools/              # Utilities for creating MCP tools
│   └── types/              # Shared types and interfaces
├── internal/               # Private implementation details
├── examples/               # Example code snippets and use cases
└── cmd/                    # Example MCP server applications

The pkg/ directory contains all publicly exposed APIs that users of the SDK should interact with.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

📧 Support & Contact

  • For questions or issues, email [email protected]
  • Open an issue directly: Issue Tracker
  • If Golang MCP Server SDK helps your work, please consider supporting:
<p align=""> <a href="https://www.buymeacoffee.com/linhdmn"> <img src="https://img.buymeacoffee.com/button-api/?text=Support MCP Server SDK&emoji=☕&slug=linhdmn&button_colour=FFDD00&font_colour=000000&font_family=Cookie&outline_colour=000000&coffee_colour=ffffff" alt="Buy Me A Coffee"/> </a> </p>