MCPサーバーの窓口は、何を差し出し、何を隠すべきか
連載「ReactでMCPクライアントを作る」第3回 — サーバー側の設計を実際に叩いて確かめる
窓口を作る側に回ると、話は「どう話しかけるか」から「何を差し出すか」へ変わります。テーブル定義は誰にでも見せてよいのか、SQLを実行する機能を素直に置いてよいのか——差し出し方を決めるのは、仕様ではなく設計する側です。
この記事は、全6回の連載「ReactでMCPクライアントを作る」の第3回です。第1回では、MCP(Model Context Protocol)がホスト・クライアント・サーバーという三者をJSON-RPC 2.0でつなぐ仕組みであること、そしてデータベースへの窓口となるMCPサーバーは、テーブル定義をResourceとして、SQLを実行する機能をToolとして持つのが自然だと述べました。第2回では、その窓口へどう話しかければ聞いてもらえるか、Streamable HTTPの必須ヘッダーやSSEの中身を実際のやり取りで確かめました。
今回は、話しかけられる側、つまり窓口そのものの設計に踏み込みます。サーバーが何を差し出せば安全で、何を差し出すと危ういのかを、実際に登録して叩いた結果とともに見ていきます。
目次
検証の前提 — 環境と最小構成のサーバー
以降の実測結果は、Node.js v22.12.0、公式TypeScript SDK(@modelcontextprotocol/sdk)のバージョン1.30.0、実行日2026-08-06の環境によるものです。第1回・第2回で確認したとおり、このSDKが実装しているプロトコルバージョンは2025-11-25までです。
今回はツール8個とリソース2個(固定URIのリソース1つ、URIテンプレートのリソース1つ)を登録した最小構成のMCPサーバーを1本立て、Streamable HTTP(セッションを発行しないステートレス構成)で叩きました。ツールは「正しく振る舞うもの」と「わざと壊したもの」を対にして並べ、何が違いを生むのかを比べています。
実際のデータベースには接続していません。特定の製品やサービスにも依存していません。
Resources・Prompts・Tools — 何を出す窓口にするか
第1回で触れたとおり、MCPの仕様はサーバーが提供してよい機能を3種類に整理しています。
- Resources: ユーザーやAIモデルが使う、コンテキストやデータ
- Prompts: ユーザー向けの、テンプレート化されたメッセージやワークフロー
- Tools: AIモデルが実行できる関数
3つとも同じ「サーバーが持てる機能」ですが、想定するユーザーインタラクションが異なります。仕様はResourcesを「アプリケーション主導(application-driven)」、Toolsを「モデル主導(model-controlled)」と位置づけています。Resourceはホストアプリケーションが選んでコンテキストに載せるデータで、Toolはモデル自身が判断して呼び出す操作、と読み替えると分かりやすいです。
冒頭のアプリで考えると、この違いがそのまま設計の判断材料になります。テーブル定義(スキーマ)は、SQLを書く前にホストが取得してLLMのAPIに渡す「材料」であり、モデルが「今から呼ぼう」と自分で決める操作ではありません。だからResourceです。一方SQLの実行は、モデルが「このSQLを実行してほしい」と判断して初めて起きる操作なので、Toolが自然な置き場所になります。
Promptsは今回使っていません。第1回で確認したとおり、自然言語からSQLを組み立てる部分はホストがMCPの外でLLMのAPIを直接呼ぶ設計にしたため、テンプレート化されたユーザー向けワークフローをサーバー側に持たせる必要がなかったためです。
inputSchema は JSON Schema draft-07 に化ける
ToolはinputSchemaというプロパティを持ち、これがモデルに見せる「この引数を渡せば呼べます」という契約になります。今日の公式TypeScript SDKでは、このinputSchemaをzodのようなスキーマ定義ライブラリで書き、SDKがJSON Schemaへ変換してtools/listのレスポンスに載せます。実測したtools/listのレスポンスは次のとおりでした(貼り付けたまま)。
{
"name": "echo",
"title": "Echo",
"description": "Echoes text",
"inputSchema": {
"type": "object",
"properties": { "text": { "type": "string" } },
"required": [ "text" ],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
},
"execution": { "taskSupport": "forbidden" }
}
ここで2点、仕様と実装の関係を押さえておく価値があります。1点目は$schemaです。仕様はinputSchemaについて「$schemaフィールドが無ければ2020-12として扱う」と定めていますが、実測した実装は明示的にhttp://json-schema.org/draft-07/schema#を$schemaとして埋め込んでいました。
JSON Schemaにはdraft-04からdraft-2020-12まで複数のバージョンがあり、キーワードの意味や対応範囲がバージョンごとに微妙に違います。draft-07はキーワードの意味づけがdraft-2020-12とほぼ共通する枯れたバージョンで、多くのバリデーションライブラリが対応しています。SDKがこのバージョンを選んでいるのは、対応ライブラリの広さを優先した実装判断と見られます(ソースコードの選定理由までは追っていません)。
2点目はadditionalProperties: falseです。プロパティを持つinputSchemaには、この値が自動で付いていました。
JSON SchemaのadditionalPropertiesは、オブジェクトがpropertiesに列挙されていないキーを持つことを許すかどうかを決めるキーワードで、falseにすると宣言していない引数はスキーマ違反になります。モデルが余計な引数を作文して渡してきても、ここで弾かれる仕組みです。
この宣言は見せかけではなく、実際に検査されています。型が違う引数(文字列を期待するtextに数値)を渡すと、次のように弾かれました(貼り付けたまま)。
event: message
data: {"result":{"content":[{"type":"text","text":"MCP error -32602: Input validation error: Invalid arguments for tool echo: Expected string, received number at text"}],"isError":true},"jsonrpc":"2.0","id":7}
必須引数を欠かした場合も、同じ経路で弾かれます。
event: message
data: {"result":{"content":[{"type":"text","text":"MCP error -32602: Input validation error: Invalid arguments for tool echo: Required at text"}],"isError":true},"jsonrpc":"2.0","id":8}
入力の検証違反はisError: trueという成功レスポンスの形で返ります。 JSON-RPCのerrorフィールドを持つプロトコルエラーではありません。この形は、このあと見る「失敗の通り道」の話にそのままつながります。
もう一つ、この応答にはexecution: { "taskSupport": "forbidden" }という項目も含まれていました。これは今回登録した全ツールに共通して付いていました。 execution.taskSupportは、そのツールをTasks拡張(処理を非同期化して後から結果を取りに行く仕組み)の対象にできるかどうかを示すフィールドで、明示的に何も指定しなければ既定値としてforbiddenになります。
Tasks拡張そのものは第5回で扱います。ここでは「何も指定しなければ非同期対応は既定で禁止という宣言になる」という事実だけを押さえておきます。
inputSchema は JSON Schema draft-07 へ変換され、宣言していない引数は弾かれるoutputSchema を宣言すると、何が起きるか
inputSchemaと対になるのがoutputSchemaです。任意と位置づけられているものを、わざわざ宣言する価値はあるのでしょうか。仕様は、宣言した場合の挙動をはっきり決めています。
If an output schema is provided: Servers MUST provide structured results that conform to this schema. Clients SHOULD validate structured results against this schema.
日本語にすると、「出力スキーマが提供された場合、サーバーはこのスキーマに適合する構造化された結果を提供しなければならない。クライアントはこの結果をこのスキーマに対して検証すべきである」という意味です。「宣言したら守らされる」がMUSTだと分かりますが、それが具体的にどう効くのかは、実際に壊してみないと分かりません。
同じoutputSchema(テーブル名と件数、{ table: string, count: number })を宣言したツールを3つ用意し、正しく返す・返し忘れる・形を間違えるの3通りを試しました。このtableとcountという組は、冒頭のアプリで言えば「どのテーブルに対して何件返ったか」にあたる、最小限の集計結果です。
正しく返した場合はこうなります(貼り付けたまま)。
event: message
data: {"result":{"content":[{"type":"text","text":"{\"table\":\"customers\",\"count\":42}"}],"structuredContent":{"table":"customers","count":42}},"jsonrpc":"2.0","id":2}
structuredContentに宣言どおりの値が乗っています。
structuredContentを返し忘れた場合はこうなります。
event: message
data: {"result":{"content":[{"type":"text","text":"MCP error -32602: Output validation error: Tool row_count_missing has an output schema but no structured content was provided"}],"isError":true},"jsonrpc":"2.0","id":3}
宣言と違う形(countに数値ではなく文字列)を返した場合はこうなります。
event: message
data: {"result":{"content":[{"type":"text","text":"MCP error -32602: Invalid structured content for tool row_count_wrong_shape: Expected number, received string at count"}],"isError":true},"jsonrpc":"2.0","id":4}
返し忘れても、形が違っても、同じように弾かれました。 どちらのケースもHTTPは200、JSON-RPCとしても成功レスポンスで、失敗はisError: trueとしてのみ現れます。本文の中に-32602という文字列が見えますが、これは独立したJSON-RPCのエラーコードではなく、メッセージ文字列の一部です。
バリデーションが働いていることは実測から分かりますが、outputSchemaを宣言しただけで自動的に守られる保証がある、と言い切るのはこのSDKに限った話です。仕様が定めているのは「サーバーは適合する結果を返さなければならない(MUST)」という義務までで、その義務違反をどう検出しどう応答するかはSDKの実装判断に委ねられています。
outputSchema の3つの結末 — 正しく返す・返し忘れる・形を間違えるannotations は素通しで出るが、信じるなと仕様は言う
サーバーが「このツールは安全です」と自己申告してきたとき、クライアントはそれを信じてよいのでしょうか。Toolにはannotationsという任意のプロパティがあります。
ツールが読み取り専用かどうか(readOnlyHint)、破壊的な操作を伴うかどうか(destructiveHint)、同じ引数で何度呼んでも結果が変わらないか(idempotentHint)、外部の開かれた世界とやり取りするか(openWorldHint)といった、ツールの振る舞いに関するヒントを表明する場所です。実測したtools/listには、宣言した値がそのまま出ていました(貼り付けたまま)。
"annotations": {
"readOnlyHint": true,
"destructiveHint": false,
"idempotentHint": true,
"openWorldHint": false
}
サーバーが「このツールは読み取り専用です」と言えば、それがそのまま素通しでクライアントに届きます。ここで仕様は、annotations の定義に添えた警告で釘を刺しています。
For trust & safety and security, clients MUST consider tool annotations to be untrusted unless they come from trusted servers.
日本語にすると、「信頼・安全性の観点から、クライアントは、信頼できるサーバーから得たものでない限り、ツールのアノテーションを信頼できないものとして扱わなければならない」という意味です。この2つを並べると、非対称な構造が見えてきます。
SDKはannotationsをサーバーが宣言したとおりに黙って伝達するだけで、内容の真偽を検証する仕組みを持ちません。一方で仕様は、その内容を鵜呑みにしてはいけないとクライアント側にMUSTで求めています。つまり「言ったもの勝ち」の経路と「言われたことを疑え」という規範が、同じannotationsというフィールドの上に同居しています。
これは、冒頭のアプリのSQL実行ツールでも他人事ではありません。あるサーバーが自分のexecute_sqlツールにreadOnlyHint: trueと表明していても、それだけを根拠に「確認なしで実行してよい」とホスト側が判断するのは、仕様が禁じているまさにその振る舞いです。
信頼できるサーバーかどうかを判断する材料(サーバーの出自、署名、レジストリでの検証など)はannotationsそのものの中にはありません。誰が発行したサーバーかという、annotationsの外側にある文脈と合わせて見るべきだ、というのが仕様の立場です。
annotations は素通しで出るが、仕様は「信じるな」と言う失敗の通り道は、ツールとリソースで違う
ここまでは、正しく設計されたツールがどう動くかを見てきました。では、存在しない機能を呼んだらどうなるのでしょうか。仕様のTools章「Error Handling」節は、失敗を2種類に分けています。
Protocol Errors indicate issues with the request structure itself that models are less likely to be able to fix… They are returned as standard JSON-RPC errors… Tool Execution Errors contain actionable feedback that language models can use to self-correct… They are reported in tool results with isError: true.
日本語にすると、「プロトコルエラーは、モデルが自力で直せる見込みが低い、リクエスト構造そのものの問題を示す。標準的なJSON-RPCエラーとして返される……ツール実行エラーは、言語モデルが自己修正のために使える実用的なフィードバックを含む。ツールの結果の中でisError: trueとして報告される」という意味です。そして仕様は「未知のツール(Unknown tool)」をプロトコルエラー側の例として挙げ、次のようなレスポンス例を示しています。
{“jsonrpc”: “2.0”, “id”: 3, “error”: {“code”: -32602, “message”: “Unknown tool: invalid_tool_name”}}
つまり仕様の文面どおりに読めば、存在しないツールを呼んだ結果は、JSON-RPCのerrorフィールドを持つ本物のプロトコルエラーになるはずです。この分類は、今回実測したSDKが実装する2025-11-25の仕様でも同じ書き方がされており、2026-07-28で新しく変わった扱いではありません。ところが実際に存在しないツールを呼んでみると、次のように返ってきました(貼り付けたまま)。
event: message
data: {"result":{"content":[{"type":"text","text":"MCP error -32602: Tool no_such_tool not found"}],"isError":true},"jsonrpc":"2.0","id":9}
errorフィールドを持つプロトコルエラーではなく、isError: trueを持つ成功レスポンスでした。 JSON-RPCとして見れば、これはresultが返っている「成功」の形です。仕様の例が示すエラーコード-32602という数字はメッセージ文字列の中に埋め込まれているだけで、実際のJSON-RPCのerror.codeとしては現れていません。
一方、同じ「存在しないものを呼ぶ」という操作でも、リソース側は違う結果になりました。存在しないURIを読もうとすると、次のように返ってきます。
event: message
data: {"jsonrpc":"2.0","id":14,"error":{"code":-32602,"message":"MCP error -32602: Resource db://nope not found"}}
こちらはerrorフィールドを持つ、本物のJSON-RPCエラーです。 Resources章のError Handling節も、これを裏付けています。
If the requested resource does not exist, servers MUST return a JSON-RPC error with code -32602 (Invalid Params)… Servers MUST NOT return an empty contents array for a non-existent resource.
「要求されたリソースが存在しない場合、サーバーはコード-32602(不正なパラメータ)を持つJSON-RPCエラーを返さなければならない……サーバーは、存在しないリソースに対して空のcontents配列を返してはならない」という意味です。こちらは仕様どおりに実装されていました。
この非対称は、クライアントを書くときの実務上の落とし穴になります。 もしクライアント側の実装が「失敗はJSON-RPCのerrorフィールドを見て判定する」という単純なルールだけで書かれていたら、存在しないツールを呼んだケースを検出できません。
resultが返ってきているので「成功した」と誤認し、contentの中のisError: trueとテキストを見落とします。ツールの失敗を正しく拾うには、errorフィールドのチェックとisErrorフィールドのチェックの両方が要る、というのが実測から見える結論です。
参考までに、正常に登録されているリソースは次のように一覧・テンプレート化されて出ます(貼り付けたまま)。
event: message
data: {"result":{"resources":[{"uri":"db://tables/customers/schema","name":"schema-customers","title":"customers schema","description":"Column definitions","mimeType":"application/json"}]},"jsonrpc":"2.0","id":10}
event: message
data: {"result":{"resourceTemplates":[{"name":"schema-any","uriTemplate":"db://tables/{table}/schema","title":"table schema","description":"Column definitions for any table"}]},"jsonrpc":"2.0","id":11}
テンプレートはresources/readで実際のURIへ展開されて呼ばれます。db://tables/orders/schemaを読むとtable = ordersが渡り、次のように返りました。
event: message
data: {"result":{"contents":[{"uri":"db://tables/orders/schema","mimeType":"application/json","text":"{\"table\":\"orders\",\"columns\":[]}"}]},"jsonrpc":"2.0","id":13}
ハンドラの例外メッセージは、そのまま外へ出る
もう一つ、実際に試すまで想定していなかった挙動があります。ツールのハンドラの中で意図的に例外を投げてみると、次のように返ってきました(貼り付けたまま)。
event: message
data: {"result":{"content":[{"type":"text","text":"boom from inside the handler"}],"isError":true},"jsonrpc":"2.0","id":6}
isError: trueに変換される点は、業務ロジックとして自分でisError: trueを返した場合(下記)と同じです。
event: message
data: {"result":{"content":[{"type":"text","text":"table not found"}],"isError":true},"jsonrpc":"2.0","id":5}
違うのは、投げた例外のメッセージ文字列がそのまま本文に載っていた点です。 意図的に返したエラーメッセージ(“table not found”)と、コード側で投げた素の例外メッセージ(“boom from inside the handler”)が、区別なく同じ経路でクライアントまで届いています。
これは、冒頭のアプリのようにDBを触るツールを書くときに効いてきます。SQLの実行に失敗したときの例外オブジェクトには、ドライバやORMの実装によっては接続文字列の断片、内部のテーブル名、クエリの一部がそのままメッセージに含まれることがあります。
ハンドラで例外をキャッチせずに投げっぱなしにすると、その文言がフィルタされないままモデルとクライアントまで届く。そう思って設計しておくのが安全です。ツール側で例外を自分で捕まえ、モデルに見せてよい言葉に作り直してからisError: trueで返す、という一段のクッションが、この経路の上では意味を持ちます。
登録していない機能は、メソッドごと存在しない
最後にもう一つ、境界そのものを確かめました。プロンプトを1つも登録していないサーバーにprompts/listを投げるとどうなるか、という実験です。空の配列({"prompts": []})が返るだろうと予想していましたが、実測は違いました(貼り付けたまま)。
event: message
data: {"jsonrpc":"2.0","id":15,"error":{"code":-32601,"message":"Method not found"}}
メソッドそのものが存在しないという扱いでした。 -32601はJSON-RPC 2.0の仕様が定める標準エラーコードで、「Method not found」を意味します。仕様のCapabilities節は、resourcesやtoolsのような各機能について「対応する場合はcapabilityとして宣言しなければならない(MUST)」と定めており、宣言していない機能は、そもそも対応するcapabilitiesのキー自体が存在しないことになります。
今回の実測はこの原則の裏返しで、「機能を1つも持たない」は「空のリストを返す」ではなく「そのメソッド自体を扱う入口がない」という形で外から見える、ということです。冒頭のアプリでいえば、Promptsを使わない設計にした窓口へprompts/listを送っても、返ってくるのは-32601です。
SQLを組み立てさせて実行する、という設計の危うさ
ここまでを踏まえると、冒頭のアプリそのものの危うさが見えてきます。自然言語の問い合わせをLLMのAPIでSQLに変換し、そのSQLをToolとして実行する——それがこのアプリの構成でした。この設計は、仕様が「Security and Trust & Safety」のTool Safety節で名指しで警告している領域に踏み込みます。
Tools represent arbitrary code execution and must be treated with appropriate caution… Hosts must obtain explicit user consent before invoking any tool. Users should understand what each tool does before authorizing its use.
日本語にすると、「ツールは任意コード実行を表しており、相応の注意を払って扱われなければならない……ホストは、いかなるツールを呼び出す前にも、明示的なユーザーの同意を得なければならない。ユーザーは、その使用を許可する前に、各ツールが何をするかを理解しているべきである」という意味です。
SQLを実行するToolは、この「任意コード実行」の典型例です。モデルが生成したSQLをそのまま実行に回すという設計は、モデルの出力を確認なしで実行する経路をアプリケーションの中に作ることと同じです。
前節で見たannotationsの非対称(宣言は素通しで出るが信頼してはいけない)も、この文脈で効いてきます。「このツールは読み取り専用です」という自己申告だけを根拠に確認ダイアログを省略する設計は、仕様が繰り返し警告している「同意なしの実行」そのものになりかねません。
実行前にユーザーへSQL文そのものを見せて確認を求める、生成されたSQLを許可された操作の範囲(たとえばSELECTのみ)に制限する、といった対策が必要になりますが、この記事ではその具体的な実装までは検証していません。仕様が求めているのは「同意を得ること」という原則であり、その原則をどう実装に落とすかは、この先の回、とくに認可の設計を扱う第6回につながります。
もう一度、アプリの全体像へ
ここまでを、冒頭のアプリのデータベース窓口に当てはめ直してみましょう。窓口となるMCPサーバーは、テーブル定義をResourceとして、SQLの実行をToolとして提供します。ToolのinputSchemaはJSON Schema draft-07へ変換され、宣言していない引数はadditionalProperties: falseで弾かれます。
outputSchemaを宣言しておけば、集計結果の形が崩れたときにサーバー側で弾けますが、弾かれ方はisError: trueであって、呼び出し側が必ず気づけるとは限りません。annotationsで「読み取り専用です」と申告することはできますが、それをクライアントが鵜呑みにしてよいかどうかは別問題です。
存在しないツールを呼んだ場合と、存在しないリソースURIを読んだ場合とでは、失敗の通り道そのものが違います。クライアント側は両方の経路を見ておきましょう。
そしてハンドラの中で例外を投げると、その文言はそのままモデルとクライアントまで届きます。DBに触れる部分は、例外を自分で捕まえて言葉を作り直す設計が要ります。
この先扱うこと
今回で拾いきれなかった論点は、次のように各回へ送ります。
| 積み残した論点 | 送り先 |
|---|---|
| React側からの呼び出しとBFFの設計 | 第4回 |
execution.taskSupportがforbidden以外の場合の挙動、Tasks拡張の往復 | 第5回 |
| 生成SQLをそのまま実行してよいかの実装レベルの対策、認可の設計、legacyとmodernの互換 | 第6回 |
まとめ
MCPサーバーが差し出せる機能はResources・Prompts・Toolsの3種類で、冒頭のアプリでは「材料を出す」テーブル定義をResourceに、「モデルが判断して実行する」SQL実行をToolに割り当てるのが自然でした。inputSchemaはJSON Schema draft-07へ変換されadditionalProperties: falseで余計な引数を弾き、outputSchemaを宣言すれば返し忘れても形が違っても弾かれますが、弾かれ方はisError: trueという成功レスポンスの形であり、errorフィールドだけを見ているクライアントは見逃します。
同じ見逃しの構図が、存在しないツールを呼んだときにも現れます。 仕様の文面は「未知のツール」をプロトコルエラーとして例示していますが、実測したSDKはisError: trueを返しました。一方、存在しないリソースURIは仕様どおりの本物のJSON-RPCエラーになります。失敗の通り道がツールとリソースで違う、という事実を押さえていないと、クライアント側の実装は静かに壊れます。
annotationsは宣言どおりに素通しで出ますが、仕様はそれを信頼できないものとして扱うようクライアントに求めており、この非対称は、冒頭のアプリのSQL実行ツールにもそのまま関わってきます。
仕様の言葉と、今日書けるコードの言葉を混同しないこと、そして「返ってきた形」と「返ってきた意味」を混同しないこと。この2つが、サーバー側の設計を安全に進めるための土台になります。次回は、ここで扱った窓口をReact側からどう呼ぶか、BFFを挟むべきかどうかを掘り下げます。
この連載の記事
第1回から順に読むと、仕様の地図を描くところから、ブラウザで動くコードまでが一本の線でつながります。どの回からでも単体で読めるようには書いていますが、前後を行き来したくなったらここから飛んでください。
- 第1回: MCPクライアントは、結局どこにいるのか — ホスト・クライアント・サーバーの三者と、legacy/modernの断層
- 第2回: MCPサーバーに、どう話しかければ聞いてもらえるのか — Streamable HTTPの必須ヘッダー、SSE、Origin検証
- 第3回: MCPサーバーの窓口は、何を差し出し、何を隠すべきか(この記事) — スキーマ、annotations、失敗の通り道
- 第4回: Reactは、MCPサーバーを直接叩けるのか — CORS、BFF、SSEの逐次読み、協調的キャンセル
- 第5回: 重い処理を、MCPはどう見せて、どう止めるのか — 進捗通知、購読、Tasks拡張
- 第6回: その扉を開けるのは、誰の仕事か — 認可の設計、legacy/modernの互換判定、生成SQLの危うさ
参考にした一次情報
- Server / Tools(2026-07-28)(
inputSchema/outputSchemaの定義、additionalProperties推奨、annotationsと信頼性の警告、x-mcp-header、Error Handlingの2分類と未知のツールの例) - Server / Tools(2025-11-25)(今回実測したSDKが実装するリビジョンでの同等の定義。
execution.taskSupport(既定値forbidden)の出典。未知のツールをプロトコルエラーとする分類が2026-07-28と共通であることの確認) - Server / Resources(2026-07-28)(リソースの定義、
resources/read、Error Handling節の-32602規定と空配列禁止) - Specification(latest)(Resources/Prompts/Toolsの概要、Security and Trust & SafetyのTool Safety節)
- Streamable HTTP(2026-07-28)(
x-mcp-headerがMcp-Param-{Name}ヘッダーへ写る仕組みの定義) - JSON Schema Validation(draft-07)(
additionalPropertiesキーワードの定義) - JSON-RPC 2.0 Specification(
-32601 Method not foundなどの標準エラーコード)








