mcpField
D
dynamic-api-integration

dynamic-api-integration

github.com/oimiragieoAgent 工作流4451 次安装17 周前更新
代码仓库

关于 dynamic-api-integration

面向 Agent 的提示驱动 Skill,指导其在运行时发现并调用外部 HTTP REST API。它通过 API 规范或手动模板选择端点、构造请求、验证响应,并在安全限制下串联调用。

主要功能

  1. 01从 OpenAPI 规范发现端点
  2. 02将意图匹配到 API 端点
  3. 03构造带认证的 HTTP 请求
  4. 04使用 curl 或 WebFetch 执行调用
  5. 05验证响应并串联调用

适用场景

  1. 01探索不熟悉的 REST API
  2. 02依据提供的 API 规范提取数据
  3. 03串联搜索与详情请求
  4. 04处理 API 认证和分页

MCP 相关

此 Skill 用于尚未封装为 MCP 工具的 API;如果 API 已有 MCP 封装,则建议直接使用 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

详细介绍

模式:认知式/提示词驱动 — 没有独立的实用脚本;需通过 Agent 上下文使用。

动态 API 集成

概述

此技能将教 Agent 如何在运行时动态发现、解析并调用外部 HTTP API。它改编自 Universal Tool Calling Protocol (UTCP) 模式,并转换为 Node.js / Claude Code 工具模式。

核心工作流(5 个阶段,灵感来自 UTCP Agent 状态机):

  1. 发现 — 获取并解析 OpenAPI/Swagger 规范(或定义手动工具模板)。
  2. 匹配 — 将用户意图在语义上匹配到合适的 API 端点。
  3. 构造 — 使用正确的方法、路径、参数、标头、请求体和身份验证构造 HTTP 请求。
  4. 执行 — 通过 Bash(curl)或 WebFetch 调用 API 并捕获响应。
  5. 串联 — 如果任务尚未完成,则重新分析并执行另一次调用(最多 max_iterations 次)。

适用场景

在以下情况下使用此技能:

  • Agent 需要调用一个此前未使用过的外部 REST API
  • 用户提供 API URL 或 OpenAPI 规范 URL,并希望提取数据
  • Agent 必须先从规范中发现可用端点,再选择要调用的端点
  • 需要迭代串联多次 API 调用(搜索 -> 获取详情 -> 筛选)
  • Agent 需要构造包含身份验证和参数的 HTTP 请求

请勿在以下情况下使用:

  • API 已封装为 MCP 工具(直接使用 MCP 工具)
  • 集成只是一次性硬编码调用(直接使用 Bash curl)
  • API 需要通过用户交互式重定向完成 OAuth 2.0 授权码流程
  • API 使用 WebSocket 或仅支持流式传输的协议(而非 HTTP REST)

铁律

  1. 绝不在请求、curl 命令或源文件中硬编码 API 密钥、令牌或机密信息 — 始终使用环境变量($ENV_VAR)或机密管理器。
  2. 始终先发现 API 规范(OpenAPI/Swagger),再编写任何集成代码 — 在没有规范依据的情况下猜测端点结构,会导致集成无法正常工作。
  3. 绝不跳过 API 列表响应的分页处理 — 假设结果只有一页,会在数据集超过页面上限时悄无声息地丢失数据。
  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 Schema

工具模板格式(灵感来自 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 Key(标头):

curl -s -X GET "https://api.example.com/data?q=test" \
  -H "X-Api-Key: $API_KEY"

Bearer Token:

curl -s -X GET "https://api.example.com/data" \
  -H "Authorization: Bearer $AUTH_TOKEN"

Basic Auth:

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)WebFetch将 HTML 转换为 Markdown
错误处理

HTTP 状态码处理:

状态含义操作
200-299成功解析响应并继续
400请求错误检查参数,修正后重试
401未授权检查 API Key/Token,重新进行身份验证
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.

**为什么这很重要:**如果没有迭代保护机制,Agent 可能会不断循环调用 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 Token 认证)
# 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 Key 认证)
# 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 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)
  • 不将敏感响应数据(个人身份信息、令牌)存储在记忆文件中
  • 为所有请求设置超时(curl --max-time 30)

验证检查清单

完成动态 API 集成任务之前:

  • 已获取 API 规范并确定端点
  • 已将用户意图对应到正确的端点和方法
  • 请求包含适当的身份验证(如有要求)
  • 请求参数符合 API 架构(包含必需参数)
  • 已检查 HTTP 状态码并处理错误
  • 如果响应超过 5KB,已对其进行截断/摘要
  • 迭代次数未超过 max_iterations(5)
  • 没有在任何命令或文件中硬编码 API 密钥

反模式(避免)

反模式失败原因正确做法
硬编码 API 密钥有安全风险,密钥轮换后会失效在所有命令中使用 $ENV_VAR
未先阅读规范就调用 API端点错误、参数错误先发现 API(阶段 1)
将完整的 100KB 响应传入上下文上下文溢出、性能下降截断/提取(阶段 4)
链式调用不设置迭代保护机制无限循环消耗令牌始终强制执行 max_iterations
猜测参数名称导致 400 错误,浪费调用构造请求前阅读规范/文档
忽略 HTTP 错误码静默失败、结果错误检查状态并处理 4xx/5xx
正确方法应为 GET 时却使用 POSTAPI 拒绝请求或创建非预期资源根据意图匹配方法(阶段 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

假设工作可能会中断:如果内容不在记忆中,就等于从未发生。

评论

支持 Markdown