{"_id":"@chaselen/knife4j-mcp","_rev":"4-b597b81d05c2cfc482c188119806edbc","name":"@chaselen/knife4j-mcp","dist-tags":{"latest":"0.4.0"},"versions":{"0.1.0":{"name":"@chaselen/knife4j-mcp","version":"0.1.0","keywords":["mcp","knife4j","swagger","openapi","codex"],"license":"MIT","_id":"@chaselen/knife4j-mcp@0.1.0","maintainers":[{"name":"chaselen","email":"lancely3@gmail.com"}],"homepage":"https://github.com/chaselen/knife4j-mcp#readme","bugs":{"url":"https://github.com/chaselen/knife4j-mcp/issues"},"bin":{"knife4j-mcp":"dist/src/index.js"},"dist":{"shasum":"06b5f3ca05fa987674b7b73d83dd4b307cfb0f58","tarball":"https://registry.npmjs.org/@chaselen/knife4j-mcp/-/knife4j-mcp-0.1.0.tgz","fileCount":13,"integrity":"sha512-3V9YUjE7jGis++hUtqNNj3v54aMk8ubO3o+7qkZjMpyP3DwutHNrr62aN9Sws86+1ldAvs8+2xwITlI0/rvRaw==","signatures":[{"sig":"MEQCIEyW0JlTGNkF7B6F7gG08/SQDpRtC2AXqCuIifuUdibJAiArFbQBJaxlsY7izTdvpPmIrJRdUoBqIuKuk+lsLca0nQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":48393},"main":"./dist/src/index.js","type":"module","engines":{"node":">=20"},"gitHead":"65c7e03f9de11241bda46acbe73f0169780be4fd","scripts":{"dev":"node --import tsx src/index.ts","build":"tsc -p tsconfig.json","check":"tsc --noEmit -p tsconfig.json","start":"node dist/src/index.js","test:smoke":"node dist/scripts/smoke-test.js","mock:swagger":"node dist/examples/mock-swagger-server.js","prepublishOnly":"npm run build","mock:swagger:dev":"node --import tsx examples/mock-swagger-server.ts"},"_npmUser":{"name":"chaselen","email":"lancely3@gmail.com"},"repository":{"url":"git+https://github.com/chaselen/knife4j-mcp.git","type":"git"},"_npmVersion":"11.12.1","description":"MCP server for querying Knife4j / Swagger multi-module API docs","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.25.76","@modelcontextprotocol/sdk":"^1.18.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","typescript":"^5.9.3","@types/node":"^24.8.1"},"_npmOperationalInternal":{"tmp":"tmp/knife4j-mcp_0.1.0_1778309239995_0.6783883622171727","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@chaselen/knife4j-mcp","version":"0.2.0","keywords":["mcp","knife4j","swagger","openapi","codex"],"license":"MIT","_id":"@chaselen/knife4j-mcp@0.2.0","maintainers":[{"name":"chaselen","email":"lancely3@gmail.com"}],"homepage":"https://github.com/chaselen/knife4j-mcp#readme","bugs":{"url":"https://github.com/chaselen/knife4j-mcp/issues"},"bin":{"knife4j-mcp":"dist/src/index.js"},"dist":{"shasum":"453fe8eaeaf720efae3b34e59770af9ada64c405","tarball":"https://registry.npmjs.org/@chaselen/knife4j-mcp/-/knife4j-mcp-0.2.0.tgz","fileCount":13,"integrity":"sha512-wzh0lXKj/s64qgMizkOzTfzmY9hFt5ruMq91s+shBdC7vhJ5h1ICJvejsYmnGzLlqsHfJemXb3CpKatULPPyYg==","signatures":[{"sig":"MEYCIQD1OQUbY7WNP4xpxBSIM2ML7cJNs/4aCc0MNNXK10k0EwIhAKxUjWmTOS6GLhuWAHmE9zsPTiChSzL0bFAGYKYdS/dM","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":63851},"main":"./dist/src/index.js","type":"module","engines":{"node":">=20"},"gitHead":"22672aa700eaab57405c2b053601715bf3026446","scripts":{"dev":"node --import tsx src/index.ts","build":"tsc -p tsconfig.json","check":"tsc --noEmit -p tsconfig.json","start":"node dist/src/index.js","test:smoke":"node dist/scripts/smoke-test.js","mock:swagger":"node dist/examples/mock-swagger-server.js","prepublishOnly":"npm run build","mock:swagger:dev":"node --import tsx examples/mock-swagger-server.ts"},"_npmUser":{"name":"chaselen","email":"lancely3@gmail.com"},"repository":{"url":"git+https://github.com/chaselen/knife4j-mcp.git","type":"git"},"_npmVersion":"10.8.2","description":"MCP server for querying Knife4j / Swagger multi-module API docs","directories":{},"_nodeVersion":"20.20.0","dependencies":{"zod":"^3.25.76","@modelcontextprotocol/sdk":"^1.18.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","typescript":"^5.9.3","@types/node":"^24.8.1"},"_npmOperationalInternal":{"tmp":"tmp/knife4j-mcp_0.2.0_1778314358480_0.9797736779272568","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@chaselen/knife4j-mcp","version":"0.3.0","keywords":["mcp","knife4j","swagger","openapi","codex"],"license":"MIT","_id":"@chaselen/knife4j-mcp@0.3.0","maintainers":[{"name":"chaselen","email":"lancely3@gmail.com"}],"homepage":"https://github.com/chaselen/knife4j-mcp#readme","bugs":{"url":"https://github.com/chaselen/knife4j-mcp/issues"},"bin":{"knife4j-mcp":"dist/src/index.js"},"dist":{"shasum":"8e7fadcd97ec1f2468d9d00e0fab49f8101cc335","tarball":"https://registry.npmjs.org/@chaselen/knife4j-mcp/-/knife4j-mcp-0.3.0.tgz","fileCount":13,"integrity":"sha512-S/dNoGpjoOFLlklc5TfUEjl3GpibAwn8aHSKCNRZVQhbF0sO/y0KNd0re2cq7DqcHE9X/m8icF21oEZLEvfTEg==","signatures":[{"sig":"MEUCIQDvZ3GYMe+4fu+OkdMYeBvJ0YorzsGm7V+Vc76vlzeCRwIgX1XdsIIPQ1cuRIEtauclXoUaUGjmiil1AEADQlNh/IQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":76914},"main":"./dist/src/index.js","type":"module","engines":{"node":">=20"},"gitHead":"6b700879b64b8681855603a9477c6e4347b4e211","scripts":{"dev":"node --import tsx src/index.ts","build":"tsc -p tsconfig.json","check":"tsc --noEmit -p tsconfig.json","start":"node dist/src/index.js","test:smoke":"node dist/scripts/smoke-test.js","mock:swagger":"node dist/examples/mock-swagger-server.js","prepublishOnly":"npm run build","mock:swagger:dev":"node --import tsx examples/mock-swagger-server.ts"},"_npmUser":{"name":"chaselen","email":"lancely3@gmail.com"},"repository":{"url":"git+https://github.com/chaselen/knife4j-mcp.git","type":"git"},"_npmVersion":"11.12.1","description":"MCP server for querying Knife4j / Swagger multi-module API docs","directories":{},"_nodeVersion":"24.14.1","dependencies":{"zod":"^3.25.76","@modelcontextprotocol/sdk":"^1.18.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","typescript":"^5.9.3","@types/node":"^24.8.1"},"_npmOperationalInternal":{"tmp":"tmp/knife4j-mcp_0.3.0_1778466299296_0.9702283986000868","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@chaselen/knife4j-mcp","version":"0.4.0","description":"MCP server for querying Knife4j / Swagger multi-module API docs","type":"module","main":"./dist/src/index.js","bin":{"knife4j-mcp":"dist/src/index.js"},"repository":{"type":"git","url":"git+https://github.com/chaselen/knife4j-mcp.git"},"homepage":"https://github.com/chaselen/knife4j-mcp#readme","bugs":{"url":"https://github.com/chaselen/knife4j-mcp/issues"},"publishConfig":{"access":"public"},"scripts":{"build":"tsc -p tsconfig.json","dev":"node --import tsx src/index.ts","start":"node dist/src/index.js","mock:swagger":"node dist/examples/mock-swagger-server.js","mock:swagger:dev":"node --import tsx examples/mock-swagger-server.ts","test:smoke":"node dist/scripts/smoke-test.js","check":"tsc --noEmit -p tsconfig.json","test":"npm run build && node --test dist/test/*.test.js","test:ci":"npm test && npm pack --dry-run","prepublishOnly":"npm run build"},"keywords":["mcp","knife4j","swagger","openapi","codex"],"license":"MIT","dependencies":{"@modelcontextprotocol/sdk":"^1.18.1","zod":"^3.25.76"},"devDependencies":{"@types/node":"^24.8.1","tsx":"^4.20.6","typescript":"^5.9.3"},"engines":{"node":">=20"},"gitHead":"5cc698c6a22e7f19e28bf94bf0404479fa4ac469","_id":"@chaselen/knife4j-mcp@0.4.0","_nodeVersion":"24.14.1","_npmVersion":"11.12.1","dist":{"integrity":"sha512-UqIsYmHXsRSDGDHN4rRUUoo8FtvYnmEu20DS705QdlCsD+Im/j0GNCcPegFAnjhO1hYdpFpsXkuU+Hio1W5WIA==","shasum":"ea0129c8ccbe9ac8d09ba8928099391ebb9c33c5","tarball":"https://registry.npmjs.org/@chaselen/knife4j-mcp/-/knife4j-mcp-0.4.0.tgz","fileCount":12,"unpackedSize":89601,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD0czDyDcYRMbDFJADZhuAPivA3IlI172XFba9xQNOpJwIgTB7/9gvDeJdxHAUoQqREBd+KydEgda649368eBGYfCE="}]},"_npmUser":{"name":"chaselen","email":"lancely3@gmail.com"},"directories":{},"maintainers":[{"name":"chaselen","email":"lancely3@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/knife4j-mcp_0.4.0_1784255270632_0.8943530808898057"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-09T06:47:19.925Z","modified":"2026-07-17T02:27:50.916Z","0.1.0":"2026-05-09T06:47:20.132Z","0.2.0":"2026-05-09T08:12:38.615Z","0.3.0":"2026-05-11T02:24:59.450Z","0.4.0":"2026-07-17T02:27:50.766Z"},"bugs":{"url":"https://github.com/chaselen/knife4j-mcp/issues"},"license":"MIT","homepage":"https://github.com/chaselen/knife4j-mcp#readme","keywords":["mcp","knife4j","swagger","openapi","codex"],"repository":{"type":"git","url":"git+https://github.com/chaselen/knife4j-mcp.git"},"description":"MCP server for querying Knife4j / Swagger multi-module API docs","maintainers":[{"name":"chaselen","email":"lancely3@gmail.com"}],"readme":"# knife4j-mcp\n\n一个基于 Node.js + TypeScript 的标准 MCP server（stdio），用于读取 Knife4j / Swagger 多模块接口文档，并为 Agent 提供结构化接口查询能力。\n\n它适合这样的场景：\n\n- 文档入口不是单个 OpenAPI spec，而是 Knife4j 聚合页\n- 需要先从 `/swagger-resources` 获取模块列表\n- 每个模块再去拉自己的 `/v2/api-docs`\n- 文档可能受 Basic Auth 或自定义 Header 保护\n- Agent 需要根据路径、关键词、tag、字段线索快速定位接口\n\n## 使用方式\n\n```bash\nSWAGGER_RESOURCES_URL=http://127.0.0.1:3301/swagger-resources \\\nnpx -y @chaselen/knife4j-mcp\n```\n\n如果文档受保护，也可以一起传认证信息：\n\n```bash\nSWAGGER_RESOURCES_URL=http://127.0.0.1:3301/swagger-resources \\\nSWAGGER_BASIC_AUTH=demo:demo \\\nnpx -y @chaselen/knife4j-mcp\n```\n\n说明：\n\n- 已发布到 npm，可直接通过 `npx` 启动\n- 要求 Node.js >= 20\n- 这是一个 stdio MCP server，通常由 MCP Client 拉起，而不是手动长期在终端里交互运行\n\n## MCP Client 接入\n\n这个包不只支持 Codex，也支持 Claude Code、OpenCode，以及其他支持本地 stdio MCP 的客户端。\n\n本质上都可以抽象成下面这组启动参数：\n\n```json\n{\n  \"command\": \"npx\",\n  \"args\": [\"-y\", \"@chaselen/knife4j-mcp\"],\n  \"env\": {\n    \"SWAGGER_RESOURCES_URL\": \"http://127.0.0.1:3301/swagger-resources\",\n    \"SWAGGER_BASIC_AUTH\": \"demo:demo\"\n  }\n}\n```\n\n### Codex CLI\n\n```bash\ncodex mcp add knife4j-swagger \\\n  --env SWAGGER_RESOURCES_URL=http://127.0.0.1:3301/swagger-resources \\\n  --env SWAGGER_BASIC_AUTH=demo:demo \\\n  -- npx -y @chaselen/knife4j-mcp\n```\n\n### Claude Code\n\nCLI 添加方式：\n\n```bash\nclaude mcp add knife4j-swagger \\\n  --env SWAGGER_RESOURCES_URL=http://127.0.0.1:3301/swagger-resources \\\n  --env SWAGGER_BASIC_AUTH=demo:demo \\\n  -- npx -y @chaselen/knife4j-mcp\n```\n\n如果你偏好项目级配置，也可以在项目根目录放一个 `.mcp.json`：\n\n```json\n{\n  \"mcpServers\": {\n    \"knife4j-swagger\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@chaselen/knife4j-mcp\"],\n      \"env\": {\n        \"SWAGGER_RESOURCES_URL\": \"http://127.0.0.1:3301/swagger-resources\",\n        \"SWAGGER_BASIC_AUTH\": \"demo:demo\"\n      }\n    }\n  }\n}\n```\n\n### OpenCode\n\n在 `opencode.json` 或 `opencode.jsonc` 中加入：\n\n```json\n{\n  \"$schema\": \"https://opencode.ai/config.json\",\n  \"mcp\": {\n    \"knife4j-swagger\": {\n      \"type\": \"local\",\n      \"command\": [\"npx\", \"-y\", \"@chaselen/knife4j-mcp\"],\n      \"enabled\": true,\n      \"environment\": {\n        \"SWAGGER_RESOURCES_URL\": \"http://127.0.0.1:3301/swagger-resources\",\n        \"SWAGGER_BASIC_AUTH\": \"demo:demo\"\n      }\n    }\n  }\n}\n```\n\n### 其他客户端\n\n如果你的 MCP 客户端支持本地 stdio server，通常只要把下面三类信息按它自己的格式填进去即可：\n\n- `command`: `npx`\n- `args`: `[\"-y\", \"@chaselen/knife4j-mcp\"]`\n- `env`: `SWAGGER_RESOURCES_URL`、`SWAGGER_BASIC_AUTH`、`SWAGGER_HEADERS` 等环境变量\n\n## 环境变量\n\n### 必填\n\n- `SWAGGER_RESOURCES_URL`\n  - Knife4j / Swagger 聚合入口地址，用来读取模块列表。\n  - 这个地址通常就是平台暴露出来的 `/swagger-resources`，例如：`http://127.0.0.1:3301/swagger-resources`\n  - server 启动后会先请求它，再根据返回结果继续拉取每个模块自己的 Swagger / OpenAPI 文档。\n  - 注意：这里填的不是某个单独模块的 `/v2/api-docs` 或 `/v3/api-docs`，而是“模块目录入口”。\n\n### 可选\n\n- `SWAGGER_BASE_URL`\n  - 用于补全 `swagger-resources` 里返回的相对路径。\n  - 如果模块文档地址是 `/api/user/v2/api-docs` 这种相对路径，server 会拿它和 `SWAGGER_BASE_URL` 进行拼接。\n  - 未设置时，默认回退到 `SWAGGER_RESOURCES_URL` 的基址。\n  - 常见场景是：`swagger-resources` 和真实文档地址不在同一个基址下，或者经过了网关改写。\n- `SWAGGER_BASIC_AUTH`\n  - 访问 Swagger 文档时使用的 HTTP Basic Auth 账号密码。\n  - 这个值会同时用于请求 `SWAGGER_RESOURCES_URL` 和每个模块的 spec 文档。\n  - 格式是 `username:password`，例如：`demo:demo`\n  - 不需要带 `Basic ` 前缀，程序会自动转成 `Authorization: Basic ...` 请求头。\n  - 如果你的文档地址本身不需要登录认证，可以不填。\n- `SWAGGER_HEADERS`\n  - 额外附带到所有文档请求上的自定义 HTTP Header。\n  - 适合需要 Token、租户标识、环境标识这类网关头的场景。\n  - 格式是 JSON 字符串，例如：`{\"X-Env\":\"dev\",\"X-Token\":\"abc\"}`\n  - 这些 Header 会和 Basic Auth 一起生效；如果两者都配置了，请求会同时带上。\n- `SWAGGER_MODULE_ALLOWLIST`\n  - 只加载指定模块，其他模块会被忽略。\n  - 适合模块很多、只想给 Agent 暴露其中一部分接口时使用。\n  - 格式为逗号分隔，例如：`sample-account,sample-auth`\n  - 这里填写的名称应与 `swagger-resources` 返回的模块名一致。\n- `CACHE_TTL_MS`\n  - 内存缓存有效期，单位是毫秒。\n  - 默认值是 `300000`，也就是 5 分钟。\n  - 在缓存有效期内，查询会直接复用已加载的索引；过期后会在下次刷新时重新拉取远端文档。\n- `SWAGGER_REQUEST_TIMEOUT_MS`\n  - 单次请求 `swagger-resources` 或模块 spec 的超时时间，单位是毫秒。\n  - 默认值是 `15000`，也就是 15 秒；必须是大于 0 的数字。\n- `SWAGGER_FETCH_CONCURRENCY`\n  - 同时拉取模块 spec 的最大请求数。\n  - 默认值是 `8`，允许设置为 `1` 到 `100` 之间的整数。\n  - 模块很多或上游网关有连接数限制时，可以适当调低。\n- `SWAGGER_EXTERNAL_REF_LIMIT`\n  - 单个模块最多自动加载的外部 `$ref` JSON 文档数。\n  - 默认值是 `32`，允许设置为 `0` 到 `200`；设置为 `0` 可关闭外部引用加载。\n  - 外部文档使用与主 spec 相同的 Basic Auth、自定义 Header 和请求超时配置。\n- `SWAGGER_EXTERNAL_REF_ORIGINS`\n  - 允许加载跨 origin 外部 `$ref` 的白名单，使用逗号分隔，例如：`https://schemas.example.com,http://localhost:8080`。\n  - 默认只允许与当前模块 spec 同 origin 的外部引用，避免把认证 Header 转发到未授权地址。\n  - 白名单按 origin 匹配，配置中的路径会被忽略；只支持 HTTP 和 HTTPS。\n- `LOG_LEVEL`\n  - 日志级别。\n  - 当前设为 `debug` 时会输出更多拉取和解析过程日志，便于排查文档地址、认证或 JSON 格式问题。\n\n### 一个更完整的例子\n\n```bash\nSWAGGER_RESOURCES_URL=https://gateway.example.com/swagger-resources \\\nSWAGGER_BASIC_AUTH=swagger_user:swagger_password \\\nSWAGGER_HEADERS='{\"X-Env\":\"prod\",\"X-Tenant\":\"platform\"}' \\\nSWAGGER_MODULE_ALLOWLIST=system-user,system-auth \\\nnpx -y @chaselen/knife4j-mcp\n```\n\n## MCP Tools\n\n对外只提供 4 个核心 tools：\n\n- `list_specs`：列出模块、spec 地址、加载状态和接口数量\n- `find_api`：按关键词、path、tag、module、method、接口类型和弃用状态搜索接口\n  - 支持 `offset` + `limit` 分页\n  - `total` 表示全部命中数，`returned` 表示本页数量，`hasMore` 表示是否还有后续结果\n  - 相同相关性分数下使用稳定排序，便于可靠翻页\n- `get_api_detail`：获取单个接口的完整详情，并递归展开请求/响应 schema\n  - 默认保持完整兼容输出\n  - 传入 `includeRaw: false` 可省略递归结果中的 `raw` 和顶层 `rawOperation`，减少 Agent 上下文占用\n- `refresh_specs`：强制刷新 `swagger-resources` 和所有模块 spec\n\n## 功能\n\n- 支持读取 Knife4j / Swagger 多模块聚合文档\n- 支持 Basic Auth 和自定义 Header\n- 支持 Swagger 2.0，并尽量兼容 OpenAPI 3\n- 支持按路径、关键词、tag、method 等条件搜索接口\n- 在刷新阶段预计算路径别名和全文搜索文本，减少查询时的重复解析\n- `get_api_detail` 可使用原始短路径、规范化路径或可唯一匹配的完整网关路径\n- 支持通过 `get_api_detail` 获取完整接口详情，并递归展开请求/响应 schema\n- 详情会显式返回 `operationId`、弃用状态、认证要求、servers、externalDocs、callbacks 和 security schemes\n- 请求与响应详情支持 examples、encoding、响应 headers 与 links\n- Schema 展开支持 OpenAPI 3.1 nullable 类型、default、const、examples、读写属性、discriminator 和常用校验约束\n- 支持自动加载并打包跨文件 `$ref`，同时限制外部文档数量\n- OpenAPI 3.1 `webhooks` 会作为 `kind: \"webhook\"` 的接口参与搜索\n- 支持模块 allowlist、缓存 TTL 和手动刷新\n- 单个模块加载失败不会影响其他模块可用\n- 刷新发生临时失败时保留该模块上一次成功的索引，并在模块状态中标记 `stale`\n- 聚合入口刷新失败时继续提供上一次成功的完整索引，并标记整体与模块状态为 `stale`\n- 模块 spec 使用可配置的并发上限拉取，避免刷新时瞬间压高网关连接数\n- 无效 spec 和重复模块名会被隔离并显示为失败状态\n\n## 兼容性边界\n\n- 支持 Swagger 2.x、OpenAPI 3.0 和常用 OpenAPI 3.1 JSON Schema 字段。\n- 本地 JSON Pointer 与 HTTP(S) JSON 外部 `$ref` 可以递归展开；不解析 YAML、`file:` 或其他协议。\n- 循环引用会保留为带 `ref` / `refName` 的节点，避免无限递归。\n- `callbacks`、`links`、`securitySchemes` 等复杂扩展会保留结构化原始定义；请求和响应的主要 Schema 会进一步展开。\n\n## 开发与验证\n\n```bash\nnpm install\nnpm test\nnpm pack --dry-run\n```\n\n- `npm test` 会构建项目并运行 parser、registry、HTTP 配置和 MCP 内存传输集成测试。\n\n## 最小可运行示例\n\n仓库自带一个 mock 的多模块 Swagger 服务。\n\n### 1. 启动 mock 文档服务\n\n```bash\nMOCK_SWAGGER_BASIC_AUTH=demo:demo npm run mock:swagger\n```\n\n默认地址：\n\n- `http://127.0.0.1:3301/swagger-resources`\n- `http://127.0.0.1:3301/sample-account/v2/api-docs`\n- `http://127.0.0.1:3301/sample-auth/v2/api-docs`\n- `http://127.0.0.1:3301/demo/sample-notify/v3/api-docs`\n\n### 2. 构建 MCP server\n\n```bash\nnpm run build\n```\n\n### 3. 运行 smoke test\n\n```bash\nSWAGGER_RESOURCES_URL=http://127.0.0.1:3301/swagger-resources \\\nSWAGGER_BASIC_AUTH=demo:demo \\\nnpm run test:smoke\n```\n\n这个脚本会通过 MCP stdio client 依次调用：\n\n- `tools/list`\n- `list_specs`\n- `find_api`\n- `get_api_detail`\n\n它会自动完成一次 `list_specs -> find_api -> get_api_detail` 的最小联调验证。\n","readmeFilename":"README.md"}