轻松掌握Go语言实现MCP服务

快速上手用Go语言搭建MCP服务

近期,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项目,首先得安装mcp-go库,它是Go语言实现的Model Context Protocol库,能支持LLM应用与外部数据源及工具的无缝集成。执行命令go get github.com/mark3labs/mcp-go进行安装。

构建MCP服务端

接下来演示如何用mcp-go提供的server模块构建一个通过stdio方式连接的MCP服务器。

  1. 创建Server对象
s := server.NewMCPServer("My Server", "1.0.0")
  1. 添加工具(Tools)

比如创建一个简单的计算器工具,实现乘法和除法功能:

calculatorTool := mcp.NewTool("calculate",
    mcp.WithDescription("执行基本的算术运算"),
    mcp.WithString("operation",
        mcp.Required(),
        mcp.Description("要执行的算术运算类型"),
        mcp.Enum("multiply", "divide"), // 仅支持乘法和除法
    ),
    mcp.WithNumber("x",
        mcp.Required(),
        mcp.Description("第一个数字"),
    ),
    mcp.WithNumber("y",
        mcp.Required(),
        mcp.Description("第二个数字"),
    ),
)

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 "multiply":
        result = x * y
    case "divide":
        if y == 0 {
            return nil, errors.New("不允许除以零")
        }
        result = x / y
    }

    return mcp.FormatNumberResult(result), nil
})
  1. 添加资源(Resources)

注册静态资源,比如README.md文件的内容:

resource := mcp.NewResource(
    "docs://readme",
    "项目说明文档",
    mcp.WithResourceDescription("项目的 README 文件"),
    mcp.WithMIMEType("text/markdown"),
)

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
})
  1. 启动基于stdio传输类型的服务器
if err := server.ServeStdio(s); err != nil {
    fmt.Printf("Server error: %v\n", err)
}

完成以上步骤,就成功搭建了一个基础的MCP服务器。

构建MCP客户端

接着展示如何用mcp-go提供的client模块构建连接上述MCP服务器的客户端。

  1. 创建MCP客户端
mcpClient, err := client.NewStdioMCPClient("./client/server", []string{})
if err != nil {
    panic(err)
}
defer mcpClient.Close()
  1. 初始化客户端连接
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

initRequest := mcp.InitializeRequest{}
initRequest.Params.ProtocolVersion = mcp.LATEST_PROTOCOL_VERSION
initRequest.Params.ClientInfo = mcp.Implementation{
    Name:    "Client Demo",
    Version: "1.0.0",
}

initResult, err := mcpClient.Initialize(ctx, initRequest)
if err != nil {
    panic(err)
}
fmt.Printf("初始化成功,服务器信息: %s %s\n", initResult.ServerInfo.Name, initResult.ServerInfo.Version)
  1. 调用远程工具

通过构造CallToolRequest调用服务器上的工具:

toolRequest := mcp.CallToolRequest{
    Request: mcp.Request{
        Method: "tools/call",
    },
}
toolRequest.Params.Name = "calculate"
toolRequest.Params.Arguments = map[string]any{
    "operation": "multiply", // 调用乘法
    "x":         2,
    "y":         3,
}

result, err := mcpClient.CallTool(ctx, toolRequest)
if err != nil {
    panic(err)
}
fmt.Println("调用工具结果:", result.Content[0].(mcp.TextContent).Text)

完整代码示例

以下是服务端和客户端的完整实现代码:

服务端代码:

package main

import (
    "context"
    "errors"
    "fmt"
    "os"

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

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

    // 添加工具
    calculatorTool := mcp.NewTool("calculate",
        mcp.WithDescription("执行基本的算术运算"),
        mcp.WithString("operation",
            mcp.Required(),
            mcp.Description("要执行的算术运算类型"),
            mcp.Enum("multiply", "divide"),
        ),
        mcp.WithNumber("x",
            mcp.Required(),
            mcp.Description("第一个数字"),
        ),
        mcp.WithNumber("y",
            mcp.Required(),
            mcp.Description("第二个数字"),
        ),
    )

    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 "multiply":
            result = x * y
        case "divide":
            if y == 0 {
                return nil, errors.New("不允许除以零")
            }
            result = x / y
        }

        return mcp.FormatNumberResult(result), nil
    })

    // 启动基于 stdio 的服务器
    if err := server.ServeStdio(s); err != nil {
        fmt.Printf("Server error: %v\n", err)
    }
}

客户端代码:

package main

import (
    "context"
    "fmt"
    "time"

    "github.com/mark3labs/mcp-go/client"
    "github.com/mark3labs/mcp-go/mcp"
)

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

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

    initRequest := mcp.InitializeRequest{}
    initRequest.Params.ProtocolVersion = mcp.LATEST_PROTOCOL_VERSION
    initRequest.Params.ClientInfo = mcp.Implementation{
        Name:    "Client Demo",
        Version: "1.0.0",
    }

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

    // 调用工具
    toolRequest := mcp.CallToolRequest{
        Request: mcp.Request{
            Method: "tools/call",
        },
    }
    toolRequest.Params.Name = "calculate"
    toolRequest.Params.Arguments = map[string]any{
        "operation": "multiply",
        "x":         2,
        "y":         3,
    }

    result, err := mcpClient.CallTool(ctx, toolRequest)
    if err != nil {
        panic(err)
    }
    fmt.Println("调用工具结果:", result.Content[0].(mcp.TextContent).Text)
}

希望本文能助力你快速开启Go语言下的MCP开发之旅!

文章整理自互联网,只做测试使用。发布者:Lomu,转转请注明出处:https://www.it1024doc.com/12794.html

(0)
LomuLomu
上一篇 2025 年 7 月 7 日
下一篇 2025 年 7 月 7 日

相关推荐

  • 2024 WebStorm最新激活码,WebStorm永久免费激活码2025-02-07 更新

    WebStorm 2024最新激活码 以下是最新的WebStorm激活码,更新时间:2025-02-07 🔑 激活码使用说明 1️⃣ 复制下方激活码 2️⃣ 打开 WebStorm 软件 3️⃣ 在菜单栏中选择 Help -> Register 4️⃣ 选择 Activation Code 5️⃣ 粘贴激活码,点击 Activate ⚠️ 必看!必看! 🔥 …

    2025 年 2 月 7 日
    40300
  • 华为OD机试E卷 –过滤组合字符串–24年OD统一考试(Java & JS & Python & C & C++)

    文章目录 题目描述 输入描述 输出描述 用例 题目解析 JS算法源码 Java算法源码 python算法源码 c算法源码 c++算法源码 题目描述 数字 0、1、2、3、4、5、6、7、8、9 分别关联 a~z 26 个英文字母。 0 关联“a””b””c 1 关联“d””e””f 2 关联“g”“h”“i” 3 关联“j”,”k”l” 4 关联“m””n”…

    未分类 2025 年 1 月 21 日
    59800
  • 2024 WebStorm最新激活码,WebStorm永久免费激活码2025-02-15 更新

    WebStorm 2024最新激活码 以下是最新的WebStorm激活码,更新时间:2025-02-15 🔑 激活码使用说明 1️⃣ 复制下方激活码 2️⃣ 打开 WebStorm 软件 3️⃣ 在菜单栏中选择 Help -> Register 4️⃣ 选择 Activation Code 5️⃣ 粘贴激活码,点击 Activate ⚠️ 必看!必看! 🔥 …

    2025 年 2 月 15 日
    81600
  • 2025年最新DataGrip激活码及永久破解教程(支持2099年)

    JetBrains系列工具(包括IDEA、PyCharm、DataGrip等)的破解方法一直备受开发者关注。本文将详细介绍如何获取最新DataGrip激活码并完成永久破解,让你的开发工具有效期延长至2099年! 破解效果预览 先来看看破解成功后的效果截图,可以看到许可证有效期已成功延长至2099年: 本教程适用于所有主流操作系统,无论你使用的是哪个版本的Da…

    2025 年 5 月 10 日
    21800
  • DataGrip永久激活码,破解教程,2024年最新DataGrip激活教程

    本教程适用于DataGrip、PyCharm、DataGrip、Goland等,支持Jetbrains全家桶! 废话不多说,先给大家看一下最新DataGrip版本的破解截图,可以看到已经成功破解至2099年,激活效果非常好! 接下来,我会通过图文方式,详细讲解如何激活DataGrip至2099年。 无论你使用的是Windows、Mac还是Linux系统,无论…

    2025 年 4 月 17 日
    47800

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信