• 设为首页
  • 收藏本站
  • 积分充值
  • VIP赞助
  • 手机版
  • 微博
  • 微信
    微信公众号 添加方式:
    1:搜索微信号(888888
    2:扫描左侧二维码
  • 快捷导航
    福建二哥 门户 查看主题

    一文弄懂用Go实现MCP服务的示例代码

    发布者: 娅水9213 | 发布时间: 2025-8-14 14:33| 查看数: 27| 评论数: 0|帖子模式

    最近这段时间,AI领域里有一个非常热门的概念——MCP(模型上下文协议)。Anthropic推出的这一开放标准旨在为大型语言模型和AI助手提供统一的接口,使其能够轻松操作外部工具并完成更复杂的任务。
    本文将带你速览MCP的核心概念,并以Go语言为例,介绍如何开发MCP服务端和客户端

    为什么MCP如此重要?

    在过去,如果想要让AI处理特定的数据,通常只能依赖于预训练数据或者手动上传数据,这既麻烦又低效。即便对于强大的AI模型而言,也存在数据隔离的问题,无法直接访问新的数据源,每次更新数据都需要重新训练或上传。现在,MCP解决了这个问题,它使得AI不再局限于静态知识库,而是能够像人类一样调用搜索引擎、访问本地文件、连接API服务等,极大提升了AI的动态交互能力

    MCP总体架构

    MCP的核心是“客户端-服务器”架构,其中MCP客户端可以连接到多个服务器。客户端是指希望通过MCP访问数据的应用程序,如CLI工具、IDE插件或AI应用。


    使用mcp-go构建MCP服务端与客户端

    要开始使用Go语言构建MCP项目,首先需要安装
    1. mcp-go
    复制代码
    库,这是Go语言实现的Model Context Protocol库,支持LLM应用与外部数据源和工具之间的无缝集成。
    1. go get github.com/mark3labs/mcp-go
    复制代码
    构建MCP服务端

    接下来,我们将演示如何使用
    1. mcp-go
    复制代码
    提供的server模块来构建一个通过stdio方式连接的MCP服务器。
    创建Server对象
    1. s := server.NewMCPServer("My Server", "1.0.0")
    复制代码
    添加工具(Tools)
    例如,我们可以创建一个简单的计算器工具,这次我们实现乘法和除法功能:
    1. calculatorTool := mcp.NewTool("calculate",
    2.     mcp.WithDescription("执行基本的算术运算"),
    3.     mcp.WithString("operation",
    4.         mcp.Required(),
    5.         mcp.Description("要执行的算术运算类型"),
    6.         mcp.Enum("multiply", "divide"), // 修改为仅支持乘法和除法
    7.     ),
    8.     mcp.WithNumber("x",
    9.         mcp.Required(),
    10.         mcp.Description("第一个数字"),
    11.     ),
    12.     mcp.WithNumber("y",
    13.         mcp.Required(),
    14.         mcp.Description("第二个数字"),
    15.     ),
    16. )

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

    21.     var result float64
    22.     switch op {
    23.     case "multiply":
    24.         result = x * y
    25.     case "divide":
    26.         if y == 0 {
    27.             return nil, errors.New("不允许除以零")
    28.         }
    29.         result = x / y
    30.     }

    31.     return mcp.FormatNumberResult(result), nil
    32. })
    复制代码

    • 添加资源(Resources)
    同样地,我们也可以注册一些静态资源,比如README.md文件的内容:
    1. resource := mcp.NewResource(
    2.     "docs://readme",
    3.     "项目说明文档",
    4.     mcp.WithResourceDescription("项目的 README 文件"),
    5.     mcp.WithMIMEType("text/markdown"),
    6. )

    7. s.AddResource(resource, func(ctx context.Context, request mcp.ReadResourceRequest) ([]mcp.ResourceContents, error) {
    8.     content, err := os.ReadFile("README.md")
    9.     if err != nil {
    10.         return nil, err
    11.     }

    12.     return []mcp.ResourceContents{
    13.         mcp.TextResourceContents{
    14.             URI:      "docs://readme",
    15.             MIMEType: "text/markdown",
    16.             Text:     string(content),
    17.         },
    18.     }, nil
    19. })
    复制代码

    • 启动基于stdio传输类型的服务器
    1. if err := server.ServeStdio(s); err != nil {
    2.     fmt.Printf("Server error: %v\n", err)
    3. }
    复制代码
    以上步骤完成后,我们就成功搭建了一个基础的MCP服务器。

    构建MCP客户端

    接着,我们将展示如何使用
    1. mcp-go
    复制代码
    提供的client模块构建一个连接至上述MCP服务器的客户端。

    • 创建MCP客户端
    1. mcpClient, err := client.NewStdioMCPClient("./client/server", []string{})
    2. if err != nil {
    3.     panic(err)
    4. }
    5. defer mcpClient.Close()
    复制代码

    • 初始化客户端连接
    1. ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    2. defer cancel()

    3. initRequest := mcp.InitializeRequest{}
    4. initRequest.Params.ProtocolVersion = mcp.LATEST_PROTOCOL_VERSION
    5. initRequest.Params.ClientInfo = mcp.Implementation{
    6.     Name:    "Client Demo",
    7.     Version: "1.0.0",
    8. }

    9. initResult, err := mcpClient.Initialize(ctx, initRequest)
    10. if err != nil {
    11.     panic(err)
    12. }
    13. fmt.Printf("初始化成功,服务器信息: %s %s\n", initResult.ServerInfo.Name, initResult.ServerInfo.Version)
    复制代码

    • 调用远程工具
    最后,我们可以通过构造
    1. CallToolRequest
    复制代码
    来调用服务器上的工具,如下所示:
    1. toolRequest := mcp.CallToolRequest{
    2.     Request: mcp.Request{
    3.         Method: "tools/call",
    4.     },
    5. }
    6. toolRequest.Params.Name = "calculate"
    7. toolRequest.Params.Arguments = map[string]any{
    8.     "operation": "multiply", // 调用乘法
    9.     "x":         2,
    10.     "y":         3,
    11. }

    12. result, err := mcpClient.CallTool(ctx, toolRequest)
    13. if err != nil {
    14.     panic(err)
    15. }
    16. fmt.Println("调用工具结果:", result.Content[0].(mcp.TextContent).Text)
    复制代码
    完整代码示例

    以下是完整的代码示例,包括服务端和客户端的实现:
    服务端代码:
    1. package main

    2. import (
    3.     "context"
    4.     "errors"
    5.     "fmt"
    6.     "os"

    7.     "github.com/mark3labs/mcp-go/mcp"
    8.     "github.com/mark3labs/mcp-go/server"
    9. )

    10. func main() {
    11.     s := server.NewMCPServer("Server Demo", "1.0.0")

    12.     // 添加工具
    13.     calculatorTool := mcp.NewTool("calculate",
    14.         mcp.WithDescription("执行基本的算术运算"),
    15.         mcp.WithString("operation",
    16.             mcp.Required(),
    17.             mcp.Description("要执行的算术运算类型"),
    18.             mcp.Enum("multiply", "divide"),
    19.         ),
    20.         mcp.WithNumber("x",
    21.             mcp.Required(),
    22.             mcp.Description("第一个数字"),
    23.         ),
    24.         mcp.WithNumber("y",
    25.             mcp.Required(),
    26.             mcp.Description("第二个数字"),
    27.         ),
    28.     )

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

    33.         var result float64
    34.         switch op {
    35.         case "multiply":
    36.             result = x * y
    37.         case "divide":
    38.             if y == 0 {
    39.                 return nil, errors.New("不允许除以零")
    40.             }
    41.             result = x / y
    42.         }

    43.         return mcp.FormatNumberResult(result), nil
    44.     })

    45.     // 启动基于 stdio 的服务器
    46.     if err := server.ServeStdio(s); err != nil {
    47.         fmt.Printf("Server error: %v\n", err)
    48.     }
    49. }
    复制代码
    客户端代码:
    1. package main

    2. import (
    3.     "context"
    4.     "fmt"
    5.     "time"

    6.     "github.com/mark3labs/mcp-go/client"
    7.     "github.com/mark3labs/mcp-go/mcp"
    8. )

    9. func main() {
    10.     mcpClient, err := client.NewStdioMCPClient("./client/server", []string{})
    11.     if err != nil {
    12.         panic(err)
    13.     }
    14.     defer mcpClient.Close()

    15.     ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    16.     defer cancel()

    17.     initRequest := mcp.InitializeRequest{}
    18.     initRequest.Params.ProtocolVersion = mcp.LATEST_PROTOCOL_VERSION
    19.     initRequest.Params.ClientInfo = mcp.Implementation{
    20.         Name:    "Client Demo",
    21.         Version: "1.0.0",
    22.     }

    23.     initResult, err := mcpClient.Initialize(ctx, initRequest)
    24.     if err != nil {
    25.         panic(err)
    26.     }
    27.     fmt.Printf("初始化成功,服务器信息: %s %s\n", initResult.ServerInfo.Name, initResult.ServerInfo.Version)

    28.     // 调用工具
    29.     toolRequest := mcp.CallToolRequest{
    30.         Request: mcp.Request{
    31.             Method: "tools/call",
    32.         },
    33.     }
    34.     toolRequest.Params.Name = "calculate"
    35.     toolRequest.Params.Arguments = map[string]any{
    36.         "operation": "multiply",
    37.         "x":         2,
    38.         "y":         3,
    39.     }

    40.     result, err := mcpClient.CallTool(ctx, toolRequest)
    41.     if err != nil {
    42.         panic(err)
    43.     }
    44.     fmt.Println("调用工具结果:", result.Content[0].(mcp.TextContent).Text)
    45. }
    复制代码
    希望这篇文章能帮助你快速入门Go语言下的MCP开发!
    到此这篇关于一文弄懂用Go实现MCP服务的示例代码的文章就介绍到这了,更多相关Go MCP服务内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    来源:互联网
    免责声明:如果侵犯了您的权益,请联系站长(1277306191@qq.com),我们会及时删除侵权内容,谢谢合作!

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    ×

    最新评论

    浏览过的版块

    QQ Archiver 手机版 小黑屋 福建二哥 ( 闽ICP备2022004717号|闽公网安备35052402000345号 )

    Powered by Discuz! X3.5 © 2001-2023

    快速回复 返回顶部 返回列表