MCPサーバーで「Invalid Params」が出る原因|JSON Schemaと引数を確認

MCPサーバーで「Invalid Params」が出る原因|JSON Schemaと引数を確認 AI開発

MCPサーバーでToolを実行したときに、次のようなエラーが発生することがあります。

エラー例
Invalid Params

JSON-RPCのエラーコードまで表示される場合は、次のようになります。

JSON-RPCエラー
{
  "code": -32602,
  "message": "Invalid params"
}

Method not foundが「そのJSON-RPC Methodを処理できない」というエラーなのに対して、Invalid Paramsは基本的に、Method自体は認識されているものの、そのMethodへ渡されたパラメータが正しくない状態を表します。

MCPはJSON-RPC 2.0を利用しており、-32602は標準のInvalid Paramsに対応しています。MCP公式SDKでも、-32602は基本的なJSON-RPCエラーコードとして定義されています。

ただしMCPのTool Callingでは、少し注意が必要です。

tools/call自体のparams構造が間違っている場合と、argumentsがToolのinputSchemaに合っていない場合は、同じ「引数が不正」に見えても、SDKによってエラーの返し方が異なることがあります。

この記事では、MCPサーバーでInvalid Paramsが発生する代表的な原因と、tools/call、JSON Schema、argumentsを確認する方法を解説します。Method自体が認識されない-32601 Method not foundとの切り分け方はMCPサーバーが「Method not found」になる原因で解説しているため、この記事ではMethodは正しく認識されている前提で、パラメータ側の原因を扱います。

スポンサーリンク
  1. Invalid ParamsはJSON-RPCの-32602エラー
  2. まずtools/callのparams構造を確認する
  3. argumentsをparams直下に書いていないか確認する
  4. tools/listでinputSchemaを確認する
  5. requiredの引数が抜けていないか確認する
  6. stringとintegerの型違いを確認する
  7. objectをstringとして渡していないか確認する
  8. arrayとobjectの取り違えも確認する
  9. enumに存在しない値を渡していないか確認する
  10. additionalPropertiesで余計な引数が拒否されるケース
  11. JSON Schemaと実際の関数定義がずれていないか確認する
  12. 高レベルSDKではSchema検証を自動で行える
  13. JSON SchemaエラーとJSON-RPC Invalid Paramsは必ずしも同じではない
  14. 本当の-32602とToolのisErrorを区別する
  15. MCPErrorで明示的にInvalid Paramsを返しているケース
  16. モデルが修正できるエラーならTool Errorとして返す方法もある
  17. MCP 2026-07-28ではJSON Schema 2020-12へ拡張されている
  18. inputSchemaのルートはobjectにする
  19. 古いSDKと新しいSchemaを組み合わせていないか確認する
  20. inputSchema自体が壊れていないか確認する
  21. tools/listのSchemaと実際に使っているSchemaが同じか確認する
  22. Toolの名前を変えずにSchemaだけ変更した場合は特に注意する
  23. minLengthやmaximumなど追加制約も確認する
  24. nullと引数なしは同じとは限らない
  25. MCP Inspectorでargumentsを直接確認する
  26. 最小のargumentsから少しずつ追加する
  27. ログにはSchema Validationの詳細を残す
  28. Streamable HTTPではHeaderMismatchとInvalid Paramsを混同しない
  29. 存在しないTool名でも-32602になることがある
  30. 2026-07-28では存在しないResourceも-32602になる
  31. tools/listにもInvalid Paramsが出る場合がある
  32. AIモデルが何度も同じ不正引数を送る場合はSchema説明を見直す
  33. 再試行させるなら同じargumentsをそのまま送らない
  34. Invalid Paramsを調べるならtools/listと実際のargumentsを比較する
  35. Invalid Paramsに関するよくある質問
  36. まとめ

Invalid ParamsはJSON-RPCの-32602エラー

MCPでは、Toolを実行するときにtools/callというJSON-RPC Methodを利用します。

たとえばsearch_booksというToolを呼ぶ場合は、概念的には次のようなRequestになります。

tools/callのリクエスト
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search_books",
    "arguments": {
      "query": "MCP",
      "limit": 10
    }
  }
}

ここではtools/callというMethodが存在し、

パラメータ
name

arguments

というパラメータを渡しています。

もしMethod名そのものが間違っていれば、前の記事で解説した-32601 Method not foundになる可能性があります。

一方、tools/callは認識できるものの、paramsの構造が正しくなければ-32602 Invalid Paramsとして拒否される可能性があります。

つまり最初に確認したいのは、

問1
Methodが間違っているのか

ではなく、

問2
Methodへ渡したparamsが間違っているのか

という違いです。

まずtools/callのparams構造を確認する

Toolを実行する場合、基本的にはparams.nameへTool名、params.argumentsへToolの引数を渡します。

正常な形は次のようになります。

正常な形
{
  "method": "tools/call",
  "params": {
    "name": "get_weather",
    "arguments": {
      "location": "Tokyo"
    }
  }
}

たとえば次のようにnameが存在しないRequestを独自クライアントから送っている場合は、正常なTool Callとして処理できません。

nameがない例
{
  "method": "tools/call",
  "params": {
    "arguments": {
      "location": "Tokyo"
    }
  }
}

逆にTool名をtoolという独自フィールドへ入れていても、MCP標準のtools/callとしては期待される形と異なります。

独自フィールドの例
{
  "method": "tools/call",
  "params": {
    "tool": "get_weather",
    "arguments": {
      "location": "Tokyo"
    }
  }
}

MCP SDKの高レベルClient APIを使っている場合、このような構造は通常SDKが生成してくれます。

一方、HTTPやstdio上のJSON-RPCを直接組み立てている場合は、Request Bodyそのものを確認してください。

argumentsをparams直下に書いていないか確認する

独自実装でよく起きるのが、Tool引数をparams直下へ展開してしまうケースです。

たとえば次の形です。

展開してしまった例
{
  "method": "tools/call",
  "params": {
    "name": "search_books",
    "query": "MCP",
    "limit": 10
  }
}

Toolへの入力は基本的にarguments内へ入れます。

正しい形
{
  "method": "tools/call",
  "params": {
    "name": "search_books",
    "arguments": {
      "query": "MCP",
      "limit": 10
    }
  }
}

MCP Python SDKのLow-level Serverの例でも、CallToolRequestParamsからparams.nameparams.argumentsを取得する形になっています。

REST APIの感覚で、

REST風の思い込み
params.query

params.limit

のように送っている場合は、まずRequest構造を見直してください。

tools/listでinputSchemaを確認する

tools/callの形が正しければ、次に確認したいのがToolのinputSchemaです。

MCPではサーバーがtools/listでTool一覧を返す際、それぞれのToolについて入力Schemaも公開します。

たとえばPython SDKで、

Tool定義
def search_books(query: str, limit: int):
    ...

のようなToolを定義すると、SDKは型情報から次のようなJSON Schemaを生成できます。

生成されるSchema
{
  "type": "object",
  "properties": {
    "query": {
      "type": "string"
    },
    "limit": {
      "type": "integer"
    }
  },
  "required": ["query", "limit"]
}

MCP Python SDKでは、Toolの型ヒントからJSON Schemaを生成し、tools/listでクライアントへ公開する仕組みが提供されています。

そのため引数エラーを調べるときは、サーバー側のコードだけを見るのではなく、実際にtools/listでクライアントへ返されたinputSchemaを確認することが重要です。

requiredの引数が抜けていないか確認する

もっとも分かりやすい原因が必須引数の欠落です。

たとえばinputSchemaが次のようになっているとします。

inputSchema
{
  "type": "object",
  "properties": {
    "query": {
      "type": "string"
    },
    "limit": {
      "type": "integer"
    }
  },
  "required": ["query", "limit"]
}

このToolを次のように呼ぶと、limitがありません。

limitがない例
{
  "name": "search_books",
  "arguments": {
    "query": "MCP"
  }
}

Schema上ではquerylimitの両方が必須なので、入力検証に失敗します。

修正するなら、

修正例
{
  "name": "search_books",
  "arguments": {
    "query": "MCP",
    "limit": 10
  }
}

とします。

AIエージェント経由で発生している場合は、モデルがrequiredの引数を生成できていない可能性があります。

その場合はTool名だけでなく、Toolのdescriptionや引数説明が十分かも確認するとよいでしょう。

stringとintegerの型違いを確認する

JSON Schemaでは値の型も重要です。

たとえばlimitがintegerとして定義されています。

Schema
{
  "limit": {
    "type": "integer"
  }
}

正常なのは次の形です。

正常
{
  "limit": 10
}

一方、

型違い
{
  "limit": "10"
}

は文字列です。

見た目は同じ「10」でも、JSON Schemaでは別の型として扱われます。

同様に、

string
{
  "enabled": "true"
}

と、

boolean
{
  "enabled": true
}

も異なります。

前者はstring、後者はbooleanです。

AIモデルがFunction Callingで引数を生成する場合だけでなく、フォーム入力や環境変数から引数を組み立てている場合にも型変換を確認してください。

objectをstringとして渡していないか確認する

Tool引数にobjectを要求する場合にも注意が必要です。

たとえばSchemaが、

Schema
{
  "filters": {
    "type": "object",
    "properties": {
      "category": {
        "type": "string"
      }
    }
  }
}

となっている場合、期待される引数は、

正常
{
  "filters": {
    "category": "AI"
  }
}

です。

次のようにJSON文字列を入れるのは別のデータ型です。

間違い
{
  "filters": "{\\"category\\":\\"AI\\"}"
}

これはobjectではなくstringです。

Tool Calling実装で、

余計な処理
JSON.stringify(filters)

を余計に実行していないか確認してください。

JSON-RPC Request全体はJSONへシリアライズしますが、その中のargumentsまで二重にJSON文字列化する必要はありません。

arrayとobjectの取り違えも確認する

配列も同様です。

Schemaが、

Schema
{
  "tags": {
    "type": "array",
    "items": {
      "type": "string"
    }
  }
}

なら、

正常
{
  "tags": ["MCP", "AI"]
}

のように渡します。

次の形ではstringです。

string
{
  "tags": "MCP,AI"
}

また、

object
{
  "tags": {
    "0": "MCP",
    "1": "AI"
  }
}

ならobjectです。

APIやHTMLフォームから取得した値をそのままMCP Toolへ渡している場合は、Schemaと実データの型が一致しているか確認してください。

enumに存在しない値を渡していないか確認する

Toolの入力を限定するためにenumを使用している場合があります。

たとえば、

Schema
{
  "unit": {
    "type": "string",
    "enum": ["celsius", "fahrenheit"]
  }
}

というSchemaなら、

有効
{
  "unit": "celsius"
}

は有効です。

一方、

無効1
{
  "unit": "Celsius"
}

や、

無効2
{
  "unit": "centigrade"
}

はSchemaに含まれていません。

大文字・小文字の違いでも一致しない可能性があります。

Toolのdescriptionでは「摂氏」と説明しているのに、enum値はcelsiusを要求するといった構成では、モデルが別の表現を生成する可能性もあります。

enumを使う場合は、モデルから見ても選択可能な値が分かりやすいSchemaにするとよいでしょう。

additionalPropertiesで余計な引数が拒否されるケース

JSON Schemaに、

Schema
{
  "additionalProperties": false
}

を設定している場合、定義されていない引数を追加すると検証に失敗します。

たとえばSchemaが、

Schema
{
  "type": "object",
  "properties": {
    "query": {
      "type": "string"
    }
  },
  "required": ["query"],
  "additionalProperties": false
}

なら、

有効
{
  "query": "MCP"
}

は有効です。

一方、

無効
{
  "query": "MCP",
  "limit": 10
}

limitがSchemaに定義されていません。

モデルが「便利そうだから」と独自パラメータを追加する場合や、古いTool Definitionで使っていた引数が会話履歴に残っている場合にも発生する可能性があります。

ToolのSchemaを変更した直後にエラーが増えた場合は、旧引数を送っていないか確認してください。

JSON Schemaと実際の関数定義がずれていないか確認する

Low-level Serverを自作している場合は、公開しているinputSchemaと内部Handlerが期待する引数が一致していないケースがあります。

たとえばtools/listでは、

公開しているSchema
{
  "properties": {
    "query": {
      "type": "string"
    }
  },
  "required": ["query"]
}

と公開しているのに、Handler側では、

Handler側
limit = arguments["limit"]

を要求している状態です。

クライアントはinputSchemaを見て正しくqueryだけを送っています。

しかしHandlerはlimitが来る前提なので失敗します。

このケースは必ずしもInvalid Paramsになるとは限りません。

MCP Python SDKのLow-level Serverはv2で、公開したinput_schemaparams.argumentsへ自動検証する機能を廃止しています。そのため存在しないキーへアクセスするとKeyErrorなどになり、結果として-32603 Internal server errorになる可能性があります。

つまり、

状況
Schema上は正しいのにInternal server errorになる

場合は、Low-level Server側の手動検証不足も疑ってください。

高レベルSDKではSchema検証を自動で行える

MCPの高レベルSDKでは、Tool定義と入力検証をまとめて管理できることがあります。

TypeScript SDK v2のregisterToolでは、Schemaを使ってtools/listで公開するJSON Schemaを生成すると同時に、tools/callで受け取った引数も検証します。

たとえばZodで文字数を2文字に制限したSchemaを使えば、それより長い値を渡した時点でHandlerを実行する前に入力検証で拒否されます。

入力検証の例
const StateSchema = z.object({
  state: z.string().min(2).max(2)
});

つまりHigh-level SDKを使えば、

公開したSchema
公開したSchema

と、

実際の入力検証
実際の入力検証

を同じ定義から生成できるため、二重管理によるズレを減らせます。

JSON SchemaエラーとJSON-RPC Invalid Paramsは必ずしも同じではない

ここは重要なポイントです。

「ToolのargumentsがSchemaに合わない=必ずJSON-RPCの-32602 Invalid Paramsになる」と考えると、ログを読み違える可能性があります。

現在のMCP SDKでは、Tool入力がSchemaに合わない場合、モデルが修正できるようにCallToolResultisError: trueとして返す実装があります。

TypeScript SDKでも、Tool入力Schemaに違反した場合は、

Tool Result
{
  "content": [
    {
      "type": "text",
      "text": "Input validation error: ..."
    }
  ],
  "isError": true
}

のようなTool Resultになる実装があります。

Java SDKでもデフォルトでは、受信したTool引数をinputSchemaに対して検証し、失敗するとHandlerを呼ばずCallToolResultのエラーとして返します。

この場合、Protocol自体は正常です。

モデルがToolへ渡した引数だけが間違っているため、「モデルにエラーを見せて修正させる」という扱いになります。

本当の-32602とToolのisErrorを区別する

ログを見るときは、

パターン1
JSON-RPC error -32602

なのか、

パターン2
tools/callは成功したがCallToolResult.isErrorがtrue

なのかを区別する必要があります。

前者では通常、JSON-RPC Responseにresultがありません。

たとえば、

Protocol Error
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32602,
    "message": "Invalid params"
  }
}

という形です。

一方、Tool入力検証エラーをResultとして返す場合は、概念的には、

Tool Result Error
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Invalid arguments for tool search_books"
      }
    ],
    "isError": true
  }
}

となります。

ユーザーから見るとどちらも「Toolが失敗した」ように見えますが、処理レイヤーが違います。

この区別ができると原因調査がかなり楽になります。

MCPErrorで明示的にInvalid Paramsを返しているケース

サーバー実装側が意図的に-32602を返している可能性もあります。

MCP Python SDKでは、Tool Handler内からMCPErrorを送出すると、通常の例外とは異なりSDKに捕捉されず、そのまま本物のJSON-RPCエラーとしてクライアントへ届きます。INVALID_PARAMSを指定することもできます。

たとえば存在しない書籍名に対して、

MCPErrorの例
raise MCPError(
    code=INVALID_PARAMS,
    message="No book titled ... in the catalog."
)

のようにすると、tools/call全体がJSON-RPCエラーとなり、クライアント側に-32602が返ります。これは、通常のPython例外が捕捉されてCallToolResult(isError=True)に変換されるのとは異なる、MCPError特有の挙動です。

つまりエラーが出たら、SDKが自動生成していると決めつけず、コード内で、

検索キーワード
INVALID_PARAMS

-32602

MCPError

を検索してみる価値があります。

アプリケーション独自の入力検証で意図的に返している可能性があります。

モデルが修正できるエラーならTool Errorとして返す方法もある

Toolの引数ミスが原因なら、Protocol Errorとして終了するより、モデルへエラー内容を返して再試行させたほうが適切な場合があります。

Protocol Error(-32602など)はモデルには見えないのに対し、CallToolResultisError: trueはcontentとしてモデルに見えるため、モデル自身が入力を修正できるかどうかが使い分けの基準になります。

たとえば、

修正可能なエラー
limitは1〜100で指定してください

というエラーなら、モデルはlimit: 1000limit: 100へ修正できます。

一方、サーバー自体が処理を受け付けられない場合などはProtocol Errorとして扱うほうが自然です。

すべてをInvalid Paramsで終了させるのではなく、モデルが自動修正できるエラーかどうかで扱いを分けるとAIエージェントが安定します。

MCP 2026-07-28ではJSON Schema 2020-12へ拡張されている

2026年7月28日のMCP仕様では、ToolのinputSchemaoutputSchemaがJSON Schema 2020-12へ拡張されています。

inputSchemaは引き続きルートがobjectである必要がありますが、oneOfanyOfallOf、条件分岐、$ref$defsなどを利用できるようになっています。

そのため新しいMCPサーバーでは、以前より複雑な入力Schemaを定義できます。

たとえば、

oneOfの例
{
  "type": "object",
  "properties": {
    "target": {
      "oneOf": [
        { "type": "string" },
        { "type": "integer" }
      ]
    }
  },
  "required": ["target"]
}

のようなSchemaも扱えるようになります。

ただしSchemaが複雑になれば、モデルが正しい引数を生成できているかの確認も重要になります。

inputSchemaのルートはobjectにする

2026-07-28でJSON Schemaの対応範囲は広がっていますが、ToolのinputSchemaは引き続きルートがobjectである必要があります。

そのため、次のようにarrayだけをルートへ置くのは避けます。

ルートをarrayにした不正例
{
  "type": "array",
  "items": {
    "type": "string"
  }
}

配列を受け取りたい場合はobjectで包みます。

objectで包む修正例
{
  "type": "object",
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  },
  "required": ["items"]
}

Schemaを自動生成している場合は、生成後のinputSchemaが実際にどうなっているかtools/listで確認してください。

古いSDKと新しいSchemaを組み合わせていないか確認する

MCP 2026-07-28ではJSON Schema対応範囲が広がっているため、新仕様を前提としたSchemaを古いSDKやクライアントへ渡す場合には互換性も確認してください。

新しいServerが、

新仕様のキーワード
oneOf

anyOf

allOf

$defs

などを利用しているのに、古いClient側のSchema処理がそれを想定していなければ、Tool引数生成や検証が意図どおり動かない可能性があります。

SDKを更新した直後にエラーが出た場合だけでなく、Serverだけ新しくした場合もProtocol VersionとSDKの組み合わせを確認するとよいでしょう。

inputSchema自体が壊れていないか確認する

Toolの引数だけでなく、inputSchemaそのものが不正なケースもあります。

たとえばJSON Schemaを手書きしていて、

間違った型名
{
  "type": "object",
  "properties": {
    "limit": {
      "type": "int"
    }
  }
}

としている場合、intは標準的なJSON Schemaの型名ではありません。

通常は、

正しい型名
{
  "type": "integer"
}

とします。

Java SDKはToolのinputSchemaなどについてJSON Schema 2020-12のメタスキーマによる検証を行い、不正なSchemaはTool登録時やServer Build時に拒否される仕組みがあります。

Low-level実装では自分でSchemaを扱う場面もあるため、「入力が間違っている」と思ったらSchema側にも問題がないか確認してください。

tools/listのSchemaと実際に使っているSchemaが同じか確認する

MCP Serverを動的に構成している場合は、古いSchemaがキャッシュされているケースにも注意してください。

たとえば以前は、

以前
{
  "query": "MCP"
}

だけで呼べるToolだったとします。

その後、

変更後
{
  "query": "MCP",
  "limit": 10
}

へ変更し、limitをrequiredにします。

しかしClientが古いtools/list結果を使っていると、モデルはlimitが必要だと知りません。

その結果、古い形式でToolを呼び続ける可能性があります。

MCPにはTool一覧が変化したことをサーバーからクライアントへ知らせるnotifications/tools/list_changedという通知が用意されています。対応するClientでは、この通知を受け取ったタイミングでtools/listを再取得する構造にしておくと、こうしたSchemaの食い違いを防ぎやすくなります。

Tool Definitionを変更した直後にInvalid Paramsや入力検証エラーが増えた場合は、Clientが最新のtools/listを取得しているかも確認してください。

Toolの名前を変えずにSchemaだけ変更した場合は特に注意する

Tool名が同じままSchemaだけを変更すると、古い会話履歴やキャッシュとの不整合が分かりにくくなります。

たとえば、

Tool名
search_books

という名前はそのままで、以前は、

以前
{
  "query": "MCP"
}

だったのを、

変更後
{
  "query": "MCP",
  "limit": 10,
  "language": "ja"
}

に変更するとします。

モデルから見ると同じTool名なので、以前のCalling Patternをそのまま再利用する可能性があります。

大きなBreaking Changeを加える場合は、

別名で分ける
search_books_v2

のように一時的にTool名を分ける方法もあります。

長期的には旧Toolを廃止できますが、移行期間中の入力不整合を減らしやすくなります。

minLengthやmaximumなど追加制約も確認する

Schemaは型とrequiredだけとは限りません。

たとえば、

Schema
{
  "limit": {
    "type": "integer",
    "minimum": 1,
    "maximum": 100
  }
}

なら、

制約違反
{
  "limit": 1000
}

はintegerとしては正しくてもSchemaには違反します。

TypeScript SDKで使われるSchemaライブラリでも、繰り返し回数などに.max()で上限を設定すれば、それを超える値はHandler実行前に入力検証エラーになります。

そのためInvalid Argument系のエラーでは、

型のみ
型が正しい

だけで判断せず、

追加制約
minimum

maximum

minLength

maxLength

pattern

enum

など追加制約も確認してください。

nullと引数なしは同じとは限らない

任意パラメータの扱いでも問題が起こります。

たとえばSchemaが、

null許容
{
  "category": {
    "type": ["string", "null"]
  }
}

なら、

有効
{
  "category": null
}

は許可されます。

しかしSchemaが、

null未許容
{
  "category": {
    "type": "string"
  }
}

ならnullはstringではありません。

また、

引数なし
{}

と、

nullを渡す
{
  "category": null
}

も意味が異なります。

AIモデルが値を取得できなかった場合に、自動的にnullを入れる設計になっていると、Schemaによっては検証エラーになります。

MCP Inspectorでargumentsを直接確認する

AIホスト経由で実行していると、モデルが実際にどの引数を生成したのか分かりにくくなる場合があります。

その場合はMCP Inspectorなどを使って、Toolを直接実行すると切り分けやすくなります。具体的な操作手順はMCP Inspectorの使い方で解説しています。

最初にtools/listでSchemaを確認します。

次にSchemaどおりの最小引数でToolを実行します。

たとえば、

最小引数
{
  "query": "test",
  "limit": 1
}

で成功するか確認します。

これで成功するならMCP ServerとSchema Validation自体は正常で、AIホスト側が生成している引数に原因がある可能性が高くなります。

逆にInspectorから正しい引数を送っても失敗するならServer側のTool定義やValidation処理を調べます。

最小のargumentsから少しずつ追加する

複雑なSchemaでは、どの引数が原因か分かりにくくなります。

たとえば、

失敗するCall
{
  "query": "MCP",
  "filters": {
    "category": "AI",
    "language": "ja",
    "year": 2026
  },
  "sort": "date",
  "limit": 20
}

というTool Callが失敗しているとします。

最初に必須項目だけへ減らします。

最小構成
{
  "query": "MCP"
}

これが成功したら、

少しずつ追加
{
  "query": "MCP",
  "limit": 20
}

へ増やします。

さらにfiltersを追加します。

このように1項目ずつ戻していけば、問題のフィールドを特定しやすくなります。

巨大なJSONを眺めて原因を探すより効率的です。

ログにはSchema Validationの詳細を残す

本番環境では、

情報不足なログ
Invalid Params

だけをログへ出しても原因を判断できません。

可能であれば、

記録したい項目
Tool名

受け取ったarguments

失敗したフィールド

期待した型

実際の型

Protocol Version

に相当する情報を追跡できるようにします。

ただしTool引数にはAPIキー、メールアドレス、ユーザーデータなどが含まれる可能性があります。

そのため本番ログへarguments全体をそのまま保存するのではなく、秘密情報や個人情報をマスキングすることも必要です。

Streamable HTTPではHeaderMismatchとInvalid Paramsを混同しない

MCP 2026-07-28のStreamable HTTPでは、Tool引数の一部をMcp-Param-* Headerへ反映する仕組みがあります。

この場合、HeaderとJSON-RPC Bodyの値が一致しなければ、-32602 Invalid Paramsではなく、-32020 HeaderMismatchとして拒否されます。

たとえばRequest Bodyでは、

Body
{
  "tenant": "company-a"
}

なのに、HTTP Header側では、

Header
Mcp-Param-Tenant: company-b

となっていれば問題です。

2026-07-28仕様でStreamable HTTPを利用している場合は、

切り分け
Invalid Params

HeaderMismatch

を別の問題として切り分けてください。

ProxyやAPI Gatewayを挟んでいる構成では特に重要です。

存在しないTool名でも-32602になることがある

-32602が出たからといって、必ずargumentsのJSON Schemaが原因とは限りません。

tools/callというMethod自体は正しく認識されていても、params.nameで指定したTool名がサーバー側に存在しなければ、そのパラメータの値自体が不正だとみなされ、-32602 Invalid Paramsとして扱われる場合があります。

たとえば、

タイプミスした呼び出し
{
  "method": "tools/call",
  "params": {
    "name": "search_product",
    "arguments": {
      "query": "RTX 5070"
    }
  }
}

と送ったものの、実際に登録されているToolが、

実際の登録名
search_products

だった場合です。

search_productsearch_productsは1文字違うだけの別のTool名であり、モデルやクライアントの単純なタイプミスでも発生します。

これはMethod not foundとは別の問題です。tools/callというMethod自体には到達しているため、まずTool名のスペルがtools/listの結果と一致しているかを確認し、それでも解決しない場合にだけargumentsのSchemaを調べるという順番にすると効率的です。

2026-07-28では存在しないResourceも-32602になる

-32602はTool引数エラーだけに使われるわけではありません。

2026-07-28仕様では、存在しないResource URIについて、以前のMCP固有コード(-32002)からJSON-RPC標準の-32602 Invalid Paramsへ変更されています。

TypeScript SDKでもResource Not Foundは-32602として扱われ、error.dataにURIが含まれることで通常のInvalid Paramsと区別できるようになっています。

そのためログに、

エラーコード
-32602

だけが出ているからといって、必ずToolのJSON Schemaが原因とは限りません。

まずどのMethodへのResponseなのか確認してください。

tools/callならTool引数を調べます。

resources/readならResource URIを調べる必要があります。

tools/listにもInvalid Paramsが出る場合がある

Invalid Paramstools/callだけのエラーでもありません。

たとえばPaginationを使うtools/listで不正なCursorを送った場合、MCPの仕様では-32602 Invalid Paramsとして拒否することになっています。

MCPのPagination仕様でも、数値ではないCursor、負数、範囲外のCursorなどは-32602 Invalid paramsとして扱い、可能な範囲を示すエラーメッセージを返すことが推奨されています。

したがってエラーを調べる順番としては、

手順
Invalid Paramsが出た

から即座にJSON Schemaを見るのではなく、

確認項目
どのMethodでInvalid Paramsが出たか

を最初に確認することが重要です。

AIモデルが何度も同じ不正引数を送る場合はSchema説明を見直す

MCP Inspectorから直接実行すれば成功するのに、AIエージェント経由だと同じ入力検証エラーを繰り返す場合があります。

この場合はServer実装だけでなく、Tool Schemaをモデルが理解しやすいか確認します。

たとえば、

情報不足
{
  "id": {
    "type": "string"
  }
}

だけでは、何のIDなのか分かりません。

具体的
{
  "customer_id": {
    "type": "string",
    "description": "検索対象の顧客ID"
  }
}

のようにしたほうが意味が明確になります。

同様にlimitなら、

description例
取得件数。1〜100の整数。

と説明できます。

Schema Validationが正しく動いていても、モデルがSchemaを理解できなければ何度もエラーになります。

再試行させるなら同じargumentsをそのまま送らない

一時的なネットワークエラーと違い、入力検証エラーは同じRequestを再送しても直りません。

たとえば、

Schema違反
{
  "limit": "ten"
}

がSchema違反なら、同じTool Callを5回Retryしても結果は同じです。

AIエージェント側で自動Retryを行う場合は、エラー内容をモデルへ返して、

修正指示
limitはintegerで指定してください

と修正させる必要があります。

単純なHTTP Retry PolicyとTool Callingの入力修正は分けて考えたほうがよいでしょう。

Invalid Paramsを調べるならtools/listと実際のargumentsを比較する

MCPサーバーでInvalid Paramsが出た場合、最も重要なのは、サーバーが公開している契約と、クライアントが実際に送った値を比較することです。

まずエラーコードだけでなく、どのJSON-RPC Methodで失敗したのか確認します。

tools/callなら、params.nameparams.argumentsの構造を確認します。

その後tools/listを実行し、対象ToolのinputSchemaを取得します。

requiredの不足、stringとintegerの違い、objectとJSON文字列の違い、arrayの形式、enum、追加フィールド、minimumやmaximumなどを実際のargumentsと照合します。

MCPの高レベルSDKでは、Schemaに合わないTool引数をJSON-RPCの-32602ではなく、モデルが読めるCallToolResult.isErrorとして返す実装もあります。

そのため、「Invalid Params」という言葉だけではなく、JSON-RPC ErrorなのかTool Resultの入力検証エラーなのかを確認することも重要です。

またMCP 2026-07-28ではTool SchemaがJSON Schema 2020-12へ拡張され、より複雑な入力制約を表現できるようになっています。

Schemaが高度になるほど、モデルやクライアントが実際に送ったargumentsとの不一致も発生しやすくなります。

MCPのInvalid Paramsを直す近道は、エラー文だけを追うのではなく、tools/listで公開されたinputSchemaと、tools/callで実際に送信されたargumentsを1項目ずつ比較することです。

Invalid Paramsに関するよくある質問

QInvalid ParamsとMethod not foundはどう違いますか

AMethod not foundはtools/listやtools/callなどJSON-RPCのMethod自体をサーバーが処理できないというエラーです。Invalid Paramsは、Methodは正しく認識されているものの、そのMethodへ渡したparamsやargumentsが正しくないというエラーで、原因のレイヤーが異なります。

Qtools/callのargumentsがinputSchemaに違反すると必ず-32602になりますか

A必ずしもそうではありません。高レベルSDKでは、Schemaに違反した入力をJSON-RPCのエラーではなく、CallToolResultのisError:trueというTool結果として返す実装があります。この場合Protocol自体は成功しており、モデルへエラー内容を見せて修正させる設計になっています。

QLow-level ServerでInvalid Paramsではなく別のエラーになるのはなぜですか

AMCP Python SDKのLow-level Serverはv2でinput_schemaの自動検証を廃止しているためです。Handler側で存在しないキーへアクセスするとKeyErrorなどが発生し、結果としてInvalid Paramsではなく-32603 Internal server errorになることがあります。

QMCPErrorを使えば必ずJSON-RPCのInvalid Paramsを返せますか

AMCP Python SDKでは、Tool Handler内からMCPErrorを送出すると、通常の例外のようにCallToolResultへ変換されず、そのままJSON-RPCエラーとしてクライアントへ返る特別な挙動になっています。INVALID_PARAMSを指定すれば-32602として返せます。

Q-32602はTool引数のエラー以外でも出ますか

A出ます。MCP 2026-07-28では存在しないResource URIへのアクセスも-32602として扱われるようになりました。またtools/listなどのPaginationで不正なCursorを送った場合も-32602になることがあります。まずどのMethodへのエラーなのかを確認してください。

QAIエージェント経由でだけInvalid Paramsが繰り返される場合はどうすればよいですか

AMCP Inspectorなどでスキーマどおりの最小引数を直接実行し、成功するか確認してください。成功するならサーバー側は正常で、AIホストが生成する引数側に原因がある可能性が高いです。Tool descriptionやSchemaの説明をモデルが理解しやすい表現に見直すことも有効です。

QInvalid Paramsが出たら再試行すれば直りますか

A通常は直りません。ネットワーク起因のエラーと違い、送信した引数自体がSchemaに違反していることが原因のため、同じargumentsを再送しても同じ結果になります。エラー内容をモデルへ返して引数を修正させるか、Tool呼び出し側のロジックを見直してください。

まとめ

MCPサーバーでInvalid Paramsが発生したときは、Method自体は認識されているという前提で、tools/callのparams構造とToolのinputSchemaを確認することが重要です。

requiredの不足、stringとintegerなどの型違い、objectとJSON文字列の取り違え、enum、additionalPropertiesといった代表的なパターンを、実際に送られたargumentsと1つずつ照合してください。

また、JSON SchemaのエラーがすべてJSON-RPCの-32602になるとは限らず、SDKによってはCallToolResult.isErrorとしてモデルへ返され、修正の機会を与える設計になっている点にも注意が必要です。

MCP 2026-07-28ではTool SchemaがJSON Schema 2020-12へ拡張され表現力が上がった一方、SDKや世代の違いによる不整合も起きやすくなっています。tools/listのinputSchemaと実際のargumentsを比較する習慣をつけておくと、原因調査がかなり楽になります。Method自体が認識されないケースの切り分けはMCPサーバーが「Method not found」になる原因を参考にしてください。