API代理
将任何API转换为MCP服务器。用英语查询。获取结果—即使API不能。
指向任何GraphQL或REST API。用自然语言提问。代理获取数据,将其存储在DuckDB中,并运行SQL后处理。排名、筛选、JOIN工作 即使API不支持它们.
是什么让它与众不同
🎯 零配置。 API没有自定义MCP代码。指向GraphQL端点或OpenAPI规范——模式会自动反思。
✨ SQL后处理。 API返回10000个未排序的行?代理商排名前十。没有分组依据?试剂聚集。需要跨端点的JOIN吗?代理组合。
🔒 默认情况下是安全的。 只读。除非明确允许,否则突变被阻止。
🧠 食谱学习。 成功的查询将成为缓存管道。无需LLM推理即可立即重用。
快速开始
1.运行(选择一个):
# Direct run (no clone needed)
OPENAI_API_KEY=your_key uvx --from git+https://github.com/agoda-com/api-agent api-agent
# Or clone & run
git clone https://github.com/agoda-com/api-agent.git && cd api-agent
uv sync && OPENAI_API_KEY=your_key uv run api-agent
# Or Docker
git clone https://github.com/agoda-com/api-agent
docker build -t api-agent .
docker run -p 3000:3000 -e OPENAI_API_KEY=your_key api-agent2.向任何MCP客户端添加:
{
"mcpServers": {
"rickandmorty": {
"url": "http://localhost:3000/mcp",
"headers": {
"X-Target-URL": "https://rickandmortyapi.com/graphql",
"X-API-Type": "graphql"
}
}
}
}3.提问:
- *“显示来自地球的角色,只显示活着的角色,按物种分组”*
- *“按剧集数排名前10的角色”*
- *“按物种比较活的和死的,只有具有10+个字符的物种”*
就是这样。代理内省模式,生成查询,运行SQL后处理。
更多示例
REST API(Petstore-OpenAPI 3.x):
{
"mcpServers": {
"petstore": {
"url": "http://localhost:3000/mcp",
"headers": {
"X-Target-URL": "https://petstore3.swagger.io/api/v3/openapi.json",
"X-API-Type": "rest"
}
}
}
}REST API(Petstore-Swagger 2.0):
{
"mcpServers": {
"petstore": {
"url": "http://localhost:3000/mcp",
"headers": {
"X-Target-URL": "https://petstore.swagger.io/v2/swagger.json",
"X-API-Type": "rest"
}
}
}
}您自己的带有auth的API:
{
"mcpServers": {
"myapi": {
"url": "http://localhost:3000/mcp",
"headers": {
"X-Target-URL": "https://api.example.com/graphql",
"X-API-Type": "graphql",
"X-Target-Headers": "{\"Authorization\": \"Bearer YOUR_TOKEN\"}"
}
}
}
}______________________________________________________________________
参考
标头
| 标题 | 必填 | 描述 |
|---|---|---|
X-Target-URL | 是 | GraphQL端点或OpenAPI/Swagger规范URL(3.x和2.0) |
X-API-Type | 是的 | graphql 或 rest |
X-Target-Headers | 否 | JSON身份验证标头,例如。 {"Authorization": "Bearer xxx"} |
X-API-Name | 否 | 覆盖工具名称前缀(默认:自动生成) |
X-Base-URL | 否 | 覆盖REST API调用的基本URL |
X-Allow-Unsafe-Paths | 否 | 包含JSON数组的标头字符串 fnmatch 地球仪(*, ?)用于POST/PUT/DELETE/PATCH |
X-Poll-Paths | 否 | 包含JSON轮询路径模式数组的标头字符串(启用轮询工具) |
X-Include-Result | 否 | 包括完全无上限 result 输出字段 |
标题值示例
X-Allow-Unsafe-Paths 和 X-Poll-Paths 使用相同的转义格式:JSON数组编码为头字符串。
MCP配置(JSON):
{
"headers": {
"X-Allow-Unsafe-Paths": "[\"/search\", \"/api/*/query\", \"/jobs/*/cancel\"]",
"X-Poll-Paths": "[\"/search\", \"/trips/*/status\"]"
}
}X-Allow-Unsafe-Paths 模式示例:
"/search"精确路径"/api/*/query"一个通配符段"/jobs/*"以下任何后缀/jobs/
X-Poll-Paths 模式示例:
"/search"精确轮询路径"/trips/*/status"通配符轮询路径
X-Poll-Paths 启用轮询指导/工具; X-Allow-Unsafe-Paths 控制不安全的方法。
逃避快速检查(两个标题相同):
- 错误:
"X-Allow-Unsafe-Paths": "["/search"]" - 正确的
"X-Allow-Unsafe-Paths": "[\"/search\"]"
MCP工具
核心工具 (每API 2个):
| 工具 | 输入 | 输出 |
|---|---|---|
{prefix}_query | 自然语言问题 | {ok, data, queries/api_calls} |
{prefix}_execute | GraphQL: query, variables /休息: method, path,参数 | {ok, data} |
从URL自动生成的工具名称(例如。, example_query).覆盖 X-API-Name.
配方工具 (动态,随着食谱的学习而添加):
| 工具 | 输入 | 输出 |
|---|---|---|
r_{recipe_slug} | 平面配方特定参数, return_directly (bool) | CSV或 {ok, data, executed_queries/calls} |
缓存管道,无LLM推理。查询成功后出现。通过以下方式通知客户 tools/list_changed.
配置
| 变量 | 必填 | 默认 | 描述 |
|---|---|---|---|
OPENAI_API_KEY | 是 | - | OpenAI API密钥(或自定义LLM密钥) |
OPENAI_BASE_URL | 否 | https://api.openai.com/v1 | 自定义LLM端点 |
API_AGENT_MODEL_NAME | 否 | gpt-5.2 | 型号(例如gpt-5.2) |
API_AGENT_PORT | 无 | 3000 | 服务器端口 |
API_AGENT_ENABLE_RECIPES | 否 | 正确 | 启用配方学习和缓存 |
API_AGENT_RECIPE_CACHE_SIZE | 否 | 64 | 最大缓存食谱(LRU驱逐) |
OTEL_EXPORTER_OTLP_ENDPOINT | 否 | - | OpenTetry跟踪端点 |
______________________________________________________________________
运作原理
sequenceDiagram
participant U as User
participant M as MCP Server
participant A as Agent
participant G as Target API
U->>M: Question + Headers
M->>G: Schema introspection
G-->>M: Schema
M->>A: Schema + question
A->>G: API call
G-->>A: Data → stored in DuckDB
A->>A: SQL post-processing
A-->>M: Summary
M-->>U: {ok, data, queries[]}建筑
flowchart TB
subgraph Client["MCP Client"]
H["Headers: X-Target-URL, X-API-Type"]
end
subgraph MCP["MCP Server (FastMCP)"]
Q["{prefix}_query"]
E["{prefix}_execute"]
R["r_{recipe} (dynamic)"]
end
subgraph Agent["Agents (OpenAI Agents SDK)"]
GA["GraphQL Agent"]
RA["REST Agent"]
end
subgraph Exec["Executors"]
HTTP["HTTP Client"]
Duck["DuckDB"]
end
Client -->|NL + headers| MCP
Q -->|graphql| GA
Q -->|rest| RA
E --> HTTP
R -->|"no LLM"| HTTP
R --> Duck
GA --> HTTP
RA --> HTTP
GA --> Duck
RA --> Duck
HTTP --> API[Target API]______________________________________________________________________
食谱学习
Agent从成功的查询中学习可重用的模式:
- 执行 -API通过LLM推理调用+SQL
- 提取物 --LLM将跟踪转换为参数化模板
- 缓存 -存储由(API、架构哈希)键控的配方
- 暴露 --配方成为MCP工具(
r_{name})无需LLM即可调用
flowchart LR
subgraph First["First Query via {prefix}_query"]
Q1["'Top 5 users by age'"]
A1["Agent reasons"]
E1["API + SQL"]
R1["Recipe extracted"]
end
subgraph Tools["MCP Tools"]
T["r_get_top_users
params: {limit}"]
end
subgraph Reuse["Direct Call"]
Q2["r_get_top_users({limit: 10})"]
X["Execute directly"]
end
Q1 --> A1 --> E1 --> R1 --> T
Q2 --> T --> X配方会在架构更改时自动过期。禁用 API_AGENT_ENABLE_RECIPES=false.
______________________________________________________________________
发展
git clone https://github.com/agoda-com/api-agent.git
cd api-agent
uv sync --group dev
uv run pytest tests/ -v # Tests
uv run ruff check api_agent/ # Lint
uv run ty check # Type check可观测性
集 OTEL_EXPORTER_OTLP_ENDPOINT 以启用OpenTetry跟踪。与Jaeger、Zipkin、Grafana Tempo、Arize Phoenix合作。
