Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

A handler that throws McpError produces a double-prefixed message on the client

オープン
#2,786 コメント 4 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@errmakov がすでに取り組んでいます。

2026年9月27日 から。

  • #2881 @MustafaKemal0146 による — オープン

評価

難易度
3/5
見積もり時間
1〜2日
初心者へのやさしさ
68/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
活発
技術スタック
typescript

調査の方向性

Protocol._onresponse と McpError.fromError から開始し、レポートに記載されている _requestResolvers と通常のレスポンスパスの両方を追跡します。InMemoryTransport 経由で callTool の拒否を再現し、その後、UrlElicitationRequired ブランチを退行させることなく、エラーメッセージにプレフィックスが 1 回だけ付くことを確認します。スローされた McpError レスポンスが 1 つの MCP エラープレフィックス付きでクライアントに届けば完了です。

索引モデルが issue の本文から書いたものです。

説明

v1

What happens

A request handler that throws McpError produces a message the client shows with the prefix twice.
Reproduced with the SDK alone over InMemoryTransport on 1.24.3, and the code path is unchanged in the
current 1.30.0:

server.setRequestHandler(CallToolRequestSchema, async () => {
  throw new McpError(ErrorCode.MethodNotFound, "Unknown tool: nope");
});
// ...
try { await client.callTool({ arguments: {}, name: "nope" }); }
catch (e) { console.log("client received:", e.message); }
server threw:   MCP error -32601: Unknown tool: nope
client received: MCP error -32601: MCP error -32601: Unknown tool: nope

Why

Three steps, each defensible alone:

  1. McpError's constructor calls super(`MCP error ${code}: ${message}`), so .message already carries
    the prefix.
  2. The server serialises a thrown error as message: error.message, so the prefix travels inside the
    JSON-RPC error.message field.
  3. Protocol._onresponse converts it back with McpError.fromError(response.error.code, response.error.message, response.error.data), whose default branch returns
    new McpError(code, message, data) and prefixes what is already prefixed. I confirmed at runtime that
    this is the path a callTool rejection takes, by counting calls into fromError: exactly one.

_onresponse also holds a new McpError(...) conversion in its _requestResolvers branch, for queued
responses, which double-prefixes for the same reason.

Throwing McpError is the SDK's own mechanism and shared/protocol throws it in several places itself, so
this is the default result rather than a misuse.

What I expected

One prefix. Either the JSON-RPC error.message carries the bare message, or the client stops re-wrapping a
message that already has the prefix.

Not checked

Only InMemoryTransport, and only a callTool rejection. The one branch of fromError that does not take
the default path is UrlElicitationRequired carrying elicitations, which returns
UrlElicitationRequiredError; that class calls super with the same code, so I would expect it to prefix
too, but I did not exercise it.

主要言語
TypeScript
スター
13.5k
フォーク
2.3k
平均マージ
1日 15時間
マージ済み PR(30日)
51

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

modelcontextprotocol/typescript-sdk のほかの issue

modelcontextprotocol/typescript-sdk の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。