ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

AI 接口测试实战:用 Agent 解析 Swagger 并生成 MCP 请求配置

AI 接口测试实战:用 Agent 解析 Swagger 并生成 MCP 请求配置 1. 接口联调为什么总在“翻文档、拼参数”里打转如果你做过接口测试或前后端联调大概率经历过这个循环Swagger 页面开着Postman 开着IDE 开着然后对着POST /api/v1/orders的请求体字段一个一个抄。字段名是orderItems还是order_itemsquantity是 integer 还是 stringX-Request-Id到底必不必填抄完一轮发出去返回 400再回去翻文档发现Content-Type写成了text/plain。这套动作本身没有技术含量但它消耗的是最贵的资源——注意力。更麻烦的是当你想让 AI Agent 帮你做接口测试时问题会放大Agent 不知道你的接口长什么样你得手动把每个端点的路径、方法、参数、认证方式写成工具定义。五个接口写五遍五十个接口就是五十遍而且接口一改全部重来。MCPModel Context Protocol解决的正是“Agent 怎么发现并调用外部能力”这件事。它把工具定义标准化成 JSON-RPC 的tools/list和tools/callAgent 不需要你教它怎么调它自己会问“你有哪些工具”。那么剩下的问题就只有一个怎么把 Swagger 里的接口定义自动变成 MCP 能识别的工具配置。这篇要走的链路很具体拿一份 Swagger/OpenAPI 文档让 Agent 解析出接口定义生成 MCP 请求配置最后真的发一次 API 请求验证跑通。适合正在做接口测试、联调或者想把内部 API 接进 AI 工作流的同学。下面给的是可复制的配置骨架和 settings.json 片段不是概念科普。2. 前置准备TaoToken 的 Key 与 MCP 配置入口在让 Agent 解析 Swagger 之前得先有一个能跑 Agent 的模型通道。我这边用的是 TaoToken 的 API 通道它兼容 OpenAI 风格的调用方式配置成本低适合做这种“解析文档 生成配置”的中间层任务。你需要先拿到 API Key。入口在控制台的 API Keys 页面创建后复制出来后面配置里会用到。地址是https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite如果你还没决定用哪个模型来做 Swagger 解析可以先在模型对话里试一下解析效果确认它能正确理解 OpenAPI 的$ref和parameters结构https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite对于长期要做接口测试、需要反复调用 Agent 的场景Coding Plan 会更划算适合把“解析 Swagger → 生成 MCP 配置 → 发起请求”这条链路固化下来https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite接入文档在这里配置 MCP Server 时如果遇到协议字段不明确可以对照查https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewriteAPI 的基础地址是https://taotoken.net/api注意这个不带 UTM 参数直接用于代码里的base_url。Key 拿到后不要写死在代码里放到环境变量后面配置片段里会用${TAOTOKEN_API_KEY}引用。3. 可复制配置从 Swagger 到 MCP 请求配置的完整骨架这一节是核心。整条链路分三步先让 Agent 读 Swagger 并输出结构化的接口清单再把清单转成 MCP 的 tool 定义最后写进 MCP 客户端的 settings.json。3.1 第一步让 Agent 解析 Swagger 并输出接口清单不要直接把整个 Swagger JSON 丢给模型让它“生成配置”那样输出不稳定。正确做法是先做一次结构化提取。下面这段 Python 脚本负责拉取 Swagger 文档并抽出关键字段然后把精简后的结构交给模型import json import os import httpx SWAGGER_URL https://petstore3.swagger.io/api/v3/openapi.json def fetch_swagger(url: str) - dict: resp httpx.get(url, timeout30) resp.raise_for_status() return resp.json() def extract_endpoints(spec: dict) - list: endpoints [] for path, methods in spec.get(paths, {}).items(): for method, detail in methods.items(): if method.lower() not in (get, post, put, delete, patch): continue params [] for p in detail.get(parameters, []): params.append({ name: p.get(name), in: p.get(in), required: p.get(required, False), type: p.get(schema, {}).get(type, string) }) body_schema {} if requestBody in detail: content detail[requestBody].get(content, {}) for ct, media in content.items(): body_schema media.get(schema, {}) break endpoints.append({ operationId: detail.get(operationId, f{method}_{path}), method: method.upper(), path: path, summary: detail.get(summary, ), parameters: params, requestBody: body_schema }) return endpoints if __name__ __main__: spec fetch_swagger(SWAGGER_URL) endpoints extract_endpoints(spec) print(json.dumps(endpoints[:3], ensure_asciiFalse, indent2))跑完你会得到类似这样的输出每个端点只保留 MCP tool 定义真正需要的字段[ { operationId: getPetById, method: GET, path: /pet/{petId}, summary: Find pet by ID, parameters: [ {name: petId, in: path, required: true, type: integer} ], requestBody: {} } ]这一步的意义是把 Swagger 里嵌套的$ref、allOf、oneOf拍平减少模型理解成本。实测下来拍平后的结构让模型生成 tool 定义的准确率明显更高。3.2 第二步生成 MCP tool 定义把上一步的endpoints数组作为上下文让模型输出 MCP 的 tool 格式。这里用 TaoToken 的 API 做一次调用import os from openai import OpenAI client OpenAI( api_keyos.environ[TAOTOKEN_API_KEY], base_urlhttps://taotoken.net/api ) PROMPT 你是一个 MCP 配置生成器。根据下面的接口清单为每个接口生成一个 MCP tool 定义。 要求 1. tool 名称使用 operationId保持唯一 2. description 拼接 summary 和 method path 3. inputSchema 使用 JSON Schema区分 path/query/header/body 参数 4. 只输出 JSON 数组不要解释 接口清单 {endpoints} def generate_mcp_tools(endpoints: list) - list: resp client.chat.completions.create( modelgpt-4o-mini, messages[ {role: user, content: PROMPT.format( endpointsjson.dumps(endpoints, ensure_asciiFalse) )} ], temperature0 ) content resp.choices[0].message.content return json.loads(content) tools generate_mcp_tools(endpoints) print(json.dumps(tools[:2], ensure_asciiFalse, indent2))输出会是这样每个 tool 都带完整的inputSchema[ { name: getPetById, description: Find pet by ID. GET /pet/{petId}, inputSchema: { type: object, properties: { petId: {type: integer, description: ID of pet to return} }, required: [petId] } } ]注意inputSchema里petId的类型是integer这是从 Swagger 的schema.type直接映射过来的。如果 Swagger 里写的是string这里就会是stringAgent 调用时也不会传错类型。3.3 第三步写入 MCP 客户端 settings.jsonMCP 客户端的配置因工具而异但结构大同小异。下面是一个通用的 settings.json 片段把上一步生成的 tool 定义挂到一个本地 MCP Server 上{ mcpServers: { swagger-api-tester: { command: python, args: [-m, mcp_server_swagger, --config, ./mcp_tools.json], env: { TAOTOKEN_API_KEY: ${TAOTOKEN_API_KEY}, API_BASE_URL: https://petstore3.swagger.io/api/v3 } } } }其中mcp_tools.json就是上一步生成的 tool 数组。MCP Server 的职责是收到tools/list时返回这些定义收到tools/call时根据 tool 名称和参数构造真实的 HTTP 请求。如果你用的是 Claude Code 这类支持 MCP 的编码工具配置位置通常在项目根目录的.mcp.json结构一致{ mcpServers: { swagger-api-tester: { command: npx, args: [-y, mcp-remote, http://localhost:8000/mcp], env: { TAOTOKEN_API_KEY: ${TAOTOKEN_API_KEY} } } } }这里用mcp-remote做传输桥接把本地 STDIO 转成远程 HTTP适合 MCP Server 跑在另一台机器上的情况。4. 验证请求从 Swagger 到真实 API 响应配置写好了得验证它真的能跑通。验证分两层先确认 MCP Server 能正确列出 tools再确认 Agent 能通过 MCP 发起真实请求。4.1 验证 tools/list启动 MCP Server 后用 MCP Inspector 或直接发 JSON-RPC 请求curl -X POST http://localhost:8000/mcp \ -H Content-Type: application/json \ -d { jsonrpc: 2.0, id: 1, method: tools/list, params: {} }期望返回{ jsonrpc: 2.0, id: 1, result: { tools: [ { name: getPetById, description: Find pet by ID. GET /pet/{petId}, inputSchema: { type: object, properties: { petId: {type: integer} }, required: [petId] } } ] } }如果tools数组为空说明mcp_tools.json没被正确加载检查文件路径和 JSON 格式。4.2 验证 tools/call 发起真实请求这一步是整条链路的关键。发一个tools/call让 MCP Server 去调真实的 Petstore APIcurl -X POST http://localhost:8000/mcp \ -H Content-Type: application/json \ -d { jsonrpc: 2.0, id: 2, method: tools/call, params: { name: getPetById, arguments: { petId: 1 } } }期望返回{ jsonrpc: 2.0, id: 2, result: { content: [ { type: text, text: {\id\:1,\name\:\doggie\,\status\:\available\} } ] } }看到doggie就说明链路通了Swagger 文档 → Agent 解析 → MCP tool 定义 → 真实 API 请求 → 结构化响应。整个过程你没有手动拼过一次 URL也没有手动写过一次参数 schema。4.3 在 Agent 里做端到端验证如果你用的是支持 MCP 的对话式 Agent可以直接用自然语言触发帮我查一下 Petstore 里 id 为 1 的宠物信息Agent 会自动匹配到getPetById这个 tool填入petId: 1通过 MCP 发起请求然后把结果返回给你。这一步验证的是 Agent 的 tool 选择能力——如果它选错了 tool或者参数类型传错了说明 tool 的description或inputSchema需要调整。5. 本篇常见错排查这条链路跑不通问题通常集中在几个地方。下面按出现频率排。5.1 tools/list 返回空数组最常见的原因是mcp_tools.json的路径不对或者 JSON 格式有误。MCP Server 启动时如果读不到文件通常会静默返回空列表。排查方法在 Server 启动日志里找Loaded N tools这样的输出N 为 0 就是没读到。另外注意 JSON 里不能有注释尾逗号也会导致解析失败。5.2 tools/call 返回 400 或 422参数类型不匹配是主因。Swagger 里petId是integer但 Agent 传了1字符串MCP Server 如果没做类型转换直接拼进 URL 可能没问题但放进 JSON body 就会 400。解决办法是在 MCP Server 的请求构造层加一层类型校验用 Pydantic 或 JSON Schema 验证后再发请求。5.3 认证头没带上Swagger 里的securitySchemes定义了认证方式但自动生成的 tool 定义通常不会包含认证信息。你需要在 MCP Server 的环境变量里配置API_TOKEN并在构造请求时注入Authorization头。如果返回 401先检查这个头有没有带上再检查 token 是否过期。5.4 Agent 选错 tool当多个 tool 的description相似时Agent 容易选错。比如getPetById和findPetsByStatus都涉及宠物查询如果 description 写得太模糊Agent 可能用findPetsByStatus去查单个 ID。解决办法是在 description 里明确写清适用场景比如getPetById的 description 加上“根据唯一 ID 查询单个宠物ID 为整数”。5.5 MCP Server 启动后 Agent 连不上检查传输模式是否匹配。如果 Agent 配置的是 STDIO但 Server 跑在 HTTP 端口上就连不上。反过来也一样。STDIO 模式下 Server 作为子进程启动HTTP 模式下需要显式指定 URL。用mcp-remote做桥接时确认桥接进程和 Server 进程都在运行。6. 把这条链路固化下来跑通一次之后下一步是把它变成可重复的流程。我的做法是把“拉取 Swagger → 提取端点 → 生成 tool 定义 → 写入配置”做成一个脚本每次接口文档更新后重新跑一遍MCP 配置自动刷新。这样接口改了字段Agent 那边不用手动同步。如果你要长期做接口测试建议把 MCP Server 的日志打开记录每次tools/call的入参和响应。这样当 Agent 调错接口时你能快速定位是 tool 定义的问题还是模型决策的问题。日志里注意脱敏Authorization头不要明文落盘。对于需要频繁调用模型的场景Coding Plan 比按量计费更稳适合把这条链路挂在 CI 里做接口回归https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite接入过程中如果遇到 MCP 协议字段或认证配置的问题文档里有完整的参数说明https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite最后一步验证建议直接在模型对话里做一次自然语言调用确认 Agent 能正确选择 tool 并返回真实数据https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite整条链路的价值不在于“自动化”这三个字而在于它把接口测试里最枯燥的“对齐字段”环节交给了机器。你只需要保证 Swagger 文档是准的剩下的解析、映射、请求构造Agent 会自己完成。
返回列表