1024 写个 Go MCP 工具前,先把协议版本和官方 SDK 对齐 在 Go 项目里加一个 MCP 工具第一步经常被跳过客户端、SDK 和协议到底采用哪一版把几个 JSON-RPC 方法拼起来最多得到一个局部演示离完整服务器还有一段距离。官方在 2026 年 7 月 28 日发布的规范说明调整了无状态请求、元数据和传输交互。这是七月的变化拿来检查十月的项目很合适不能写成十月刚发布。旧客户端是否还能接入要看实际 SDK 的兼容表。先写出三层责任业务函数负责“这个请求能不能做”SDK 适配负责把结果变成工具调用响应协议层负责版本、传输、取消和错误。三层可以在同一进程验收时仍要分开。以只读报价为例工具名叫 quote并不代表它天然安全。SKU 是否属于当前租户、数量是否合理都得由业务代码核验。下面只实现参数边界不自称 MCP SDKpackage main import ( context encoding/json errors fmt io strings ) type QuoteRequest struct { SKU string json:sku Qty int json:qty } func parse(ctx context.Context, raw string) (QuoteRequest, error) { var q QuoteRequest if err : ctx.Err(); err ! nil { return q, err } dec : json.NewDecoder(strings.NewReader(raw)) dec.DisallowUnknownFields() if err : dec.Decode(q); err ! nil { return q, err } var extra any if err : dec.Decode(extra); err ! io.EOF { return q, errors.New(expected one JSON value) } if q.SKU || q.Qty 1 || q.Qty 99 { return q, errors.New(invalid quote request) } return q, nil } func main() { for _, raw : range []string{ {sku:book,qty:2}, {sku:book,qty:2,role:admin}, } { q, err : parse(context.Background(), raw) fmt.Printf(sku%q qty%d accepted%t\n, q.SKU, q.Qty, err nil) } }保存成 main.go执行 go run main.go。第一条应被接受第二条因未知字段被拒绝。拒绝 role 字段只减少参数歧义不能代替身份认证真实角色应从可信会话取得不能从模型入参读取。接 SDK 时别把局部通过当互通通过官方 Go SDK提供服务器、客户端和授权相关包并维护协议版本兼容关系。选择 tag 以后至少检查四件事检查对象需要留下的证据客户端与服务器版本精确 tag、协议版本和协商/拒绝行为输入与输出契约必填项、未知字段、错误结果、文本内容类型调用生命周期取消是否传给业务资源是否及时释放业务权限同工具不同租户、只读与写入是否独立授权前面的程序只覆盖输入契约。它没有启动 MCP 服务器没有完成 SDK 互通也没有测试 OAuth。把这个边界写清楚比贴“生产级”三个字更有用。泛型可以简化调用不能替你证明性能Go 1.27 发布说明确认加入了方法独立类型参数。现有服务器若仍用旧工具链是否升级要单独决定。本文示例使用普通结构体本地验证环境为 Go 1.26.5不依赖这一新语法。结构体也不意味着反序列化没有反射更不能顺手推出 CPU 降六成、连接零泄漏。真要比较 SDK 与自研适配应使用同样的工具、负载、硬件和错误比例再看分配、尾延迟及维护成本。没有测过就别先把结论写进封面。本文本地实验只验证标准库参数解析协议互通、权限集成和性能仍需在项目实际版本中验证。