轻松掌握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 日

相关推荐

  • 🚀 2025最新PyCharm永久激活教程|亲测可用至2099年(附激活码+破解补丁)

    还在为PyCharm的试用期到期而烦恼吗?😫 今天给大家带来一个超级实用的教程,手把手教你如何将PyCharm破解至2099年!这个方法适用于JetBrains全家桶(IDEA、PyCharm、DataGrip、Goland等),无论你是Windows、Mac还是Linux系统,统统都能搞定!💪 先看看成功破解后的效果吧~👇 🔍 准备工作 1. 下载PyCh…

    2025 年 6 月 2 日
    83700
  • Python在多个Excel文件中找出缺失数据行数多的文件

    本文介绍基于Python 语言,针对一个文件夹 下大量的Excel 表格文件,基于其中每一个文件 内、某一列数据 的特征,对其加以筛选,并将符合要求 与不符合要求 的文件分别复制到另外两个新的文件夹 中的方法。 首先,我们来明确一下本文的具体需求。现有一个文件夹,其中有大量的Excel 表格文件(在本文中我们就以csv格式的文件为例);如下图所示。 其中,每…

    2025 年 1 月 12 日
    41500
  • 2025年PyCharm破解详解:最新激活码获取与永久激活教程

    PyCharm是目前最流行的Python IDE之一,由JetBrains公司开发,拥有强大的代码分析、调试和自动补全功能。虽然社区版是免费的,但许多高级功能仅在专业版中提供。今天,我将为大家分享如何在2025年永久激活PyCharm专业版,让你可以使用所有高级功能。 首先展示一下激活成功的效果,如下图所示,激活有效期直到2099年,这足以支持我们长期使用了…

    PyCharm破解教程 2025 年 4 月 28 日
    95900
  • Java中的IP协议(如果想知道Java中有关IP协议的知识,那么只看这一篇就足够了!)

    前言:在当今高度信息化的社会中,互联网已经深刻影响了人类的生活方式和交流方式,从电子邮件的收发到视频会议的举行,从社交媒体的互动到云计算的广泛应用,这一切的背后都离不开网络通信协议的支持。 ✨✨ ✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSDN博客 在正式开始讲解之前,先让我们看一下本文大致的讲解内容: 目录 1.…

    未分类 2025 年 5 月 12 日
    16500
  • 促销系统:促销活动、优惠券、优惠规则概念模型设计

    大家好,我是汤师爷~ 概念模型设计是促销系统开发的关键环节,我们需要基于之前的功能分析,将复杂的促销业务拆解成清晰的领域概念,这些概念之间的关系界定和边界划分,将直接决定系统的可维护性和扩展性。 促销系统核心概念模型 通过对促销业务的分析,我们可以抽象出促销系统的关键概念模型。 1、促销活动模型 促销活动模型对活动的各个要素和规则进行抽象,包含活动名称、描述…

    2025 年 1 月 13 日
    51500

发表回复

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

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

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

关注微信