关于 GoMCP — Gin-like Framework for MCP Servers in Go
GoMCP 是面向 Go 开发者的 MCP 服务框架,适用于需要类型化工具、中间件和现有 API 集成的项目。它根据结构体标签生成模式,并提供 Gin、OpenAPI 和 gRPC 适配器。
主要功能
- 01根据结构体标签生成模式
- 02校验类型化工具参数
- 03中间件、身份验证与 RBAC
- 04导入 Gin、OpenAPI 和 gRPC API
- 05支持资源、提示词与异步任务
- 06支持 stdio 和 Streamable HTTP 传输
适用场景
- 01在 Go 中构建类型化 MCP 工具
- 02将现有 Gin 或 gRPC API 暴露为工具
- 03实施身份验证和角色检查
- 04使用内存客户端测试 MCP 服务
MCP 相关
GoMCP 是用于实现 MCP 服务的框架,支持注册工具、资源和提示词,并提供 stdio 与 Streamable HTTP 传输。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
GoMCP
在 Go 中构建 MCP 服务的快速、惯用方式。
🚀 快速链接
- GitHub:https://github.com/zhangpanda/gomcp
- Gitee:https://gitee.com/rilegouasas/gomcp
- MCP Protocol:https://modelcontextprotocol.io
🎯 什么是 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 生成 | 手动 | jsonschema 标签 | mcp 标签 + 自动校验 |
| 中间件 | 基础钩子 | 无 | 完整链路(Logger、Auth、RateLimit、OTel…) |
| 工具分组 | 否 | 否 | 是(user.get、admin.delete) |
| 导入 Gin 路由 | 否 | 否 | ✅ 一行代码 |
| 导入 OpenAPI/Swagger | 否 | 否 | ✅ 一行代码 |
| 导入 gRPC 服务 | 否 | 否 | ✅ |
| 内置身份验证 | 否 | 否 | Bearer / API Key / Basic + RBAC(Bearer = 你的令牌/JWT 验证器) |
| Inspector UI | 否 | 否 | ✅ |
| 测试工具 | 基础 | 无 | mcptest 包 |
🛠️ 技术栈
环境要求
| 要求 | 版本 |
|---|---|
| Go | ≥ 1.25 |
| MCP Protocol | 2024-11-05(向后兼容 2025-11-25) |
关于 Go 1.25 要求的说明。 GoMCP 的
go.mod声明了go 1.25.0,以确保项目始终使用包含最新安全和运行时修复的工具链进行构建。如果你在本地运行 Go 1.21+,并使用默认的GOTOOLCHAIN=auto,Go 会自动下载并使用匹配的工具链,无需手动升级。如果你设置了固定的GOTOOLCHAIN=local,请安装 Go 1.25+ 或取消该固定设置。
核心依赖
| 技术 | 说明 |
|---|---|
| Go 标准库 | 框架路由、JSON-RPC、传输层——不会强制依赖数据库/ORM |
| Gin | 仅作为适配器——导入现有 Gin 路由 |
| gRPC | 仅作为适配器——导入 gRPC 服务 |
| OpenTelemetry | 可选——分布式追踪 |
| YAML v3 | 仅作为 Provider——热重载工具定义 |
🌟 核心功能
🔧 工具开发
- 通过结构体标签自动生成 Schema — 使用 Go 结构体和
mcp标签定义参数,自动生成 JSON Schema - 类型化处理程序 —
func(*Context, Input) (Output, error)— 无需手动解析参数 - 参数校验 — required、min/max、enum、pattern——在处理程序运行前进行检查
- 组件版本管理 — 注册多个版本,客户端调用
name@version - 异步任务 — 长时间运行的工具返回任务 ID,并支持轮询和取消
🔌 适配器(核心差异化优势)
- Gin 适配器 — 一行代码即可将现有 Gin 路由导入为 MCP 工具
- OpenAPI 适配器 — 根据 Swagger/OpenAPI 3.x 文档生成工具
- gRPC 适配器 — 将 gRPC 服务方法导入为 MCP 工具
🔐 安全
- BearerAuth — 通过你的验证器检查 Bearer 令牌(JWT 解析由你负责;此库不会解码 JWT)
- APIKeyAuth — 通过请求头验证 API Key
- BasicAuth — HTTP Basic 身份验证
- RequireRole / RequirePermission — 对工具组进行 RBAC 授权
🧩 框架特性
- 中间件链 — Logger、Recovery、RequestID、Timeout、RateLimit、OpenTelemetry
- 工具组 — 使用前缀和组级中间件组织工具
- 资源与提示词 — 全面支持 MCP,包括 URI 模板和参数化提示词
- 自动补全 — 为提示词/资源参数建议取值
🚀 可用于生产环境
- 多种传输方式 — stdio(Claude Desktop、Cursor、Kiro)和支持 SSE 的 Streamable HTTP
- MCP Inspector — 内置 Web 调试界面,可浏览和测试工具
- 热重载 — 从 YAML 文件加载工具定义,并监视文件变化
- mcptest 包 — 用于单元测试的内存客户端,支持快照
- 生命周期 —
Close()、会话空闲清理、异步并发 — 参见服务生命周期、会话与异步任务。
🏗️ 架构
┌──────────────────────────────────────────────────────────────┐
│ 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 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
📖 食谱
常见任务的分步指南(每个用时 5 分钟):
- 构建搜索工具 — 从零开始接入 Claude Desktop
- 导入现有 API — 一行代码接入 Gin / OpenAPI / gRPC
- 添加身份验证 + RBAC — Bearer 令牌 + 基于角色的访问控制
📦 安装
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
📖 使用指南
结构体标签参考
| 标签 | 类型 | 描述 | 示例 |
|---|---|---|---|
required | 标志 | 必须提供此字段 | mcp:"required" |
desc | 字符串 | 易于理解的描述 | mcp:"desc=Search keyword" |
default | 任意 | 默认值 | mcp:"default=10" |
min | 数字 | 最小值(含) | mcp:"min=0" |
max | 数字 | 最大值(含) | mcp:"max=100" |
enum | 字符串 | 用竖线分隔的允许值 | mcp:"enum=asc|desc" |
pattern | 字符串 | 正则表达式验证 | mcp:"pattern=^[a-z]+$" |
组合使用:mcp:"required,desc=User email,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 MCP method + 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
// Pick one: BearerAuth (token required on initialize too) or BearerAuthSkipHandshake (initialize/ping anonymous).
s.Use(gomcp.BearerAuthSkipHandshake(tokenValidator))
s.Use(gomcp.APIKeyAuthSkipHandshake("X-API-Key", keyValidator))
身份验证错误格式。 当 BearerAuth / APIKeyAuth / BasicAuth / RequireRole / RequirePermission 中间件拒绝调用时, 框架会返回常规的 JSON-RPC
result,其中isError = true,拒绝原因位于content[0].text中 — 而不是 JSON-RPCerror对象,也不是 HTTP 401/403。客户端必须 检查工具调用结果的isError,以检测身份验证失败。
自定义中间件:
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, "[email protected]" → 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})
YAML 工具文件格式:
name: search
description: Full-text document search
version: "1.0" # OPTIONAL — non-empty renames the tool to "[email protected]"
method: GET
handler: https://example.com/search
params:
- {name: query, type: string, required: true, description: Query text}
请注意 —
version会重命名工具。 非空的version字段会使 Provider 将工具注册为name@version(例如[email protected]),遵循与gomcp.Version()相同的约定。这就是 客户端必须传给tools/call的名称,也是tools/list中显示的名称。如果想要一个未带版本的普通search工具, 请完全删除version字段。
服务生命周期、会话与异步任务
Server.Close()— 当进程或测试关闭使用LoadDir(..., Watch: true)或长连接 HTTP 的服务时,调用一次Close()。它会停止 YAML 监视循环、会话清理后台 goroutine,以及异步任务管理器清理循环。此调用具有幂等性。- 会话 — 会话状态仅存储在内存中。标识符来自客户端的
Mcp-Session-Id标头(参见 Streamable HTTP)。闲置 30 分钟的会话(未通过该 ID 访问)会被删除;下一个使用相同 ID 的请求会获得一个新的空会话。除非客户端持续发送请求或你自行刷新状态,否则不要依赖Session存储跨越长时间闲置。 SetMaxConcurrentTasks(n)— 必须在首次使用AsyncTool/AsyncToolFunc之前设置。内部任务管理器创建后,之后的调用会不执行任何操作(避免与正在执行的工作发生竞态)。- 关闭与异步工作 —
Close()不会等待仍在运行的异步工具处理程序;如果需要在退出前确保工作完成,请自行添加超时 / 等待。
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
// Browser clients: wrap the handler with transport.WrapCORS(h, []string{"https://your.app"}) when needed
与 AI 客户端配合使用
{
"mcpServers": {
"my-server": {
"command": "/path/to/your/binary"
}
}
}
兼容 Claude Desktop、Cursor、Kiro、Windsurf、VS Code Copilot,以及任何兼容 MCP 的客户端。
📋 路线图
- 核心功能:工具、资源、提示词,完整支持 MCP 协议
- 通过结构体标签自动生成 Schema + 参数验证
- 中间件链(Logger、Recovery、RateLimit、Timeout、RequestID)
- 身份验证中间件(Bearer / API Key / Basic)+ RBAC 授权
- 带前缀命名和嵌套分组的工具组
- stdio + Streamable HTTP 传输方式,支持 SSE 通知
- Gin 适配器 — 将现有 Gin 路由导入为 MCP 工具
- OpenAPI 适配器 — 根据 Swagger/OpenAPI 文档生成工具
- gRPC 适配器 — 将 gRPC 服务导入为 MCP 工具
- OpenTelemetry 集成
- 支持快照测试的 mcptest 包
- 组件版本控制 + 弃用
- 支持轮询和取消的异步任务
- MCP Inspector 网页调试界面
- 从 YAML 热重载 Provider
- 提示词 / 资源参数自动补全
🤝 反馈与支持
- Bug 报告:GitHub Issues
- 功能请求:GitHub Issues
- 讨论:GitHub Discussions
💡 推荐阅读:聪明地提问的方式
🔒 安全
HTTP 传输与身份验证
Use中间件会对每个 JSON-RPC 方法运行(不包括没有响应的通知notifications/initialized):initialize、tools/list、tools/call、resources/read、prompts/get、tasks/*、completion/complete等。公开POST /mcp时,请使用BearerAuth/APIKeyAuth/BasicAuth。对于APIKeyAuth,如果没有发送请求头,api_key(以及其他合并的参数)会从tools/call参数、prompts/get参数或resources/read参数的 JSON 中获取——生产环境中优先使用请求头。BearerAuthSkipHandshake/APIKeyAuthSkipHandshake/BasicAuthSkipHandshake(或SkipAuthForMCPMethods)允许initialize和ping在没有凭据的情况下运行,同时保护其他方法——这适用于先协商、再发送令牌的 MCP HTTP 客户端。- 请求上下文会传递到工具、资源和提示词处理程序(截止时间、
Authorization,以及从 Streamable HTTP 注入的请求头)。 - SSE(
GET /mcp)不会执行 MCP 中间件。请使用WithSSEAuth搭配SSEBearerAuth、SSEAPIKeyAuth、SSEBasicAuth或自定义门控。若不使用WithSSEAuth,任何能够打开GET的客户端都会收到广播通知。 - 浏览器
fetch:使用github.com/zhangpanda/gomcp/transport中的transport.WrapCORS(h, allowedOrigins)包装/mcp处理程序;启用凭据时,切勿使用*,只能列出可信来源。
在生产环境中部署 Streamable HTTP 时,请结合使用 TLS、应用于 POST 的身份验证中间件,以及在通知不得公开时使用的 WithSSEAuth。
如需报告安全漏洞,请参阅 SECURITY.md。
⚖️ 版权与许可
版权所有 © 2026 GoMCP Contributors
根据 Apache License 2.0 授权。
重要说明
- 本项目根据 Apache 2.0 许可证开源且免费,可用于个人和商业用途。
- 在软件的所有副本或实质性部分中,必须保留版权声明、许可证文本和任何署名声明。
- Apache 2.0 许可证包含贡献者向用户明确授予的专利权。
- 对本项目的贡献根据相同的 Apache 2.0 许可证授权。
- 未经授权删除版权声明可能导致法律诉讼。
专利声明
本框架的某些功能(结构体标签模式生成、HTTP 到 MCP 自动适配器、OpenAPI 到 MCP 自动适配器)涉及正在申请中的专利。Apache 2.0 许可证授予你永久、全球范围内、免版税的专利许可,可将这些功能作为本软件的一部分使用。
⭐ Star 历史
如果你觉得 GoMCP 有用,请考虑为它点亮一颗星!这有助于其他人发现本项目。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。