mcp: typed tool handlers lose wrapped JSON-RPC errors
维护者通常 1 天内回复
还没有人认领这个 Issue。
- #1528 来自 @ktsoator —— 已关闭,未合并
评估
- 难度
- 2/5
- 预计耗时
- 1-3 小时
- 新手友好度
- 85/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- go
调研方向
从 MCP 包中的 toolForErr 以及 ClientSession.CallTool 所使用的 JSON-RPC 错误处理入手;比较直接处理 *jsonrpc.Error 与处理被包装错误的方式。运行提供的内存中客户端/服务端复现,然后验证 errors.As 是否保留了 JSON-RPC 的代码、消息和数据,并且结果没有被错误地标记为执行错误。为被包装和未被包装的协议错误添加或更新针对性测试。
由索引模型根据 Issue 内容生成。
描述
Checklist
- I searched the existing issues, and this has not been reported before.
- This is a real problem that I ran into myself, using the latest release of the SDK.
- I ran into it in a production system, not in a toy example, a benchmark, or an automated or AI-driven scan of the code.
- I (a human) examined the relevant SDK code, and wrote or reviewed every line of this report. It is not unreviewed AI output.
- This report is brief and concise, and sticks to the facts needed to understand the problem.
What happened?
A typed tool handler returning a wrapped *jsonrpc.Error is treated as a tool execution error. ClientSession.CallTool returns a nil Go error and a result with IsError: true, so the JSON-RPC error code and data are lost. Returning the same protocol error directly works.
toolForErr checks err.(*jsonrpc.Error) instead of searching the error chain. The expected result is a JSON-RPC error with the underlying code, message, and data preserved when wrapped with %w.
How to reproduce
Run this program with github.com/modelcontextprotocol/go-sdk v1.8.0:
package main
import (
"context"
"errors"
"fmt"
"github.com/modelcontextprotocol/go-sdk/jsonrpc"
"github.com/modelcontextprotocol/go-sdk/mcp"
)
func main() {
ctx := context.Background()
s := mcp.NewServer(&mcp.Implementation{Name: "server", Version: "1"}, nil)
mcp.AddTool(s, &mcp.Tool{Name: "demo"}, func(context.Context, *mcp.CallToolRequest, map[string]any) (*mcp.CallToolResult, any, error) {
return nil, nil, fmt.Errorf("backend: %w", &jsonrpc.Error{
Code: jsonrpc.CodeInvalidParams,
Message: "bad input",
})
})
st, ct := mcp.NewInMemoryTransports()
ss, err := s.Connect(ctx, st, nil)
if err != nil {
panic(err)
}
defer ss.Close()
c := mcp.NewClient(&mcp.Implementation{Name: "client", Version: "1"}, nil)
cs, err := c.Connect(ctx, ct, nil)
if err != nil {
panic(err)
}
defer cs.Close()
result, err := cs.CallTool(ctx, &mcp.CallToolParams{Name: "demo"})
var rpcErr *jsonrpc.Error
fmt.Printf("protocolError=%v, err=%v\n", errors.As(err, &rpcErr), err)
if result != nil {
fmt.Printf("isError=%v\n", result.IsError)
}
}
Observed:
protocolError=false, err=<nil>
isError=true
Expected: protocolError=true, with JSON-RPC code -32602.
Where did you hit this?
Found during local code inspection and reproduced with an in-memory client and server.
Go MCP SDK version
v1.8.0
Go version
go1.26.10 darwin/arm64, also reproduced on main at 0fa5e8407aa3fda65166e4207156c03d084bfd44.
Proposed fix
Use errors.As and return the underlying protocol error.
- 主要语言
- Go
- 星标
- 5.3k
- 派生
- 614
- 平均合并
- 23 小时 55 分钟
- 30 天内合并 PR
- 62
环境准备
在浏览器里用你自己的 GitHub 账号启动这个项目的开发容器。
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
modelcontextprotocol/go-sdk 的其他 Issue
-
Expose generic `SendNotification` on `ServerSession` for custom protocol extensions可能重新可做 关联的 PR 已关闭且未合并。 未关闭needs investigation
难度 2/5 1-3 小时 新手友好度 72/100
modelcontextprotocol/go-sdk#745 · 13 条评论 · 1 个 reaction ·
维护者通常 1 天内回复
-
mcp: ClientSession.ReadResource keeps uncacheable and expired results until the session ends可能重新可做 关联的 PR 已关闭且未合并。 未关闭
难度 3/5 1-2 天 新手友好度 74/100
modelcontextprotocol/go-sdk#1526 ·
维护者通常 1 天内回复
-
mcp: streamable client keeps the session ID from a rejected server/discover, so the fallback initialize fails可能已有人在做 @simon0191 于 1 天前认领。 未关闭
modelcontextprotocol/go-sdk#1522 · 1 条评论 · 已指派 1 人 ·
维护者通常 1 天内回复
-
auth: OAuth client rejects protected resource metadata when the MCP server URL has a query string可能已有人在做 @beiryu 于 2 天前认领。 未关闭
难度 3/5 1-2 天 新手友好度 74/100
modelcontextprotocol/go-sdk#1519 · 2 条评论 ·
维护者通常 1 天内回复
-
`ping` and `logging/setLevel` still sent for protocol 2026-07-28可能已有人在做 @nahapetyan-serob 于 1 天前认领。 未关闭
难度 3/5 1-2 天 新手友好度 65/100
modelcontextprotocol/go-sdk#1518 · 1 条评论 · 已指派 1 人 ·
维护者通常 1 天内回复
查看 modelcontextprotocol/go-sdk 的全部 Issue
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 62/100
-
evener-transcript-v2-upgrade tool still scans transcript files through bufio's 4 KiB default buffer未关闭
难度 1/5 1 小时以内 新手友好度 78/100
prime-radiant-inc/evener#6370 ·
维护者通常 1 天内回复
-
ManageSieve proxy: a backend's NO/BYE greeting is skipped as a capability line and reported as EOF未关闭bug
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 1 天内回复
-
Mend: dependency security vulnerability
难度 2/5 1-3 小时 新手友好度 65/100
-
Mend: dependency security vulnerability
难度 2/5 1-3 小时 新手友好度 62/100
ManageIQ/manageiq-pods#1476 ·
维护者通常 1 天内回复