mcp: typed tool handlers lose wrapped JSON-RPC errors
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
- #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分
- マージ済み PR(30日)
- 62
環境構築
このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
modelcontextprotocol/go-sdk のほかの issue
-
Expose generic `SendNotification` on `ServerSession` for custom protocol extensions再び着手できるかも このイシューのプルリクエストはマージされずにクローズされました。 オープンneeds investigation
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
modelcontextprotocol/go-sdk#745 · コメント 13 件 · リアクション 1 件 ·
メンテナーはふだん 1 日以内に返信
-
mcp: ClientSession.ReadResource keeps uncacheable and expired results until the session ends再び着手できるかも このイシューのプルリクエストはマージされずにクローズされました。 オープン
難易度 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 日以内に返信