mcpgo

package module
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 6, 2026 License: MIT Imports: 12 Imported by: 0

README ΒΆ

mcp-go

A clean, well-architected Go implementation of the Model Context Protocol (MCP)

Go Version Go Report Card License GitHub last commit

Table of Contents

Overview

mcp-go provides a production-ready implementation of MCP in Go, featuring a clean layered architecture and innovative transport options. Built for seamless integration with AI frameworks like pydantic-ai and tools like Claude Desktop.

Why mcp-go?

πŸ—οΈ Clean Architecture - Properly separated protocol, transport, and application layers make the codebase maintainable and extensible

πŸš€ Streamable HTTP Transport - Industry-first stateless HTTP transport designed for cloud-native deployments and microservices architectures

🐍 Python-First Design - Built from the ground up for seamless pydantic-ai integration with first-class HTTP client support

πŸ§ͺ Test-Driven - Comprehensive test coverage across all layers ensures reliability in production

πŸ“¦ Modular - Use just the components you need: transport layer, protocol handler, or full server/client

Quick Start

Installation
go get github.com/DR1N0/mcp-go
Server Example
package main

import (
    "context"
    "fmt"
    "log"
    "time"
    
    mcp "github.com/DR1N0/mcp-go"
    "github.com/DR1N0/mcp-go/transport/stdio"
)

// Define tool arguments as Go structs
type GetTimeArgs struct {
    Timezone string `json:"timezone" jsonschema:"required,description=Timezone name (e.g., America/New_York, UTC, Asia/Tokyo)"`
    Format   string `json:"format" jsonschema:"description=Time format (default: RFC3339)"`
}

func main() {
    // Create server with stdio transport
    server := mcp.NewServer(
        stdio.NewStdioServerTransport(),
        mcp.WithName("time-server"),
        mcp.WithVersion("1.0.0"),
    )
    
    // Register tool with automatic schema generation
    err := server.RegisterTool(
        "get_time",
        "Get current time in a specific timezone",
        func(ctx context.Context, args GetTimeArgs) (*mcp.ToolResponse, error) {
            // Load the timezone
            loc, err := time.LoadLocation(args.Timezone)
            if err != nil {
                return nil, fmt.Errorf("invalid timezone: %w", err)
            }
            
            // Get current time in that timezone
            now := time.Now().In(loc)
            
            // Format the time
            format := args.Format
            if format == "" {
                format = time.RFC3339
            }
            
            result := fmt.Sprintf("Current time in %s: %s", args.Timezone, now.Format(format))
            return mcp.NewToolResponse(mcp.NewTextContent(result)), nil
        },
    )
    if err != nil {
        log.Fatal(err)
    }
    
    // Start serving
    if err := server.Serve(); err != nil {
        log.Fatal(err)
    }
}
Client Example
package main

import (
    "context"
    "log"
    
    mcp "github.com/DR1N0/mcp-go"
    "github.com/DR1N0/mcp-go/transport/stdio"
)

func main() {
    // Create client
    client := mcp.NewClient(
        stdio.NewStdioClientTransport("go", "run", "./server/main.go"),
    )
    
    // Initialize connection
    if _, err := client.Initialize(context.Background()); err != nil {
        log.Fatal(err)
    }
    
    // Call a tool
    response, err := client.CallTool(context.Background(), "get_time", map[string]string{
        "timezone": "America/New_York",
        "format":   "2006-01-02 15:04:05 MST",
    })
    if err != nil {
        log.Fatal(err)
    }
    
    log.Printf("Result: %s", response.Content[0].Text)
}
Python Integration

Connect your Go MCP server to pydantic-ai using the streamable HTTP transport:

Go Server:

server := mcp.NewServer(
    streamable.NewServerTransport("/mcp", ":8080"),
    mcp.WithName("my-tools"),
)
server.RegisterTool("get_time", "Get current time in timezone", getTimeHandler)
server.Serve()

Python Client (pydantic-ai):

from pydantic_ai import Agent
from pydantic_ai.mcp import MCPServerStreamableHTTP

# Connect to Go MCP server
server = MCPServerStreamableHTTP(
    url="http://localhost:8080/mcp",
    tool_prefix="mytools_"
)

agent = Agent(
    model="anthropic:claude-sonnet-4",
    toolsets=[server]
)

# Agent can now use tools from the Go server
result = agent.run_sync("What time is it in Tokyo?")

Features

  • βœ… Multiple Transport Options

    • stdio - Standard I/O for subprocess communication
    • SSE - Server-Sent Events for real-time updates
    • Streamable HTTP - Stateless HTTP for cloud deployments
    • gRPC - High-performance bidirectional streaming for remote deployment
  • βœ… Type-Safe Tool Registration

    • Automatic JSON schema generation from Go structs
    • Reflection-based argument validation
    • Context support for cancellation and timeouts
  • βœ… Full MCP Support

    • Tools - Expose functions to AI agents
    • Prompts - Reusable prompt templates
    • Resources - Access to external data sources
    • Sampling - LLM completion requests
  • βœ… Production Ready

    • Comprehensive test coverage
    • Clean error handling
    • Graceful shutdown
    • Request/response correlation

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              Application Layer                  β”‚
β”‚  (Your Tools, Prompts, Resources, Handlers)     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚            Server / Client Layer                β”‚
β”‚  (Registration, Schema Gen, Lifecycle)          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚            Protocol Layer                       β”‚
β”‚  (JSON-RPC 2.0, Request/Response Correlation)   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚            Transport Layer                      β”‚
β”‚  (stdio / SSE / Streamable HTTP)                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Each layer has clear interfaces and can be tested independently. See docs/architecture.md for details.

Transports

stdio

Perfect for Claude Desktop integration and subprocess-based tools.

transport := stdio.NewStdioServerTransport()
SSE (Server-Sent Events)

Ideal for long-lived HTTP connections with server push capabilities.

transport := sse.NewSSEServerTransport("/events", ":8080")
Streamable HTTP

Industry-first stateless HTTP transport for cloud-native deployments.

transport := streamable.NewServerTransport("/mcp", ":8080")
gRPC

High-performance bidirectional streaming for remote MCP server deployment.

transport := grpc.NewServerTransport()

See docs/transport-guide.md for detailed comparison and usage.

Examples

Example Description Transport
stdio/ Basic tool server with subprocess communication stdio
sse/ Real-time updates with Server-Sent Events SSE
streamable_http/ Stateless HTTP server for cloud deployment Streamable HTTP
grpc/ Remote server with bidirectional streaming gRPC

Each example includes both Go server and client implementations (Python client support varies by transport).

Documentation

Development

# Clone the repository
git clone https://github.com/DR1N0/mcp-go.git
cd mcp-go

# Run tests
make test

# Run a specific example
cd examples/stdio/server
go run main.go

# Run linter
make lint

Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.

Areas where we'd love help:

  • Additional transport implementations
  • More example servers
  • Documentation improvements
  • Performance optimizations

License

MIT License - See LICENSE for details.


Built with ❀️ for the MCP community

Documentation ΒΆ

Index ΒΆ

Constants ΒΆ

View Source
const (
	RoleUser      = types.RoleUser
	RoleAssistant = types.RoleAssistant
)

Re-export constants

Variables ΒΆ

View Source
var (
	NewTextContent      = types.NewTextContent
	NewToolResponse     = types.NewToolResponse
	NewPromptMessage    = types.NewPromptMessage
	NewPromptResponse   = types.NewPromptResponse
	NewTextResource     = types.NewTextResource
	NewResourceResponse = types.NewResourceResponse
)

Re-export helper functions

Functions ΒΆ

func GenerateSchema ΒΆ

func GenerateSchema(handler interface{}) (map[string]interface{}, error)

GenerateSchema generates a JSON schema from a function signature

Types ΒΆ

type BaseJSONRPCMessage ΒΆ

type BaseJSONRPCMessage = types.BaseJSONRPCMessage

Re-export message types

type Client ΒΆ

type Client interface {
	// Initialize connects to the server and retrieves its capabilities
	Initialize(ctx context.Context) (*InitializeResponse, error)

	// ListTools retrieves the list of available tools from the server
	ListTools(ctx context.Context, cursor *string) (*ToolsResponse, error)

	// CallTool calls a specific tool on the server with the provided arguments
	CallTool(ctx context.Context, name string, args interface{}) (*ToolResponse, error)

	// ListPrompts retrieves the list of available prompts from the server
	ListPrompts(ctx context.Context, cursor *string) (*ListPromptsResponse, error)

	// GetPrompt retrieves a specific prompt from the server
	GetPrompt(ctx context.Context, name string, args interface{}) (*PromptResponse, error)

	// ListResources retrieves the list of available resources from the server
	ListResources(ctx context.Context, cursor *string) (*ListResourcesResponse, error)

	// ReadResource reads a specific resource from the server
	ReadResource(ctx context.Context, uri string) (*ResourceResponse, error)

	// Ping sends a ping request to check server connectivity
	Ping(ctx context.Context) error

	// GetCapabilities returns the server capabilities obtained during initialization
	GetCapabilities() *ServerCapabilities

	// Close closes the client connection
	Close() error
}

Client represents an MCP client that can connect to and interact with MCP servers

func NewClient ΒΆ

func NewClient(transport Transport) Client

NewClient creates a new MCP client that returns the Client interface

type CloseHandler ΒΆ

type CloseHandler = transport.CloseHandler

type Content ΒΆ

type Content = types.Content

type ErrorHandler ΒΆ

type ErrorHandler = transport.ErrorHandler

type InitializeResponse ΒΆ

type InitializeResponse = types.InitializeResponse

Re-export MCP types

type ListPromptsResponse ΒΆ

type ListPromptsResponse = types.ListPromptsResponse

type ListResourcesResponse ΒΆ

type ListResourcesResponse = types.ListResourcesResponse

type LoggingCapability ΒΆ

type LoggingCapability = types.LoggingCapability

type MCPServer ΒΆ

type MCPServer struct {
	// contains filtered or unexported fields
}

MCPServer implements the Server interface with automatic tool management

func (*MCPServer) Close ΒΆ

func (s *MCPServer) Close() error

Close shuts down the server

func (*MCPServer) DeregisterPrompt ΒΆ added in v0.0.2

func (s *MCPServer) DeregisterPrompt(name string) error

DeregisterPrompt removes a prompt from the server

func (*MCPServer) DeregisterResource ΒΆ added in v0.0.2

func (s *MCPServer) DeregisterResource(uri string) error

DeregisterResource removes a resource from the server

func (*MCPServer) DeregisterTool ΒΆ added in v0.0.2

func (s *MCPServer) DeregisterTool(name string) error

DeregisterTool removes a tool from the server

func (*MCPServer) HasPrompt ΒΆ added in v0.0.2

func (s *MCPServer) HasPrompt(name string) bool

HasPrompt checks if a prompt is registered

func (*MCPServer) HasResource ΒΆ added in v0.0.2

func (s *MCPServer) HasResource(uri string) bool

HasResource checks if a resource is registered

func (*MCPServer) HasTool ΒΆ added in v0.0.2

func (s *MCPServer) HasTool(name string) bool

HasTool checks if a tool is registered

func (*MCPServer) RegisterPrompt ΒΆ

func (s *MCPServer) RegisterPrompt(name, description string, handler interface{}) error

RegisterPrompt registers a prompt with automatic argument extraction

func (*MCPServer) RegisterResource ΒΆ

func (s *MCPServer) RegisterResource(uri, name, description, mimeType string, handler interface{}) error

RegisterResource registers a resource

func (*MCPServer) RegisterTool ΒΆ

func (s *MCPServer) RegisterTool(name, description string, handler interface{}) error

RegisterTool registers a tool with automatic schema generation

func (*MCPServer) Serve ΒΆ

func (s *MCPServer) Serve() error

Serve starts the server

type MessageHandler ΒΆ

type MessageHandler = transport.MessageHandler

type MessageRole ΒΆ

type MessageRole = types.MessageRole

type Prompt ΒΆ

type Prompt = types.Prompt

type PromptArgument ΒΆ

type PromptArgument = types.PromptArgument

type PromptMessage ΒΆ

type PromptMessage = types.PromptMessage

type PromptResponse ΒΆ

type PromptResponse = types.PromptResponse

type PromptsCapability ΒΆ

type PromptsCapability = types.PromptsCapability

type RPCError ΒΆ

type RPCError = types.RPCError

type Resource ΒΆ

type Resource = types.Resource

type ResourceContent ΒΆ

type ResourceContent = types.ResourceContent

type ResourceResponse ΒΆ

type ResourceResponse = types.ResourceResponse

type ResourcesCapability ΒΆ

type ResourcesCapability = types.ResourcesCapability

type Server ΒΆ

type Server interface {
	// RegisterTool registers a new tool with the server
	// The handler should be a function with signature:
	// func(ctx context.Context, args YourArgsStruct) (*ToolResponse, error)
	// or
	// func(args YourArgsStruct) (*ToolResponse, error)
	RegisterTool(name, description string, handler interface{}) error

	// RegisterPrompt registers a new prompt with the server
	RegisterPrompt(name, description string, handler interface{}) error

	// RegisterResource registers a new resource with the server
	RegisterResource(uri, name, description, mimeType string, handler interface{}) error

	// DeregisterTool removes a tool from the server
	DeregisterTool(name string) error

	// DeregisterPrompt removes a prompt from the server
	DeregisterPrompt(name string) error

	// DeregisterResource removes a resource from the server
	DeregisterResource(uri string) error

	// HasTool checks if a tool is registered
	HasTool(name string) bool

	// HasPrompt checks if a prompt is registered
	HasPrompt(name string) bool

	// HasResource checks if a resource is registered
	HasResource(uri string) bool

	// Serve starts the server and begins handling requests
	Serve() error

	// Close shuts down the server gracefully
	Close() error
}

Server represents an MCP server that can register and serve tools, prompts, and resources

func NewServer ΒΆ

func NewServer(transport Transport, opts ...ServerOption) Server

NewServer creates a new MCP server

type ServerCapabilities ΒΆ

type ServerCapabilities = types.ServerCapabilities

type ServerInfo ΒΆ

type ServerInfo = types.ServerInfo

type ServerOption ΒΆ

type ServerOption func(*MCPServer)

ServerOption configures the server

func WithName ΒΆ

func WithName(name string) ServerOption

WithName sets the server name

func WithPaginationLimit ΒΆ added in v0.0.2

func WithPaginationLimit(limit int) ServerOption

WithPaginationLimit sets the pagination limit for list responses

func WithVersion ΒΆ

func WithVersion(version string) ServerOption

WithVersion sets the server version

type Tool ΒΆ

type Tool = types.Tool

type ToolResponse ΒΆ

type ToolResponse = types.ToolResponse

type ToolsCapability ΒΆ

type ToolsCapability = types.ToolsCapability

type ToolsResponse ΒΆ

type ToolsResponse = types.ToolsResponse

type Transport ΒΆ

type Transport = transport.Transport

Re-export transport types

Directories ΒΆ

Path Synopsis
examples
grpc/clients/go command
grpc/server command
sse/clients/go command
sse/server command
stdio/server command
sse

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL