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

相关推荐

  • JetBrains 官方正版账号,全家桶全版本全平台都可激活

    官方授权,激活你自己的JetBrains账号,1年只要66元! 平均一个月不到6块钱!(共享单车一个月都要9.9元了!) 有一个账号有什么优势? 激活您自己的专属账号(官网可查) 不限制任何版本,所有版本登录账号即可使用 不限制任何产品,无论是IDEA、DataGrip、PyCharm、WebStorm等17个工具都直接使用 不需要任何配置,登录你的账号就可…

    2024 年 6 月 22 日
    2.7K00
  • Java Dubbo 面试题

    谈谈你理解的Dubbo? Dubbo是一个高性能的Java RPC框架,它提供了服务的注册、发现、调用以及监控等功能,使得开发者可以方便地构建分布式系统和服务化架构。 服务治理:Dubbo提供了一套服务治理的解决方案,包括服务的注册、发现、负载均衡、容错和监控等。 高性能:Dubbo支持多种协议,如Dubbo协议、RMI协议、HTTP协议等,其中Dubbo协…

    未分类 2025 年 1 月 15 日
    85400
  • 永久datagrip激活码导入教程+最新破解应用

    本教程适用于 IDEA、PyCharm、DataGrip、Goland 等 JetBrains 全家桶! 话不多说,先上图:最新版已成功激活到 2099 年,爽! 下面用图文方式,手把手教你把 DataGrip 激活到 2099 年。老版本同样适用,无论 Windows、macOS 还是 Linux,我都给你准备好了。 下载 DataGrip 安装包 已安装…

    DataGrip激活码 2025 年 12 月 1 日
    26500
  • 【深度学习】Java DL4J基于 CNN 构建农作物病虫害检测模型

    🧑 博主简介:CSDN博客专家 ,历代文学网 (PC端可以访问:https://literature.sinhy.com/#/?__c=1000,移动端可微信小程序搜索“历代文学 ”)总架构师,15年工作经验,精通Java编程,高并发设计,Springboot和微服务,熟悉Linux,ESXI虚拟化以及云原生Docker和K8s,热衷于探索科技的边界,并将理…

    未分类 2025 年 1 月 10 日
    69000
  • ChatGPT Plus自己账号订阅教程新手教程

    国内用户想开通 ChatGPT Plus,常见阻碍不是注册,而是订阅付款。不想在 App 和网页之间来回切换,会让原本简单的升级变得绕。对于主要用 ChatGPT 来整理知识库条目的课程学习者,更稳的做法是适合不熟悉海外订阅的人;如果准备长期维护一个固定账号,同时希望保留完整对话历史,可以优先把会员开到自己的原账号里。

    未分类 2026 年 8 月 14 日
    5900

发表回复

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

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

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

关注微信