mcpField
G
GoMCP — Gin-like Framework for MCP Servers in Go

GoMCP — Gin-like Framework for MCP Servers in Go

本地服务
github.com/zhangpanda开发工具1412 周前更新

关于 GoMCP — Gin-like Framework for MCP Servers in Go

GoMCP 是面向 Go 开发者的 MCP 服务框架,适用于需要类型化工具、中间件和现有 API 集成的项目。它根据结构体标签生成模式,并提供 Gin、OpenAPI 和 gRPC 适配器。

主要功能

  1. 01根据结构体标签生成模式
  2. 02校验类型化工具参数
  3. 03中间件、身份验证与 RBAC
  4. 04导入 Gin、OpenAPI 和 gRPC API
  5. 05支持资源、提示词与异步任务
  6. 06支持 stdio 和 Streamable HTTP 传输

适用场景

  1. 01在 Go 中构建类型化 MCP 工具
  2. 02将现有 Gin 或 gRPC API 暴露为工具
  3. 03实施身份验证和角色检查
  4. 04使用内存客户端测试 MCP 服务

MCP 相关

GoMCP 是用于实现 MCP 服务的框架,支持注册工具、资源和提示词,并提供 stdio 与 Streamable HTTP 传输。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

暂未收录安装方式

我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。

代码仓库

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

GoMCP

Go Version License Release gomcp MCP server

在 Go 中构建 MCP 服务的快速、惯用方式。

中文文档


🚀 快速链接


🎯 什么是 GoMCP?

GoMCP 是一个用于构建 Model Context Protocol (MCP) 服务的框架,而不只是 SDK。可以把它看作是「MCP 领域的 Gin」。

MCP 是一项开放协议,可让 AI 应用(Claude Desktop、Cursor、Kiro、VS Code Copilot)调用外部工具、读取数据源并使用提示词模板。GoMCP 让构建这些服务变得轻而易举。

为什么选择 GoMCP?
mcp-go (mark3labs)官方 Go SDKGoMCP
层级SDKSDK框架
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 Protocol2024-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 分钟):


📦 安装

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-RPC error 对象,也不是 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
  • 提示词 / 资源参数自动补全

🤝 反馈与支持

💡 推荐阅读:聪明地提问的方式


🔒 安全

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 授权。

重要说明
  1. 本项目根据 Apache 2.0 许可证开源且免费,可用于个人和商业用途。
  2. 在软件的所有副本或实质性部分中,必须保留版权声明、许可证文本和任何署名声明。
  3. Apache 2.0 许可证包含贡献者向用户明确授予的专利权。
  4. 对本项目的贡献根据相同的 Apache 2.0 许可证授权。
  5. 未经授权删除版权声明可能导致法律诉讼。
专利声明

本框架的某些功能(结构体标签模式生成、HTTP 到 MCP 自动适配器、OpenAPI 到 MCP 自动适配器)涉及正在申请中的专利。Apache 2.0 许可证授予你永久、全球范围内、免版税的专利许可,可将这些功能作为本软件的一部分使用。


⭐ Star 历史

如果你觉得 GoMCP 有用,请考虑为它点亮一颗星!这有助于其他人发现本项目。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。