コンテンツにスキップ

Handle approvals and user input

facts /Claude Code /agent-sdk-user-input

stable1 か月前 · 2026-08-17

概要

Claude がツール使用許可や作業方針の確認を必要とする場合に canUseTool コールバックを通じてユーザーとやり取りする機能。

仕様

canUseTool コールバックの発火条件

状況発火するか
allow ルール・パーミッションモードで自動承認済みのツール発火しない
パーミッションフローで未解決のツール呼び出し発火する
AskUserQuestion ツール呼び出し発火する(toolName == "AskUserQuestion" で識別)
dontAsk モードのとき発火せず拒否される

コールバックは戻り値を返すまで実行を一時停止する。SDKはクエリ自体がキャンセルされるまで待ち続ける。プロセスを終了して後で再開したい場合は defer フックデシジョンを返す。

コールバックの引数

引数PythonTypeScript説明
ツール名tool_name: strtoolName: stringツール名(例: "Bash", "Write", "AskUserQuestion")
入力データinput_data: dictinput: objectツールへのパラメータ
コンテキストcontext: ToolPermissionContextoptions: { signal, suggestions? }キャンセルシグナルと提案パーミッション更新

主要ツールの入力フィールド

ツール入力フィールド
Bashcommand, description, timeout
Writefile_path, content
Editfile_path, old_string, new_string
Readfile_path, offset, limit

レスポンス形式

種別PythonTypeScript
許可PermissionResultAllow(updated_input=input_data){ behavior: "allow", updatedInput: input }
拒否PermissionResultDeny(message="理由"){ behavior: "deny", message: "理由" }
  • 許可時: updated_input / updatedInput を省略すると Claude Code v2.1.207 以前では拒否扱いになるため必ず渡す
  • 拒否時: message は Claude に渡され、次の行動の判断に使われる

パーミッション更新の保持

updatedPermissions (TypeScript) / updated_permissions (Python) に context.suggestions / options.suggestions の要素を返すと、次回以降の同パターン呼び出しをプロンプトなしで承認するルールを保存できる。

  • destination == "localSettings" の提案を返すと .claude/settings.local.json にルールを書き込む
  • Python では claude-agent-sdk 0.1.80 以降が必要

AskUserQuestion ツール

Claude が複数の選択肢から方針を確認するときに使うツール。canUseTool コールバックが toolName == "AskUserQuestion" で発火する。

tools 配列でツールを制限している場合(例: 読み取り専用エージェント)、AskUserQuestion を明示的に含める必要がある。

入力スキーマ

{
"questions": [
{
"question": "質問テキスト(answers のキーに使う)",
"header": "短いラベル(最大12文字)",
"options": [
{ "label": "選択肢ラベル", "description": "説明" }
],
"multiSelect": false
}
]
}
  • 各 AskUserQuestion 呼び出しで 1〜4 問まで
  • 各問に 2〜4 つの選択肢
  • multiSelect: true のとき複数選択可

レスポンス形式

{
"questions": ["(受け取った配列をそのまま)"],
"answers": {
"質問テキスト": "選択されたラベル",
"複数選択の質問": ["ラベルA", "ラベルB"]
}
}

オプションフィールド:

  • response: ユーザーが構造化質問に回答せず自由記述した場合のみ設定。設定すると Claude は per-question の回答リストではなく "The user responded: …" として受け取る

questions をそのまま返すことが必須(ツール処理で必要)。

オプションプレビュー(TypeScript のみ)

toolConfig.askUserQuestion.previewFormat を設定すると、各選択肢に preview フィールドが追加される:

previewFormatpreview の内容
未設定(デフォルト)フィールドなし(Claude はプレビューを生成しない)
"markdown"ASCII art・フェンスコードブロック
"html"スタイル付き <div> フラグメント(SDK が <script>・<style>・<!DOCTYPE> を事前除去)

フォーマットはセッション全体に適用される。視覚的な比較が有用な選択肢にのみ preview が付き、有用でない選択肢には付かない。undefined チェックが必要。

Python における ストリーミングモード要件

Python の can_use_tool はストリーミングモードが必要。query(prompt=generator) や ClaudeSDKClient.connect(prompt=async_iterable) でプロンプトストリームが終わると SDK が入力ストリームを閉じ、コールバックが呼ばれる前にプロセスが終了する。

PreToolUse フックを登録してストリームを開いた状態に保つことで回避できる:

async def dummy_hook(input_data, tool_use_id, context):
return {"continue_": True}
options = ClaudeAgentOptions(
can_use_tool=can_use_tool,
hooks={"PreToolUse": [HookMatcher(matcher=None, hooks=[dummy_hook])]},
)

ClaudeSDKClient.query() でメッセージを送信する場合はこの問題は発生しない。

制約・注意点

関連

  • facts/claude-code/agent-sdk-permissions.md
  • facts/claude-code/agent-sdk-python.md
  • facts/claude-code/agent-sdk-typescript.md