MCP Go 🚀

MCP Go 🚀

模型上下文协议(MCP)的Go语言实现,能够使LLM应用程序与外部数据源和工具无缝集成。

简介

MCP-Go 是模型上下文协议(Model Context Protocol)的 Go 语言实现,能使 LLM 应用程序与外部数据源和工具无缝集成。

Build Go Report Card GoDoc

🚨 MCP-Go 及 MCP 规范正在积极开发中,核心功能可用,但部分高级功能仍在开发中。

安装

go get github.com/mark3labs/mcp-go

基本用法

创建简单的 MCP 工具

package main

import (
    "context"
    "errors"
    "fmt"

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

func main() {
    // 创建 MCP 服务器
    s := server.NewMCPServer(
        "Demo 🚀",
        "1.0.0",
    )

    // 添加工具
    tool := mcp.NewTool("hello_world",
        mcp.WithDescription("向某人问好"),
        mcp.WithString("name",
            mcp.Required(),
            mcp.Description("要问候的人的名字"),
        ),
    )

    // 添加工具处理函数
    s.AddTool(tool, helloHandler)

    // 启动 stdio 服务器
    if err := server.ServeStdio(s); err != nil {
        fmt.Printf("服务器错误: %v\n", err)
    }
}

func helloHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
    name, ok := request.Params.Arguments["name"].(string)
    if !ok {
        return nil, errors.New("名字必须是字符串")
    }

    return mcp.NewToolResultText(fmt.Sprintf("你好, %s!", name)), nil
}

创建计算器示例

// 添加一个计算器工具
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("第一个数字"),
    ),
    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 "add":
        result = x + y
    case "subtract":
        result = x - y
    case "multiply":
        result = x * y
    case "divide":
        if y == 0 {
            return nil, errors.New("不能除以零")
        }
        result = x / y
    }

    return mcp.NewToolResultText(fmt.Sprintf("%.2f", result)), nil
})

资源示例

静态资源

// 静态资源示例 - 暴露 README 文件
resource := mcp.NewResource(
    "docs://readme",
    "项目 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
})

动态资源

// 动态资源示例 - 通过 ID 获取用户资料
template := mcp.NewResourceTemplate(
    "users://{id}/profile",
    "用户资料",
    mcp.WithTemplateDescription("返回用户资料信息"),
    mcp.WithTemplateMIMEType("application/json"),
)

// 添加模板及其处理函数
s.AddResourceTemplate(template, func(ctx context.Context, request mcp.ReadResourceRequest) ([]mcp.ResourceContents, error) {
    // 从 URI 中提取 ID
    userID := extractIDFromURI(request.Params.URI)
    
    profile, err := getUserProfile(userID)
    if err != nil {
        return nil, err
    }
    
    return []mcp.ResourceContents{
        mcp.TextResourceContents{
            URI:      request.Params.URI,
            MIMEType: "application/json",
            Text:     profile,
        },
    }, nil
})

服务器选项

// 创建带有选项的 MCP 服务器
s := server.NewMCPServer(
    "Calculator Demo",
    "1.0.0",
    server.WithResourceCapabilities(true, true),  // 启用资源功能
    server.WithLogging(),  // 启用日志
)

查看更多信息请访问 MCP 官方网站GitHub 仓库