dynamic-api-integration について
エージェントが実行時に外部 HTTP REST API を発見して呼び出すための、プロンプト駆動型スキルです。API 仕様または手動テンプレートを使い、エンドポイント選択、リクエスト構築、レスポンス検証、制限付きの連続呼び出しを行います。
主な機能
- 01OpenAPI 仕様からエンドポイントを検出
- 02意図に合う API エンドポイントを選択
- 03認証付き HTTP リクエストを構築
- 04curl または WebFetch で呼び出し
- 05レスポンス検証と連続呼び出し
活用シーン
- 01未知の REST API を調査
- 02提供された API 仕様からデータを取得
- 03検索と詳細取得を連続実行
- 04認証やページネーションを伴う API 呼び出し
MCP 対応
MCP ツールとして公開されていない API が対象です。API が MCP ツールで利用できる場合は、直接そのツールを使うよう案内します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ oimiragieo/ agent-studio --skill dynamic-api-integrationインストール後、Claude Code で/dynamic-api-integrationを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
commands/dynamic-api-integration.mdhooks/post-execute.cjspre-execute.cjsreferences/research-requirements.mdrules/dynamic-api-integration.mdschemas/input.schema.jsonoutput.schema.jsonscripts/main.cjstemplates/implementation-template.md詳細
モード:認知/プロンプト駆動型 — 単独で実行するユーティリティスクリプトはありません。エージェントのコンテキストを通じて使用します。
動的 API 統合
概要
このスキルでは、エージェントが実行時に外部 HTTP API を動的に検出、解析、呼び出しする方法を説明します。Universal Tool Calling Protocol (UTCP) のパターンをもとに、Node.js/Claude Code のツールパターン向けに適用したものです。
基本的なワークフロー(UTCP エージェント状態マシンを参考にした5段階):
- 検出 — OpenAPI/Swagger 仕様を取得して解析します(または手動でツールテンプレートを定義します)。
- 照合 — ユーザーの意図を意味的に適切な API エンドポイントに対応付けます。
- 構築 — 適切なメソッド、パス、パラメーター、ヘッダー、本文、認証を指定して HTTP リクエストを構築します。
- 実行 — Bash(curl)または WebFetch を使って API を呼び出し、レスポンスを取得します。
- 連鎖 — タスクがまだ完了していない場合は、再分析して別の呼び出しを実行します(max_iterations まで)。
使用する場面
次のような場合にこのスキルを使用します:
- エージェントが、これまで使用したことのない外部 REST API を呼び出す必要がある
- ユーザーが API URL または OpenAPI 仕様の URL を提示し、データの抽出を求めている
- 呼び出すエンドポイントを選ぶ前に、エージェントが仕様から利用可能なエンドポイントを検出する必要がある
- 複数の API 呼び出しを反復的に連鎖させる必要がある(検索 -> 詳細の取得 -> 絞り込み)
- エージェントが認証とパラメーターを指定して HTTP リクエストを構築する必要がある
次の場合は使用しないでください:
- API がすでに MCP ツールとしてラップされている(MCP ツールを直接使用してください)
- 一度限りのハードコードされた呼び出しである(Bash curl を直接使用してください)
- API がユーザーによる対話的なリダイレクトを伴う OAuth 2.0 認可コードフローを必要とする
- API が WebSocket またはストリーミング専用プロトコルを使用している(HTTP REST ではない)
絶対遵守事項
- API キー、トークン、シークレットをリクエスト、curl コマンド、ソースファイルに決してハードコードしないでください。必ず環境変数(
$ENV_VAR)またはシークレットマネージャーを使用してください。 - 統合コードを書く前に、API 仕様(OpenAPI/Swagger)を必ず確認してください。仕様に基づかずエンドポイントの形式を推測すると、統合が動作しなくなります。
- API がリスト形式のレスポンスを返す場合、ページネーション処理を決して省略しないでください。1ページ分だけの結果だと仮定すると、ページ上限を超えるデータセットではデータが黙って欠落します。
- 一時的な障害(429、503)に備え、指数バックオフを伴う再試行ロジックを必ず実装してください。動的 API は本質的に信頼性に欠けるため、再試行のない統合は通常の本番環境でも失敗します。
- 使用前に各レスポンスのスキーマを検証せず、API レスポンスを決して信用しないでください。動的 API のレスポンス形式は予告なく変更されるため、検証しないレスポンスは呼び出し元の実行時クラッシュを引き起こします。
フェーズ 1:検出 — API 仕様を取得して解析する
オプション A:OpenAPI/Swagger 仕様の検出
API が OpenAPI 仕様を提供している場合(最新の API の多くが提供しています):
# Step 1: Fetch the OpenAPI spec
WebFetch({
url: "https://api.example.com/openapi.json",
prompt: "Extract all API endpoints. For each endpoint, list: HTTP method, path, description, required parameters, optional parameters, authentication requirement. Return as a structured list."
})
仕様から抽出する情報:
| 項目 | 仕様内の場所 | 用途 |
|---|---|---|
| ベース URL | servers[0].url | すべてのリクエストの API ルート |
| エンドポイント | paths.* | 利用可能な操作 |
| メソッド | paths.*.get/post/put/delete | エンドポイントごとの HTTP メソッド |
| パラメーター | paths.*.*.parameters[] | クエリ、パス、ヘッダーのパラメーター |
| リクエスト本文 | paths.*.*.requestBody | POST/PUT ペイロードのスキーマ |
| 認証 | components.securitySchemes | API キー、Bearer、OAuth |
| レスポンススキーマ | paths.*.*.responses.200 | 想定されるレスポンス形式 |
OpenAPI 仕様の一般的な場所:
https://api.example.com/openapi.jsonhttps://api.example.com/swagger.jsonhttps://api.example.com/v3/api-docshttps://api.example.com/.well-known/openapi.jsonhttps://api.example.com/docs(HTML ページから仕様へのリンクが見つかる場合があります)
オプション B:手動のツールテンプレート(仕様がない場合)
OpenAPI 仕様がない場合は、ツールテンプレートを手動で定義します。
{
"name": "search_books",
"description": "Search Open Library for books by query",
"base_url": "https://openlibrary.org/search.json",
"method": "GET",
"auth": null,
"parameters": {
"q": {
"type": "string",
"required": true,
"in": "query",
"description": "Search query (title, author, ISBN)"
},
"limit": {
"type": "integer",
"required": false,
"in": "query",
"description": "Max results to return (default 10)"
},
"page": {
"type": "integer",
"required": false,
"in": "query",
"description": "Page number for pagination"
}
},
"response_hint": "Returns { numFound, docs: [{ title, author_name, first_publish_year }] }"
}
ツールテンプレートの JSON スキーマ
ツールテンプレート形式(UTCP の manual_call_templates に着想を得ています):
{
"name": "string (required) — unique tool identifier, lowercase_snake_case",
"description": "string (required) — what this tool does, used for semantic matching",
"base_url": "string (required) — full URL including path",
"method": "string (required) — GET | POST | PUT | PATCH | DELETE",
"content_type": "string (optional) — default: application/json",
"auth": {
"type": "string — api_key | bearer | basic | none",
"header": "string — header name (e.g., X-Api-Key, Authorization)",
"env_var": "string — environment variable name holding the secret",
"prefix": "string (optional) — e.g., 'Bearer ' for bearer auth"
},
"parameters": {
"<param_name>": {
"type": "string | integer | boolean | array | object",
"required": "boolean",
"in": "query | path | header | body",
"description": "string — what this parameter does",
"default": "any (optional) — default value if not provided"
}
},
"response_hint": "string (optional) — brief description of response shape"
}
フェーズ 2:照合 — セマンティックな意図とエンドポイントのマッピング
API を呼び出す前に、ユーザーの意図に合ったエンドポイントを選びます。
ステップ 1:ユーザーの目的を理解する
自問してください。ユーザーはどのようなデータを求めていますか?どのような操作を実行してほしいと考えていますか?
ステップ 2:意図をエンドポイントにマッピングする
| ユーザーの意図 | 想定される HTTP メソッド | エンドポイントのパターン |
|---|---|---|
| 「検索/リスト表示/取得」 | GET | /search、/list、/{resource} |
| 「作成/追加/登録」 | POST | /{resource} |
| 「更新/修正/変更」 | PUT または PATCH | /{resource}/{id} |
| 「削除/取り除く」 | DELETE | /{resource}/{id} |
| 「X の詳細を取得」 | GET | /{resource}/{id} |
ステップ 3:パラメーターを選択する
- 必須パラメーター: 指定する必要があります(仕様またはテンプレートで
required: trueを確認してください)。 - オプションパラメーター: ユーザーが指定した場合、または結果の改善に役立つ場合にのみ使用します。
- パスパラメーター: URL に置き換えて指定します(例:
/repos/{owner}/{repo})。 - クエリパラメーター:
?key=value&key2=value2の形式で追加します。 - ボディパラメーター: POST/PUT/PATCH の JSON ペイロードとして送信します。
フェーズ 3:構築 — HTTP リクエストを作成する
リクエスト作成チェックリスト
- URL: ベース URL + パス + パスパラメーターの置換
- メソッド: GET、POST、PUT、PATCH、DELETE
- ヘッダー: Content-Type、Authorization、Accept、カスタムヘッダー
- クエリパラメーター: URL エンコードして URL に追加
- ボディ: POST/PUT/PATCH 用の JSON ペイロード
- 認証: 環境変数から挿入
認証パターン
API キー(ヘッダー):
curl -s -X GET "https://api.example.com/data?q=test" \
-H "X-Api-Key: $API_KEY"
Bearer トークン:
curl -s -X GET "https://api.example.com/data" \
-H "Authorization: Bearer $AUTH_TOKEN"
Basic 認証:
curl -s -X GET "https://api.example.com/data" \
-u "$USERNAME:$PASSWORD"
認証なし(パブリック API):
curl -s -X GET "https://api.example.com/data?q=test"
メソッド別リクエストテンプレート
クエリパラメーター付き GET:
curl -s -X GET "https://api.example.com/search?q=test&limit=10&page=1" \
-H "Accept: application/json" \
-H "Authorization: Bearer $TOKEN"
JSON ボディ付き POST:
curl -s -X POST "https://api.example.com/items" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"name": "New Item", "category": "tools", "price": 29.99}'
パスパラメーター付き PUT:
curl -s -X PUT "https://api.example.com/items/123" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"name": "Updated Item", "price": 39.99}'
DELETE:
curl -s -X DELETE "https://api.example.com/items/123" \
-H "Authorization: Bearer $TOKEN"
フェーズ 4:実行 — API を呼び出してレスポンスを処理する
Bash(curl)を使用 — 主な方法
# Execute and capture response + HTTP status
RESPONSE=$(curl -s -w "\n%{http_code}" -X GET "https://api.example.com/search?q=test" \
-H "Accept: application/json")
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
BODY=$(echo "$RESPONSE" | sed '$d')
echo "Status: $HTTP_CODE"
echo "Body: $BODY" | head -c 2000 # Truncate to 2KB for context safety
WebFetch を使用 — AI による処理が必要な場合
WebFetch({
url: 'https://api.example.com/search?q=test',
prompt:
'Extract the top 5 results with their titles and descriptions. Format as a numbered list.',
});
使い分け:
| シナリオ | ツール | 理由 |
|---|---|---|
| 後続の処理用に生の JSON が必要 | Bash(curl) | 完全に制御でき、解析可能な出力 |
| データの要約/抽出が必要 | WebFetch | AI がレスポンスをその場で処理する |
| HTTP ステータスコードの確認が必要 | Bash(curl) | WebFetch ではステータスが抽象化される |
| 大きなレスポンス(>50KB) | Bash(curl)+ 切り詰め | WebFetch は大きなページでタイムアウトする可能性がある |
| HTML ページ(JSON ではない) | WebFetch | HTML を Markdown に変換する |
エラー処理
HTTP ステータスコードの処理:
| ステータス | 意味 | 対応 |
|---|---|---|
| 200-299 | 成功 | レスポンスを解析して続行する |
| 400 | 不正なリクエスト | パラメーターを確認し、修正して再試行する |
| 401 | 認証されていない | API キー/トークンを確認し、再認証する |
| 403 | 禁止 | 権限を確認し、ユーザーに報告する |
| 404 | 見つからない | URL/リソース ID を確認し、別のエンドポイントを試す |
| 429 | レート制限 | 待機して(Retry-After ヘッダーを確認)、再試行する |
| 500-599 | サーバーエラー | 待機して最大 3 回まで再試行する |
指数バックオフによる再試行:
# Retry pattern for transient errors (429, 5xx)
for attempt in 1 2 3; do
RESPONSE=$(curl -s -w "\n%{http_code}" -X GET "$URL" -H "Authorization: Bearer $TOKEN")
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
if [ "$HTTP_CODE" -lt 400 ]; then
break # Success
fi
echo "Attempt $attempt failed ($HTTP_CODE), retrying in $((attempt * 2))s..."
sleep $((attempt * 2))
done
レスポンスの処理
JSON レスポンスを解析する(Bash):
# Extract specific fields from JSON response
echo "$BODY" | node -e "
const data = JSON.parse(require('fs').readFileSync('/dev/stdin', 'utf8'));
console.log('Total:', data.totalResults);
data.items?.slice(0, 5).forEach((item, i) => {
console.log(\`\${i+1}. \${item.title} — \${item.description?.substring(0, 80)}\`);
});
"
大きなレスポンスを切り詰める:
# Safety: never pass >10KB of API response into context
BODY_TRUNCATED=$(echo "$BODY" | head -c 10000)
if [ ${#BODY} -gt 10000 ]; then
echo "[TRUNCATED: Response was $(echo "$BODY" | wc -c) bytes, showing first 10KB]"
fi
フェーズ 5:チェーン — 反復型の複数呼び出しワークフロー
多くのタスクでは、複数の API 呼び出しを連鎖させる必要があります。UTCP を参考にした反復パターンを使用します。
チェーンパターン
Iteration 1: Search -> Get list of results
Iteration 2: Get details for top result
Iteration 3: Perform action on result
(max_iterations guard: stop at 5)
反復ガード(必須)
MAX_ITERATIONS = 5
Before each API call:
IF iteration_count >= MAX_ITERATIONS:
STOP. Summarize what was gathered so far and respond.
ELSE:
Execute the call, increment counter, re-analyze task.
重要な理由: 反復ガードがないと、エージェントが API を呼び出し続けて無限ループに陥る可能性があります。UTCP ではデフォルト値に 3 を使用していますが、より複雑な複数ステップのワークフローには 5 を推奨します。
チェーンの例
例 1:検索して詳細を取得する
User: "Find information about the book '1984' by George Orwell"
Iteration 1:
Call: GET https://openlibrary.org/search.json?q=1984+george+orwell&limit=5
Result: Found 5 matches, top result has key "/works/OL1168083W"
Iteration 2:
Call: GET https://openlibrary.org/works/OL1168083W.json
Result: Full book details (title, description, subjects, covers)
Task complete: Return summarized book information.
例 2:GitHub — リポジトリを見つけて分析する
User: "What are the most recent issues in the react repository?"
Iteration 1:
Call: GET https://api.github.com/repos/facebook/react/issues?state=open&per_page=10&sort=created
Headers: Authorization: Bearer $GITHUB_TOKEN
Result: 10 most recent open issues
Task complete: Summarize issue titles, labels, and dates.
例 3:複数の API を連鎖させる
User: "Find news about AI safety and summarize the top article"
Iteration 1:
Call: GET https://newsapi.org/v2/everything?q=AI+safety&sortBy=publishedAt&pageSize=5
Headers: X-Api-Key: $NEWS_API_KEY
Result: 5 articles with titles, URLs
Iteration 2:
Call: WebFetch({ url: articles[0].url, prompt: "Summarize this article in 3 bullet points" })
Result: Article summary
Task complete: Return article title + summary.
実際の API の例
GitHub API(Bearer トークン認証)
# List repositories for a user
curl -s -X GET "https://api.github.com/users/octocat/repos?sort=updated&per_page=5" \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $GITHUB_TOKEN"
ツールテンプレート:
{
"name": "github_list_repos",
"description": "List repositories for a GitHub user, sorted by most recently updated",
"base_url": "https://api.github.com/users/{username}/repos",
"method": "GET",
"auth": {
"type": "bearer",
"header": "Authorization",
"env_var": "GITHUB_TOKEN",
"prefix": "Bearer "
},
"parameters": {
"username": {
"type": "string",
"required": true,
"in": "path",
"description": "GitHub username"
},
"sort": {
"type": "string",
"required": false,
"in": "query",
"description": "Sort field: created, updated, pushed, full_name",
"default": "updated"
},
"per_page": {
"type": "integer",
"required": false,
"in": "query",
"description": "Results per page (max 100)",
"default": 10
}
}
}
Open Library API(認証なし)
# Search for books
curl -s -X GET "https://openlibrary.org/search.json?q=george+orwell&limit=5" \
-H "Accept: application/json"
JSONPlaceholder(テスト/プロトタイピング)
# GET all posts
curl -s https://jsonplaceholder.typicode.com/posts?_limit=5
# POST new item
curl -s -X POST https://jsonplaceholder.typicode.com/posts \
-H "Content-Type: application/json" \
-d '{"title": "Test Post", "body": "Hello world", "userId": 1}'
Weather API(API キー認証)
# Get current weather
curl -s "https://api.open-meteo.com/v1/forecast?latitude=51.5074&longitude=-0.1278¤t_weather=true"
大きなレスポンスのコンテキスト管理
API レスポンスは非常に大きくなることがあります。コンテキストのオーバーフローを防ぐため、次のルールを適用してください。
レスポンスサイズの上限
| レスポンスサイズ | 対応 |
|---|---|
| < 5 KB | レスポンス全体を使用 |
| 5-20 KB | 関連するフィールドのみを抽出 |
| 20-50 KB | WebFetch または node スクリプトで要約 |
| > 50 KB | 先頭の 5KB に切り詰め、残りの件数を数える |
抽出パターン(大きなレスポンスに推奨)
# Instead of dumping full response, extract what you need
curl -s "https://api.example.com/search?q=test" | node -e "
const data = JSON.parse(require('fs').readFileSync('/dev/stdin', 'utf8'));
// Extract only what the user asked for
const results = data.results.slice(0, 5).map(r => ({
id: r.id,
title: r.title,
summary: r.description?.substring(0, 200)
}));
console.log(JSON.stringify(results, null, 2));
"
セキュリティチェックリスト
- すべての API キーが環境変数に保存されている(コードやコマンドには決して記述しない)
- すべての API 呼び出しで HTTPS を使用している(認証が必要なリクエストでは HTTP を決して使用しない)
- 使用前にレスポンスデータを検証している(ステータスコードを確認する)
- ユーザーの秘密情報をログに記録したり、ファイルに書き込んだりしていない
- レート制限を遵守している(X-RateLimit-Remaining などのヘッダーを確認する)
- 機密性の高いレスポンスデータ(PII、トークン)をメモリファイルに保存していない
- すべてのリクエストにタイムアウトを設定している(
curl --max-time 30)
検証チェックリスト
動的な API 統合タスクを完了する前に、次の項目を確認してください。
- API 仕様を取得し、エンドポイントを特定した
- ユーザーの意図を適切なエンドポイントとメソッドに対応付けた
- リクエストに適切な認証が含まれている(必要な場合)
- リクエストパラメーターが API スキーマと一致している(必須パラメーターが含まれている)
- HTTP ステータスコードを確認し、エラーを処理した
- 5KB を超えるレスポンスを切り詰めるか、要約した
- 反復回数が max_iterations(5)を超えていない
- コマンドやファイルに API キーをハードコードしていない
アンチパターン(避けてください)
| アンチパターン | 失敗する理由 | 正しい方法 |
|---|---|---|
| API キーをハードコードする | セキュリティリスクがあり、キーのローテーション時に動作しなくなる | すべてのコマンドで $ENV_VAR を使用する |
| 仕様を先に読まずに API を呼び出す | エンドポイントやパラメーターを誤る | まず確認する(フェーズ 1) |
| 100KB のレスポンス全体をコンテキストに渡す | コンテキストがオーバーフローし、パフォーマンスが低下する | 切り詰める/抽出する(フェーズ 4) |
| 連鎖呼び出しに反復ガードを設定しない | トークンを消費し続ける無限ループが発生する | 必ず max_iterations を適用する |
| パラメーター名を推測する | 400 エラーが発生し、呼び出しが無駄になる | リクエストを組み立てる前に仕様/ドキュメントを読む |
| HTTP エラーコードを無視する | 失敗に気付かず、誤った結果になる | ステータスを確認し、4xx/5xx を処理する |
| GET が適切な場面で POST を使用する | API に拒否されるか、意図しないリソースが作成される | 意図に合ったメソッドを使用する(フェーズ 2) |
クイックリファレンスカード
DISCOVER → WebFetch(spec_url) or define manual tool template
MATCH → Map user intent to endpoint + method + params
CONSTRUCT → Build curl command with URL, headers, auth, body
EXECUTE → Bash(curl) for JSON, WebFetch for HTML/summarize
CHAIN → Re-analyze task, call again (max 5 iterations)
認証クイックリファレンス:
API Key: -H "X-Api-Key: $KEY"
Bearer: -H "Authorization: Bearer $TOKEN"
Basic: -u "$USER:$PASS"
None: (no auth header needed)
ツールテンプレートをすばやく作成する:
{
"name": "...",
"description": "...",
"base_url": "...",
"method": "GET",
"auth": { "type": "api_key", "header": "...", "env_var": "..." },
"parameters": { "q": { "type": "string", "required": true, "in": "query" } }
}
調査の基盤
このスキルは、以下を参考にしています。
- Universal Tool Calling Protocol (UTCP) — AI エージェントのツール呼び出しのオープン標準
- UTCP Agent — LangGraph ベースのリファレンス実装
- UTCP Specification — RFC およびプロトコルの定義
- OpenAPI Specification 3.1 — API 記述の標準
- OpenAPI Best Practices — コミュニティのガイドライン
- agents.json Specification — API エージェントの契約標準
- API Integration Patterns (2026) — パターンの分類
関連スキル
auth-security-expert— OAuth 2.1、JWT、暗号化パターンnodejs-expert— Node.js の HTTP パターンdebugging— API 呼び出しの失敗調査research-synthesis— 統合前の新しい API の調査
メモリプロトコル
開始前:
.claude/context/memory/learnings.md を読みます
完了後:
- 新しい API パターンを発見した場合 ->
.claude/context/memory/learnings.md - API の問題や制限を発見した場合 ->
.claude/context/memory/issues.md - API の設計上の決定を行った場合 ->
.claude/context/memory/decisions.md - 再利用可能なツールテンプレートを作成した場合 ->
.claude/context/memory/named/api-templates.mdに保存します
中断されることを想定してください。メモリに記録されていない場合、それは起きていません。