MCP 的核心目标是让 LLM 应用程序能够轻松集成外部系统,这在当前 AI 驱动的应用开发中非常重要。学习完本文章内容,您可以自己根据自己的业务逻辑部署对应的MCP服务,再结合AI客户端的MCP功能配置,实现项目自动化的功能。

1.基于go语言的mcp包

在go官网可以搜索到基于go语言的 MCP 包

enter image description here

  • 包地址和目录结构

    https://github.com/mark3labs/mcp-go

    目录功能描述
    examples/包含 MCP 示例实现,方便开发者参考和学习
    mcp/定义 MCP 的核心类型和接口,项目核心逻辑
    client/提供 MCP 客户端实现,负责客户端交互
    server/包含服务器相关功能,支持 MCP 服务器端逻辑

2.支持MCP的客户端

常见支持MCP的客户端软件有以下几种:
软件名称功能描述地址
5ire开源跨平台桌面AI助手,支持MCP工具github.com/nanbingxy...
Apify MCP Tester开源客户端,用于测试MCP服务器,支持SSE连接apify.com/jiri.spilk...
BeeAI FrameworkAI框架,支持MCP工具开发i-am-bee.github.io/b...
Cline轻量级AI工具,支持MCP协议github.com/cline/cli...
CursorAI增强的代码编辑器,支持通过MCP连接外部工具cursor.com
Claude Desktop AppAnthropic的桌面AI应用,支持MCP连接外部系统www.anthropic.com/cl...
Continue开源AI编码助手,支持MCP,适合构建自定义AI工作流continue.dev
Daydreams AgentsAI代理,支持MCP扩展功能github.com/daydreams...
Emacs McpEmacs插件,支持MCP客户端功能github.com/lizqwersc...
fast-agent快速AI代理框架,支持MCPgithub.com/evalstate...
GenAIScriptMicrosoft的AI脚本工具,支持MCP工具microsoft.github.io/...
GenkitFirebase的AI开发工具,支持MCPgithub.com/firebase/...
Goose开源AI代理,专注于自动化编码任务,支持MCPgithub.com/gooseai/g...
LibreChat开源AI聊天界面,支持多个AI提供商和MCP集成librechat.ai
mcp-agent简单框架,用于构建基于MCP的AI代理github.com/lastmile-...
Microsoft Copilot Studio微软的AI工作室,支持通过MCP扩展动作copilotstudio.micros...
OpenSumi开源IDE,支持MCP客户端功能opensumi.com
Roo CodeAI编码平台,支持MCP集成roocode.com
Sourcegraph CodyAI编码助手,支持MCP,优化代码上下文理解sourcegraph.com/cody
SpinAIAI开发平台,支持MCP工具spinai.dev
SuperinterfaceAI接口工具,支持MCP扩展superinterface.ai
TheiaAI/TheiaIDEEclipse的IDE,支持MCPtheia-ide.org
VS Code GitHub Copilot微软的AI编码扩展,支持MCPcopilot.github.com
Windsurf EditorCodeium的编辑器,支持MCPcodeium.com/windsurf
WitsyAI工具,支持MCP协议github.com/nbonamy/w...
Zed高性能代码编辑器,支持MCPzed.dev

3.创建一个go MCP项目demo

  • go版本

    go1.24.1

  • 环境变量

    export PATH="/usr/local/go1.24.1/bin:/usr/bin:/opt/homebrew/bin:$PATH"
    export GOPATH="$HOME/go/mcp"
    export GOPROXY=http://可以用于加载github的代理url

2.1.创建demo1 MCP操作步骤

该 mcp 可以通过输入 demo_id的值,返回不通的 x、y的值

步骤1:创建项目目录和文件

mkdir my_go_mcp
cd my_go_mcp
mkdir main
cd main
vim main.go

enter image description here

在 main.go 中输入如下内容
package main

import (
    "context"
    "errors"
    "flag"
    "fmt"

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

func main() {
    var transport string
    flag.StringVar(&transport, "t", "stdio", "Transport type (stdio or sse)")
    flag.Parse()
    // Create MCP server
    mcpServer := server.NewMCPServer(
        "Demo 🚀",
        "1.0.0",
    )

    // Add tool
    demoTool := mcp.NewTool("demoMcp",
        mcp.WithDescription("这是一个用于查询Demo信息的MCP服务"),
        mcp.WithString("demo_id",
            mcp.Required(),
            mcp.Description("可以是'demo_id','demoID','demoId'"),
        ),
    )

    mcpServer.AddTool(demoTool, demoHandler)

    if transport == "sse" {
        sseServer := server.NewSSEServer(mcpServer, server.WithBaseURL("http://localhost:8080"))
        fmt.Printf("SSE server listening on :8080\n")
        if err := sseServer.Start(":8080"); err != nil {
            fmt.Printf("Server error: %v\n", err)
        }
    } else {
        if err := server.ServeStdio(mcpServer); err != nil {
            fmt.Printf("Server error: %v\n", err)
        }
    }
}

func demoHandler(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
    demoId, ok := req.Params.Arguments["demo_id"].(string)
    if !ok {
        return nil, errors.New("demo_id must be a string")
    }

    if demoId == "100" {
        demoInfo, err := getDemo100()
        if err != nil {
            return nil, err
        }
        return mcp.NewToolResultText(fmt.Sprintf("demo 信息: %s", string(demoInfo))), nil
    }

    if demoId == "200" {
        demoInfo, err := getDemo200()
        if err != nil {
            return nil, err
        }
        return mcp.NewToolResultText(fmt.Sprintf("demo 信息: %s", string(demoInfo))), nil
    }

    return mcp.NewToolResultText(fmt.Sprintf("demo 信息: %s", "未找到")), nil
}

func getDemo100() (string, error) {
    return "x 等于 155,y 等于 255", nil
}

func getDemo200() (string, error) {
    return "x 等于 88,y 等于 99", nil
}

步骤2:加载go mod 依赖

cd my_go_mcp
go mod init my_go_mcp
go mod tidy

enter image description here

步骤3:编译MCP代码

go build -o demoMcp main.go

步骤4:运行MCP服务

  • stdio

./demoMcp

enter image description here

  • sse

./demoMcp -t sse

enter image description hereenter image description here

步骤4:配置MCP客户端

基于上述两种运行方式,以Cursor为例,两种配置方式
  • stdio

    {
      "mcpServers": {
        "mainMcp": {
          "command": "/Users/xx你的项目路径xx/go/mcp/src/my_go_mcp/main/demoMcp"
        }
      }
    }

    enter image description hereenter image description here

  • sse

这种方式可以将MCP部署到不通的web服务
{
  "mcpServers": {
    "sseMcp": {
      "name": "我的 SSE 服务器",
      "transport": "sse",
      "url": "http://localhost:8080/sse"
    }
  }
}

enter image description here

步骤5:在客户端调用MCP

在调用之前,我先说明一下demoMcp主要功能:

enter image description here
enter image description here

在cursor的聊天窗口表达意图,让大模型自动选择是否调用MCP

enter image description here

3.如何联动多个MCP功能

按照上述方法可以按照自己的业务逻辑构造不同的MCP服务,这里直接贴一个上篇文章实现的加减乘除运算 calculate.go 代码
package main

import (
    "context"
    "errors"
    "fmt"

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

func main() {
    // Create a new MCP server
    s := server.NewMCPServer(
        "Calculator Demo",
        "1.0.0",
        server.WithResourceCapabilities(true, true),
        server.WithLogging(),
        server.WithRecovery(),
    )
    // Add a calculator tool
    calculatorTool := mcp.NewTool("calculate",
        mcp.WithDescription("用于计算两个数的加减乘除"),
        mcp.WithString("operation",
            mcp.Required(),
            mcp.Description("用于计算两个数的加减乘除 (add, subtract, multiply, divide) 或 (+,-,*,/)"),
            mcp.Enum("add", "subtract", "multiply", "divide"),
        ),
        mcp.WithNumber("x",
            mcp.Required(),
            mcp.Description("参数1"),
        ),
        mcp.WithNumber("y",
            mcp.Required(),
            mcp.Description("参数2"),
        ),
    )
    // Add the calculator handler
    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 "add":
            result = x + y
        case "subtract":
            result = x - y
        case "multiply":
            result = x * y
        case "divide":
            if y == 0 {
                return nil, errors.New("Cannot divide by zero")
            }
            result = x / y
        }
        return mcp.NewToolResultText(fmt.Sprintf("%.2f", result)), nil
    })
    // Start the server
    if err := server.ServeStdio(s); err != nil {
        fmt.Printf("Server error: %v\n", err)
    }
}
编译并配置MCP,并记录calculateMcp 的路径,配置到Cusor中
go build -i calculateMcp calculate.go
{
  "mcpServers": {
    "calculateMcp": {
      "name": "计算x、y的值",
      "command": "/Users/xxxx你的项目路径/go/mcp/src/my_go_mcp/main/calculate"
    },
    "sseMcp": {
      "name": "获取x、y的值",
      "transport": "sse",
      "url": "http://localhost:8080/sse"
    }
  }
}

enter image description here

在cursor的聊天窗口表达意图,让大模型自动选择是否调用MCP

enter image description here

作者:admin  创建时间:2025-04-22 16:45
最后编辑:admin  更新时间:2025-04-25 17:35