云计算百科
云计算领域专业知识百科平台

Bifrost 仓库实战:用 Go 构建 MCP 测试服务器 go-test-server 的完整指南

  • 人工智能
  • LLM 网关
  • API网关
  • 后端

【免费下载链接】bifrost

Fastest enterprise AI gateway (50x faster than LiteLLM) with adaptive load balancer, cluster mode, guardrails, 1000+ models support & <100 µs overhead at 5k RPS.

项目地址:
https://gitcode.com/gh_mirrors/bifrost31/bifrost

点击查看 免费下载

导读

examples/mcps/go-test-server 是 Bifrost 开源仓库中一个用 Go 语言编写的 MCP(Model Context Protocol)测试服务器示例,它对外暴露 6 个纯函数式工具:字符串变换、JSON 校验、UUID 生成、哈希计算与编解码。本文以该示例为骨架,深入讲解它的工具注册、参数定义、编译运行方式,并结合 Bifrost 的 MCP 测试框架(core/internal/mcptests)说明它如何被真实接入网关测试链路,帮助读者理解「如何为 MCP 网关编写一个可复用的 STDIO 测试服务器」这一实战主题。

一、go-test-server 是什么:一个为网关测试而生的 STDIO MCP Server

go-test-server 位于仓库的 examples/mcps/go-test-server 目录下,是一个独立的 Go module(模块名 github.com/maximhq/bifrost/examples/mcps/go-test-server,详见 go.mod)。它的定位非常明确:不是生产级业务服务器,而是为 Bifrost 的 MCP 测试体系提供稳定、可预测的 STDIO 工具提供方。

从 main.go 的入口可以看到它的技术选型与启动方式:

s := server.NewMCPServer(
"go-test-server",
"1.0.0",
server.WithToolCapabilities(true),
)

// Register all tools
registerStringTransformTool(s)
registerJSONValidateTool(s)
registerUUIDGenerateTool(s)
registerHashTool(s)
registerEncodeTool(s)
registerDecodeTool(s)

// Start STDIO server
if err := server.ServeStdio(s); err != nil {
fmt.Fprintf(os.Stderr, "Server error: %v\\n", err)
os.Exit(1)
}

这段代码体现了两个关键事实:

  • 它基于 github.com/mark3labs/mcp-go 库构建(版本 v0.43.2,见 go.mod),调用 server.NewMCPServer 创建名为 go-test-server、版本 1.0.0 的 MCP 服务器,并通过 server.WithToolCapabilities(true) 声明支持工具能力协商。
  • 它通过 server.ServeStdio(s) 以 STDIO 传输协议启动——即通过标准输入/输出与宿主进程通信,这正是 Bifrost 测试框架中「外部 MCP 客户端」的标准接入形态(对应 schemas.MCPConnectionTypeSTDIO)。
  • 从源码结构看,这种「独立二进制 + STDIO 协议」的设计让测试服务器可以被 Bifrost 网关像真实第三方 MCP 服务器一样拉起、握手、发现工具并调用,从而完整覆盖真实接入链路,而不是在进程内模拟。

    二、六个工具逐一拆解:参数契约、实现与返回格式

    go-test-server 的全部工具都以「注册(注册函数声明工具 Schema)+ 处理(回调函数实现业务逻辑)」两段式组织。所有工具在回调中统一采用「request.GetArguments() 取参 → JSON 序列化到本地 struct → 校验 → 计算 → mcp.NewToolResultText 返回」的范式,并且参数均通过 mcp.Required() 标记为必填、通过 mcp.Enum(…) 限定取值范围,这与 README 中「required + 枚举」的文档描述完全一致。

    1. string_transform:字符串变换

    • 功能:对输入字符串执行大小写转换、反转、标题化。
    • 参数: | 参数 | 类型 | 必填 | 取值范围/说明 | |—|—|—|—| | input | string | 是 | 待变换的字符串 | | operation | string | 是 | uppercase / lowercase / reverse / title |
    • 实现要点(见 main.go 的 registerStringTransformTool):uppercase/lowercase 直接使用 strings.ToUpper/strings.ToLower;reverse 按 []rune 逐字符反转,避免多字节 UTF-8 字符被按字节截断;title 则先 strings.ToLower 再 strings.Title 实现首字母大写。未知 operation 返回 Unknown operation: xxx 的工具错误。

    请求 / 响应示例:

    // 请求
    { "input": "hello world", "operation": "uppercase" }
    // 响应
    { "input": "hello world", "operation": "uppercase", "result": "HELLO WORLD" }

    2. json_validate:JSON 合法性校验

    • 功能:判断输入字符串是否为合法 JSON。
    • 参数: | 参数 | 类型 | 必填 | 说明 | |—|—|—|—| | json_string | string | 是 | 待校验的 JSON 字符串 |
    • 实现要点:对 json_string 执行 json.Unmarshal 到 interface{}。合法时返回 {"valid": true, "parsed": <解析后的对象>};非法时返回 {"valid": false, "error": <解析错误信息>}。

    // 请求
    { "json_string": "{\\"name\\": \\"test\\"}" }
    // 响应
    { "valid": true, "parsed": {"name": "test"} }

    3. uuid_generate:生成 UUID v4

    • 功能:生成随机 UUID v4。
    • 参数:无。
    • 实现要点:调用 github.com/google/uuid(v1.6.0)的 uuid.New(),返回 {"uuid": "<uuid>"}。因为它不需要任何参数,所以注册时 mcp.NewTool("uuid_generate", mcp.WithDescription(…)) 无需声明任何参数 Schema——这也是测试「零参数工具」调用链路的理想对象。

    // 响应
    { "uuid": "550e8400-e29b-41d4-a716-446655440000" }

    4. hash:哈希计算

    • 功能:按指定算法计算输入字符串的哈希。
    • 参数: | 参数 | 类型 | 必填 | 取值范围/说明 | |—|—|—|—| | input | string | 是 | 待哈希字符串 | | algorithm | string | 是 | md5 / sha256 / sha512 |
    • 实现要点:分别调用 crypto/md5、crypto/sha256、crypto/sha512 计算摘要,再经 hex.EncodeToString 输出十六进制小写字符串。README 中给出的示例哈希值 2cf24dba…b9824 即 "hello" 的 SHA-256 摘要,可作为手工验证实现的基准值。

    // 请求
    { "input": "hello", "algorithm": "sha256" }
    // 响应
    { "input": "hello", "algorithm": "sha256",
    "hash": "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824" }

    5. encode:编码

    • 功能:按指定编码方式对输入字符串编码。
    • 参数: | 参数 | 类型 | 必填 | 取值范围/说明 | |—|—|—|—| | input | string | 是 | 待编码字符串 | | encoding | string | 是 | base64 / hex / url |
    • 实现要点:base64 用 base64.StdEncoding.EncodeToString;hex 用 hex.EncodeToString;url 用 url.QueryEscape(Query 风格 URL 编码)。

    // 请求
    { "input": "hello world", "encoding": "base64" }
    // 响应
    { "input": "hello world", "encoding": "base64", "encoded": "aGVsbG8gd29ybGQ=" }

    6. decode:解码

    • 功能:解码已编码字符串,是 encode 的逆操作。
    • 参数: | 参数 | 类型 | 必填 | 取值范围/说明 | |—|—|—|—| | input | string | 是 | 已编码的字符串 | | encoding | string | 是 | base64 / hex / url |
    • 实现要点:base64 用 base64.StdEncoding.DecodeString,hex 用 hex.DecodeString,url 用 url.QueryUnescape。与 encode 不同,decode 是失败敏感的:解码出错(如非法 base64/hex 字符)时直接返回 Decode error: <err> 工具错误,而不会返回空结果——这一点在测试「工具返回错误」场景时非常有用。

    // 请求
    { "input": "aGVsbG8gd29ybGQ=", "encoding": "base64" }
    // 响应
    { "input": "aGVsbG8gd29ybGQ=", "encoding": "base64", "decoded": "hello world" }

    小结:这 6 个工具覆盖了字符串处理、数据校验、随机数、摘要计算、编解码五类常见纯函数操作,返回值全部以 JSON 文本形式通过 mcp.NewToolResultText 返回,方便测试断言直接匹配 JSON 子串。

    三、构建与运行:从源码到可执行二进制

    1. 手动构建与运行

    在 examples/mcps/go-test-server 目录内执行:

    # 构建(输出二进制到 bin/ 目录)
    go build -o bin/go-test-server

    # 运行(以 STDIO 模式启动,等待宿主进程通过 stdin/stdout 交互)
    ./bin/go-test-server

    注意事项:

    • 该模块声明 go 1.27.0(见 go.mod),构建前需确认 Go 工具链版本满足要求;建议在模块目录内构建(模块独立,不依赖 Bifrost 主 go.mod)。
    • 二进制默认通过 server.ServeStdio 启动,不会有任何 HTTP 端口,直接以命令行进程形式常驻等待 MCP 协议消息,因此不能用浏览器访问。

    2. 通过 Makefile 一键构建(推荐)

    Bifrost 仓库根目录的 Makefile 提供了统一的 MCP 测试服务器构建目标 setup-mcp-tests,它会遍历 examples/mcps/*/ 下的所有目录,对含 go.mod 的目录执行 GOWORK=off go build -o bin/<目录名> .,对含 package.json 的目录执行 npm install && npm run build:

    make setup-mcp-tests

    执行后 go-test-server 的二进制会被统一输出到 examples/mcps/go-test-server/bin/go-test-server,这正是 Bifrost 测试框架引用的默认路径(见下文)。

    四、在 Bifrost 测试框架中接入 go-test-server

    go-test-server 的价值核心在于它是 Bifrost 网关 MCP 测试体系的标准「外部 STDIO 客户端」夹具。以下内容均可从 core/internal/mcptests 的源码得到印证。

    1. 客户端配置结构:STDIO 接入的完整契约

    README 末尾给出的接入示例对应 Bifrost 的 schemas.MCPClientConfig。测试框架中的真实实现位于 fixtures.go 的 GetGoTestServerConfig:

    return schemas.MCPClientConfig{
    ID: "go-test-server",
    Name: "GoTestServer",
    ConnectionType: schemas.MCPConnectionTypeSTDIO,
    StdioConfig: &schemas.MCPStdioConfig{
    Command: serverPath, // 指向 examples/mcps/go-test-server/bin/go-test-server
    Args: []string{},
    },
    ToolsToExecute: []string{"*"},
    ToolsToAutoExecute: []string{},
    IsCodeModeClient: true, // CodeMode enabled for testing
    }

    各字段含义如下:

    • ID:网关内部唯一标识,用于测试中按客户端过滤/配置;
    • Name:工具命名前缀的来源。根据 agent_test_helpers.go 中 CreateSTDIOToolCall 的注释,STDIO 工具的实际全名格式为 {Name}-{tool_name},即 GoTestServer-uuid_generate、GoTestServer-hash 等;
    • ConnectionType:MCPConnectionTypeSTDIO,声明该客户端通过标准输入输出连接;
    • StdioConfig.Command:指向构建出的二进制路径;fixtures.go 中 mcpServerPaths.GoTestServer 被初始化为 examples/mcps/go-test-server/bin/go-test-server;
    • ToolsToExecute:"*" 表示该客户端所有工具都可被执行;
    • ToolsToAutoExecute:空数组表示默认不自动执行(工具仍需要 LLM 决策后调用);
    • IsCodeModeClient:标记为 CodeMode 客户端,用于测试 Bifrost 的 CodeMode 工具执行路径。

    2. 测试框架中的两种接入方式

    • 声明式接入:测试通过 AgentTestConfig{ STDIOClients: []string{"go-test-server"} } 声明需要接入的 STDIO 客户端,SetupAgentTest(agent_test_helpers.go)会据此自动调用 GetGoTestServerConfig 生成配置并注册到 MCPManager。支持多客户端并存,例如 STDIOClients: []string{"go-test-server", "parallel-test-server"}。
    • 路径初始化:InitMCPServerPaths(fixtures.go)在测试前统一初始化各 MCP 服务器二进制路径,并在 stdio_respawn_test.go 等测试中先检查二进制是否存在(不存在则 t.Skipf 并提示先执行 make setup-mcp-tests)。

    3. go-test-server 支撑了哪些测试场景

    从 core/internal/mcptests 的引用情况可以归纳出它的典型用途:

    • 工具过滤与权限测试(tool_filtering_test.go、agent_mixed_permissions_test.go):通过配置 ToolsToAutoExecute、ToolsToExecute 及上下文过滤,验证哪些工具允许 LLM 可见、哪些允许自动执行。例如把 go-test-server 设为全自动执行、或仅自动执行 uuid_generate(用基础工具名,而非带前缀全名)。
    • 上下文过滤测试(agent_context_filtering_test.go):通过 MCPContextKeyIncludeClients/MCPContextKeyIncludeTools 在上下文中限定可见客户端/工具,验证未被白名单包含的 go-test-server 工具不会被调用。
    • 多连接与 Agent 编排测试(agent_multiconnection_test.go、agent_adapter_test.go):将 go-test-server 与其他服务器组合,验证 Agent 模式(CheckAndExecuteAgentForChatRequest)的多轮工具调用、并行工具调用与最大深度限制。
    • CodeMode 测试(codemode_stdio_test.go):验证 go-test-server 以 IsCodeModeClient 方式接入 CodeMode 执行链路。
    • 进程重生(respawn)测试(stdio_respawn_test.go):验证 STDIO 子进程异常退出后的拉起与重连逻辑。

    4. 运行 MCP 测试

    Bifrost 仓库为 MCP 测试提供了完整入口(见 Makefile 的 test-mcp 目标):

    # 一键执行:先构建所有 examples/mcps 测试服务器,再运行 core/internal/mcptests 下的测试
    make test-mcp

    该目标支持可选变量 TYPE(如 connection)、TESTCASE(精确匹配测试名)与 PATTERN(子串匹配),二者互斥。例如按子串过滤运行:

    make test-mcp PATTERN=Respawn

    五、深入:从 go-test-server 看 Bifrost 的 MCP 测试设计哲学

    • 外部进程 > 进程内模拟:go-test-server 是独立二进制而非库内桩实现,Bifrost 网关必须以真实 MCP 握手流程(initialize → tools/list → tools/call)与它交互。从源码结构看,这能暴露真实 STDIO 场景下的进程拉起、协议帧解析、错误恢复等问题,测试可信度远高于 mock。
    • 工具集刻意简单、行为确定:6 个工具均为无外部依赖的纯函数,输出可精确预期(如固定的 SHA-256 基准值),这使得测试断言可以精确到返回 JSON 的具体字段值,适合作为工具调用、自动执行、过滤、并行等复杂行为的「控制变量」。
    • 多服务器协同:examples/mcps 目录下还有 parallel-test-server(并行调用)、edge-case-server(Unicode/大载荷/空值等边界输入)、error-test-server(错误路径)、temperature(TypeScript 实现)等互补服务器,配合 go-test-server 可覆盖协议功能、性能、错误与边界四类测试场景。

    六、扩展实践:如何仿写一个自己的测试服务器

    基于 go-test-server 的范式,编写一个自定义测试 MCP 服务器只需四步:

  • 初始化模块与依赖:创建目录并执行 go mod init <module>,引入 github.com/mark3labs/mcp-go(如需 UUID 能力可同时引入 github.com/google/uuid),参照 go.mod 管理依赖。
  • 创建服务器:server.NewMCPServer(name, version, server.WithToolCapabilities(true))。
  • 注册工具:用 mcp.NewTool(name, mcp.WithDescription(…), mcp.WithString("arg", mcp.Required(), mcp.Enum(…))) 声明 Schema;在 s.AddTool(tool, handler) 的 handler 中按「GetArguments → 反序列化 → 计算 → NewToolResultText/NewToolResultError」实现逻辑。
  • 启动并构建:server.ServeStdio(s) 启动;go build -o bin/<name> 构建;如需接入 Bifrost 测试体系,把二进制路径配置进 schemas.MCPClientConfig(ConnectionType: MCPConnectionTypeSTDIO)并在 STDIOClients 中登记。
  • 结语

    go-test-server 虽然只有约 380 行 Go 代码,却是理解 Bifrost 网关如何对接外部 MCP 服务器的一把钥匙:它同时承担了「协议规范参考实现」与「测试夹具」双重角色。希望读者通过本文既能独立跑通这个示例,也能把它作为模板,为自己的 MCP 网关测试体系编写定制化、可预期的测试服务器。

    赞

    分享

    • 人工智能
    • LLM 网关
    • API网关
    • 后端

    【免费下载链接】bifrost

    Fastest enterprise AI gateway (50x faster than LiteLLM) with adaptive load balancer, cluster mode, guardrails, 1000+ models support & <100 µs overhead at 5k RPS.

    项目地址:
    https://gitcode.com/gh_mirrors/bifrost31/bifrost

    点击查看 免费下载

    上一篇:
    Univer办公套件完全指南:从零开始构建企业级协作平台

    下一篇:
    微信小程序WXAPKG解压工具unwxapkg使用指南

    创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » Bifrost 仓库实战:用 Go 构建 MCP 测试服务器 go-test-server 的完整指南
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!