generic-go-mcp
A reusable Go framework for building Model Context Protocol (MCP) servers with support for both stdio and Streaming HTTP transports.
Overview
generic-go-mcp is a library that abstracts away the complexity of implementing MCP servers. It handles JSON-RPC 2.0 message parsing, transport layer management, authentication, and configuration—allowing you to focus on building powerful tools for Claude and other MCP clients.
What is MCP?
The Model Context Protocol enables AI assistants like Claude to interact with external tools and data sources. This library makes it easy to create custom MCP servers that expose your own functionality to AI models.
Features
- Dual Transport Support - Run in stdio mode (for desktop integration) or Streaming HTTP mode (for web services)
- OAuth Authentication - Built-in GitHub OAuth 2.0 support with PKCE for HTTP mode
- Flexible Configuration - Load from YAML files, environment variables, or mounted secrets
- Structured Logging - Multi-level logging (trace/debug/info/warn/error) with JSON and text formats
- Simple Tool API - Register tools with JSON schema definitions and type-safe handlers
- Production Ready - BoltDB token storage, session management, graceful shutdown
Quick Start
package main
import (
"encoding/json"
"github.com/spirilis/generic-go-mcp/config"
"github.com/spirilis/generic-go-mcp/logging"
"github.com/spirilis/generic-go-mcp/mcp"
"github.com/spirilis/generic-go-mcp/transport"
"time"
)
func main() {
// Load configuration
cfg, _ := config.Load("config.yaml")
logging.Initialize(cfg.Logging)
// Create tool registry
registry := mcp.NewToolRegistry()
// Define a simple tool
timeTool := mcp.Tool{
Name: "current_time",
Description: "Returns the current UTC time",
InputSchema: json.RawMessage(`{"type": "object", "properties": {}}`),
}
// Register tool with implementation
registry.Register(timeTool, func(args json.RawMessage) (interface{}, error) {
return mcp.ToolCallResult{
Content: []mcp.ToolContent{
{Type: "text", Text: time.Now().UTC().String()},
},
}, nil
})
// Create MCP server
server := mcp.NewServer(registry, &mcp.ServerConfig{
Name: "my-mcp-server",
Version: "1.0.0",
})
// Start stdio transport
trans := transport.NewStdioTransport()
trans.Start(server)
}
Installation
go get github.com/spirilis/generic-go-mcp
Project Structure
generic-go-mcp/
├── config/ # Configuration loading (YAML, env vars, secrets)
├── logging/ # Structured logging with multiple levels
├── auth/ # OAuth 2.0 authentication (GitHub)
├── transport/ # Transport abstractions (stdio, Streaming HTTP)
├── mcp/ # MCP protocol implementation (JSON-RPC 2.0)
├── examples/
│ ├── go-mcp/ # Complete example server application
│ └── tools/ # Reference tool implementations (date, fortune)
├── CLAUDE-new-project-harness.md # Comprehensive getting started guide
├── CLAUDE.md # Architecture and design patterns
├── HTTP-TRANSPORT.md # HTTP transport documentation
└── LOGGING.md # Logging system documentation
All packages are public and designed to be imported by your projects.
Getting Started
For a comprehensive guide on building your own MCP server, see CLAUDE-new-project-harness.md.
This guide covers:
- Setting up a new project with the library
- Creating tools with and without arguments
- Main application template with stdio/HTTP mode switching
- Configuration examples (stdio, HTTP, auth-enabled)
- Build commands including cross-compilation and Docker
- Testing with Claude Code and HTTP clients
- Debugging tips and common issues
Configuration
The library supports flexible configuration from multiple sources (in priority order):
- YAML configuration files - Specified via
-config flag
- Defaults - Fallback values
Example Configuration (stdio mode)
server:
mode: "stdio"
logging:
level: "info"
format: "text"
Example Configuration (HTTP mode with auth)
server:
mode: "http"
http:
host: "0.0.0.0"
port: 8080
auth:
enabled: true
github:
client_id: "your-github-oauth-app-id"
client_secret: "your-github-oauth-secret"
redirect_url: "http://localhost:8080/auth/callback"
db_path: "./auth.db"
logging:
level: "info"
format: "json"
See examples/ for more configuration samples.
Documentation
Examples
The examples/ directory contains:
- go-mcp/ - A complete MCP server demonstrating stdio/HTTP mode, auth integration, and graceful shutdown
- tools/date.go - Example tool with arguments (timezone parameter)
- tools/fortune.go - Example tool without arguments (executes fortune command)
To build and run the example:
go build -o go-mcp ./examples/go-mcp
./go-mcp -config config.yaml
Key Concepts
Transport Layer
Abstracts communication mechanisms behind a common interface:
- StdioTransport - Reads from stdin, writes to stdout (for Claude Code, desktop apps)
- HTTPTransport - HTTP streaming (for web services, remote access)
Simple API for registering and invoking tools:
registry := mcp.NewToolRegistry()
registry.Register(toolDefinition, toolFunction)
registry.List() // Returns all registered tools
registry.Call(name, arguments) // Invokes a tool
JSON-RPC 2.0 Protocol
All MCP communication follows JSON-RPC 2.0 specification with automatic message parsing, validation, and error handling.
Building
Standard Build
go build -o my-mcp-server
Cross-Compilation
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o my-mcp-server
docker buildx build --platform linux/amd64,linux/arm64 -t my-mcp-server:latest .
See CLAUDE-new-project-harness.md for complete build instructions and Dockerfile examples.
License
MIT License - see LICENSE file for details.
Contributing
Contributions are welcome! This library is designed to be general-purpose and not specialized to any particular use case. When contributing:
- Keep the core library transport-agnostic
- Follow JSON-RPC 2.0 and MCP specification conventions
- Add tests for both stdio and HTTP transports
- Document new features in the appropriate .md files
Acknowledgments
Built following the Model Context Protocol specification by Anthropic.