or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

client.mdcontent-types.mdindex.mdserver.mdtransport-http.mdtransport-stdio.mdtransport.md
tile.json

index.mddocs/

mcp-golang

mcp-golang is a comprehensive Go implementation of the Model Context Protocol (MCP), enabling developers to build both MCP servers and clients with minimal boilerplate. It provides type-safe tool argument definitions using native Go structs with automatic JSON schema generation, multiple transport options, and a modular architecture.

Package Information

  • Package Name: mcp-golang
  • Package Type: golang
  • Language: Go
  • Module Path: github.com/metoro-io/mcp-golang
  • Installation: go get github.com/metoro-io/mcp-golang
  • Minimum Go Version: 1.21

Core Imports

import (
    mcp "github.com/metoro-io/mcp-golang"
    "github.com/metoro-io/mcp-golang/transport/stdio"
    "github.com/metoro-io/mcp-golang/transport/http"
)

Basic Usage

Creating an MCP Server

package main

import (
    "fmt"
    mcp "github.com/metoro-io/mcp-golang"
    "github.com/metoro-io/mcp-golang/transport/stdio"
)

// Tool arguments are Go structs with jsonschema tags
type CalculateArgs struct {
    Operation string `json:"operation" jsonschema:"required,description=The operation to perform (add, subtract, multiply, divide)"`
    A         int    `json:"a" jsonschema:"required,description=First number"`
    B         int    `json:"b" jsonschema:"required,description=Second number"`
}

func main() {
    // Create server with stdio transport
    server := mcp.NewServer(stdio.NewStdioServerTransport())

    // Register a tool
    err := server.RegisterTool("calculate", "Perform arithmetic operations",
        func(args CalculateArgs) (*mcp.ToolResponse, error) {
            var result int
            switch args.Operation {
            case "add":
                result = args.A + args.B
            case "subtract":
                result = args.A - args.B
            case "multiply":
                result = args.A * args.B
            case "divide":
                if args.B == 0 {
                    return nil, fmt.Errorf("division by zero")
                }
                result = args.A / args.B
            default:
                return nil, fmt.Errorf("unknown operation: %s", args.Operation)
            }
            return mcp.NewToolResponse(
                mcp.NewTextContent(fmt.Sprintf("Result: %d", result)),
            ), nil
        })
    if err != nil {
        panic(err)
    }

    // Start server
    err = server.Serve()
    if err != nil {
        panic(err)
    }
}

Creating an MCP Client

package main

import (
    "context"
    "log"
    mcp "github.com/metoro-io/mcp-golang"
    "github.com/metoro-io/mcp-golang/transport/stdio"
)

type CalculateArgs struct {
    Operation string `json:"operation"`
    A         int    `json:"a"`
    B         int    `json:"b"`
}

func main() {
    // Create client with stdio transport
    transport := stdio.NewStdioServerTransport()
    client := mcp.NewClient(transport)

    // Initialize connection
    _, err := client.Initialize(context.Background())
    if err != nil {
        log.Fatalf("Failed to initialize: %v", err)
    }

    // Call a tool
    args := CalculateArgs{
        Operation: "add",
        A:         10,
        B:         5,
    }
    response, err := client.CallTool(context.Background(), "calculate", args)
    if err != nil {
        log.Fatalf("Failed to call tool: %v", err)
    }

    if len(response.Content) > 0 {
        log.Printf("Result: %s", response.Content[0].TextContent.Text)
    }
}

Architecture

mcp-golang uses a modular architecture with three main layers:

  1. Protocol Layer: The core Client and Server types implement the MCP protocol, handling tool/prompt/resource registration and execution
  2. Content Layer: Rich content types support text, images, and embedded resources with annotations
  3. Transport Layer: Pluggable transports (stdio, HTTP, Gin) handle message delivery

Transport Options

  • Stdio: Full bidirectional support for all MCP features including notifications
  • HTTP: Stateless request-response for simple scenarios (no notifications)
  • Gin: HTTP transport with Gin framework integration (stateless, no notifications)

Capabilities

MCP Client

Build MCP clients that connect to and interact with MCP servers.

type Client struct { /* ... */ }

func NewClient(transport transport.Transport) *Client
func NewClientWithInfo(transport transport.Transport, info ClientInfo) *Client

Client API Documentation

MCP Server

Build MCP servers that expose tools, prompts, and resources to clients.

type Server struct { /* ... */ }

func NewServer(transport transport.Transport, options ...ServerOptions) *Server

Server API Documentation

Content Types and Responses

Rich content system supporting text, images, and embedded resources with comprehensive response types for tools, prompts, and resources.

type Content struct {
    Type             ContentType
    TextContent      *TextContent
    ImageContent     *ImageContent
    EmbeddedResource *EmbeddedResource
    Annotations      *Annotations
}

func NewTextContent(content string) *Content
func NewImageContent(base64EncodedStringData string, mimeType string) *Content

Content Types Documentation

Transport Layer

Abstract transport interface with multiple implementations for different communication patterns.

type Transport interface {
    Start(ctx context.Context) error
    Send(ctx context.Context, message *BaseJsonRpcMessage) error
    Close() error
    SetCloseHandler(handler func())
    SetErrorHandler(handler func(error))
    SetMessageHandler(handler func(ctx context.Context, message *BaseJsonRpcMessage))
}

Transport Layer Documentation

Stdio Transport

Standard input/output transport for full bidirectional MCP communication.

type StdioServerTransport struct { /* ... */ }

func NewStdioServerTransport() *StdioServerTransport
func NewStdioServerTransportWithIO(in io.Reader, out io.Writer) *StdioServerTransport

Stdio Transport Documentation

HTTP Transports

HTTP-based transports for stateless MCP communication with standard HTTP or Gin framework.

type HTTPTransport struct { /* ... */ }
type HTTPClientTransport struct { /* ... */ }
type GinTransport struct { /* ... */ }

func NewHTTPTransport(endpoint string) *HTTPTransport
func NewHTTPClientTransport(endpoint string) *HTTPClientTransport
func NewGinTransport() *GinTransport

HTTP Transports Documentation

Key Features

  • Type Safety: Define tool arguments as native Go structs with automatic JSON schema generation and validation
  • Minimal Boilerplate: Automatic endpoint generation for tools, prompts, and resources
  • Flexible Transports: Choose between stdio (full features), HTTP (stateless), or Gin (framework integration)
  • Change Notifications: Support for notifying clients about changes to tools, prompts, and resources (stdio only)
  • Pagination: Built-in pagination support for listing tools, prompts, and resources
  • Bidirectional Communication: Full support for both server and client implementations through stdio transport

Common Use Cases

Building an MCP Server for Claude Desktop

server := mcp.NewServer(
    stdio.NewStdioServerTransport(),
    mcp.WithName("my-mcp-server"),
    mcp.WithVersion("1.0.0"),
    mcp.WithInstructions("Instructions for using this server"),
)

// Register your tools, prompts, and resources
server.RegisterTool("tool-name", "description", handlerFunc)
server.Serve()

Configure Claude Desktop to use your server by adding to claude_desktop_config.json:

{
  "mcpServers": {
    "my-server": {
      "command": "/path/to/your/server/executable",
      "args": [],
      "env": {}
    }
  }
}

Building an HTTP-based MCP Server

// Standard HTTP
transport := http.NewHTTPTransport("/mcp")
transport.WithAddr(":8080")
server := mcp.NewServer(transport)
server.RegisterTool("tool-name", "description", handlerFunc)
server.Serve()

// Or with Gin
router := gin.Default()
transport := http.NewGinTransport()
router.POST("/mcp", transport.Handler())
server := mcp.NewServer(transport)
server.RegisterTool("tool-name", "description", handlerFunc)
server.Serve()
router.Run(":8080")

Connecting to an MCP Server

// Via stdio (for subprocess communication)
cmd := exec.Command("./mcp-server")
stdin, _ := cmd.StdinPipe()
stdout, _ := cmd.StdoutPipe()
cmd.Start()
defer cmd.Process.Kill()

transport := stdio.NewStdioServerTransportWithIO(stdout, stdin)
client := mcp.NewClient(transport)
client.Initialize(context.Background())

// Via HTTP
transport := http.NewHTTPClientTransport("http://localhost:8080/mcp")
client := mcp.NewClient(transport)
client.Initialize(context.Background())