# swagger-docs-map **Repository Path**: lincq_cn/swagger-docs-map ## Basic Information - **Project Name**: swagger-docs-map - **Description**: swagger接口文档 MCP 服务:缓存 OpenAPI 文档,为 AI 提供精确的接口查询能力 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: https://www.lincq.cn - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-24 - **Last Updated**: 2026-07-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # swagger-docs-map — 通用接口文档 MCP 服务(多文档源) 把任意 Springdoc/OpenAPI v3 接口文档封装成本地 MCP (Model Context Protocol) 服务,让 AI 编码助手可以: - **同时服务多个文档源**(如 project-a、项目乙、pc端、移动端),AI 通过 `source` 参数指定查哪个 - **精确查询**任意接口的完整契约(参数、请求体、响应 schema,`$ref` 全部展开) - **本地缓存**文档,按源隔离,默认按需加载,只有首次真正查询或显式刷新时才会访问文档源 - **按标签/关键字搜索**接口,快速定位目标 API 文档地址、认证方式全部走**外部配置**,不写死。支持 Basic / Bearer / 自定义请求头 / URL 参数 / 无认证。 ## 快速开始 ```bash cd swagger-docs-map npm install cp sources.example.json sources.json # 填入你的文档源列表与认证方式 cp .env.example .env # 填入认证所需的用户名/密码/令牌 node cli.js help # 查看本地 CLI 用法(推荐 AI 优先走本地查询) node index.js # 以 stdio 方式启动 MCP server ``` 服务启动后不会主动拉取所有源;只有在首次查询某个源且本地没有缓存时,才会访问远程文档并写入 `cache/<源名>/`。如果本地已有缓存,则优先直接使用缓存;即使缓存过期,也只在你显式调用 `refresh_docs` 或 CLI 的 `refresh` 时才拉取最新文档。 ## 配置说明 ### sources.json(文档源列表,可提交 git) ```json { "sources": [ { "name": "project-a", "title": "项目甲", "aliases": ["项目甲", "甲项目"], "docUrl": "https://your-doc-host.com/v3/api-docs", "auth": { "type": "basic", "username": "${A_DOC_USERNAME}", "password": "${A_DOC_PASSWORD}" }, "cacheTtlHours": 24 }, { "name": "project-b", "title": "项目乙", "aliases": ["项目乙", "乙"], "docUrl": "https://admin.example.com/v3/api-docs", "auth": { "type": "bearer", "token": "${B_API_TOKEN}" } }, { "name": "public-api", "docUrl": "https://c.example.com/openapi.json", "auth": { "type": "none" } } ] } ``` 每个源的字段: | 字段 | 必填 | 说明 | | --- | --- | --- | | `name` | **是** | 源唯一标识(字母/数字/连字符/下划线),`source` 参数的取值之一 | | `title` | 否 | 中文显示名(如「项目甲」),`source` 参数也可用它;缺省回落为 `name` | | `aliases` | 否 | 别名数组(如 `["项目甲", "甲项目"]`),`source` 参数可用任意一个 | | `docUrl` | **是** | OpenAPI 文档地址 | | `auth` | 否 | 认证配置,缺省为 `{"type":"none"}` | | `cacheTtlHours` | 否 | 缓存有效期(小时),默认 24 | | `fetchTimeoutMs` | 否 | 拉取超时(毫秒),默认 30000 | **`source` 参数支持 name / title / alias 三种写法,大小写不敏感**——以下三种调用等价: ``` search_apis({ source: "project-a", keyword: "登录" }) search_apis({ source: "PROJECT-A", keyword: "登录" }) search_apis({ source: "项目甲", keyword: "登录" }) ``` 这样 AI 用自然语言里的中文项目名(「查项目甲的登录接口」)就能直接定位到正确的源。 **也兼容单源写法**:顶层直接写 `{ "name": "...", "docUrl": "...", ... }`(不带 `sources` 数组),会自动归一为单元素数组。 **任何字符串值都可以用 `${VAR_NAME}` 引用环境变量**(在 `.env` 或 shell 中定义)。这样 `sources.json` 本身不含密钥,可以安全提交 git;密钥只放在 `.env`(已 gitignore)。 ### 支持的认证方式(auth.type) | type | 需要的字段 | 效果 | | --- | --- | --- | | `none` | — | 不认证 | | `basic` | `username`, `password` | `Authorization: Basic base64(user:pass)` | | `bearer` | `token` | `Authorization: Bearer ` | | `header` | `name`, `value` | 自定义请求头,如 `X-API-Key: xxx` | | `query` | `name`, `value` | URL 参数,如 `?api_key=xxx` | ### .env(密钥,不提交) ```bash A_DOC_USERNAME=your-username A_DOC_PASSWORD=your-password B_API_TOKEN=your-token ``` 也可以通过环境变量 `SOURCES_CONFIG` 指定其他配置文件路径(默认读项目根目录的 `sources.json`)。 ### 增删文档源 改 `sources.json` 的 `sources` 数组即可,重启服务生效。每个源按 `name` 隔离缓存目录(`cache//`),增删源互不影响。 ## 接入 AI 客户端 ### Workspace Skill(推荐) 项目内已提供 Workspace Skill 主入口: `/Users/macmini2/ZCodeProject/api-docs-map/.trae/skills/swagger-docs-map/SKILL.md` 如果你想直接复制一段更短的系统提示词模板,可用: `/Users/macmini2/ZCodeProject/api-docs-map/.trae/skills/swagger-docs-map/AI-QUICK-PROMPT.md` 推荐让 AI 按下面顺序使用本项目: 1. 先读 `SKILL.md` 2. 优先执行本地 CLI 3. 只有本地 CLI 不够时再回退到 MCP 这样可以尽量做到: - 不调用就不烧 token - 先走本地缓存和本地索引 - 只在必要时才使用 MCP 自动编排 - 降低模型误选 tool / 误猜 path / 反复重试的概率 ### 本地 CLI(推荐 AI 优先使用) ```bash npm run docs:cli -- sources npm run docs:cli -- status --source project-a npm run docs:cli -- search --source project-a --keyword 登录 npm run docs:cli -- detail --source project-a --path /api/v1/example/login --method POST npm run docs:cli -- schema --source project-a --name UserVO npm run docs:cli -- refresh --source project-a ``` - `status` 只读取本地缓存状态与标签摘要,不会触发远程拉取 - `search` / `paths` / `detail` / `schema` 会优先使用内存或本地缓存;只有本地没有缓存时才访问远程 - 对 AI 来说,推荐流程是:`SKILL.md -> sources -> search/paths -> detail -> schema`,只有需要 MCP 自动编排时再走 `index.js` ### ZCode / Claude Code(MCP 配置) 在 MCP 配置中加入(路径改为实际绝对路径): ```json { "mcpServers": { "swagger-api-docs": { "command": "node", "args": ["/Users/macmini2/ZCodeProject/api-docs-map/index.js"] } } } ``` 配置后,对 AI 说「查一下 project-a 的登录接口定义」「项目乙的订单接口需要哪些参数」即可自动调用并带上对应 `source`。 ## MCP Tools 一览 | Tool | 入参 | 说明 | | --- | --- | --- | | `list_sources` | 无 | 列出所有文档源及状态(接口数、缓存时间、是否可用),多源环境下先确认有哪些源 | | `list_api_paths` | `source`, `tag?`, `keyword?`, `limit?` | 列出指定源的接口路径清单,可按标签或关键字过滤 | | `search_apis` | `source`, `keyword`, `limit?` | 在指定源中按关键字模糊搜索接口(按相关度排序:path > summary > tag > description) | | `get_api_detail` | `source`, `path`, `method` | **精确获取接口完整契约**:参数表、请求体 schema、各状态码响应 schema(`$ref` 已展开) | | `get_schema` | `source`, `name` | 查询指定源中某个数据模型的完整字段定义 | | `refresh_docs` | `source?` | 强制从远程重新拉取指定源的文档并更新缓存 | | `docs_status` | `source?` | **只查看本地缓存状态与标签摘要**,不会触发远程拉取 | > **多源环境下 `source` 参数必填**;漏传时会返回中文提示并列出所有可选源,AI 可自行补上重试。单源时 `source` 可省略。 ### 典型使用流程(AI 视角) 1. `list_sources()` → 确认有 project-a、project-b 两个源 2. `search_apis({ source: "project-a", keyword: "登录" })` → 找到 `POST /api/v1/example/login` 3. `get_api_detail({ source: "project-a", path: "/api/v1/example/login", method: "POST" })` → 拿到完整契约 4. (可选)`get_schema({ source: "project-a", name: "ExampleLoginResponse" })` → 深入理解嵌套模型 5. 接口有更新时:`refresh_docs({ source: "project-a" })` → 拉取最新文档 ## 缓存策略 - 缓存文件:`cache/<源名>/openapi.json`(文档)+ `meta.json`(拉取时间、来源) - **按需加载**:服务启动时不主动读取远程文档,避免未使用时的额外消耗 - **首次查询**:某个源第一次被查询时,优先尝试读取本地缓存;若本地无缓存才会拉远程 - **只读状态查询**:`docs_status` 与 CLI 的 `status` 只读取本地缓存状态,不会隐式访问远程文档 - **过期缓存**:即使缓存超过 `cacheTtlHours`,查询阶段仍优先使用旧缓存,并在 `docs_status` 中提示;只有 `refresh_docs` / CLI `refresh` 才会强制拉最新 - **失败降级**:首次拉取失败且无本地缓存时,该源标记为不可用,不影响其他源 - **手动刷新**:随时调用 `refresh_docs` 刷新指定源 - 缓存加载后驻留内存(path+method 索引 Map),查询零 IO - **启动校验模式**:默认 `API_DOCS_STARTUP_MODE=lazy`,只检查本地缓存;如需恢复启动期强校验,可设置 `API_DOCS_STARTUP_MODE=strict` ## 开发 ```bash npm test # 运行单元测试(node --test) node --check index.js && node --check src/*.js # 语法检查 ``` ### 目录结构 ``` ├── index.js # 入口:启动 stdio MCP server(文档源按需加载) ├── cli.js # 本地低成本查询入口,推荐 AI 优先使用 ├── .trae/skills/ │ └── swagger-docs-map/ │ └── SKILL.md # AI 使用说明主入口:默认引导走 CLI,再按需回退到 MCP │ └── AI-QUICK-PROMPT.md # 可直接复制到系统提示词里的短版模板 ├── sources.json # 文档源列表(gitignore,参考 sources.example.json) ├── .env # 密钥(gitignore) ├── src/ │ ├── config.js # sources 数组加载 + ${ENV_VAR} 插值 + 源名唯一性/合法性校验 │ ├── fetcher.js # 远程拉取(basic/bearer/header/query/none 认证,超时,错误处理) │ ├── cache.js # 按源名隔离的文件缓存读写、TTL 判断(原子写入) │ ├── resolver.js # OpenAPI 解析:$ref 展开(循环保护)、索引、查询 │ ├── formatter.js # 查询结果 → Markdown │ └── server.js # DocStore(多源管理)+ 7 个 MCP tools 注册 └── test/ # node:test 单元测试 + petstore-mini fixture ``` ### 实现要点 - **配置与密钥分离**:`sources.json` 用 `${VAR}` 占位,密钥只在 `.env`;引用未定义变量时启动即报出具体变量名 - **多源隔离**:按源 `name` 建缓存子目录,增删源互不污染;单个源加载失败不影响其他源 - **中文别名**:每个源可配 `title`(中文名)与 `aliases`(别名),`source` 参数按 name/title/alias 大小写不敏感匹配,AI 用中文项目名即可查询 - **友好的 source 提示**:多源时漏传 `source`,返回中文提示并列出可选源(而非 zod 英文校验报错),AI 可自我纠错 - **$ref 展开**:`#/components/schemas/Xxx` 递归内联,保留 `_model` 标注模型名;循环引用以 `_circular: true` 截断 - **相关度排序**:`search_apis` 按 path(8) > summary(4) > tag(2) > description(1) 加权排序 - **找不到时的提示**:`get_api_detail` 对不存在的接口会返回相近路径建议,帮助 AI 自我纠错