Claude Agent SDK:Session 履歴、MCP 制御、Thinking 設定
Claude Agent SDK Python v0.1.36-0.1.48 で Session 履歴クエリ、ランタイム MCP サーバー管理、型付き Task メッセージ、Thinking 設定、effort 制御が追加されました。
Claude Agent SDK for Python は、バージョン 0.1.36 から 0.1.48 にかけて多数の重要な機能をリリースしました。本記事では、Session 履歴クエリ、ランタイム MCP サーバー管理、型付き Task メッセージ、Thinking 設定、およびいくつかの重要なバグ修正について解説します。
以下のコード例はすべて claude_agent_sdk v0.1.48 以降がインストールされていることを前提としています。
Session 履歴 (v0.1.46)
2つの新しいトップレベル関数により、生の JSONL トランスクリプトファイルに直接触れることなく、過去の Session データを読み取ることができます。どちらもファイルシステムのみの同期操作で、実行中の Claude プロセスは不要です。
list_sessions()
最終更新日時でソートされた SDKSessionInfo オブジェクトのリストを返します。各エントリには Session ID、表示用サマリー、ファイルサイズ、オプションのカスタムタイトル、最初のプロンプト、git ブランチ、作業ディレクトリが含まれます。
from claude_agent_sdk import list_sessions
# All sessions for a specific project
sessions = list_sessions(directory="/path/to/project")
for s in sessions:
print(f"{s.session_id} {s.summary} ({s.file_size} bytes)")
# All sessions across every project
all_sessions = list_sessions()
# Limit results and skip git worktree scanning
recent = list_sessions(
directory="/path/to/project",
limit=10,
include_worktrees=False,
)
get_session_messages()
Session の完全なメッセージリストを SessionMessage オブジェクトとして返します。各メッセージには type(“user” または “assistant”)、uuid、session_id、および生の Anthropic API message dict が含まれます。
from claude_agent_sdk import get_session_messages
messages = get_session_messages(
"550e8400-e29b-41d4-a716-446655440000",
directory="/path/to/project",
)
for msg in messages:
role = msg.type
content = msg.message.get("content", "")
print(f"[{role}] {content[:80]}...")
# Paginate through a long session
page = get_session_messages(
"550e8400-e29b-41d4-a716-446655440000",
limit=20,
offset=40,
)
ユースケース:管理ダッシュボード、監査ログ、Session リプレイ UI、または Session 間のトークン使用量を集計する分析パイプラインの構築。
MCP ランタイム制御 (v0.1.46)
SDK は、Session の実行中に MCP サーバーの追加と削除をサポートするようになりました。ClaudeSDKClient の2つの新しいメソッド — add_mcp_server() と remove_mcp_server() — により、会話を再起動することなく利用可能なツールセットを変更できます。
既存の toggle_mcp_server() と reconnect_mcp_server() メソッドは、すでに設定されているサーバーの有効化/無効化や再接続を補完します。
from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions
options = ClaudeAgentOptions(
model="claude-sonnet-4-5",
permission_mode="bypassPermissions",
)
async with ClaudeSDKClient(options) as client:
await client.query("Analyze project structure")
# Check which MCP servers are connected
status = await client.get_mcp_status()
for server in status["mcpServers"]:
print(f"{server['name']}: {server['status']}")
# Temporarily disable a server
await client.toggle_mcp_server("heavy-analytics", enabled=False)
await client.query("Quick task without analytics tools")
# Re-enable it
await client.toggle_mcp_server("heavy-analytics", enabled=True)
# Reconnect a failed server
for server in status["mcpServers"]:
if server["status"] == "failed":
await client.reconnect_mcp_server(server["name"])
McpServerStatus TypedDict は、ステータスフィールドへの型付きアクセスを提供します:name、status("connected"、"pending"、"failed"、"needs-auth"、"disabled" のいずれか)、オプションの error、config、scope、serverInfo、tools。
ユースケース:適応的なツール可用性。コーディングエージェントはデータベース関連のタスク時にのみデータベース MCP サーバーをロードし、フロントエンドタスクに切り替える際にそれを削除できます。これによりツールリストが整理され、プロンプトの冗長性が削減されます。
型付き Task メッセージ (v0.1.46)
以前は、すべての Task ライフサイクルイベントが汎用の SystemMessage オブジェクトとして到着し、subtype と data フィールドを手動で検査する必要がありました。3つの新しいメッセージサブクラスが構造化されたアクセスを提供します:
| クラス | Subtype | 主要フィールド |
|---|---|---|
TaskStartedMessage | task_started | task_id, description, session_id, task_type |
TaskProgressMessage | task_progress | task_id, description, usage, last_tool_name |
TaskNotificationMessage | task_notification | task_id, status, summary, output_file |
3つすべてが SystemMessage を継承しているため、既存の isinstance(msg, SystemMessage) チェックは引き続きマッチします。
from claude_agent_sdk import (
ClaudeSDKClient,
TaskStartedMessage,
TaskProgressMessage,
TaskNotificationMessage,
)
async with ClaudeSDKClient(options) as client:
await client.query("Run the full test suite")
async for msg in client.receive_messages():
match msg:
case TaskStartedMessage():
print(f"Task {msg.task_id} started: {msg.description}")
case TaskProgressMessage():
tokens = msg.usage.input_tokens + msg.usage.output_tokens
print(f" Progress: {tokens} tokens, last tool: {msg.last_tool_name}")
case TaskNotificationMessage():
print(f"Task {msg.task_id} {msg.status}: {msg.summary}")
if msg.status == "failed":
print(f" Output: {msg.output_file}")
TaskNotificationStatus は Literal["completed", "failed", "stopped"] です — 網羅的な match チェックに使用してください。
ユースケース:トークンカウント付きのリアルタイム Task ステータスを表示するプログレス UI の構築、または Task の完了/失敗イベントに反応するオーケストレーターの構築。
ResultMessage の stop_reason (v0.1.46)
ResultMessage に stop_reason フィールド(オプションの文字列)が追加され、会話ターンが終了した理由がわかるようになりました。既存の is_error、num_turns、total_cost_usd フィールドと組み合わせることで、クエリがどのように、なぜ終了したかの全体像を把握できます。
from claude_agent_sdk import ResultMessage
async for msg in client.receive_response():
if isinstance(msg, ResultMessage):
print(f"Stopped: {msg.stop_reason}")
print(f"Turns: {msg.num_turns}, Cost: ${msg.total_cost_usd:.4f}")
print(f"Error: {msg.is_error}")
Thinking 設定 (v0.1.36)
Extended thinking に適切な設定システムが導入されました。ClaudeAgentOptions の thinking フィールドは、非推奨の max_thinking_tokens を置き換え、3つの設定形式を受け付けます:
from claude_agent_sdk import (
ClaudeAgentOptions,
ThinkingConfigAdaptive,
ThinkingConfigEnabled,
ThinkingConfigDisabled,
query,
)
# Adaptive: let the model decide when and how much to think
options_adaptive = ClaudeAgentOptions(
model="claude-opus-4-6",
thinking=ThinkingConfigAdaptive(type="adaptive"),
)
# Enabled with a specific token budget
options_budgeted = ClaudeAgentOptions(
model="claude-opus-4-6",
thinking=ThinkingConfigEnabled(type="enabled", budget_tokens=10000),
)
# Disabled entirely
options_fast = ClaudeAgentOptions(
model="claude-sonnet-4-5",
thinking=ThinkingConfigDisabled(type="disabled"),
)
Effort 制御
effort フィールドは、正確なトークンバジェットを指定することなく、Thinking の深さを制御するよりシンプルな方法を提供します:
# Quick, low-effort response
options = ClaudeAgentOptions(
model="claude-sonnet-4-5",
effort="low",
)
# Maximum reasoning depth
options = ClaudeAgentOptions(
model="claude-opus-4-6",
effort="max",
)
有効な値:"low"、"medium"、"high"、"max"。effort オプションは thinking とは独立しており、どちらか一方または両方を使用できます。
Hook の拡張 (v0.1.46)
ツールライフサイクル hook の入力に agent_id と agent_type フィールドが追加されました。これらは、複数のサブエージェントが並列で実行され、ツールライフサイクル hook が同じ制御チャネル上でインターリーブするマルチエージェント構成において重要です。
これらのフィールドは PreToolUseHookInput、PostToolUseHookInput、PostToolUseFailureHookInput に追加されています:
agent_id— hook が Task から生成されたサブエージェント内で発火した場合に存在します。複数のエージェントが同時に実行される場合、ツール呼び出しを特定のサブエージェントに帰属させる唯一の信頼できる方法です。agent_type— エージェントタイプ名(例:“general-purpose”、“code-reviewer”)。サブエージェント内ではagent_idと共に存在し、--agentで開始されたメインスレッドでも存在します。
options = ClaudeAgentOptions(
hooks={
"PreToolUse": [
HookMatcher(
matcher="Edit",
hooks=[HookCallback(callback=my_hook)],
)
]
}
)
async def my_hook(input_data):
agent = input_data.get("agent_id", "main")
agent_type = input_data.get("agent_type", "unknown")
tool = input_data["tool_name"]
print(f"[{agent_type}:{agent}] using {tool}")
return {"decision": "approve"}
バグ修正
これらのバージョンで3つの注目すべき修正が行われました:
細粒度ツールストリーミング (v0.1.48) — include_partial_messages=True が input_json_delta イベントを配信しない問題がありました。サブプロセスで CLAUDE_CODE_ENABLE_FINE_GRAINED_TOOL_STREAMING 環境変数が設定されていなかったことが原因です。このリグレッションは、サーバーサイドの feature flag を持たないユーザーのバージョン 0.1.36 から 0.1.47 に影響していました。
文字列プロンプトの MCP 初期化 (v0.1.46) — プレーンな文字列プロンプトを渡すと、MCP サーバーの初期化が完了する前に stdin が閉じられ、MCP サーバーの登録に失敗していました。この問題は修正されました。
不明なメッセージタイプの処理 (v0.1.40) — 認識されない CLI メッセージタイプ(例:rate_limit_event)が MessageParseError を発生させて Session をクラッシュさせていました。不明なタイプはサイレントにスキップされるようになり、SDK は将来の CLI メッセージ追加に対して前方互換性を持つようになりました。
アップグレードパス
変更はすべて追加的です。v0.1.36 から v0.1.48 の間に破壊的変更は導入されていません。唯一の非推奨は max_thinking_tokens で、thinking フィールドが推奨されます。古いフィールドは引き続き動作しますが、両方が設定されている場合は thinking が優先されます。
pip install --upgrade claude-agent-sdk
バンドルされている Claude CLI は、これらのバージョンを通じて v2.1.42 から v2.1.71 に更新されました。cli_path で特定の CLI バージョンを固定している場合は、ここで説明したすべての機能を利用するために少なくとも v2.1.69 以上であることを確認してください。