何のためのものか
SDK の in-process MCP サーバーで自前の関数をツールとして定義し、Claude に呼ばせる仕組み。データベース、外部 API、ドメイン固有のロジックを渡せる。
別プロセスではなくアプリケーション内で動くので、MCP サーバーを立てる話とは手間が違う。
触る
@tool(Python)/tool()(TypeScript)に name・description・schema・handler を渡すcreate_sdk_mcp_server/createSdkMcpServerで包み、query()のmcpServersに渡す- 事前承認するなら allowed tools に加える
ツールは 4 要素でできている。Name(一意な識別子)、Description(何をするか)、Input schema、Handler(async 関数)。
- TypeScript の schema は常に Zod スキーマで、handler の
argsはそこから自動で型付けされる - Python は
{"latitude": float}のような dict。enum・範囲・任意フィールド・入れ子が要るときは完全な JSON Schema の dict も直接受け付ける
入れる
description が呼ばれるかどうかを決める。 Claude はこれを読んでいつ呼ぶかを判断するので、曖昧だと呼ばれないか誤って呼ばれる。TypeScript では Zod の .describe() がフィールドの説明になる。
handler の戻り値は次の形。
| キー | 必須 | 内容 |
|---|---|---|
content | 必須 | 結果ブロックの配列("text" / "image" / "audio" / "resource" / "resource_link") |
structuredContent | 任意 | 機械可読なデータとしての結果。content と併せて返る |
isError | 任意 | true でツールの失敗を伝える |
効かせる
- 並列で呼ばせたいなら
readOnlyHint: true。 ただし副作用の無いツールにのみ設定する。並列実行の可否がこれで決まる - エラーの文面を自分で組む。 生の例外を出す代わりに
isError: trueを返し、Claude が次に何をすべきか分かる文面にする - 機械可読な結果は
structuredContent。 表示用テキストと別に返せる - 画像やファイルを返すなら content 配列で
image/resourceブロックを使う - ツールが増えたら tool search で必要時に読み込ませる
落とし穴
- 組み込みツールを外したいなら、残したい組み込みだけを列挙した
tools配列を渡す。 足し算ではなく引き算で指定する readOnlyHint: trueを副作用のあるツールに付けると、並列に呼ばれる- description は Claude 向けの仕様書である。実装コメントのつもりで書かない