Claude Media
Claude CodeのMCPツールが任意パラメータ省略で拒否される原因と回避策

Claude CodeのMCPツールが任意パラメータ省略で拒否される原因と回避策

Claude DesktopのCodeタブでMCPツールの任意パラメータを省略すると、nonoptionalの検証エラーで呼び出しが拒否される不具合の原因と回避策を一次資料から解説します。

Claude Desktop(claude.aiのデスクトップアプリ)のCodeタブでMCPサーバーのツールを呼び出すと、JSON Schemaに default を持つ任意パラメータを省略しただけで拒否されることがあります。エラーは expected: "nonoptional", received: "undefined" という検証エラーで、ツール本体のロジックに届く前にクライアント側で止まります。ツールが「AとBのどちらか一方だけを指定する」という排他ルールを持つ場合は、省略しても明示指定してもどちらも通らない手詰まりになります。GitHub issue #94718で2026年9月16日から報告が続き、原因と回避策が技術的に特定されています。

Claude CodeのMCPツールで何が起きているか

症状は大きく2種類あります。1つ目は、任意パラメータを省略しただけで起きる単純な拒否です。Home Assistant連携の ha-mcp サーバーでは、fields と attribute_keys という2つの任意パラメータがどちらもJSON Schemaで {"default": null} と宣言されています。

{
  "error": "MCP error -32602: Input validation error: Invalid arguments for tool ha_get_state: [
    {\"code\":\"invalid_type\",\"expected\":\"nonoptional\",\"path\":[\"fields\"],\"message\":\"Invalid input: expected nonoptional, received undefined\"},
    {\"code\":\"invalid_type\",\"expected\":\"nonoptional\",\"path\":[\"attribute_keys\"],\"message\":\"Invalid input: expected nonoptional, received undefined\"}
  ]"
}

この単純なケースは、省略していた値を明示的に渡せば回避できます。問題は2つ目のケースです。ha_call_service というツールは、通常のサービス呼び出し(domain/service/entity_id)と、ws_command を使う一発呼び出しのどちらか一方しか受け付けません。ws_command を省略すると先ほどと同じ「値が無い」エラーになりますが、ws_command を指定すると今度はツール自身のロジックが「サービス呼び出し用のパラメータは ws_command を指定したときに含めてはいけない」と拒否します。省略も指定もどちらも失敗するため、通常のサービス呼び出しが一切できません。同じ手詰まりの形は ha_get_integration(entry_id と domain のどちらか一方)や ha_get_entity(entity_id と unique_id のどちらか一方)、ha_manage_hacs(操作ごとに必須・禁止パラメータが切り替わる)でも再現しています。

原因は同梱された2つのZodバージョンの判定のズレ

Claude DesktopのCodeタブは、MCPサーバーから受け取ったJSON Schemaを内部でいったんスキーマ検証ライブラリZodの形に変換し、その結果をもとにツール呼び出しの引数を検証します。issueのコメントでは、この変換と検証が実は別バージョンのZodで行われていることが、アプリのビルド済みコードを直接読む形で特定されました。

変換側はZod 4.5.4を使い、JSON Schemaの default を .prefault(default) に、必須でないプロパティを .optional() に変換します。Zod 4.5ではこの組み合わせが内部的に optin: "defaulted" という印を持ちます。ところが検証側はAgent SDKにバンドルされた別コピーのZod 4.4.3を使っており、こちらは optin === "optional" のときだけそのキーを省略可能と判定します。"defaulted" は "optional" と一致しないため、default を持つプロパティはすべて「値が必要」と誤判定されます。default を持たないプロパティはこの問題を受けません。

この不整合は最小構成でも再現します。Zod 4.5.4で作った z.number().prefault(200).optional() を、Zod 4.4.3の z.object() に組み込んで空オブジェクトを検証すると、limit フィールドだけが nonoptional エラーになります。同じバージョンのZodで両方を作ればエラーは起きません。issue内の検証では、あるサーバーの26個のツールのうち24個、別のサーバーの33個のツールのうち15個が、必須パラメータのみを指定した呼び出しでもこの不整合により拒否されました。

見分け方はシンプルです。エラーメッセージに "expected":"nonoptional" が含まれ、かつ拒否されたパラメータがサーバーの tools/list レスポンスで default を宣言しているなら、まずこの不整合を疑ってよいということです。MCPのツール定義がJSON Schemaのどの機能をどこまで表現できるかは、MCPのツール定義がJSON Schema 2020-12の全機能に対応で扱っています。default を含むプロパティの扱いは、そちらで解説しているスキーマ機能のひとつです。

どの環境で再現するか

報告はすべてClaude DesktopのCodeタブから寄せられており、本issueにターミナル単体の claude CLIでの再現報告はありません。トランスポート(ローカルstdioかリモートHTTPか)やOSを問わず同じ形で再現している点が、原因をクライアント側の変換・検証ロジックに絞り込む決め手になりました。

環境状況
Claude Desktop Codeタブ・ローカルstdioサーバー(macOS)状況再現。複数の独立したサーバー・OS更新で確認
Claude Desktop Codeタブ・ローカルstdioサーバー(Windows 11)状況再現。ビルド26200・MSIX版で確認
Claude Desktop Codeタブ・リモートHTTP/SSEサーバー(mcp-remote 経由含む)状況再現。トランスポートは無関係と確認済み
claude.aiのWebコネクタ経由・同一サーバー状況再現しない。同じ呼び出しが成功する対照実験で確認

claude.aiのWebコネクタ経由では同じサーバー・同じ呼び出しが成功しているため、サーバー側の実装が原因ではなく、Claude DesktopのCodeタブが持つツール呼び出しの経路に限定した問題だとわかります。

なお、MCPのツール呼び出しがクライアント側の検証で拒否される不具合はこれが初めてではありません。tools/list の応答に含まれる ttlMs や cacheScope といった拡張フィールドが原因で呼び出しが拒否される別の不具合も報告されており、詳細はMCPのtools/list応答がttlMs/cacheScopeで拒否される問題と回避策にまとめています。原因は異なりますが、いずれもサーバーが返すスキーマの特定のキーがクライアント側の検証を通らないという同じ構造の症状です。

バージョンごとの経緯

GitHub issueのコメントを時系列で追うと、この不具合が入ったバージョンと、一部の報告者で解消が確認されたバージョンは次のとおりです。

Desktop / Claude Codeのバージョン状況
Claude Code 2.1.270状況任意パラメータを省略する呼び出しが最後に成功したバージョン
Claude Code 2.1.271状況同じ形の呼び出しで初めてnonoptional拒否が発生
Claude Desktop 2.110.0〜2.110.1状況同じ不具合が継続して再現。関連issue #94608は一度クローズされたが再現は解消していない
Claude Code 2.1.274(Desktop 2.2553.0)状況ローカル拡張の呼び出しで解消したという報告あり

2.1.274での解消は、ある報告者がローカルのDesktop拡張(Apify連携)で確認した結果です。リモートHTTPサーバーやWindows環境でこの版まで検証した報告はissue内に見当たらず、どのビルドが実際に修正したのかも断定されていません。バージョンを更新しても再現するようなら、issueのコメント欄で他の報告者の環境と照合すると判断しやすくなります。

nonoptionalエラーを回避する方法

対処はサーバーを自分で管理しているかどうかで変わります。

サーバーを管理していない場合にできること

省略していた任意パラメータに、スキーマ上有効な値を明示的に渡すと、単純な拒否(先ほどの ha_get_state の例)は避けられます。ただし2つの制約があります。1つは、entity_id のように「AかBのどちらか一方」を要求するツールでは、この方法自体が使えないことです。もう1つは、anyOf: [{"type": X}, {"type": "null"}] のようにnullを許容する型では、Claude DesktopがJSONの null ではなく文字列の "null" を送ってしまう報告があることです。サーバー側がこの文字列を null として扱わない実装だと、明示的に値を渡しても失敗します。

MCPサーバーを自分で公開している場合の対処

サーバーを実装・運用しているなら、tools/list が返す inputSchema.properties から default キーだけを取り除き、デフォルト値の適用自体はサーバー側のハンドラで続ける方法が有効です。Claude Desktopの変換ロジックは default が無いプロパティを単純な .optional() に変換するため、Zod 4.4.3の検証も通過します。issueではこの対処をFastMCP 3.xのミドルウェアで実装した例が共有されています。

# FastMCP 3.x: tools/list が返すスキーマから default だけを構造的に取り除く
@server.on_list_tools
def strip_defaults(tools):
    return [
        tool.model_copy(update={"parameters": schema_without_property_defaults(tool.parameters)})
        for tool in tools
    ]

スキーマを書き換える際は、プロパティ名で default を探すのではなく、スキーマの構造を辿って properties オブジェクト直下の default だけを対象にする必要があります。パラメータ自体が properties という名前を持つケースもあるためです。

設定を直しても直らないときに確認すること

MCPサーバー側のスキーマを修正しても、Claude Desktopの /mcp パネルからサーバーを再接続するだけでは反映されなかったという報告があります。ツールの一覧はアプリ本体の接続単位でキャッシュされており、反映にはClaude Desktop自体をいったん完全に終了し、再起動する操作が必要だったとされています。

/mcp

公式ドキュメントによると、/mcp でのリモートサーバーの再接続はディスカバリーキャッシュのエントリを破棄し、サーバーからツール一覧を取り直す操作です。ローカルのstdioサーバーは自動再接続の対象外で、プロセスを再起動してもClaude Code側からの自動再接続は行われません。サーバーが list_changed 通知を送れば、Claude Codeは本来ツール定義を自動で取り直します。この仕組みの詳細はMCPのツール更新と接続断からの自動再接続の仕組みで扱っています。今回の不具合のように、Claude Desktopアプリ自体がツール一覧をアプリ単位で保持しているケースでは、list_changed 通知や /mcp の再接続操作だけでは反映されない場合がある点を覚えておくとよいでしょう。

Zodを別々に同梱する構成は変換と検証の意味をずらす

今回の原因は、単一の製品の中に同じライブラリの異なるバージョンが独立してバンドルされ、片方の判定結果をもう片方が正しく解釈できなかったことです。Claude DesktopはMCP用のTypeScript SDKと、ツール実行を担うAgent SDKをそれぞれ別々に同梱しており、両者が内部で使うZodのバージョンが揃っていませんでした。MCPのようにサーバー側が任意のJSON Schemaを宣言し、クライアント側がそれを別の型システムに変換して検証するアーキテクチャでは、変換とその後の検証を同じライブラリ・同じバージョンで行わない限り、こうした意味論のズレはいつでも起こり得ます。Claude Codeを含め、MCPクライアントを自作・拡張する開発者にとっても、依存ライブラリを分離してバンドルする構成には注意が必要だという教訓です。

まとめ

Claude DesktopのCodeタブでMCPツールを呼び出す際、任意パラメータに default が宣言されていると、省略した呼び出しが nonoptional エラーで拒否されることがあります。原因は、JSON Schemaをツール呼び出し用の型に変換する処理と、その型を検証する処理で異なるバージョンのスキーマ検証ライブラリが使われていることです。排他的なパラメータ設計を持つツールでは、省略も明示指定もどちらも失敗する完全な手詰まりになります。自分でサーバーを管理しているなら tools/list のスキーマから default を外す対処が有効ですが、反映にはClaude Desktopの完全な再起動が必要になる場合があります。管理していないサーバーでは、Claude Desktop側の修正を待つか、issueのコメント欄で該当バージョンでの再現状況を確認してください。

この記事を共有:XはてブLinkedIn