返回市场
gin-MCP服务器

gin-MCP服务器

作者:ckanthony63 星标更新:2025-11-07

项目介绍

Gin-MCP: 零配置 Gin 到 MCP 桥接

Go 参考 CI codecov

信任评分

<table border="0"> <tr> <td valign="top"> <strong>通过一行代码启用任何 Gin API 的 MCP 功能。</strong> <br><br> Gin-MCP 是一个<strong>有意见、零配置</strong>库,它会自动将现有的 Gin 端点暴露为<a href="https://modelcontextprotocol.io/introduction">模型上下文协议 (MCP)</a>工具,使其立即可用于兼容 MCP 的客户端,如<a href="https://cursor.sh/">Cursor</a>、<a href="https://claude.ai/desktop">Claude Desktop</a>、<a href="https://continue.dev/">Continue</a>、<a href="https://zed.dev/">Zed</a>和其他支持 MCP 的工具。 <br><br> 我们的理念很简单:<strong>最小设置,最大生产力</strong>。只需将 Gin-MCP 插入您的 Gin 应用程序,剩下的由它来处理。 </td> <td valign="top" align="right" width="200"> <img src="gin-mcp.png" alt="Gin-MCP 标志" width="200"/> </td> </tr> </table>

为什么选择 Gin-MCP?

  • **轻松集成:**无需编写繁琐的样板代码即可将您的 Gin API 连接到 MCP 客户端。
  • **零配置(默认):**立即开始。Gin-MCP 自动发现路由并推断模式。
  • **开发者生产力:**减少配置工具的时间,增加构建功能的时间。
  • **灵活性:**虽然零配置是默认选项,但需要时可以自定义模式和端点暴露。
  • **现有 API:**与您现有的 Gin API 兼容——无需更改任何代码。

示例

gin-mcp-example

特性

  • **自动发现:**智能地找到所有注册的 Gin 路由。
  • **模式推断:**从路由参数和请求/响应类型(如果可能的话)自动生成 MCP 工具模式。
  • **直接 Gin 集成:**将 MCP 服务器直接挂载到您的现有 gin.Engine 上。
  • **参数保留:**准确反映您的 Gin 路由参数(路径、查询)在生成的 MCP 工具中。
  • **动态 BaseURL 解析:**支持代理环境(Quicknode、RAGFlow),具有每个用户/部署端点。
  • **可定制模式:**使用 RegisterSchema 手动注册特定路由的模式以进行细粒度控制。
  • **选择性暴露:**使用操作 ID 或标签过滤哪些端点被暴露。
  • **灵活部署:**在同一 Gin 应用程序内挂载 MCP 服务器或单独部署。

安装

go get github.com/ckanthony/gin-mcp

基本用法:即时 MCP 服务器

几分钟内运行您的 MCP 服务器,只需少量代码:

package main

import (
	"net/http"

	server "github.com/ckanthony/gin-mcp/"
	"github.com/gin-gonic/gin"
)

func main() {
	// 1. 创建您的 Gin 引擎
	r := gin.Default()

	// 2. 定义您的 API 路由(Gin-MCP 将发现这些)
	r.GET("/ping", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{"message": "pong"})
	})

	r.GET("/users/:id", func(c *gin.Context) {
		// 示例处理器...
		userID := c.Param("id")
		c.JSON(http.StatusOK, gin.H{"user_id": userID, "status": "fetched"})
	})

	// 3. 创建并配置 MCP 服务器
	// 提供 MCP 客户端所需的基本信息。
	mcp := server.New(r, &server.Config{
		Name:        "我的简单 API",
		Description: "一个通过 MCP 自动暴露的示例 API。",
		// BaseURL 至关重要!它告诉 MCP 客户端在哪里发送请求。
		BaseURL: "http://localhost:8080",
	})

	// 4. 挂载 MCP 服务器端点
	mcp.Mount("/mcp") // MCP 客户端将连接到这里

	// 5. 运行您的 Gin 服务器
	r.Run(":8080") // Gin 服务器按常规运行
}

就这样!您的 MCP 工具现在可以在 http://localhost:8080/mcp 访问。Gin-MCP 自动为 /ping/users/:id 创建了工具。

**关于 BaseURL 的注意事项:**始终提供显式的 BaseURL。这告诉 MCP 服务器当客户端执行工具时应转发 API 请求到哪个地址。没有它,在代理环境或内部/外部 URL 不同的情况下,自动检测可能会失败。

高级用法

虽然 Gin-MCP 力求零配置,但您可以自定义其行为。

使用注释标注处理器

Gin-MCP 自动从处理器函数注释中提取元数据以生成丰富的工具描述。使用这些注释使您的 MCP 工具更易于发现和使用:

// listProducts 获取分页的产品列表
// @summary 列出所有产品
// @description 返回带有可选价格、标签和可用性过滤器的分页产品列表
// @param page 分页的页码(默认:1)
// @param limit 每页项目数(默认:10,最大:100)
// @param minPrice 最小价格过滤器
// @param tag 通过标签过滤产品
// @tags public catalog
func listProducts(c *gin.Context) {
    // 处理程序实现...
}

支持的注释:

  • @summary - 成为工具主要描述的一行简短描述
  • @description - 追加到摘要的附加详细解释
  • @param <name> <text> - 在生成的模式中为特定输入参数附加描述性文本
  • @tags - 用于过滤工具的空间或逗号分隔标签(参见“过滤暴露的端点”下方)
  • @operationId <id> - 工具的自定义操作 ID(覆盖默认的 METHOD_path 命名方案)。必须在整个路由中唯一;重复会被跳过(首次声明获胜)并记录警告。

所有注释都是可选的,但使用它们会使您的 API 工具在 MCP 客户端(如 Claude Desktop 和 Cursor)中更加用户友好。

自定义操作 ID:

默认情况下,Gin-MCP 使用 METHOD_path 格式(例如,GET_users_id)生成操作 ID。对于路径非常长的路由,可以使用 @operationId 指定一个更短、更易管理的名字:

// getUserProfile 获取用户的扩展元数据资料
// @summary 获取用户资料
// @operationId getUserProfile
// @param id 用户标识符
func getUserProfile(c *gin.Context) {
    // 而不是默认的 "GET_api_v2_users_userId_profile_extended"
    // 这个工具将命名为 "getUserProfile"
}

**重要:**操作 ID 必须是唯一的。如果两个处理器使用相同的 @operationId,重复将完全被跳过(首次声明获胜),并且总是记录警告。这确保了工具列表和操作映射之间的一致性。

使用 RegisterSchema 进行细粒度模式控制

有时,自动模式推断不够。RegisterSchema 允许您明确定义特定路由的查询参数或请求体模式。这在以下情况下很有用:

  • 您使用复杂的结构体作为查询参数(ShouldBindQuery)。
  • 您想要为请求体定义不同的模式(例如,POST/PUT)。
  • 自动推断未捕获您希望在 MCP 工具定义中暴露的具体约束(枚举、描述等)。
package main

import (
	// ... 其他导入
	"github.com/ckanthony/gin-mcp/pkg/server"
	"github.com/gin-gonic/gin"
)

// 查询参数示例结构体
type ListProductsParams struct {
	Page  int    `form:"page,default=1" json:"page,omitempty" jsonschema:"description=页码,minimum=1"`
	Limit int    `form:"limit,default=10" json:"limit,omitempty" jsonschema:"description=每页项目数,maximum=100"`
	Tag   string `form:"tag" json:"tag,omitempty" jsonschema:"description=通过标签过滤"`
}

// POST 请求体示例结构体
type CreateProductRequest struct {
	Name  string  `json:"name" jsonschema:"required,description=产品名称"`
	Price float64 `json:"price" jsonschema:"required,minimum=0,description=产品价格"`
}

func main() {
	r := gin.Default()

	// --- 定义路由 ---
	r.GET("/products", func(c *gin.Context) { /* ... 处理程序 ... */ })
	r.POST("/products", func(c *gin.Context) { /* ... 处理程序 ... */ })
	r.PUT("/products/:id", func(c *gin.Context) { /* ... 处理程序 ... */ })


	// --- 配置 MCP 服务器 ---
	mcp := server.New(r, &server.Config{
		Name:        "产品 API",
		Description: "管理产品的 API。",
		BaseURL:     "http://localhost:8080",
	})

	// --- 注册模式 ---
	// 注册 ListProductsParams 作为 GET /products 的查询模式
	mcp.RegisterSchema("GET", "/products", ListProductsParams{}, nil)

	// 注册 CreateProductRequest 作为 POST /products 的请求体模式
	mcp.RegisterSchema("POST", "/products", nil, CreateProductRequest{})

	// 按需为其他方法/路由注册模式
	// 例如,mcp.RegisterSchema("PUT", "/products/:id", nil, UpdateProductRequest{})

	mcp.Mount("/mcp")
	r.Run(":8080")
}

解释:

  • mcp.RegisterSchema(method, path, querySchema, bodySchema)
  • method:HTTP 方法(例如,“GET”,“POST”)。
  • path:Gin 路由路径(例如,“/products”,“/products/:id”)。
  • querySchema:用于查询参数的结构体实例(或 nil 如果没有)。Gin-MCP 使用反射和 jsonschema 标签生成模式。
  • bodySchema:用于请求体的结构体实例(或 nil 如果没有)。

过滤暴露的端点

使用操作 ID 或标签控制哪些 Gin 端点成为 MCP 工具。标签来自处理器注释中的 @tags 注释(参见“标注处理器”上方)。

基于标签的过滤

标签在处理器函数注释中使用 @tags 注释指定。您可以使用空格、逗号或两者指定标签:

// listUsers 处理用户列表
// @summary 列出所有用户
// @tags public users
func listUsers(c *gin.Context) {
    // 实现...
}

// deleteUser 处理用户删除
// @summary 删除用户
// @tags admin, internal
func deleteUser(c *gin.Context) {
    // 实现...
}

过滤配置

// 仅包括特定的操作 ID
mcp := server.New(r, &server.Config{
    // ... 其他配置 ...
    IncludeOperations: []string{"GET_users", "POST_users"},
})

// 排除特定的操作 ID
mcp := server.New(r, &server.Config{
    // ... 其他配置 ...
    ExcludeOperations: []string{"DELETE_users_id"}, // 不暴露删除工具
})

// 仅包括标记为 "public" 或 "users" 的操作
// 如果工具具有指定的任何标签,则会被包括
mcp := server.New(r, &server.Config{
    // ... 其他配置 ...
    IncludeTags: []string{"public", "users"},
})

// 排除标记为 "admin" 或 "internal" 的操作
// 如果工具具有指定的任何标签,则会被排除
mcp := server.New(r, &server.Config{
    // ... 其他配置 ...
    ExcludeTags: []string{"admin", "internal"},
})

过滤规则:

  • 您只能使用一个包含过滤器(IncludeOperations IncludeTags)。
    • 如果两者都设置了,IncludeOperations 优先,并记录警告。
  • 您只能使用一个排除过滤器(ExcludeOperations ExcludeTags)。
    • 如果两者都设置了,ExcludeOperations 优先,并记录警告。
  • 您可以结合使用包含过滤器和排除过滤器(例如,包含标签 "public" 但排除操作 "legacyPublicOp")。
  • **排除总是优先:**如果一个工具同时匹配包含和排除过滤器,它将被排除。
  • **标签匹配:**如果工具具有指定的任何标签(逻辑 OR),则会被包括/排除。

示例:

// 包括所有 "public" 端点但排除也标记为 "internal" 的端点
mcp := server.New(r, &server.Config{
    IncludeTags: []string{"public"},
    ExcludeTags: []string{"internal"},
})

// 包括特定操作但排除管理员端点
mcp := server.New(r, &server.Config{
    IncludeOperations: []string{"GET_users", "GET_products"},
    ExcludeTags:       []string{"admin"},  // 这将被忽略(优先规则)
})

自定义模式描述(较少使用)

对于高级控制如何在生成的工具中描述响应模式(通常不需要):

mcp := server.New(r, &server.Config{
    // ... 其他配置 ...
    DescribeAllResponses:    true, // 在工具描述中包含所有可能的响应模式(例如,200,404)
    DescribeFullResponseSchema: true, // 包含完整的 JSON 模式对象而不是仅仅引用
})

示例

查看 示例 目录以获取演示各种功能的完整、可运行示例:

基本用法示例

代理场景的动态 BaseURL

对于每个用户/部署都有不同端点的环境(如 Quicknode 或 RAGFlow),您可以配置动态 BaseURL 解析:

// Quicknode 示例 - 解析用户特定端点
mcp := server.New(r, &server.Config{
    Name: "您的 API",
    Description: "具有动态 Quicknode 端点的 API",
    // 不需要静态 BaseURL!
})

resolver := server.NewQuicknodeResolver("http://localhost:8080")
mcp.SetExecuteToolFunc(func(operationID string, parameters map[string]interface{}) (interface{}, error) {
    return mcp.ExecuteToolWithResolver(operationID, parameters, resolver)
})

支持的环境变量:

  • QuicknodeQUICKNODE_USER_ENDPOINTUSER_ENDPOINTHOST
  • RAGFlowRAGFLOW_ENDPOINTRAGFLOW_WORKFLOW_URLRAGFLOW_BASE_URL + WORKFLOW_ID

这消除了启动时静态 BaseURL 配置的需求,非常适合多租户代理环境!

连接 MCP 客户端

一旦您的 Gin 应用程序与 Gin-MCP 正在运行:

  1. 启动您的应用程序。
  2. 在您的 MCP 客户端中,提供您挂载 MCP 服务器的位置的 URL(例如,http://localhost:8080/mcp)作为 SSE 端点:
    • Cursor:设置 → MCP → 添加服务器
    • Claude Desktop:添加到 MCP 配置文件
    • Continue:在 VS Code 设置中配置
    • Zed:添加到 MCP 设置
  3. 客户端将连接并自动发现可用的 API 工具。

贡献

欢迎贡献!请随时提交问题或拉取请求。