OpenAPI动态转换工具

将任意OpenAPI规范即时转换为AI可调用的工具集,支持JSON/YAML格式、自动认证及零配置部署。

  • by forattini-dev
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 forattini-dev/dynamic-openapi-mcp

使用说明

动态openapi-mcp

任何OpenAPI规范的即时AI工具。

指向一个规范-你的人工智能代理可以调用API。
OpenAPI v3 • JSON和YAML • 自动身份验证 • 零配置
每个端点都变成了一个工具。每个模式都变成了一种资源。

快速开始 · 家庭 · 代理设置 · 认证 · 过滤 · 程序化API · 命令行界面


快速开始

npx dynamic-openapi-mcp -s https://petstore3.swagger.io/api/v3/openapi.json

就是这样。MCP服务器启动,你的人工智能代理发现所有工具,并可以调用Petstore API。

对于Claude Code,将其添加到一个命令中:

claude mcp add petstore -- npx dynamic-openapi-mcp -s https://petstore3.swagger.io/api/v3/openapi.json

现在问克劳德: “列出所有可用的宠物” --它将呼叫 listPets 并返回真实数据。


目录


里面是什么

类别 你得到了什么
工具 每次操作一个-- GET /pets 成为 listPets,具有完全键入的输入
资源 全规格 openapi://spec +每个模式为 openapi://schemas/{name}
提示 describe-api 为了概述, explore-endpoint 有关任何操作的详细信息
认证 承载,API密钥(头/查询/cookie),基本,OAuth2客户端凭据,令牌交换
躯体 JSON、表单url编码、多部分/表单数据和八位字节流请求体
来源 URL、本地文件(JSON/YAML)、内联字符串或JavaScript对象

流程很简单:AI调用工具→ dynamic-openapi-mcp 发出真正的HTTP请求→ 响应以MCP内容的形式返回。

家庭

三个互补的项目,一个规范,三个输出表面——选择适合用例的一个:

兄弟姐妹 输出 运行时间 最佳时间
dynamic-openapi-mcp 实时MCP服务器(stdio) 每次工具调用都会旋转服务器 您需要实时自检、自动刷新OAuth令牌、键入工具I/O
dynamic-openapi-cli Bash CLI(可选捆绑) 人类和脚本调用它 你想要一个人类和CI可以运行的提交友好的垫片
dynamic-openapi-skill 静态 SKILL.md Claude按需加载 您希望通过以下方式实现零运行时、差异友好的文档和模型驱动的调用 curl / fetch

这三个共享相同的解析器和身份验证层。在它们之间切换就是将它们指向相同的规格。

使用AI代理进行设置

克劳德代码

添加到您的项目 .mcp.json:

{
  "mcpServers": {
    "my-api": {
      "command": "npx",
      "args": ["dynamic-openapi-mcp", "-s", "https://api.example.com/openapi.json"],
      "env": {
        "OPENAPI_AUTH_TOKEN": "your-bearer-token"
      }
    }
  }
}

或者通过CLI添加:

claude mcp add my-api -- npx dynamic-openapi-mcp -s https://api.example.com/openapi.json

光标

首选 设置→ MCP 并添加新服务器,或添加到 .cursor/mcp.json:

{
  "mcpServers": {
    "my-api": {
      "command": "npx",
      "args": ["dynamic-openapi-mcp", "-s", "./specs/api.yaml"],
      "env": {
        "OPENAPI_API_KEY": "your-api-key"
      }
    }
  }
}

帆板运动

添加 ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "my-api": {
      "command": "npx",
      "args": ["dynamic-openapi-mcp", "-s", "https://api.example.com/openapi.json"],
      "env": {
        "OPENAPI_AUTH_TOKEN": "sk-..."
      }
    }
  }
}

克劳德桌面版

添加到您的配置(~/Library/Application Support/Claude/claude_desktop_config.json 在macOS上):

{
  "mcpServers": {
    "my-api": {
      "command": "npx",
      "args": ["dynamic-openapi-mcp", "-s", "/absolute/path/to/spec.yaml"],
      "env": {
        "OPENAPI_AUTH_TOKEN": "your-token"
      }
    }
  }
}

多个API

一次连接多个API——每个API都作为一个单独的MCP服务器运行,AI会看到它们的所有工具都结合在一起:

{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["dynamic-openapi-mcp", "-s", "https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json"],
      "env": { "OPENAPI_AUTH_TOKEN": "ghp_..." }
    },
    "stripe": {
      "command": "npx",
      "args": ["dynamic-openapi-mcp", "-s", "./specs/stripe.yaml"],
      "env": { "OPENAPI_AUTH_TOKEN": "sk_..." }
    },
    "internal-api": {
      "command": "npx",
      "args": ["dynamic-openapi-mcp", "-s", "https://internal.company.com/api/v1/openapi.json"],
      "env": { "OPENAPI_API_KEY": "key-..." }
    }
  }
}

认证

选择授权策略

如果您的API使用。.. 使用此功能 自动刷新 最适合
静态承载令牌 OPENAPI_AUTH_TOKEN 或 auth.bearerToken 否 个人访问令牌、固定服务令牌
静态API密钥 OPENAPI_API_KEY 或 auth.apiKey 规范中未声明 Header/query/cookie API键
基本身份验证 auth.basicAuth 否 旧版用户名/密码API
OAuth2客户端凭据 auth.oauth2 是 机器对机器OAuth流 tokenUrl
临时代币兑换 auth.tokenExchange 是 非标准 credId / credSecret 登录流程
完全自定义身份验证逻辑 auth.custom 您实现了它 内置策略未涵盖的边缘情况

通过环境变量

# Bearer token (most common)
OPENAPI_AUTH_TOKEN=sk-123 npx dynamic-openapi-mcp -s ./spec.yaml

# API key
OPENAPI_API_KEY=key-456 npx dynamic-openapi-mcp -s ./spec.yaml

# Per-scheme (matches securitySchemes names in your spec)
OPENAPI_AUTH_BEARERAUTH_TOKEN=sk-123 npx dynamic-openapi-mcp -s ./spec.yaml

或者在MCP配置中设置它们 env block——效果相同,设置更简洁。

支持的方案

方案 环境变量 程序化配置
持票人 OPENAPI_AUTH_TOKEN 或 OPENAPI_AUTH_<SCHEME>_TOKEN auth.bearerToken
API密钥(头/查询/cookie) OPENAPI_API_KEY 或 OPENAPI_AUTH_<SCHEME>_KEY auth.apiKey
基础 OPENAPI_AUTH_<SCHEME>_TOKEN 作为 user:pass auth.basicAuth
OAuth2(客户端凭据) -- auth.oauth2
代币兑换 -- auth.tokenExchange
自定义 -- auth.custom (功能)

解析顺序:程序化配置→ 每方案环境变量→ 全局环境变量。

每个方案的环境变量都是从 securitySchemes OpenAPI文档中的名称:

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer

此方案名称映射到:

OPENAPI_AUTH_BEARERAUTH_TOKEN=sk-123

对于名为的基本身份验证方案 basicAuth,使用:

OPENAPI_AUTH_BASICAUTH_TOKEN=username:password

程序示例

持有者代币:

const mcp = await createOpenApiMcp({
  source: './spec.yaml',
  auth: { bearerToken: process.env.MY_API_TOKEN! },
})

API密钥:

const mcp = await createOpenApiMcp({
  source: './spec.yaml',
  auth: { apiKey: process.env.MY_API_KEY! },
})

基本身份验证:

const mcp = await createOpenApiMcp({
  source: './spec.yaml',
  auth: {
    basicAuth: {
      username: process.env.API_USER!,
      password: process.env.API_PASSWORD!,
    },
  },
})

带有自动令牌缓存和刷新的OAuth2客户端凭据:

const mcp = await createOpenApiMcp({
  source: './spec.yaml',
  auth: {
    oauth2: {
      clientId: process.env.OAUTH_CLIENT_ID!,
      clientSecret: process.env.OAUTH_CLIENT_SECRET!,
      tokenUrl: 'https://auth.example.com/oauth/token',
      scopes: ['pets:read', 'pets:write'],
    },
  },
})

dynamic-openapi-mcp 将检索到的访问令牌缓存在内存中,并在接近过期时刷新它。

临时令牌和刷新

许多API不是真正的OAuth2,但在交换凭据后仍会发出短暂的承载令牌,例如 credId 和 credSecret.

对于这些API,请使用 auth.tokenExchange内置策略:

  1. 交换临时令牌的凭据。
  2. 将令牌缓存在内存中。
  3. 之前稍微提神 expires_in 或 expires_at.
  4. 重试一次 401 Unauthorized 在强迫一个新的令牌之后。
  5. 重用单个正在进行的刷新承诺,这样并发的MCP调用就不会踩踏认证服务器。

例子:

import { createOpenApiMcp } from 'dynamic-openapi-mcp'

const mcp = await createOpenApiMcp({
  source: './spec.yaml',
  auth: {
    tokenExchange: {
      tokenUrl: 'https://auth.example.com/session',
      request: {
        contentType: 'application/json',
        fields: {
          credId: process.env.CRED_ID!,
          credSecret: process.env.CRED_SECRET!,
        },
      },
      response: {
        tokenField: 'access_token',
        expiresInField: 'expires_in',
      },
      apply: {
        location: 'header',
        name: 'Authorization',
        prefix: 'Bearer ',
      },
    },
  },
})

笔记:

  • auth.tokenExchange 还支持通过表单编码的请求 request.contentType: 'application/x-www-form-urlencoded'.
  • 如果令牌响应是嵌套的,请使用点路径,例如 response.tokenField: 'data.accessToken'.
  • 如果没有到期元数据,则令牌将保持缓存状态,直到API返回 401,则尝试一次新的交换。
  • apply.location 可以是 header, query,或 cookie.
  • 令牌缓存在内存中。如果MCP进程重新启动,它将在下一个请求中获取新的令牌。
  • 如果您的身份验证流不能以声明方式描述,请回退到 auth.custom.

高级回退功能 auth.custom:

const mcp = await createOpenApiMcp({
  source: './spec.yaml',
  auth: {
    custom: async (_url, init) => {
      const headers = new Headers(init.headers)
      headers.set('Authorization', `Bearer ${await getMyTokenSomehow()}`)
      return { ...init, headers }
    },
  },
})

OpenAPI中通常如何建模Auth

对于受保护的端点,OpenAPI通常描述调用API时使用的最终身份验证机制,而不是客户端应如何获取和刷新凭据的整个生命周期。

标准持有者身份验证:

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
security:
  - bearerAuth: []

API密钥身份验证:

components:
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      name: X-API-Key
      in: header
security:
  - apiKeyAuth: []

OAuth2客户端凭据:

components:
  securitySchemes:
    oauth:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: https://auth.example.com/oauth/token
          scopes:
            pets:read: Read pets
security:
  - oauth: [pets:read]

自定义临时令牌流通常记录在两个单独的地方:

  1. 受保护的端点声明 bearerAuth 或 apiKeyAuth 在 securitySchemes.
  2. 正常操作 paths 记录登录或令牌交换端点。

例子:

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer

paths:
  /auth/token:
    post:
      summary: Exchange credId and credSecret for a temporary token
      requestBody:
        required: true
      responses:
        '200':
          description: Token issued

这种模式很常见,但它并不能完全告诉通用客户端:

  • 哪些凭据应该来自环境变量
  • 哪个响应字段包含令牌
  • 令牌的有效期有多长
  • 何时刷新
  • 是否一个 401 应该触发新的交换

这就是为什么真正的OAuth2最容易从OpenAPI中自动化,而自定义临时令牌系统通常需要显式 auth.tokenExchange config或少量用户提供的代码。

如果你想更明确地为这个库的用户记录这些自定义流,未来的供应商扩展可能看起来像这样:

x-dynamic-openapi-mcp-auth:
  type: tokenExchange
  tokenUrl: https://auth.example.com/session
  request:
    contentType: application/json
    fields:
      credId:
        env: CRED_ID
      credSecret:
        env: CRED_SECRET
  response:
    tokenField: access_token
    expiresInField: expires_in
    tokenType: Bearer

这不是由使用 dynamic-openapi-mcp 今天,它展示了一种元数据,可以使临时令牌流更容易自动化。

身份验证故障排除

  • 如果请求返回 401 Unauthorized,首先确认OpenAPI规范 securitySchemes 匹配真正的API对auth的期望。
  • 如果使用环境变量,当规范定义了多个身份验证方案时,最好使用每方案变量。
  • 如果您的令牌每隔几分钟就会过期,请使用程序化身份验证而不是静态环境变量。
  • 如果您的提供商为您提供的登录端点不是OAuth2,请从 auth.tokenExchange.使用 auth.custom 只有当交换太不规则而无法声明性地描述时。
  • 如果提供者需要查询字符串或cookie中的临时令牌, auth.tokenExchange 支持 apply.location: 'query' 和 apply.location: 'cookie'.

程序化使用

pnpm add dynamic-openapi-mcp
import { createOpenApiMcp } from 'dynamic-openapi-mcp'

const mcp = await createOpenApiMcp({
  source: 'https://petstore3.swagger.io/api/v3/openapi.json',
  auth: { bearerToken: 'my-token' },
})

// Start as MCP server over stdio
await mcp.serve()

自定义基本URL

const mcp = await createOpenApiMcp({
  source: './spec.yaml',
  baseUrl: 'http://localhost:3000',
  headers: { 'X-Custom-Header': 'value' },
})

根据内联规范

const mcp = await createOpenApiMcp({
  source: {
    openapi: '3.0.3',
    info: { title: 'My API', version: '1.0.0' },
    servers: [{ url: 'https://api.example.com' }],
    paths: {
      '/hello': {
        get: {
          operationId: 'sayHello',
          summary: 'Say hello',
          responses: { '200': { description: 'OK' } },
        },
      },
    },
  },
})

检查解析的规范

const mcp = await createOpenApiMcp({ source: './spec.yaml' })

console.log(mcp.spec.title)       // "My API"
console.log(mcp.spec.operations)  // ParsedOperation[]
console.log(mcp.spec.schemas)     // { Pet: {...}, User: {...} }

重试行为

默认情况下, dynamic-openapi-mcp 只重试安全方法: GET, HEAD, OPTIONS,以及 TRACE.

这可以保持读取的弹性,而不会有重复写入的风险 POST, PUT, PATCH,或 DELETE.

如果你想要不同的行为,设置 fetchOptions.retryPolicy:

const mcp = await createOpenApiMcp({
  source: './spec.yaml',
  fetchOptions: {
    retries: 2,
    retryPolicy: 'all', // 'safe-only' (default) | 'all' | 'none'
  },
})

笔记:

  • retryPolicy: 'safe-only' 是默认值。
  • retryPolicy: 'all' 也会重试更改请求。
  • retryPolicy: 'none' 完全禁用请求重试。
  • 内置的身份验证令牌获取使用自己的内部重试行为,并且不会被默认的仅安全策略阻止。

CLI参考

dynamic-openapi-mcp [options] [source]

Options:
  -s, --source <url|file>        OpenAPI spec URL or file path
  -b, --base-url <url>           Override the base URL from the spec
      --server-index <n>         Select Nth server entry (default: 0)
      --include-tag <name>       Only expose operations with this tag (repeatable, comma-separated)
      --exclude-tag <name>       Hide operations with this tag (repeatable, comma-separated)
      --include-operation <id>   Only expose these operationIds (repeatable, comma-separated)
      --exclude-operation <id>   Hide these operationIds (repeatable, comma-separated)
  -h, --help                     Show help
环境变量 描述
OPENAPI_SOURCE 规范URL或文件路径(替代 -s)
OPENAPI_BASE_URL 覆盖基本URL
OPENAPI_AUTH_TOKEN 用于身份验证的承载令牌
OPENAPI_API_KEY 用于身份验证的API密钥

线下捆绑包

将任何OpenAPI规范打包成一个独立的bash二进制文件,该文件表现为MCP服务器——启动时没有网络调用,确定性md5,可跨机器移植。

dynamic-openapi-mcp bundle \
  -s https://petstore3.swagger.io/api/v3/openapi.json \
  --name petstore-mcp \
  --out ./bin/petstore-mcp

生成的文件将解引用的规范嵌入为base64 JSON execs dynamic-openapi-mcp 随着 --source <tmpfile> 在运行时。任何额外的参数都会转发给运行者,因此它直接进入 .mcp.json:

{
  "mcpServers": {
    "petstore": {
      "command": "/absolute/path/to/bin/petstore-mcp"
    }
  }
}

捆绑的二进制文件还公开了:

子命令 目的
--show-spec 解码并打印嵌入式规范
--spec-md5 打印嵌入式规范的md5
--spec <url|file> 在运行时覆盖嵌入式规范
update 重新获取原始规范并就地重写二进制文件
install Symlink(或 --copy)二进制进入 $XDG_BIN_HOME 或 ~/.local/bin
uninstall 删除上一个 install

跑 dynamic-openapi-mcp bundle --help 查看完整的选项列表。

滤波操作

并非所有端点都需要到达AI。切割曲面的两种方法:

标志(和程序 filters)

# only expose the `pets` and `store` tags
dynamic-openapi-mcp -s ./spec.yaml --include-tag pets --include-tag store

# hide admin endpoints and one noisy op
dynamic-openapi-mcp -s ./spec.yaml --exclude-tag admin --exclude-operation debugDump

# allowlist specific operations — tags are ignored for these
dynamic-openapi-mcp -s ./spec.yaml --include-operation listPets,getPetById

# mix-and-match: everything under `pets`, minus one write op
dynamic-openapi-mcp -s ./spec.yaml --include-tag pets --exclude-operation deletePet

程序等效:

const mcp = await createOpenApiMcp({
  source: './spec.yaml',
  filters: {
    tags: { include: ['pets'], exclude: ['admin'] },
    operations: { include: ['healthCheck'], exclude: ['debugDump'] },
  },
})

优先 (首场比赛获胜): x-hidden → operations.exclude → operations.include → tags.exclude → 包括作为反对者。 operations.include 逃避匹配 tags.exclude但是 operations.exclude 战胜一切,除了 x-hidden.

x-hidden 厂商扩展

让规范作者对该工具的每个使用者隐藏一个端点——不需要标志:

paths:
  /admin/reset:
    post:
      operationId: adminReset
      x-hidden: true       # always removed, regardless of filter flags

适用于公共规范中附带的仅限内部端点,但不应从AI代理/捆绑的CLI/技能中调用。

x-mcp-hidden --MCP仅选择退出

有时,您希望操作在CLI或技能使用者中可见,但 不 作为MCP工具公开——通常是有风险的操作,你信任终端上的人,但不信任自主代理:

paths:
  /admin/wipe:
    delete:
      operationId: wipeEverything
      x-mcp-hidden: true   # invisible to MCP; still callable from the CLI

不同于 x-hidden,这消除了所有地方的操作。

MCP_MAX_TOOLS --工具预算

包含数百个操作的规范会通过工具列表毒害代理上下文。盖上盖子:

MCP_MAX_TOOLS=50 dynamic-openapi-mcp -s ./huge-spec.yaml

当规格超出预算时,操作将被排名(非弃用+先标记,然后按字母顺序排列),剩余部分将被注册为单个 list_available_operations 代理可以调用工具来发现修剪了什么。

工具安全注释

每个注册的工具都会获得MCP 工具注释 源于HTTP方法,因此主机(Claude Desktop、Cursor)可以提示确认正确的操作:

方法 readOnlyHint destructiveHint idempotentHint openWorldHint
GET, HEAD, OPTIONS, TRACE ✓ ✗ ✓ ✓
POST ✗ ✗ ✗ ✓
PUT ✗ ✗ ✓ ✓
PATCH ✗ ✗ ✗ ✓
DELETE ✗ ✓ ✓ ✓

在规范级别使用供应商扩展进行覆盖:

paths:
  /search:
    post:
      operationId: searchThings
      x-side-effect: read-only   # POST that only reads — read-only annotations
  /admin/wipe:
    get:
      operationId: wipeEverything
      x-destructive: true        # GET that actually destroys — destructive annotation

决心 x-side-effect > x-destructive >HTTP方法默认值。

工具说明

工具描述是根据操作的确定性综合而成的 summary/description 加上参数签名加上响应形状——比 truncate(summary):

Fetch pet by id

Parameters:
  - petId(path, integer<int64>, required)
  - status(query, enum: "available"|"pending"|"sold", optional)

Returns: 200 — array<Pet> — OK

精心策划的描述通过以下方式获胜 x-description-override:

paths:
  /search:
    post:
      operationId: searchThings
      x-description-override: |
        Search returns up to 25 pets matching the query, ordered by relevance.
        Call get-pet-by-id afterwards for full details.

地图是如何工作的

运营→ Tools

规范中的每个操作都成为一个MCP工具:

OpenAPI MCP工具
operationId: listPets 工具名称: listPets
GET /pets/{petId} (无操作ID) 工具名称: get_pets_by_petId
summary 或 description 工具描述(截断为200个字符)
路径+查询+标头参数 顶级输入属性
请求正文 在下面输入属性 body 钥匙

请求机构尽可能保留原始媒体类型:

  • application/json 以JSON格式发送。
  • application/x-www-form-urlencoded 序列化为 URLSearchParams.
  • multipart/form-data 序列化为 FormData.
  • application/octet-stream 和其他二元体支持 { dataBase64, filename?, contentType? }.

响应处理遵循相同的想法:

  • JSON打印得很好。
  • 图像作为MCP图像内容返回。
  • 其他二进制有效载荷在小到可以内联时以二进制元数据加base64的形式返回。

模式→ 资源

OpenAPI MCP资源URI
完全取消引用的规范 openapi://spec
components.schemas.Pet openapi://schemas/Pet
components.schemas.User openapi://schemas/User

提示

Prompt Args 返回什么
describe-api -- 概述,包括标题、版本、所有端点、身份验证方案、模式
explore-endpoint operationId 完整细节:参数、请求体模式、响应、安全性

许可证

麻省理工学院