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

相关推荐

  • Apache IoTDB Docker部署:单机至集群全场景实战指导

    引言 当下,高效存储与管理大量时序数据成为企业进行数字化转型的关键所在。Apache IoTDB是一款专为物联网场景打造的时序数据库,它凭借高性能、轻量级以及生态集成能力,在工业监测、智慧城市、智能农业等诸多领域有着广泛应用。本文将会深入剖析IoTDB的核心特性,并且详细讲解单机版和集群版在Docker环境下的部署实践。 关于虚拟机测试节点的单机版和集群版安…

    2025 年 9 月 18 日
    25900
  • 思维导图xmind如何安装?附安装包

    前言 大家好,我是小徐啊。我们在Java开发中,有时候是需要用到思维导图的,这可以帮助我们更好的理清思路,提高开发的效率。而说到思维导图,最有名的就是xmind了,它的功能十分强大,几乎是思维导图里面最强大的那一个。但是,默认只能使用初级功能,高级功能需要额外再开通,今天小徐就来介绍下如何安装xmind以及升级,让我们可以使用pro的功能。文末附获取方式。 …

    2025 年 1 月 13 日
    56700
  • 永久datagrip激活码配置视频+最新破解演示

    申明:本教程 DataGrip破解补丁、激活码均收集于网络,请勿商用,仅供个人学习使用,如有侵权,请联系作者删除。若条件允许,希望大家购买正版 ! DataGrip是 JetBrains 推出的开发编辑器,功能强大,适用于 Windows、Mac 和 Linux 系统。本文将详细介绍如何通过破解补丁实现永久激活,解锁所有高级功能。 如果觉得破解麻烦,可以购买…

    DataGrip激活码 2025 年 12 月 22 日
    28100
  • 2026国内ChatGPT Plus充值开通攻略

    现在用ChatGPT,开不开Plus的体验差距真的非常大。开通Plus后,不仅响应速度更快、基本不用排队,还能第一时间用上最新模型,加上代码解释、文件分析等专属功能,早已不只是普通聊天工具,更像一个全能生产力助手。但问题摆在国内用户面前:在国内怎么付款开通ChatGPT Plus? 如果想用国内信用卡直接支付,哪怕是Visa/Mastercard,大概率也会…

    ChatGPT 2026 年 4 月 7 日
    17600
  • 最新IDEA激活码和永久IDEA激活码哪个好

    免责声明:本文所提及的 IntelliJ IDEA 破解补丁与激活码均来源于互联网公开渠道,仅供个人学习研究,禁止任何商业用途。若条件允许,请支持正版!如有侵权,请联系作者删除。 话不多说,先放一张 2025.2.1 版 IDEA 成功激活到 2099 年的截图镇楼,看着就舒坦! 下面用图文形式手把手演示如何给最新版 IDEA 打上“永久”补丁。 嫌折腾?直…

    IDEA破解教程 2025 年 11 月 28 日
    19800

发表回复

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

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

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

关注微信