GoMCP

The fast, idiomatic way to build MCP servers in Go.
δΈζζζ‘£
π Quick Links
π― What is GoMCP?
GoMCP is a framework for building Model Context Protocol (MCP) servers β not just an SDK. Think of it as "Gin for MCP".
MCP is the open protocol that lets AI applications (Claude Desktop, Cursor, Kiro, VS Code Copilot) call external tools, read data sources, and use prompt templates. GoMCP makes building those servers trivial.
Why GoMCP?
| mcp-go (mark3labs) | Official Go SDK | GoMCP |
|---|
| Level | SDK | SDK | Framework |
| Schema generation | Manual | jsonschema tag | mcp tag + auto validation |
| Middleware | Basic hooks | None | Full chain (Logger, Auth, RateLimit, OTelβ¦) |
| Tool groups | No | No | Yes (user.get, admin.delete) |
| Import Gin routes | No | No | β
One line |
| Import OpenAPI/Swagger | No | No | β
One line |
| Import gRPC services | No | No | β
|
| Built-in auth | No | No | Bearer / API Key / Basic + RBAC (Bearer = your token/JWT validator) |
| Inspector UI | No | No | β
|
| Test utilities | Basic | No | mcptest package |
π οΈ Tech Stack
Environment Requirements
| Requirement | Version |
|---|
| Go | β₯ 1.25 |
| MCP Protocol | 2024-11-05 (backward compatible with 2025-11-25) |
Note on the Go 1.25 requirement. GoMCP's go.mod declares go 1.25.0 so the project always builds with the toolchain that ships current security and runtime fixes. If you are running Go 1.21+ locally with the default GOTOOLCHAIN=auto, Go will automatically download and use the matching toolchain for you β no manual upgrade is needed. If you have pinned GOTOOLCHAIN=local, install Go 1.25+ or unset the pin.
Core Dependencies
| Technology | Description |
|---|
| Go standard library | Framework routing, JSON-RPC, transports β no forced DB/ORM deps |
| Gin | Adapter only β import existing Gin routes |
| gRPC | Adapter only β import gRPC services |
| OpenTelemetry | Optional β distributed tracing |
| YAML v3 | Provider only β hot-reload tool definitions |
π Core Features
π§ Tool Development
- Struct-tag auto schema β define parameters with Go structs and
mcp tags, JSON Schema generated automatically
- Typed handlers β
func(*Context, Input) (Output, error) β no manual parameter parsing
- Parameter validation β required, min/max, enum, pattern β checked before your handler runs
- Component versioning β register multiple versions, clients call
name@version
- Async tasks β long-running tools return task ID, with polling and cancellation
π Adapters (Core Differentiator)
- Gin adapter β import existing Gin routes as MCP tools with one line
- OpenAPI adapter β generate tools from Swagger/OpenAPI 3.x docs
- gRPC adapter β import gRPC service methods as MCP tools
π Security
- BearerAuth β Bearer token check via your validator (JWT parsing is up to you; this library does not decode JWTs)
- APIKeyAuth β API key validation via header
- BasicAuth β HTTP Basic authentication
- RequireRole / RequirePermission β RBAC authorization on tool groups
π§© Framework Features
- Middleware chain β Logger, Recovery, RequestID, Timeout, RateLimit, OpenTelemetry
- Tool groups β organize tools with prefixes and group-level middleware
- Resource & Prompt β full MCP support including URI templates and parameterized prompts
- Auto-completions β suggest values for prompt/resource arguments
π Production Ready
- Multiple transports β stdio (Claude Desktop, Cursor, Kiro) and Streamable HTTP with SSE
- MCP Inspector β built-in web debug UI for browsing and testing tools
- Hot-reload β load tool definitions from YAML files with file watching
- mcptest package β in-memory client for unit testing with snapshot support
- Lifecycle β
Close(), session idle eviction, async concurrency β see Server lifecycle, sessions & async tasks.
ποΈ Architecture
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β User Code β
β s.Tool() / s.ToolFunc() / s.Resource() / s.Prompt() β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Framework Core β
β Router β Middleware Chain β Validation β Handler β Result β
ββββββββββββββ¬ββββββββββββββ¬ββββββββββββββββ¬ββββββββββββββββββββ€
β Schema β Validator β Adapters β Observability β
β Generator β Engine β Gin/OpenAPI/ β OTel / Logger β
β (mcp tags) β (auto) β gRPC β / Inspector β
ββββββββββββββ΄ββββββββββββββ΄ββββββββββββββββ΄ββββββββββββββββββββ€
β Protocol Layer β
β JSON-RPC 2.0 / MCP / Capability Negotiation β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Transport Layer β
β stdio / Streamable HTTP + SSE β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Project Structure
gomcp/
βββ server.go # Server core, tool/resource/prompt registration
βββ context.go # Request context with typed accessors
βββ group.go # Tool groups with prefix naming
βββ middleware.go # Middleware chain helpers (SkipAuthForMCPMethods, handshake skips)
βββ middleware_builtin.go # Logger, Recovery, RequestID, Timeout, RateLimit
βββ middleware_auth.go # Bearer/API key/Basic auth, RBAC, SSE auth helpers
βββ middleware_otel.go # OpenTelemetry tracing
βββ schema/ # struct tag β JSON Schema generator + validator
βββ transport/ # stdio + Streamable HTTP + optional CORS helper
βββ adapter/ # Gin, OpenAPI, gRPC adapters
βββ mcptest/ # Testing utilities
βββ task.go # Async task support
βββ completion.go # Auto-completions
βββ inspector.go # Web debug UI
βββ provider.go # Hot-reload from YAML
βββ examples/ # Working examples
βββ basic/ # Minimal stdio server
βββ filesystem/ # Real-world file ops
βββ gin-adapter/ # Import Gin routes
βββ openapi-adapter/ # Import Swagger/OpenAPI
βββ grpc-adapter/ # Import gRPC services
π Cookbook
Step-by-step guides for common tasks (5 minutes each):
π¦ Installation
go get github.com/zhangpanda/gomcp
β‘ Quick Start
5 lines to a working MCP server
package main
import (
"fmt"
"github.com/zhangpanda/gomcp"
)
type SearchInput struct {
Query string `json:"query" mcp:"required,desc=Search keyword"`
Limit int `json:"limit" mcp:"default=10,min=1,max=100"`
}
type SearchResult struct {
Items []string `json:"items"`
Total int `json:"total"`
}
func main() {
s := gomcp.New("my-server", "1.0.0")
s.ToolFunc("search", "Search documents by keyword", func(ctx *gomcp.Context, in SearchInput) (SearchResult, error) {
items := []string{fmt.Sprintf("Result for %q", in.Query)}
return SearchResult{Items: items, Total: len(items)}, nil
})
s.Stdio()
}
The SearchInput struct automatically generates this JSON Schema:
{
"type": "object",
"properties": {
"query": { "type": "string", "description": "Search keyword" },
"limit": { "type": "integer", "default": 10, "minimum": 1, "maximum": 100 }
},
"required": ["query"]
}
Invalid parameters are rejected before your handler runs:
validation failed: query: required; limit: must be <= 100
π Usage Guide
Struct Tag Reference
| Tag | Type | Description | Example |
|---|
required | flag | Field must be provided | mcp:"required" |
desc | string | Human-readable description | mcp:"desc=Search keyword" |
default | any | Default value | mcp:"default=10" |
min | number | Minimum value (inclusive) | mcp:"min=0" |
max | number | Maximum value (inclusive) | mcp:"max=100" |
enum | string | Pipe-separated allowed values | mcp:"enum=asc|desc" |
pattern | string | Regex validation | mcp:"pattern=^[a-z]+$" |
Combine: mcp:"required,desc=User email,pattern=^[^@]+@[^@]+$"
Supported types: string, int, float64, bool, []T, nested structs.
Tools
Simple handler:
s.Tool("hello", "Say hello", func(ctx *gomcp.Context) (*gomcp.CallToolResult, error) {
return ctx.Text("Hello, " + ctx.String("name")), nil
})
Typed handler (recommended):
type Input struct {
Name string `json:"name" mcp:"required,desc=User name"`
Email string `json:"email" mcp:"required,pattern=^[^@]+@[^@]+$"`
}