GoMCP
GoMCP
在 Go 中构建 MCP 服务器的快速、地道的方式。
🚀 快速链接
MCP 协议: https://modelcontextprotocol.io
Related MCP server: Filesystem MCP Server
🎯 什么是 GoMCP?
GoMCP 是一个用于构建 Model Context Protocol (MCP) 服务器的框架,而不仅仅是一个 SDK。你可以把它看作是 “MCP 版的 Gin”。
MCP 是一种开放协议,允许 AI 应用程序(如 Claude Desktop、Cursor、Kiro、VS Code Copilot)调用外部工具、读取数据源并使用提示词模板。GoMCP 让构建这些服务器变得非常简单。
为什么选择 GoMCP?
mcp-go (mark3labs) | 官方 Go SDK | GoMCP | |
层级 | SDK | SDK | 框架 |
Schema 生成 | 手动 |
| |
中间件 | 基础钩子 | 无 | 完整链式(日志、认证、限流、OTel 等) |
工具分组 | 不支持 | 不支持 | |
导入 Gin 路由 | 不支持 | 不支持 | ✅ 一行代码 |
导入 OpenAPI/Swagger | 不支持 | 不支持 | ✅ 一行代码 |
导入 gRPC 服务 | 不支持 | 不支持 | ✅ |
内置认证 | 不支持 | 不支持 | Bearer, API Key, Basic + RBAC |
Inspector UI | 不支持 | 不支持 | ✅ |
测试工具 | 基础 | 不支持 | mcptest 包 |
🛠️ 技术栈
环境要求
要求 | 版本 |
Go | ≥ 1.25 |
MCP 协议 | 2024-11-05 (向下兼容 2025-11-25) |
核心依赖
技术 | 描述 |
Go 标准库 | 核心框架 — 零外部依赖 |
Gin | 仅适配器 — 导入现有的 Gin 路由 |
gRPC | 仅适配器 — 导入 gRPC 服务 |
OpenTelemetry | 可选 — 分布式追踪 |
YAML v3 | 仅提供程序 — 热重载工具定义 |
🌟 核心特性
🔧 工具开发
结构体标签自动生成 Schema — 使用 Go 结构体和
mcp标签定义参数,自动生成 JSON Schema类型化处理器 —
func(*Context, Input) (Output, error)— 无需手动解析参数参数校验 — 必填、最小/最大值、枚举、正则 — 在处理器运行前自动校验
组件版本控制 — 注册多个版本,客户端通过
name@version调用异步任务 — 长时间运行的工具返回任务 ID,支持轮询和取消
🔌 适配器(核心差异点)
Gin 适配器 — 一行代码将现有的 Gin 路由导入为 MCP 工具
OpenAPI 适配器 — 从 Swagger/OpenAPI 3.x 文档生成工具
gRPC 适配器 — 将 gRPC 服务方法导入为 MCP 工具
🔐 安全性
BearerAuth — JWT 令牌校验
APIKeyAuth — 通过 Header 进行 API Key 校验
BasicAuth — HTTP Basic 认证
RequireRole / RequirePermission — 工具组的 RBAC 授权
🧩 框架特性
中间件链 — 日志、恢复、请求 ID、超时、限流、OpenTelemetry
工具分组 — 使用前缀和组级中间件组织工具
资源与提示词 — 全面支持 MCP,包括 URI 模板和参数化提示词
自动补全 — 为提示词/资源参数提供建议值
🚀 生产就绪
多种传输方式 — stdio (Claude Desktop, Cursor, Kiro) 和带 SSE 的流式 HTTP
MCP Inspector — 内置 Web 调试 UI,用于浏览和测试工具
热重载 — 通过文件监控从 YAML 文件加载工具定义
mcptest 包 — 用于单元测试的内存客户端,支持快照测试
🏗️ 架构
┌──────────────────────────────────────────────────────────────┐
│ 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 │
└──────────────────────────────────────────────────────────────┘项目结构
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 interface and chain execution
├── middleware_builtin.go # Logger, Recovery, RequestID, Timeout, RateLimit
├── middleware_auth.go # BearerAuth, APIKeyAuth, BasicAuth, RBAC
├── middleware_otel.go # OpenTelemetry tracing
├── schema/ # struct tag → JSON Schema generator + validator
├── transport/ # stdio + Streamable HTTP
├── 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📦 安装
go get github.com/zhangpanda/gomcp⚡ 快速开始
5 行代码构建一个可用的 MCP 服务器
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()
}SearchInput 结构体自动生成以下 JSON Schema:
{
"type": "object",
"properties": {
"query": { "type": "string", "description": "Search keyword" },
"limit": { "type": "integer", "default": 10, "minimum": 1, "maximum": 100 }
},
"required": ["query"]
}无效参数会在处理器运行前被拒绝:
validation failed: query: required; limit: must be <= 100📖 使用指南
结构体标签参考
标签 | 类型 | 描述 | 示例 | |
| 标志 | 字段必须提供 |
| |
| 字符串 | 人类可读的描述 |
| |
| 任意 | 默认值 |
| |
| 数字 | 最小值(包含) |
| |
| 数字 | 最大值(包含) |
| |
| 字符串 | 竖线分隔的允许值 | `mcp:"enum=asc | desc"` |
| 字符串 | 正则校验 |
|
组合使用:mcp:"required,desc=用户邮箱,pattern=^[^@]+@[^@]+$"
支持的类型:string, int, float64, bool, []T, 嵌套结构体。
工具
简单处理器:
s.Tool("hello", "Say hello", func(ctx *gomcp.Context) (*gomcp.CallToolResult, error) {
return ctx.Text("Hello, " + ctx.String("name")), nil
})类型化处理器(推荐):
type Input struct {
Name string `json:"name" mcp:"required,desc=User name"`
Email string `json:"email" mcp:"required,pattern=^[^@]+@[^@]+$"`
}
s.ToolFunc("create_user", "Create user", func(ctx *gomcp.Context, in Input) (User, error) {
return db.CreateUser(in.Name, in.Email)
})资源
// Static
s.Resource("config://app", "App config", func(ctx *gomcp.Context) (any, error) {
return map[string]any{"version": "1.0"}, nil
})
// Dynamic URI template
s.ResourceTemplate("db://{table}/{id}", "DB record", func(ctx *gomcp.Context) (any, error) {
return db.Find(ctx.String("table"), ctx.String("id")), nil
})提示词
s.Prompt("code_review", "Code review",
[]gomcp.PromptArgument{gomcp.PromptArg("language", "Language", true)},
func(ctx *gomcp.Context) ([]gomcp.PromptMessage, error) {
return []gomcp.PromptMessage{
gomcp.UserMsg(fmt.Sprintf("Review this %s code for bugs.", ctx.String("language"))),
}, nil
},
)中间件
s.Use(gomcp.Logger()) // Log tool name + duration
s.Use(gomcp.Recovery()) // Recover from panics
s.Use(gomcp.RequestID()) // Unique request ID
s.Use(gomcp.Timeout(10 * time.Second)) // Deadline enforcement
s.Use(gomcp.RateLimit(100)) // 100 calls/minute
s.Use(gomcp.OpenTelemetry()) // Distributed tracing
s.Use(gomcp.BearerAuth(tokenValidator)) // JWT auth
s.Use(gomcp.APIKeyAuth("X-API-Key", keyValidator)) // API key auth自定义中间件:
func AuditLog() gomcp.Middleware {
return func(ctx *gomcp.Context, next func() error) error {
start := time.Now()
err := next()
log.Printf("tool=%s duration=%s err=%v", ctx.String("_tool_name"), time.Since(start), err)
return err
}
}工具分组
user := s.Group("user", authMiddleware)
user.Tool("get", "Get user", getUser) // → user.get
user.Tool("update", "Update user", updateUser) // → user.update
admin := user.Group("admin", gomcp.RequireRole("admin"))
admin.Tool("delete", "Delete user", deleteUser) // → user.admin.delete适配器
Gin — 一行代码导入现有 API:
adapter.ImportGin(s, ginRouter, adapter.ImportOptions{
IncludePaths: []string{"/api/v1/"},
})
// GET /api/v1/users/:id → Tool get_api_v1_users_by_id (id = required param)OpenAPI — 从 Swagger 文档生成:
adapter.ImportOpenAPI(s, "./swagger.yaml", adapter.OpenAPIOptions{
TagFilter: []string{"pets"},
ServerURL: "https://api.example.com",
})gRPC:
adapter.ImportGRPC(s, grpcConn, adapter.GRPCOptions{
Services: []string{"user.UserService"},
})组件版本控制
s.ToolFunc("search", "v1", searchV1, gomcp.Version("1.0"))
s.ToolFunc("search", "v2 with embeddings", searchV2, gomcp.Version("2.0"))
// "search" → latest, "search@1.0" → exact version异步任务
s.AsyncTool("report", "Generate report", func(ctx *gomcp.Context) (*gomcp.CallToolResult, error) {
// long-running work
return ctx.Text("done"), nil
})
// Client gets taskId immediately, polls tasks/get, can tasks/cancel热重载
s.LoadDir("./tools/", gomcp.DirOptions{Watch: true})MCP Inspector
s.Dev(":9090") // http://localhost:9090 — browse and test all tools测试
func TestSearch(t *testing.T) {
c := mcptest.NewClient(t, setupServer())
c.Initialize()
result := c.CallTool("search", map[string]any{"query": "golang"})
result.AssertNoError(t)
result.AssertContains(t, "golang")
mcptest.MatchSnapshot(t, "search_result", result)
}传输方式
s.Stdio() // Claude Desktop, Cursor, Kiro
s.HTTP(":8080") // Remote deployment with SSE
s.Handler() // Embed in existing HTTP server与 AI 客户端配合使用
{
"mcpServers": {
"my-server": {
"command": "/path/to/your/binary"
}
}
}适用于 Claude Desktop、Cursor、Kiro、Windsurf、VS Code Copilot 以及任何兼容 MCP 的客户端。
📋 路线图
[x] 核心:工具、资源、提示词,全面支持 MCP 协议
[x] 结构体标签自动生成 Schema + 参数校验
[x] 中间件链(日志、恢复、限流、超时、请求 ID)
[x] 认证中间件(Bearer / API Key / Basic)+ RBAC 授权
[x] 带前缀命名和嵌套分组的工具组
[x] stdio + 带 SSE 通知的流式 HTTP 传输
[x] Gin 适配器 — 将现有 Gin 路由导入为 MCP 工具
[x] OpenAPI 适配器 — 从 Swagger/OpenAPI 文档生成工具
[x] gRPC 适配器 — 将 gRPC 服务导入为 MCP 工具
[x] OpenTelemetry 集成
[x] 支持快照测试的 mcptest 包
[x] 组件版本控制 + 弃用机制
[x] 支持轮询和取消的异步任务
[x] MCP Inspector Web 调试 UI
[x] 从 YAML 热重载提供程序
[x] 提示词/资源参数的自动补全
[ ] MCP 客户端支持(服务器到服务器调用)
🤝 反馈与支持
Bug 报告: GitHub Issues
功能请求: GitHub Issues
💡 推荐阅读:提问的智慧
⚖️ 版权与许可
版权所有 © 2026 GoMCP 贡献者
基于 Apache License 2.0 许可。
重要说明
本项目是开源且免费的,根据 Apache 2.0 许可协议,可用于个人和商业用途。
您必须保留所有副本或软件重要部分中的版权声明、许可文本和任何归属声明。
Apache 2.0 许可包含贡献者向用户提供的明确专利权授予。
对本项目的贡献均受相同的 Apache 2.0 许可协议约束。
未经授权删除版权声明可能会导致法律诉讼。
专利声明
本框架的某些功能(结构体标签 Schema 生成、HTTP 转 MCP 自动适配器、OpenAPI 转 MCP 自动适配器)是正在申请的专利的主题。Apache 2.0 许可授予您永久、全球、免版税的专利许可,以将这些功能作为本软件的一部分使用。
⭐ Star 历史
如果您觉得 GoMCP 有用,请考虑给它一个 Star!这有助于其他人发现该项目。
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/zhangpanda/gomcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server