mcpField
D
dynamic-api-integration

dynamic-api-integration

github.com/oimiragieoエージェントワークフロー4451 回インストール17 週間前に更新
リポジトリ

dynamic-api-integration について

エージェントが実行時に外部 HTTP REST API を発見して呼び出すための、プロンプト駆動型スキルです。API 仕様または手動テンプレートを使い、エンドポイント選択、リクエスト構築、レスポンス検証、制限付きの連続呼び出しを行います。

主な機能

  1. 01OpenAPI 仕様からエンドポイントを検出
  2. 02意図に合う API エンドポイントを選択
  3. 03認証付き HTTP リクエストを構築
  4. 04curl または WebFetch で呼び出し
  5. 05レスポンス検証と連続呼び出し

活用シーン

  1. 01未知の REST API を調査
  2. 02提供された API 仕様からデータを取得
  3. 03検索と詳細取得を連続実行
  4. 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.md
hooks/
post-execute.cjs
pre-execute.cjs
references/
research-requirements.md
rules/
dynamic-api-integration.md
schemas/
input.schema.json
output.schema.json
scripts/
main.cjs
templates/
implementation-template.md

詳細

モード:認知/プロンプト駆動型 — 単独で実行するユーティリティスクリプトはありません。エージェントのコンテキストを通じて使用します。

動的 API 統合

概要

このスキルでは、エージェントが実行時に外部 HTTP API を動的に検出、解析、呼び出しする方法を説明します。Universal Tool Calling Protocol (UTCP) のパターンをもとに、Node.js/Claude Code のツールパターン向けに適用したものです。

基本的なワークフロー(UTCP エージェント状態マシンを参考にした5段階):

  1. 検出 — OpenAPI/Swagger 仕様を取得して解析します(または手動でツールテンプレートを定義します)。
  2. 照合 — ユーザーの意図を意味的に適切な API エンドポイントに対応付けます。
  3. 構築 — 適切なメソッド、パス、パラメーター、ヘッダー、本文、認証を指定して HTTP リクエストを構築します。
  4. 実行 — Bash(curl)または WebFetch を使って API を呼び出し、レスポンスを取得します。
  5. 連鎖 — タスクがまだ完了していない場合は、再分析して別の呼び出しを実行します(max_iterations まで)。

使用する場面

次のような場合にこのスキルを使用します:

  • エージェントが、これまで使用したことのない外部 REST API を呼び出す必要がある
  • ユーザーが API URL または OpenAPI 仕様の URL を提示し、データの抽出を求めている
  • 呼び出すエンドポイントを選ぶ前に、エージェントが仕様から利用可能なエンドポイントを検出する必要がある
  • 複数の API 呼び出しを反復的に連鎖させる必要がある(検索 -> 詳細の取得 -> 絞り込み)
  • エージェントが認証とパラメーターを指定して HTTP リクエストを構築する必要がある

次の場合は使用しないでください:

  • API がすでに MCP ツールとしてラップされている(MCP ツールを直接使用してください)
  • 一度限りのハードコードされた呼び出しである(Bash curl を直接使用してください)
  • API がユーザーによる対話的なリダイレクトを伴う OAuth 2.0 認可コードフローを必要とする
  • API が WebSocket またはストリーミング専用プロトコルを使用している(HTTP REST ではない)

絶対遵守事項

  1. API キー、トークン、シークレットをリクエスト、curl コマンド、ソースファイルに決してハードコードしないでください。必ず環境変数($ENV_VAR)またはシークレットマネージャーを使用してください。
  2. 統合コードを書く前に、API 仕様(OpenAPI/Swagger)を必ず確認してください。仕様に基づかずエンドポイントの形式を推測すると、統合が動作しなくなります。
  3. API がリスト形式のレスポンスを返す場合、ページネーション処理を決して省略しないでください。1ページ分だけの結果だと仮定すると、ページ上限を超えるデータセットではデータが黙って欠落します。
  4. 一時的な障害(429、503)に備え、指数バックオフを伴う再試行ロジックを必ず実装してください。動的 API は本質的に信頼性に欠けるため、再試行のない統合は通常の本番環境でも失敗します。
  5. 使用前に各レスポンスのスキーマを検証せず、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."
})

仕様から抽出する情報:

項目仕様内の場所用途
ベース URLservers[0].urlすべてのリクエストの API ルート
エンドポイントpaths.*利用可能な操作
メソッドpaths.*.get/post/put/deleteエンドポイントごとの HTTP メソッド
パラメーターpaths.*.*.parameters[]クエリ、パス、ヘッダーのパラメーター
リクエスト本文paths.*.*.requestBodyPOST/PUT ペイロードのスキーマ
認証components.securitySchemesAPI キー、Bearer、OAuth
レスポンススキーマpaths.*.*.responses.200想定されるレスポンス形式

OpenAPI 仕様の一般的な場所:

  • https://api.example.com/openapi.json
  • https://api.example.com/swagger.json
  • https://api.example.com/v3/api-docs
  • https://api.example.com/.well-known/openapi.json
  • https://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 リクエストを作成する

リクエスト作成チェックリスト
  1. URL: ベース URL + パス + パスパラメーターの置換
  2. メソッド: GET、POST、PUT、PATCH、DELETE
  3. ヘッダー: Content-Type、Authorization、Accept、カスタムヘッダー
  4. クエリパラメーター: URL エンコードして URL に追加
  5. ボディ: POST/PUT/PATCH 用の JSON ペイロード
  6. 認証: 環境変数から挿入
認証パターン

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)完全に制御でき、解析可能な出力
データの要約/抽出が必要WebFetchAI がレスポンスをその場で処理する
HTTP ステータスコードの確認が必要Bash(curl)WebFetch ではステータスが抽象化される
大きなレスポンス(>50KB)Bash(curl)+ 切り詰めWebFetch は大きなページでタイムアウトする可能性がある
HTML ページ(JSON ではない)WebFetchHTML を 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&current_weather=true"

大きなレスポンスのコンテキスト管理

API レスポンスは非常に大きくなることがあります。コンテキストのオーバーフローを防ぐため、次のルールを適用してください。

レスポンスサイズの上限
レスポンスサイズ対応
< 5 KBレスポンス全体を使用
5-20 KB関連するフィールドのみを抽出
20-50 KBWebFetch または 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" } }
}

調査の基盤

このスキルは、以下を参考にしています。

関連スキル

  • 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 に保存します

中断されることを想定してください。メモリに記録されていない場合、それは起きていません。

コメント