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

相关推荐

  • 全网通用clion激活码获取方式与权威clion破解教程

    申明:本教程Clion破解补丁、激活码均收集于网络,请勿商用,仅供个人学习使用,如有侵权,请联系作者删除。若条件允许,希望大家购买正版 ! 废话不多说,先上 Clion2025.2.1 版本破解成功的截图,如下图,可以看到已经成功破解到 2099 年辣,舒服的很! 接下来就给大家通过图文的方式分享一下如何破解最新的Clion。 准备工作 注意:如果你之前用过…

    2025 年 12 月 28 日
    4200
  • 🔥2025最新PyCharm永久激活码分享 | 亲测可用至2099年(附详细破解教程)

    还在为PyCharm激活问题发愁?😫 本教程将手把手教你如何永久激活PyCharm至2099年!适用于所有JetBrains全家桶(IDEA、PyCharm、DataGrip、Goland等),Windows/Mac/Linux全平台通用!💪 先上最新PyCharm 2024.3.5版本破解成功截图,有效期直达2099年!🎉 📥 第一步:下载PyCharm安…

    2025 年 5 月 12 日
    1.8K00
  • IntelliJ IDEA 2025.3 破解直接用

    IDEA 2024最新破解教程 永久激活至2099年(亲测有效) 本方法通用于IDEA、PyCharm、DataGrip、Goland等JetBrains系列软件! 先展示最新版IDEA破解成功的界面截图,如图所示,许可证有效期至2099年,非常稳定! 接下来,我将通过图文结合的方式,手把手教你如何将IDEA激活到2099年。 当然,这个激活方案同样适用于历…

    IDEA破解教程 2025 年 12 月 25 日
    58900
  • 无需账号注册的webstorm激活码免费领取与破解教程

    WebStorm 破解教程:2025最新永久激活方法(附破解补丁和激活码) 声明:本教程所涉及的 WebStorm 破解补丁与激活码均来源于网络收集,严禁用于商业用途,仅限个人学习研究使用。若涉及侵权问题,请联系作者进行删除。经济条件允许的情况下,强烈建议购买官方正版授权! WebStorm 是 JetBrains 公司推出的一款功能强大的开发编辑器,支持 …

    2026 年 1 月 12 日
    2700
  • JavaScript获取URL参数常见的4种方法

    🚀 个人简介:某大型国企资深软件开发工程师,信息系统项目管理师、CSDN优质创作者、阿里云专家博主,华为云云享专家,分享前端后端相关技术与工作常见问题~ 💟 作 者:码喽的自我修养🥰 📝 专 栏:JavaScript深入研究 🎉 🌈 创作不易,如果能帮助到带大家,欢迎 收藏+关注 哦💕 在前端开发中,处理URL参数是一个常见的任务,尤其是在没有框架支持的情况…

    2025 年 1 月 6 日
    40900

发表回复

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

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

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

关注微信