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

Where does validation of a peer's declarations belong? Four things the client accepts today

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

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

まだ誰も着手していません。

評価

難易度
5/5
見積もり時間
1週間以上
初心者へのやさしさ
30/100
issue の種類
機能追加
明瞭さ
説明が足りない
活発さ
活発
技術スタック
node.js, typescript
領域
api, security

調査の方向性

ファイルもテストも指定されていません。client.listTools() のレスポンスパスとその Zod バリデーションから始め、次にリクエスト ID がどのように照合されるかを確認してください。完了の条件は、どの宣言チェックを SDK に含めるべきか、またそのポリシーを文書化すべきかについて、メンテナーの判断が下されることです。

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

説明

v1 v2

This is a scope question rather than four bug reports, and I would rather ask it than assume the answer.

Probing the stdio client against deliberately malformed servers, I found four things it accepts without comment. Some of them the spec says something about; for others it is silent. In every case the SDK is the one place that sees the data before any application does, which is why it seems worth asking where the line is — not because accepting them is obviously wrong.

All on @modelcontextprotocol/[email protected], Node 22.22.1, via client.listTools().

# Server returns Client result What the spec says
1 two tools both named same tools.length === 2, both kept "name: Unique identifier for the tool"
2 a tool named safe​‮tool accepted verbatim name is "used as a display name ... fallback (if title isn't present)"
3 numeric request id 0, response id "0" matched, resolves normally RequestId = string | number; JSON-RPC 2.0 requires the response id to equal the request's
4 100,000 tools in one response all 100,000 returned, 406ms nothing

Reproduction for any row — server answers initialize normally, then returns the listed payload for tools/list:

// #1
{ tools: [
  { name: 'same', description: 'First.',  inputSchema: { type: 'object' } },
  { name: 'same', description: 'Second.', inputSchema: { type: 'object' } },
]}
// #2  — U+200B zero width space, U+202E right-to-left override
{ tools: [{ name: 'safe​‮tool', description: 'd', inputSchema: { type: 'object' } }] }
// #3  — request went out with id 0
{ jsonrpc: '2.0', id: '0', result: { tools: [] } }

Why #2 is the one I would actually argue about

The other three are conformance questions. This one interacts with a control the spec asks clients to provide:

For trust & safety and security, there SHOULD always be a human in the loop with the ability to deny tool invocations.

U+202E reverses the display order of everything after it. Combined with name being the display fallback when title is absent, a server can choose a name that renders in an approval dialog as something other than the name the model will call. The human in the loop is then approving a string that does not exist.

That is not a transport bug — the bytes are delivered faithfully, which is the transport's job. But the SDK is the last place that sees the name as bytes before an application renders it as text, and an application author has no particular reason to expect a tool name to contain a bidi override.

The actual question

Is any of this the SDK's business, or is it all the application's?

A defensible answer is "all of it" — the SDK transports and parses, and what a client does with a hostile server's declarations is a policy decision above it. If that is the position, then it is worth saying so somewhere, because the current behaviour reads as "validated" rather than "passed through": responses go through a Zod schema, so an application author could reasonably conclude that anything reaching them has been checked.

If some of it is in scope, #1 and #3 are the cheap ones — a duplicate-name check and an id type comparison, both a few lines and neither a breaking change for a conforming server.

I am not proposing a PR yet because the answer determines whether there is anything to write. Happy to do so once the direction is clear.


Context on where this came from, since it explains the odd angle: I maintain a scanner that connects to MCP servers before anyone has established they are trustworthy, so it treats hostile declarations as the normal case. #2775 and #2776 came out of the same probing.

主要言語
TypeScript
スター
13.6k
フォーク
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 を短くまとめたダイジェスト。