支持私有云部署
AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


使用Go开发MCP Server, 太简单了!

发布日期:2025-04-03 10:44:29 浏览次数: 1538 作者:鸟窝聊技术
推荐语

快速掌握Go语言开发MCP Server,从入门到实践。

核心内容:
1. Go生态中MCP库的选择与比较
2. 使用mark3labs/mcp-go库快速搭建MCP服务
3. 资源与工具的添加,实现数据暴露与LLM执行

杨芳贤
53A创始人/腾讯云(TVP)最具价值专家


不多废话,假定你已经了解了 MCP (Model Context Protocol)的背景知识。

当前 Go 生态圈有两个比较知名的开发 MCP 的库,一个是mark3labs/mcp-go[1],另一个是metoro-io/mcp-golang[2],两个使用起来都很简单,这次我们根据 star 数量选择第一个做演示。

mcp-go 入门

mark3labs/mcp-go 库提供了功能丰富的例子,而且 README 也给出了 MCP Tool 每种类型的示例。

启动服务

MCP 支持 SSE 和标准输入输出两种类型,一般我们在自己的机器上常用标准输入输出传输方式:

// Create a basic server
s := server.NewMCPServer(
    "My Server",  // Server name
    "1.0.0",     // Version
)

// Start the server using stdio
if err := server.ServeStdio(s); err != nil {
    log.Fatalf("Server error: %v", err)
}

增加资源

资源是你向 LLMs 暴露数据的方式。它们可以是任何东西:文件、API 响应、数据库查询、系统信息等。资源可以是:

  • 静态资源(固定 URI)
  • 动态资源(使用 URI 模板)

这是一个静态资源的简单示例:

// Static resource example - exposing a README file
resource := mcp.NewResource(
    "docs://readme",
    "Project README",
    mcp.WithResourceDescription("The project's README file"),
    mcp.WithMIMEType("text/markdown"),
)

// Add resource with its handler
s.AddResource(resource, func(ctx context.Context, request mcp.ReadResourceRequest) ([]mcp.ResourceContents, error) {
    content, err := os.ReadFile("README.md")
    if err != nil {
        return nil, err
    }

    return []mcp.ResourceContents{
        mcp.TextResourceContents{
            URI:      "docs://readme",
            MIMEType: "text/markdown",
            Text:     string(content),
        },
    }, nil
})

增加工具

工具让 LLM 通过你的服务器执行操作。与资源不同,工具预期会进行计算并产生副作用。它们类似于 REST API 中的 POST 端点。 下面是一个算术运算的工具示例:

calculatorTool := mcp.NewTool("calculate",
    mcp.WithDescription("Perform basic arithmetic calculations"),
    mcp.WithString("operation",
        mcp.Required(),
        mcp.Description("The arithmetic operation to perform"),
        mcp.Enum("add""subtract""multiply""divide"),
    ),
    mcp.WithNumber("x",
        mcp.Required(),
        mcp.Description("First number"),
    ),
    mcp.WithNumber("y",
        mcp.Required(),
        mcp.Description("Second number"),
    ),
)

s.AddTool(calculatorTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
    op := request.Params.Arguments["operation"].(string)
    x := request.Params.Arguments["x"].(float64)
    y := request.Params.Arguments["y"].(float64)

    var result float64
    switch op {
    case "add":
        result = x + y
    case "subtract":
        result = x - y
    case "multiply":
        result = x * y
    case "divide":
        if y == 0 {
            return nil, errors.New("Division by zero is not allowed")
        }
        result = x / y
    }

    return mcp.FormatNumberResult(result), nil
})

工具可以用于任何种类的计算:

  • Database queries   数据库查询
  • File operations   文件操作
  • External API calls   外部 API 调用
  • Calculations   计算
  • System operations   系统操作

每个工具应该:

  • 有清晰的描述
  • 验证输入
  • 优雅处理错误
  • 返回结构化的响应
  • 使用适当的结果类型

增加提示

下面是一个简单的提示词示例,它需要一个名称参数,然后返回一个问候提示词:

// Simple greeting prompt
s.AddPrompt(mcp.NewPrompt("greeting",
    mcp.WithPromptDescription("A friendly greeting prompt"),
    mcp.WithArgument("name",
        mcp.ArgumentDescription("Name of the person to greet"),
    ),
), func(ctx context.Context, request mcp.GetPromptRequest) (*mcp.GetPromptResult, error) {
    name := request.Params.Arguments["name"]
    if name == "" {
        name = "friend"
    }

    return mcp.NewGetPromptResult(
        "A friendly greeting",
        []mcp.PromptMessage{
            mcp.NewPromptMessage(
                mcp.RoleAssistant,
                mcp.NewTextContent(fmt.Sprintf("Hello, %s! How can I help you today?", name)),
            ),
        },
    ), nil
})

实战:实现一个查询 IP 地理信息的 MCP Tool

首先我们先实现这个 MCP Tool main 函数的主逻辑:

package main

import (
 "context"
 "errors"
 "fmt"
 "io"
 "net"
 "net/http"

 "github.com/kataras/golog"
 "github.com/mark3labs/mcp-go/mcp"
 "github.com/mark3labs/mcp-go/server"
)

func main() {
 // Create MCP server
 s := server.NewMCPServer(
  "ip-mcp",
  "1.0.0",
 )

 // Add tool
 tool := mcp.NewTool("ip_query",
  mcp.WithDescription("query geo location of an IP address"),
  mcp.WithString("ip",
   mcp.Required(),
   mcp.Description("IP address to query"),
  ),
 )

 // Add tool handler
 s.AddTool(tool, ipQueryHandler)

 // Start the stdio server
 if err := server.ServeStdio(s); err != nil {
  fmt.Printf("Server error: %v\n", err)
 }
}

这里我们增加了一个ip_query查询 IP 信息的工具,描述清楚它的功能是查询 IP 地址的地理位置。 这个工具需要一个参数:待查询的 IP 地址。 然后这个工具具体的实现是ipQueryHandler函数。 这个 MCP Server 使用标准输入输出传输。

接下来就是ipQueryHandler函数实现了。先前我实现了一个 IP 地址查询的网站 https://ip.rpcx.io, 所以这里我调用它的 API 进行封装就很简单了。

我将请求的数据以文本的方式返回 MCP Client。 因为这个数据是 JSON 格式,所以 MCP Client 会得到一个 JSON 格式的文本。

func ipQueryHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
 ip, ok := request.Params.Arguments["ip"].(string)
 if !ok {
  return nil, errors.New("ip must be a string")
 }

 parsedIP := net.ParseIP(ip)
 if parsedIP == nil {
  golog.Errorf("invalid IP address: %s", ip)
  return nil, errors.New("invalid IP address")
 }

 resp, err := http.Get("https://ip.rpcx.io/api/ip?ip=" + ip)
 if err != nil {
  golog.Errorf("Error fetching IP information: %v", err)
  return nil, fmt.Errorf("Error fetching IP information: %v", err)
 }
 defer resp.Body.Close()

 data, err := io.ReadAll(resp.Body)
 if err != nil {
  golog.Errorf("Error reading response body: %v", err)
  return nil, fmt.Errorf("Error reading response body: %v", err)
 }

 return mcp.NewToolResultText(string(data)), nil
}

注意检查参数的合法性,处理程序中的 error。在 2025 年的今天,这些琐碎的事都可以由代码辅助工具如 github copilot 自动完成,我们一路回车即可。

编译这个程序为可执行二进制:

你可以把这个程序放在系统目录中方便执行,也可以不放在系统目录中,后面我们配置这个 mcp server 的时候会用到它的路径。

测试 MCP Server

我们使用deepchat[3]来测试我们开发的这个 IP 查询的 MCP 工具。 deepchat 已经支持 MCP 了,而且配置起来也非常简单。

在 MCP 配置界面,我们增加一个 MCP Server,配置如下(注意:ip-mcp 工具的实际路径):

然后启动它:

这个时候你应该在对话框窗口看到运行着的 MCP Tool,包括我们的 IP 查询工具:

对话框中测试一把:

测试正常。看起来 deepchat 还会把工具的返回结果交给 deepseek 处理。

这样,我们就简单了实现了一个 MCP Server 并测试成功。可以看到我们可以对既有的 API 或者产品很快的进行封装成 MCP 工具,这也是 baidu 地图、高德地图能够很快推出 MCP Server 的原因。

53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费场景POC验证,效果验证后签署服务协议。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询