mcp-go

GitHub
8.5k 806 简单 1 次阅读 今天MIT语言模型开发框架Agent
AI 解读 由 AI 自动生成,仅供参考

mcp-go 是模型上下文协议(MCP)的 Go 语言实现,旨在帮助开发者轻松构建能够连接大语言模型(LLM)与外部数据源及工具的服务端应用。它解决了大模型应用难以安全、标准化地调用本地资源或第三方服务的痛点,让 AI 不仅能“对话”,还能真正“做事”,如执行计算、查询数据库或操作文件。

这款工具特别适合熟悉 Go 语言的后端开发者及 AI 应用工程师使用。通过提供高层级的抽象接口,mcp-go 屏蔽了底层复杂的协议交互细节,用户只需关注业务逻辑即可快速定义工具、资源和提示词。其代码简洁优雅,无需大量样板代码就能启动一个标准的 MCP 服务器,显著提升了开发效率。

技术亮点方面,mcp-go 不仅完整覆盖了 MCP 核心规范,还支持灵活的会话管理、工具过滤及中间件机制,允许开发者针对不同会话动态调整可用工具。尽管项目仍处于活跃开发阶段,但其稳定的核心功能已能胜任大多数集成场景。如果你希望用 Go 语言为大模型赋予强大的外部扩展能力,mcp-go 是一个值得尝试的开源选择。

使用场景

某金融科技公司后端团队正在构建一个智能运维助手,需要让大模型实时读取内部监控数据库并执行重启服务等高危操作。

没有 mcp-go 时

  • 协议实现繁琐:开发人员需手动解析复杂的 JSON-RPC 消息格式,编写大量样板代码来处理握手、心跳和错误重试,分散了业务逻辑精力。
  • 上下文割裂严重:大模型无法直接调用现有的 Go 语言监控库,必须额外开发中间 HTTP 服务进行数据转发,增加了架构复杂度和延迟。
  • 类型安全缺失:在传递工具参数时缺乏编译期检查,经常因字段名拼写错误或类型不匹配导致运行时崩溃,排查困难。
  • 会话管理混乱:难以追踪不同用户会话的工具调用状态,无法灵活控制特定会话的权限或过滤敏感工具,存在安全隐患。

使用 mcp-go 后

  • 开发极速聚焦:利用 mcp-go 的高级接口,仅需几行代码即可定义“查询库存”或“重启服务”工具,自动处理底层协议细节,开发效率提升数倍。
  • 原生无缝集成:直接在 Go 项目中引入内部监控 SDK 作为工具处理器,大模型通过标准 MCP 协议即可安全调用本地函数,无需额外网关。
  • 强类型保障:借助 Go 的静态类型系统和 mcp-go 的参数校验机制(如 RequireString),在编译阶段即可发现参数定义错误,运行更稳定。
  • 精细会话控制:内置的会话管理和中间件功能,轻松实现基于用户角色的工具过滤和上下文隔离,确保高危操作仅限授权会话执行。

mcp-go 将复杂的协议交互转化为简单的 Go 函数调用,让开发者能专注于构建强大的 AI 业务能力而非通信基础设施。

运行环境要求

GPU

未说明

内存

未说明

依赖
notes该工具是基于 Go 语言开发的 Model Context Protocol (MCP) 实现,非 Python 项目。运行环境需安装 Go 语言开发套件(README 未指定具体 Go 版本,通常建议使用最新稳定版)。通过 'go get' 命令安装依赖。支持 stdio 传输方式,用于构建 LLM 应用与外部数据源之间的集成服务。
python不适用
github.com/mark3labs/mcp-go
mcp-go hero image

快速开始

MCP Go Logo

构建 Go Report Card GoDoc

AgentRank Model Context Protocol (MCP) 的 Go 语言实现,可实现 LLM 应用程序与外部数据源和工具之间的无缝集成。


教程


Discord 上讨论该 SDK

package main

import (
    "context"
    "fmt"

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

func main() {
    // 创建一个新的 MCP 服务器
    s := server.NewMCPServer(
        "演示 🚀",
        "1.0.0",
        server.WithToolCapabilities(false),
    )

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

    // 添加工具处理程序
    s.AddTool(tool, helloHandler)

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

func helloHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
    name, err := request.RequireString("name")
    if err != nil {
        return mcp.NewToolResultError(err.Error()), nil
    }

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

就是这样!

MCP Go 负责处理所有复杂的协议细节和服务器管理,因此您可以专注于构建优秀的工具。它的目标是提供高层次且易于使用的接口。

主要特性:

  • 快速:高层次接口意味着更少的代码和更快的开发速度
  • 简单:只需最少的样板代码即可构建 MCP 服务器
  • 完整*:MCP Go 致力于提供对核心 MCP 规范的完整实现

(*强调“致力于”)

🚨 🚧 🏗️ MCP Go 和 MCP 规范本身目前仍在积极开发中。核心功能已经可用,但一些高级功能仍在开发中。

目录

安装

go get github.com/mark3labs/mcp-go

快速入门

让我们创建一个简单的 MCP 服务器,公开一个计算器工具和一些数据:

package main

import (
    "context"
    "fmt"

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

func main() {
    // 创建一个新的 MCP 服务器
    s := server.NewMCPServer(
        "计算器演示",
        "1.0.0",
        server.WithToolCapabilities(false),
        server.WithRecovery(),
    )

    // 添加一个计算器工具
    calculatorTool := mcp.NewTool("calculate",
        mcp.WithDescription("执行基本的算术运算"),
        mcp.WithString("operation",
            mcp.Required(),
            mcp.Description("要执行的操作(加、减、乘、除)"),
            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, err := request RequireString("operation")
        if err != nil {
            return mcp.NewToolResultError(err.Error()), nil
        }
        
        x, err := request RequireFloat("x")
        if err != nil {
            return mcp.NewToolResultError(err.Error()), nil
        }
        
        y, err := request RequireFloat("y")
        if err != nil {
            return mcp.NewToolResultError(err.Error()), nil
        }

        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 mcp.NewToolResultError("不能除以零"), nil
            }
            result = x / y
        }

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

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

什么是 MCP?

Model Context Protocol (MCP) 允许您构建以安全、标准化的方式向 LLM 应用程序公开数据和功能的服务器。可以把它想象成一个 Web API,但它专为 LLM 交互而设计。

MCP 服务器可以:

  • 通过 资源 公开数据(可以将其视为 GET 端点;用于将信息加载到 LLM 的上下文中)
  • 通过 工具 提供功能(类似于 POST 端点;用于执行代码或产生其他副作用)
  • 通过 提示 定义交互模式(LLM 交互的可重用模板)
  • 以及更多!

mcp-go 实现了 Model Context Protocol 规范版本 2025-11-25,并向后兼容 2025-06-18、2025-03-26 和 2024-11-05 版本。

核心概念

服务器

显示服务器示例

服务器是您与 MCP 协议的核心接口。它负责连接管理、协议合规性和消息路由:

// 创建一个基础服务器
s := server.NewMCPServer(
    "我的服务器",  // 服务器名称
    "1.0.0",     // 版本
)

// 使用标准输入输出启动服务器
if err := server.ServeStdio(s); err != nil {
    log.Fatalf("服务器错误: %v", err)
}

资源

显示资源示例 资源是您向 LLM 公开数据的方式。它们可以是任何内容——文件、API 响应、数据库查询、系统信息等。资源可以分为:
  • 静态(固定 URI)
  • 动态(使用 URI 模板)

以下是一个静态资源的简单示例:

// 静态资源示例 - 公开 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
    // 服务器会自动将 URI 匹配到模板
    userID := extractIDFromURI(request.Params.URI)
    
    profile, err := getUserProfile(userID)  // 您的数据库/API 调用在此处
    if err != nil {
        return nil, err
    }
    
    return []mcp.ResourceContents{
        mcp.TextResourceContents{
            URI:      request.Params.URI,
            MIMEType: "application/json",
            Text:     profile,
        },
    }, nil
})

这些示例虽然简单,但展示了核心概念。资源可以更加复杂——提供多种内容、集成数据库或外部 API 等。

工具

显示工具示例

工具允许 LLM 通过您的服务器执行操作。与资源不同,工具通常用于执行计算并产生副作用。它们类似于 REST API 中的 POST 端点。

任务增强型工具

任务增强型工具以异步方式执行,并通过轮询获取结果。这对于长时间运行的操作非常有用,否则可能会导致阻塞或超时。任务工具支持三种模式:

  • TaskSupportForbidden(默认):该工具不能作为任务调用
  • TaskSupportOptional:该工具既可以作为任务调用,也可以同步调用
  • TaskSupportRequired:该工具必须作为任务调用
// 示例:需要任务执行的工具
processBatchTool := mcp.NewTool("process_batch",
    mcp.WithDescription("异步处理一批项目"),
    mcp.WithTaskSupport(mcp.TaskSupportRequired),
    mcp.WithArray("items",
        mcp.Description("待处理的项目列表"),
        mcp.WithStringItems(),
        mcp.Required(),
    ),
)

// 任务工具处理器返回 CreateTaskResult 而不是 CallToolResult
s.AddTaskTool(processBatchTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CreateTaskResult, error) {
    items := request.GetStringSlice("items", []string{})
    
    // 长时间运行的工作在此处
    for i, item := range items {
        select {
        case <-ctx.Done():
            // 任务被取消
            return nil, ctx.Err()
        default:
            // 处理项目...
            processItem(item)
        }
    }
    
    // 返回结果——任务 ID 和元数据由服务器管理
    return &mcp.CreateTaskResult{
        Task: mcp.Task{
            // 任务字段(ID、状态等)由服务器填充
        },
    }, nil
})

// 在创建服务器时启用任务功能
s := server.NewMCPServer(
    "任务服务器",
    "1.0.0",
    server.WithTaskCapabilities(
        true, // listTasks:允许客户端列出所有任务
        true, // cancel:允许客户端取消正在运行的任务
        true, // toolCallTasks:为工具启用任务增强功能
    ),
    server.WithMaxConcurrentTasks(10), // 可选:限制同时运行的任务数量
)

任务执行流程:

  1. 客户端调用工具并指定任务参数
  2. 服务器立即返回任务 ID
  3. 工具在后台异步执行
  4. 客户端轮询 tasks/result 来获取结果
  5. 服务器在任务完成时发送状态通知

对于可选任务工具,同一工具既可以同步调用(不带任务参数),也可以异步调用(带任务参数):

// 具有可选任务支持的工具
analyzeTool := mcp.NewTool("analyze_data",
    mcp.WithDescription("分析数据——可同步或异步执行"),
    mcp.WithTaskSupport(mcp.TaskSupportOptional),
    mcp.WithString("data", mcp.Required()),
)

// 对于支持两种模式的混合工具,使用 AddTaskTool
s.AddTaskTool(analyzeTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CreateTaskResult, error) {
    // 当作为任务调用时,此处理器运行
    data := request.GetString("data", "")
    result := analyzeData(data)
    
    return &mcp.CreateTaskResult{
        Task: mcp.Task{},
    }, nil
})

// 服务器会自动处理同步和异步调用
// 不带任务参数时:直接执行处理器并立即返回结果
// 带任务参数时:异步执行处理器
限制并发任务数

为防止资源耗尽,您可以限制同时运行的任务数量:

s := server.NewMCPServer(
    "任务服务器",
    "1.0.0",
    server.WithTaskCapabilities(true, true, true),
    server.WithMaxConcurrentTasks(10), // 允许最多 10 个并发任务
)

当达到限制时,新的任务创建请求将失败并返回错误。已完成、失败或已取消的任务不计入限制——只有处于“进行中”状态的任务才会被计算在内。如果未指定 WithMaxConcurrentTasks 或将其设置为 0,则没有并发任务限制。

对于传统的同步工具,它们会立即执行并返回结果:

简单的计算示例:

calculatorTool := mcp.NewTool("calculate",
    mcp.WithDescription("执行基本的算术计算"),
    mcp.WithString("operation",
        mcp.Required(),
        mcp.Description("要执行的算术运算"),
        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) {
    args := request.GetArguments()
    op := args["operation"].(string)
    x := args["x"].(float64)
    y := args["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 mcp.NewToolResultError("不能除以零"), nil
        }
        result = x / y
    }
    
    return mcp.FormatNumberResult(result), nil
})

HTTP 请求示例:

httpTool := mcp.NewTool("http_request",
    mcp.WithDescription("向外部 API 发送 HTTP 请求"),
    mcp.WithString("method",
        mcp.Required(),
        mcp.Description("要使用的 HTTP 方法"),
        mcp.Enum("GET", "POST", "PUT", "DELETE"),
    ),
    mcp.WithString("url",
        mcp.Required(),
        mcp.Description("发送请求的 URL"),
        mcp.Pattern("^https?://.*"),
    ),
    mcp.WithString("body",
        mcp.Description("请求体(用于 POST/PUT)"),
    ),
)

s.AddTool(httpTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
    args := request.GetArguments()
    method := args["method"].(string)
    url := args["url"].(string)
    body := ""
    if b, ok := args["body"].(string); ok {
        body = b
    }

    // 创建并发送请求
    var req *http.Request
    var err error
    if body != "" {
        req, err = http.NewRequest(method, url, strings.NewReader(body))
    } else {
        req, err = http.NewRequest(method, url, nil)
    }
    if err != nil {
        return mcp.NewToolResultErrorFromErr("无法创建请求", err), nil
    }

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return mcp.NewToolResultErrorFromErr("无法执行请求", err), nil
    }
    defer resp.Body.Close()

    // 返回响应
    respBody, err := io.ReadAll(resp.Body)
    if err != nil {
        return mcp.NewToolResultErrorFromErr("无法读取请求响应", err), nil
    }

    return mcp.NewToolResultText(fmt.Sprintf("状态: %d\n正文: %s", resp.StatusCode, string(respBody))), nil
})

工具可用于任何类型的计算或副作用:

  • 数据库查询
  • 文件操作
  • 外部 API 调用
  • 计算
  • 系统操作

每个工具应:

  • 具有清晰的描述
  • 验证输入
  • 妥善处理错误
  • 返回结构化响应
  • 使用适当的结果类型

提示词

显示提示词示例

提示词是可重用的模板,可帮助大模型有效地与您的服务器交互。它们就像是编码到您服务器中的“最佳实践”。以下是一些示例:

// 简单的问候提示词
s.AddPrompt(mcp.NewPrompt("greeting",
    mcp.WithPromptDescription("友好的问候提示词"),
    mcp.WithArgument("name",
        mcp.ArgumentDescription("要问候的人的名字"),
    ),
), func(ctx context.Context, request mcp.GetPromptRequest) (*mcp.GetPromptResult, error) {
    name := request.Params.Arguments["name"]
    if name == "" {
        name = "朋友"
    }
    
    return mcp.NewGetPromptResult(
        "友好的问候",
        []mcp.PromptMessage{
            mcp.NewPromptMessage(
                mcp.RoleAssistant,
                mcp.NewTextContent(fmt.Sprintf("你好,%s!今天有什么可以帮你的吗?", name)),
            ),
        },
    ), nil
})

// 带嵌入资源的代码审查提示词
s.AddPrompt(mcp.NewPrompt("code_review",
    mcp.WithPromptDescription("代码审查协助"),
    mcp.WithArgument("pr_number",
        mcp.ArgumentDescription("要审查的拉取请求编号"),
        mcp.RequiredArgument(),
    ),
), func(ctx context.Context, request mcp.GetPromptRequest) (*mcp.GetPromptResult, error) {
    prNumber := request.Params.Arguments["pr_number"]
    if prNumber == "" {
        return nil, fmt.Errorf("需要提供拉取请求编号")
    }
    
    return mcp.NewGetPromptResult(
        "代码审查协助",
        []mcp.PromptMessage{
            mcp.NewPromptMessage(
                mcp.RoleUser,
                mcp.NewTextContent("请审查这些更改,并提供建设性的反馈。"),
            ),
            mcp.NewPromptMessage(
                mcp.RoleAssistant,
                mcp.NewEmbeddedResource(mcp.ResourceContents{
                    URI: fmt.Sprintf("git://pulls/%s/diff", prNumber),
                    MIMEType: "text/x-diff",
                }),
            ),
        },
    ), nil
})

// 数据库查询构建器提示词
s.AddPrompt(mcp.NewPrompt("query_builder",
    mcp.WithPromptDescription("SQL 查询构建助手"),
    mcp.WithArgument("table",
        mcp.ArgumentDescription("要查询的表名"),
        mcp.RequiredArgument(),
    ),
), func(ctx context.Context, request mcp.GetPromptRequest) (*mcp.GetPromptResult, error) {
    tableName := request.Params.Arguments["table"]
    if tableName == "" {
        return nil, fmt.Errorf("需要提供表名")
    }
    
    return mcp.NewGetPromptResult(
        "SQL 查询构建助手",
        []mcp.PromptMessage{
            mcp.NewPromptMessage(
                mcp.RoleUser,
                mcp.NewTextContent("请为提供的模式构建高效且安全的查询。"),
            ),
            mcp.NewPromptMessage(
                mcp.RoleUser,
                mcp.NewEmbeddedResource(mcp.ResourceContents{
                    URI: fmt.Sprintf("db://schema/%s", tableName),
                    MIMEType: "application/json",
                }),
            ),
        },
    ), nil
})

提示词可以包含:

  • 系统指令
  • 必需参数
  • 嵌入式资源
  • 多条消息
  • 不同的内容类型(文本、图片等)
  • 自定义 URI 方案

示例

有关示例,请参阅 examples/ 目录。

主要示例包括:

附加内容

传输层

MCP-Go 支持标准输入输出、SSE 以及可流式传输的 HTTP 传输层。对于 SSE 传输,您可以使用 SetConnectionLostHandler() 来检测并处理连接断开情况,从而实现重连逻辑。

会话管理

MCP-Go 提供了一个强大的会话管理系统,使您能够:

  • 为每个连接的客户端维护独立的状态
  • 注册并跟踪客户端会话
  • 向特定客户端发送通知
  • 提供基于会话的工具自定义功能
显示会话管理示例

基本会话处理

// 创建一个支持会话功能的服务器
s := server.NewMCPServer(
    "会话演示",
    "1.0.0",
    server.WithToolCapabilities(true),
)

// 实现自定义的 ClientSession
type MySession struct {
    id           string
    notifChannel chan mcp.JSONRPCNotification
    isInitialized bool
    // 根据应用需求添加自定义字段
}

// 实现 ClientSession 接口
func (s *MySession) SessionID() string {
    return s.id
}

func (s *MySession) NotificationChannel() chan<- mcp.JSONRPCNotification {
    return s.notifChannel
}

func (s *MySession) Initialize() {
    s.isInitialized = true
}

func (s *MySession) Initialized() bool {
    return s.isInitialized
}

// 注册一个会话
session := &MySession{
    id:           "user-123",
    notifChannel: make(chan mcp.JSONRPCNotification, 10),
}
if err := s.RegisterSession(context.Background(), session); err != nil {
    log.Printf("注册会话失败: %v", err)
}

// 向特定客户端发送通知
err := s.SendNotificationToSpecificClient(
    session.SessionID(),
    "notification/update",
    map[string]any{"message": "有新数据可用!"},
)
if err != nil {
    log.Printf("发送通知失败: %v", err)
}

// 使用完毕后注销会话
s.UnregisterSession(context.Background(), session.SessionID())

基于会话的工具

对于更高级的用例,您可以实现 SessionWithTools 接口,以支持基于会话的工具自定义:

// 实现 SessionWithTools 接口,用于支持基于会话的工具
type MyAdvancedSession struct {
    MySession  // 嵌入基础会话
    sessionTools map[string]server.ServerTool
}

// 实现 SessionWithTools 的额外方法
func (s *MyAdvancedSession) GetSessionTools() map[string]server.ServerTool {
    return s.sessionTools
}

func (s *MyAdvancedSession) SetSessionTools(tools map[string]server.ServerTool) {
    s.sessionTools = tools
}

// 创建并注册一个支持工具的会话
advSession := &MyAdvancedSession{
    MySession: MySession{
        id:           "user-456",
        notifChannel: make(chan mcp.JSONRPCNotification, 10),
    },
    sessionTools: make(map[string]server.ServerTool),
}
if err := s.RegisterSession(context.Background(), advSession); err != nil {
    log.Printf("注册会话失败: %v", err)
}

// 添加会话专属工具
userSpecificTool := mcp.NewTool(
    "user_data",
    mcp.WithDescription("访问用户专属数据"),
)
// 可以使用 AddSessionTool(类似于 AddTool)
err := s.AddSessionTool(
    advSession.SessionID(),
    userSpecificTool,
    func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
        // 此处理器仅对该特定会话可用
        return mcp.NewToolResultText("针对 " + advSession.SessionID() 的用户专属数据"), nil
    },
)
if err != nil {
    log.Printf("添加会话工具失败: %v", err)
}

// 或者直接使用 AddSessionTools 并传入 ServerTool
/*
err := s.AddSessionTools(
    advSession.SessionID(),
    server.ServerTool{
        Tool: userSpecificTool,
        Handler: func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
            // 此处理器仅对该特定会话可用
            return mcp.NewToolResultText("针对 " + advSession.SessionID() 的用户专属数据"), nil
        },
    },
)
if err != nil {
    log.Printf("添加会话工具失败: %v", err)
}
*/

// 当不再需要时,删除会话专属工具
err = s.DeleteSessionTools(advSession.SessionID(), "user_data")
if err != nil {
    log.Printf("删除会话工具失败: %v", err)
}

工具过滤

您还可以应用过滤器来控制哪些工具对特定会话可见:

// 添加一个工具过滤器,只显示具有特定前缀的工具
s := server.NewMCPServer(
    "工具过滤演示",
    "1.0.0",
    server.WithToolCapabilities(true),
    server.WithToolFilter(func(ctx context.Context, tools []mcp.Tool) []mcp.Tool {
        // 从上下文中获取会话
        session := server.ClientSessionFromContext(ctx)
        if session == null {
            return tools // 如果没有会话,则返回所有工具
        }
        
        // 示例:根据会话 ID 前缀过滤工具
        if strings.HasPrefix(session.SessionID(), "admin-") {
            // 管理员用户可使用所有工具
            return tools
        } else {
            // 普通用户仅能使用带有 "public-" 前缀的工具
            var filteredTools []mcp.Tool
            for _, tool := range tools {
                if strings.HasPrefix(tool.Name, "public-") {
                    filteredTools = append(filteredTools, tool)
                }
            }
            return filteredTools
        }
    }),
)

使用上下文

会话上下文会自动传递给工具和资源处理器:

s.AddTool(mcp.NewTool("session_aware"), func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
    // 从上下文中获取当前会话
    session := server.ClientSessionFromContext(ctx)
    if session == null {
        return mcp.NewToolResultError("无活动会话"), nil
    }
    
    return mcp.NewToolResultText("你好,会话 " + session.SessionID()), nil
})

// 在使用 HTTP/SSE 服务器的处理器时,需要将包含会话的上下文传递过去
httpHandler := func(w http.ResponseWriter, r *http.Request) {
    // 从某个地方(如 Cookie 或 Header)获取会话
    session := getSessionFromRequest(r)
    
    // 将会话添加到上下文中
    ctx := s.WithContext(r.Context(), session)
    
    // 处理请求时使用此上下文
    // ...
}

请求钩子

通过创建一个包含您所选回调函数的 Hooks 对象,可以钩入请求生命周期。这使得在整个功能范围内进行遥测成为可能,并能够观察各种情况,例如统计格式不正确的请求数量,或在初始化过程中记录代理身份。

在创建服务器时,使用 server.WithHooks 选项将 Hooks 添加到服务器中。

工具处理器中间件

使用 server.WithToolHandlerMiddleware 选项为工具调用处理器添加中间件。中间件可以在服务器创建时注册,并应用于每次工具调用。

此外,还提供了一个恢复中间件选项,用于在工具调用发生 panic 时进行恢复,可以通过 server.WithRecovery 选项将其添加到服务器中。

提示处理器中间件

使用 server.WithPromptHandlerMiddleware 选项为提示处理器添加中间件。中间件可以在创建服务器时注册,并应用于每次 prompts/get 调用。

提示过滤

使用 server.WithPromptFilter 选项根据上下文过滤提示。其工作方式与工具过滤相同,但适用于 prompts/list 的结果。

重新生成服务器代码

服务器钩子和请求处理器是自动生成的。通过运行以下命令可以重新生成它们:

go generate ./...

您需要安装 go 并确保 goimports 工具可用。生成器会自动运行 goimports 来格式化并修复导入语句。

自动补全

当用户正在填写特定提示(按名称标识)或资源模板(按 URI 标识)的参数值时,服务器可以提供上下文相关的建议。要启用补全支持,请在创建服务器时使用 server.WithCompletions() 选项。

补全提供者

您可以通过实现相应的接口并将它们作为选项传递给服务器,为提示参数和资源模板参数提供补全逻辑。

显示补全提供者示例
type MyPromptCompletionProvider struct{}

func (p *MyPromptCompletionProvider) CompletePromptArgument(
    ctx context.Context,
    promptName string,
    argument mcp.CompleteArgument,
    context mcp.CompleteContext,
) (*mcp.Completion, error) {
    // 示例:为 "code_review" 提供样式建议
    if promptName == "code_review" && argument.Name == "style" {
        styles := []string{"正式", "随意", "技术性", "创意"}
        var suggestions []string
        
        // 根据当前输入进行筛选
        for _, style := range styles {
            if strings.HasPrefix(style, argument.Value) {
                suggestions = append(suggestions, style)
            }
        }
        
        return &mcp.Completion{
            Values: suggestions,
        }, nil
    }
    
    // 对于未处理的情况返回空建议
    return &mcp.Completion{Values: []string{}}, nil
}

type MyResourceCompletionProvider struct{}

func (p *MyResourceCompletionProvider) CompleteResourceArgument(
    ctx context.Context,
    uri string,
    argument mcp.CompleteArgument,
    context mcp.CompleteContext,
) (*mcp.Completion, error) {
    // 示例:提供文件路径补全
    if uri == "file:///{path}" && argument.Name == "path" {
        // 您可以从 context.Arguments 中访问之前已完成的参数
        // context.Arguments 是一个已解析参数的 map[string]string
        
        paths := getMatchingPaths(argument.Value) // 您的自定义逻辑
        
        return &mcp.Completion{
            Values:  paths[:min(len(paths), 100)], // 最多 100 项
            Total:   len(paths),                    // 总共有多少匹配项
            HasMore: len(paths) > 100,              // 是否还有更多结果
        }, nil
    }
    
    return &mcp.Completion{Values: []string{}}, nil
}

// 注册提供者
mcpServer := server.NewMCPServer(
    "my-server",
    "1.0.0",
    server.WithCompletions(),
    server.WithPromptCompletionProvider(&MyPromptCompletionProvider{}),
    server.WithResourceCompletionProvider(&MyResourceCompletionProvider{}),
)

补全上下文

对于具有多个参数的提示或资源模板,CompleteContext 参数提供了对先前已完成参数的访问权限。这使您可以根据之前的选项提供上下文相关的建议。

显示补全上下文示例
func (p *MyProvider) CompleteResourceArgument(
    ctx context.Context,
    uri string,
    argument mcp.CompleteArgument,
    context mcp.CompleteContext,
) (*mcp.Completion, error) {
    // 访问之前完成的参数
    if previousValue, ok := context.Arguments["previous_arg"]; ok {
        // 根据 previous_arg 的值提供建议
        return getSuggestionsFor(argument.Value, previousValue), nil
    }
    
    return &mcp.Completion{Values: []string{}}, nil
}

响应约束

在返回补全结果时:

  • 每次响应最多包含 100 项
  • 使用 Total 表示总共有多少个匹配项
  • 使用 HasMore 标记是否还有超出返回结果之外的其他匹配项

版本历史

v0.47.02026/04/04
v0.46.02026/03/26
v0.45.02026/03/06
v0.44.12026/02/27
v0.44.02026/02/15
v0.44.0-beta.32026/02/04
v0.44.0-beta.22026/01/09
v0.44.0-beta.12025/12/19
v0.43.22025/12/04
v0.43.12025/11/23
v0.43.02025/11/02
v0.43.0-beta.32025/10/30
v0.43.0-beta.22025/10/25
v0.43.0-beta.12025/10/21
v0.42.02025/10/21
v0.42.0-beta.32025/10/17
v0.42.0-beta.22025/10/14
v0.42.0-beta.12025/09/30
v0.41.12025/09/30
v0.41.02025/09/27

常见问题

相似工具推荐

stable-diffusion-webui

stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面,旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点,将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。 无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师,还是想要深入探索模型潜力的开发者与研究人员,都能从中获益。其核心亮点在于极高的功能丰富度:不仅支持文生图、图生图、局部重绘(Inpainting)和外绘(Outpainting)等基础模式,还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外,它内置了 GFPGAN 和 CodeFormer 等人脸修复工具,支持多种神经网络放大算法,并允许用户通过插件系统无限扩展能力。即使是显存有限的设备,stable-diffusion-webui 也提供了相应的优化选项,让高质量的 AI 艺术创作变得触手可及。

162.1k|★★★☆☆|今天
开发框架图像Agent

everything-claude-code

everything-claude-code 是一套专为 AI 编程助手(如 Claude Code、Codex、Cursor 等)打造的高性能优化系统。它不仅仅是一组配置文件,而是一个经过长期实战打磨的完整框架,旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。 通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能,everything-claude-code 能显著提升 AI 在复杂任务中的表现,帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略,使得模型响应更快、成本更低,同时有效防御潜在的攻击向量。 这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库,还是需要 AI 协助进行安全审计与自动化测试,everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目,它融合了多语言支持与丰富的实战钩子(hooks),让 AI 真正成长为懂上

139k|★★☆☆☆|今天
开发框架Agent语言模型

ComfyUI

ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎,专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式,采用直观的节点式流程图界面,让用户通过连接不同的功能模块即可构建个性化的生成管线。 这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景,也能自由组合模型、调整参数并实时预览效果,轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性,不仅支持 Windows、macOS 和 Linux 全平台,还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构,并率先支持 SDXL、Flux、SD3 等前沿模型。 无论是希望深入探索算法潜力的研究人员和开发者,还是追求极致创作自由度的设计师与资深 AI 绘画爱好者,ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能,使其成为当前最灵活、生态最丰富的开源扩散模型工具之一,帮助用户将创意高效转化为现实。

107.7k|★★☆☆☆|2天前
开发框架图像Agent

NextChat

NextChat 是一款轻量且极速的 AI 助手,旨在为用户提供流畅、跨平台的大模型交互体验。它完美解决了用户在多设备间切换时难以保持对话连续性,以及面对众多 AI 模型不知如何统一管理的痛点。无论是日常办公、学习辅助还是创意激发,NextChat 都能让用户随时随地通过网页、iOS、Android、Windows、MacOS 或 Linux 端无缝接入智能服务。 这款工具非常适合普通用户、学生、职场人士以及需要私有化部署的企业团队使用。对于开发者而言,它也提供了便捷的自托管方案,支持一键部署到 Vercel 或 Zeabur 等平台。 NextChat 的核心亮点在于其广泛的模型兼容性,原生支持 Claude、DeepSeek、GPT-4 及 Gemini Pro 等主流大模型,让用户在一个界面即可自由切换不同 AI 能力。此外,它还率先支持 MCP(Model Context Protocol)协议,增强了上下文处理能力。针对企业用户,NextChat 提供专业版解决方案,具备品牌定制、细粒度权限控制、内部知识库整合及安全审计等功能,满足公司对数据隐私和个性化管理的高标准要求。

87.6k|★★☆☆☆|今天
开发框架语言模型

ML-For-Beginners

ML-For-Beginners 是由微软推出的一套系统化机器学习入门课程,旨在帮助零基础用户轻松掌握经典机器学习知识。这套课程将学习路径规划为 12 周,包含 26 节精炼课程和 52 道配套测验,内容涵盖从基础概念到实际应用的完整流程,有效解决了初学者面对庞大知识体系时无从下手、缺乏结构化指导的痛点。 无论是希望转型的开发者、需要补充算法背景的研究人员,还是对人工智能充满好奇的普通爱好者,都能从中受益。课程不仅提供了清晰的理论讲解,还强调动手实践,让用户在循序渐进中建立扎实的技能基础。其独特的亮点在于强大的多语言支持,通过自动化机制提供了包括简体中文在内的 50 多种语言版本,极大地降低了全球不同背景用户的学习门槛。此外,项目采用开源协作模式,社区活跃且内容持续更新,确保学习者能获取前沿且准确的技术资讯。如果你正寻找一条清晰、友好且专业的机器学习入门之路,ML-For-Beginners 将是理想的起点。

85k|★★☆☆☆|今天
图像数据工具视频

ragflow

RAGFlow 是一款领先的开源检索增强生成(RAG)引擎,旨在为大语言模型构建更精准、可靠的上下文层。它巧妙地将前沿的 RAG 技术与智能体(Agent)能力相结合,不仅支持从各类文档中高效提取知识,还能让模型基于这些知识进行逻辑推理和任务执行。 在大模型应用中,幻觉问题和知识滞后是常见痛点。RAGFlow 通过深度解析复杂文档结构(如表格、图表及混合排版),显著提升了信息检索的准确度,从而有效减少模型“胡编乱造”的现象,确保回答既有据可依又具备时效性。其内置的智能体机制更进一步,使系统不仅能回答问题,还能自主规划步骤解决复杂问题。 这款工具特别适合开发者、企业技术团队以及 AI 研究人员使用。无论是希望快速搭建私有知识库问答系统,还是致力于探索大模型在垂直领域落地的创新者,都能从中受益。RAGFlow 提供了可视化的工作流编排界面和灵活的 API 接口,既降低了非算法背景用户的上手门槛,也满足了专业开发者对系统深度定制的需求。作为基于 Apache 2.0 协议开源的项目,它正成为连接通用大模型与行业专有知识之间的重要桥梁。

77.1k|★★★☆☆|昨天
Agent图像开发框架