Claude Agent SDKを使うと、Claude Codeが持つファイル検索、読み取り、編集、コマンド実行、MCP、Hooks、Subagentsなどの仕組みを、TypeScriptアプリから利用できます。
通常のMessages APIは「入力に対して回答を返す」実装に向きます。Agent SDKは、リポジトリを調べ、必要なツールを選び、複数の手順を進めるエージェントをアプリへ組み込みたい場合に向いています。ただし、ファイル編集やBashを許可するほど、作業ディレクトリ、権限、承認、ログ、隔離環境の設計が重要になります。
この記事では、TypeScriptで読み取り専用のコード調査エージェントを作り、編集・テストへ段階的に拡張する方法、ストリーミング結果、セッション、ツール制限、安全なサーバー構成を解説します。
情報確認日:2026年7月11日(日本時間)
結論:最初はRead・Glob・Grepだけに限定し、編集とBashは別の承認フローで追加する
この記事の結論
- TypeScriptでは
@anthropic-ai/claude-agent-sdkを使う query()が返す非同期イテレーターから、進行状況と最終結果を受け取るcwdを固定し、ユーザー入力から任意のローカルパスを直接指定させないallowedToolsで必要なツールだけを許可する- 本番環境で編集やコマンド実行を行う場合は、コンテナや一時Worktreeへ隔離する
Claude Agent SDKとは?
Claude Agent SDKは、Claude Codeのエージェント実行環境をプログラムから呼び出すSDKです。Claudeへ質問するだけでなく、コードベースの探索、ファイル変更、テスト実行、外部ツールとの連携を、複数ターンの作業として進められます。
TypeScript SDKで扱える主な機能には次があります。
Read、Glob、Grepによるコード調査Edit、Writeによるファイル変更Bashによる既存コマンドの実行- Web SearchとWeb Fetch
- MCPサーバーのツール
- HooksとSubagents
- 会話セッションの継続
- ツール権限と承認の制御
通常のAnthropic APIとの違い
| 比較 | Messages API | Claude Agent SDK |
|---|---|---|
| 主な用途 | チャット、要約、分類、独自Tool Use | ファイルやコマンドを使う複数段階のエージェント |
| ツール | アプリ側で定義・実行する | Claude Codeの組み込みツールを利用できる |
| 作業ディレクトリ | 概念なし | cwd配下のプロジェクトを扱う |
| 安全設計 | Tool Useごとに実装 | 許可ツール、権限、サンドボックス、Hooksを設計 |
プロジェクトを作成する
mkdir claude-agent-sdk-sample
cd claude-agent-sdk-sample
npm init -y
npm install @anthropic-ai/claude-agent-sdk dotenv zod
npm install --save-dev typescript tsx @types/node
npx tsc --init
npm pkg set type=module
mkdir src workspace
.envへAPIキーを保存します。
ANTHROPIC_API_KEY=your_anthropic_api_key
.gitignoreへ追加します。
.env
.env.*
node_modules/
workspace/
logs/
開発者のホームディレクトリや本番サーバーのルートをcwdにしないでください。エージェント専用にコピーしたリポジトリ、コンテナ、一時Worktreeなど、失敗しても戻せる場所を使います。
読み取り専用のコード調査エージェントを作る
最初はファイルを変更せず、構造を調べてレポートを返すだけにします。src/review.tsを作成します。
import "dotenv/config";
import { resolve } from "node:path";
import { query } from "@anthropic-ai/claude-agent-sdk";
const workspace = resolve("./workspace");
const prompt = `
このリポジトリの認証処理を調査してください。
確認すること:
- ログインの入口
- セッションまたはトークンの保存場所
- サーバー側の認可
- ログアウト
- 関連テスト
ファイルは変更しないでください。
確認したファイルと、未確認の点を分けて報告してください。
`;
for await (const message of query({
prompt,
options: {
cwd: workspace,
allowedTools: ["Read", "Glob", "Grep"],
maxTurns: 10,
},
})) {
if (message.type === "assistant") {
console.log(JSON.stringify(message, null, 2));
}
if (message.type === "result") {
console.log("result:", message);
}
}
実行前に、調査対象のリポジトリをworkspace/へコピーまたはcloneします。
git clone --depth=1 https://github.com/example/example-app.git workspace
npx tsx src/review.ts
実際のリポジトリURLは自分の管理するものへ変更してください。第三者から受け取ったリポジトリには、悪意のある指示、スクリプト、シンボリックリンクが含まれる可能性があります。
query()から返るメッセージを扱う
query()は非同期イテレーターを返します。最終結果だけでなく、エージェントのメッセージ、ツール実行、利用量、エラーなどを順次受け取れます。
SDKのメッセージ型は更新される可能性があるため、最初はログへ出して、自分が利用するバージョンの型定義を確認します。
for await (const message of query({ prompt, options })) {
switch (message.type) {
case "assistant":
// 画面へ進行状況を表示する場合に利用
break;
case "result":
// 最終状態、利用量、結果を保存
break;
default:
// SDKバージョンごとのイベントを確認
break;
}
}
結果をWeb APIとして返す
Webアプリから利用する場合は、利用者の入力をそのままローカルプロンプトへ渡さず、許可したタスクへ変換します。次はコード調査専用の関数です。
import { z } from "zod";
import { query } from "@anthropic-ai/claude-agent-sdk";
const RequestSchema = z.object({
topic: z.enum([
"authentication",
"data-flow",
"test-coverage",
"api-boundary",
]),
});
const prompts: Record<z.infer<typeof RequestSchema>["topic"], string> = {
authentication:
"認証と認可の流れを調査し、関連ファイル、確認済み事項、未知の点を報告してください。",
"data-flow":
"画面からAPI、データベースまでのデータフローを調査してください。",
"test-coverage":
"既存テストを調査し、未検証の重要な挙動を報告してください。テストは実行しないでください。",
"api-boundary":
"外部公開APIの入口、入力検証、認証、エラー処理を調査してください。",
};
export async function inspectRepository(
rawInput: unknown,
workspace: string,
) {
const input = RequestSchema.parse(rawInput);
const events = [];
for await (const message of query({
prompt: prompts[input.topic],
options: {
cwd: workspace,
allowedTools: ["Read", "Glob", "Grep"],
maxTurns: 8,
},
})) {
events.push(message);
}
return events;
}
利用者が「任意のコマンドを実行して」「別ディレクトリを読んで」と入力しても、選択式のtopicとallowedToolsによって実行範囲を制限できます。
ファイル編集を許可する
調査が安定したら、対象の一時リポジトリに限ってEditとWriteを追加します。
for await (const message of query({
prompt: `
次の作業だけを行ってください。
- src/utils/formatDate.tsに単体テストを追加
- 既存のテストフレームワークを使う
- production codeは変更しない
- テスト実行後、変更ファイルと結果を報告
対象外のファイルが必要なら、変更せず理由を報告してください。
`,
options: {
cwd: workspace,
allowedTools: [
"Read",
"Glob",
"Grep",
"Edit",
"Write",
],
maxTurns: 12,
},
})) {
// 進行状況と結果を保存
}
編集前にGitを初期化する
cd workspace
git status --short
git switch -c agent/add-format-date-tests
git add -A
git commit -m "chore: baseline before agent task"
変更前の状態をコミットまたはスナップショット化すると、失敗時に差分を破棄できます。エージェントが作業したブランチを、そのまま本番ブランチへmergeしないでください。
Bashでテストを実行する
Bashを許可すると、テストだけでなく、インストール、ネットワーク、削除なども提案できる可能性があります。専用コンテナで実行し、外部ネットワークと秘密情報を外したうえで追加します。
const options = {
cwd: workspace,
allowedTools: [
"Read",
"Glob",
"Grep",
"Edit",
"Write",
"Bash",
],
maxTurns: 16,
};
プロンプトにも実行可能なコマンドを明示します。
実行してよいコマンド:
- npm run test:unit -- ...
- npm run typecheck
- npm run lint -- ...
禁止:
- npm install
- curl / wget
- git push
- docker
- データベースの更新
- .envや秘密ファイルの読み取り
プロンプトの禁止事項だけでは十分ではありません。コンテナのネットワークを無効にする、読み取り専用マウントを使う、シークレットを渡さない、OS権限を落とすといった実行環境の制限を併用します。
ツール承認をアプリへ組み込む
Agent SDKでは、ツール利用の可否をアプリ側で判断する仕組みを利用できます。SDKバージョンのcanUseToolなどの権限コールバックを確認し、パス、コマンド、引数を検証します。
判断ロジックの考え方は次のとおりです。
function isAllowedCommand(command: string): boolean {
const normalized = command.trim();
return [
/^npm run test:unit(?:\s|$)/,
/^npm run typecheck$/,
/^npm run lint(?:\s|$)/,
/^git diff(?:\s|$)/,
/^git status(?:\s|$)/,
].some((pattern) => pattern.test(normalized));
}
function isSafeWorkspacePath(
workspace: string,
targetPath: string,
): boolean {
const root = resolve(workspace);
const target = resolve(workspace, targetPath);
return (
target === root ||
target.startsWith(`${root}/`)
);
}
シェル文字列の正規表現だけで完全な安全性を保証することは難しいため、可能であればシェルを使わず、固定した引数で子プロセスを起動する専用ツールを作ります。
セッションを継続する
長い作業では、最初の調査結果を引き継いで修正へ進めたいことがあります。Agent SDKはセッションの再開をサポートしています。セッションIDを利用者、リポジトリ、ブランチと結び付けて保存します。
- 別の利用者が他人のセッションを再開できないようにする
- リポジトリのHEADが変わった場合は再調査する
- 一定時間でセッションを失効させる
- 秘密情報をセッションへ含めない
- 再開前にツール権限を再確認する
セッションの具体的なオプション名はSDKの型定義と最新ドキュメントを確認してください。
Subagentsと組み合わせる
1つのエージェントに調査、実装、テスト、レビューをすべてさせると、コンテキストと権限が膨らみます。Claude Code Subagentsを使い、読み取り専用の探索担当やセキュリティ担当へ分けられます。
メインAgent SDKプロセス
├─ architecture-explorer(Read / Glob / Grep)
├─ test-reviewer(Read / Grep / 制限したBash)
└─ implementation(隔離WorktreeでEdit / Write)
Subagentを並列化すると利用量が増えるため、依頼の依存関係を確認し、本当に独立した調査だけを並列にします。
MCPで自社ツールを追加する
MCPを使うと、社内ドキュメント検索、チケット、監視、デザインデータなどをAgent SDKへ追加できます。
追加する前に次を決めます。
- 読み取り専用と更新操作を別ツールにする
- 利用者の権限をツール側でも確認する
- 結果の最大件数と文字数を制限する
- 外部データ内の命令を信用しない
- 削除・公開・課金は人間の承認を要求する
本番環境の安全な構成
APIサーバー
├─ 利用者認証
├─ 許可タスクの検証
├─ ジョブキュー
└─ 実行環境を起動
├─ 一時コンテナ
├─ 一時Worktree
├─ 必要なファイルだけマウント
├─ 最小権限ユーザー
├─ ネットワーク無効または許可先限定
├─ 短期トークン
└─ 実行後に破棄
結果保存
├─ 差分
├─ テスト結果
├─ ツール監査ログ
└─ 人間の承認状態
Webリクエストの中で長時間待たない
エージェント作業は数分以上かかる可能性があります。HTTPリクエスト内で完了を待つのではなく、ジョブIDを返し、SSE、WebSocket、ポーリングで進行状況を表示します。
ワーカーを使い回さない
異なる利用者のリポジトリやセッションが同じディレクトリに残らないよう、ジョブごとに環境を初期化して破棄します。
差分を人間が確認する
エージェントが作成した変更は、Pull Requestまたはパッチとして提示し、テスト、秘密情報、依存追加、生成物、設定変更をレビューします。
エラー処理とタイムアウト
- 最大ターン数を設定する
- ジョブ全体のタイムアウトを設定する
- APIレート制限は指数バックオフで小さく再試行する
- 同じ編集ジョブを重複起動しない
- 途中失敗時も差分とログを保存する
- 利用者がキャンセルできるようにする
自動再試行する前に、ファイル編集や外部操作が重複しないか確認します。読み取り処理と副作用のある処理では再試行方針を分けてください。
利用量と費用を管理する
各ジョブで次を記録します。
- 使用モデル
- 開始・終了時刻
- ターン数とツール呼び出し数
- 入出力トークン
- 変更ファイル数
- テスト実行回数
- 成功、失敗、キャンセル
調査だけのタスクに編集権限や高性能モデルを使わないなど、記事の目的ごとにプリセットを用意すると管理しやすくなります。
あわせて読みたい記事
よくある質問
Claude Codeを別途インストールする必要がありますか?
TypeScript SDKはClaude Codeの実行バイナリを依存関係として扱う構成が案内されています。利用するSDKバージョンのインストール要件を確認してください。
ブラウザだけでAgent SDKを実行できますか?
ローカルファイルやコマンドを扱うため、通常は信頼できるサーバーまたはデスクトップ側で実行します。APIキーやファイル権限をブラウザへ渡さないでください。
allowedToolsを指定すれば安全ですか?
重要な制限ですが、それだけでは十分ではありません。cwd、OS権限、コンテナ、ネットワーク、秘密情報、承認、監査ログも組み合わせます。
ユーザーが指定したGitHubリポジトリを自動でcloneしてもよいですか?
未知のリポジトリは信頼しないでください。隔離環境へ取得し、スクリプトを自動実行せず、シンボリックリンク、巨大ファイル、秘密情報の探索を制限します。
Agent SDKとClaude Code CLIはどう使い分けますか?
開発者が対話的に作業するならCLI、アプリやバックエンドの決まったフローへ組み込むならAgent SDKが向いています。
まとめ
Claude Agent SDKを使うと、Claude Codeのコード探索、編集、コマンド実行、MCP、SubagentsをTypeScriptアプリから利用できます。最初はRead、Glob、Grepだけの読み取り専用エージェントを作り、挙動とログを確認してください。
編集とBashを追加するときは、一時Worktreeやコンテナへ隔離し、cwd、ツール、コマンド、ネットワーク、秘密情報、最大ターン、承認を制限します。能力の高いエージェントを作ることより、失敗しても安全に破棄・復旧できる実行環境を作ることが重要です。