关于 OpenAPI MCP Server
OpenAPI MCP Server 是一个 MCP 服务,可将 OpenAPI 规范中定义的 REST 端点暴露为 MCP 工具,并可选提供提示词和资源。它面向需要让 LLM 发现并调用 REST API 的开发者和用户,支持以 CLI 或库的方式使用。
主要功能
- 01将 OpenAPI 端点转换为 MCP 工具
- 02支持从 URL、本地文件、标准输入或内联内容加载规范
- 03支持 stdio 与 Streamable HTTP 两种传输方式
- 04按标签、资源路径、HTTP 方法等条件筛选工具
- 05支持双向 TLS 与自定义 CA 证书
- 06可选的提示词和资源配置
适用场景
- 01让 Claude Desktop 或 Cursor 通过 MCP 调用内部 REST API
- 02按标签或操作类型限制向 LLM 暴露的 API 端点
- 03在 Node.js 应用中以库的形式构建自定义 MCP 服务
MCP 相关
该项目是 MCP 服务端,将 OpenAPI 端点以 MCP 工具的形式提供给 MCP 客户端,并可额外暴露提示词和资源。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
OpenAPI MCP 服务
一个模型上下文协议(MCP)服务,可将 OpenAPI 端点公开为 MCP 工具,并可选支持 MCP 提示词和资源。此服务允许大模型通过 MCP 协议发现并调用由 OpenAPI 规范定义的 REST API。
📖 文档
- 用户指南 - 供希望将此 MCP 服务与 Claude Desktop、Cursor 或其他 MCP 客户端搭配使用的用户参考
- 库的使用方法 - 供使用此软件包作为库来创建自定义 MCP 服务的开发者参考
- 开发者指南 - 供参与代码库工作的贡献者和开发者参考
- AuthProvider 指南 - 详细的身份验证模式和示例
用户指南
本节介绍如何作为终端用户,将此 MCP 服务与 Claude Desktop、Cursor 或其他兼容 MCP 的工具搭配使用。
概述
此 MCP 服务有两种使用方式:
- CLI 工具:直接使用
npx @ivotoby/openapi-mcp-server和命令行参数,快速完成设置 - 库:在自己的 Node.js 应用程序中导入并使用
OpenAPIServer类,实现自定义方案
此服务支持两种传输方式:
- Stdio 传输(默认):用于与 Claude Desktop 等通过标准输入/输出管理 MCP 连接的 AI 系统直接集成。
- Streamable HTTP 传输:用于通过 HTTP 连接到服务,使 Web 客户端和其他支持 HTTP 的系统能够使用 MCP 协议。
用户快速入门
选项 1:与 Claude Desktop 搭配使用(Stdio 传输)
无需克隆此代码库。只需配置 Claude Desktop 以使用此 MCP 服务:
-
找到或创建 Claude Desktop 配置文件:
- 在 macOS 上:
~/Library/Application Support/Claude/claude_desktop_config.json
- 在 macOS 上:
-
添加以下配置:
{
"mcpServers": {
"openapi": {
"command": "npx",
"args": ["-y", "@ivotoby/openapi-mcp-server"],
"env": {
"API_BASE_URL": "https://api.example.com",
"OPENAPI_SPEC_PATH": "https://api.example.com/openapi.json",
"API_HEADERS": "Authorization:Bearer token123,X-API-Key:your-api-key"
}
}
}
}
- 将环境变量替换为实际的 API 配置:
API_BASE_URL:API 的基础 URLOPENAPI_SPEC_PATH:OpenAPI 规范的 URL 或路径API_HEADERS:以逗号分隔的 key:value 键值对,用于设置 API 身份验证标头
选项 2:与 HTTP 客户端搭配使用(HTTP 传输)
要将此服务与 HTTP 客户端搭配使用:
- 无需安装!使用 npx 直接运行此软件包:
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec https://api.example.com/openapi.json \
--headers "Authorization:Bearer token123" \
--transport http \
--port 3000
- 使用 HTTP 请求与服务交互:
# Initialize a session (first request)
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"curl-client","version":"1.0.0"}}}'
# The response includes a Mcp-Session-Id header that you must use for subsequent requests
# and the InitializeResult directly in the POST response body.
# Send a request to list tools
# This also receives its response directly on this POST request.
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Mcp-Session-Id: your-session-id" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
# Open a streaming connection for other server responses (e.g., tool execution results)
# This uses Server-Sent Events (SSE).
curl -N http://localhost:3000/mcp -H "Mcp-Session-Id: your-session-id"
# Example: Execute a tool (response will arrive on the GET stream)
# curl -X POST http://localhost:3000/mcp \
# -H "Content-Type: application/json" \
# -H "Mcp-Session-Id: your-session-id" \
# -d '{"jsonrpc":"2.0","id":2,"method":"tools/execute","params":{"name":"yourToolName", "arguments": {}}}'
# Terminate the session when done
curl -X DELETE http://localhost:3000/mcp -H "Mcp-Session-Id: your-session-id"
配置选项
可通过环境变量或命令行参数配置此服务:
环境变量
API_BASE_URL- API 端点的基础 URLOPENAPI_SPEC_PATH- OpenAPI 规范的路径或 URLOPENAPI_SPEC_FROM_STDIN- 设置为 "true",以从标准输入读取 OpenAPI 规范OPENAPI_SPEC_INLINE- 直接以字符串形式提供 OpenAPI 规范内容API_HEADERS- 用逗号分隔的 API 标头键值对CLIENT_CERT_PATH- 用于双向 TLS 的客户端证书 PEM 文件路径CLIENT_KEY_PATH- 用于双向 TLS 的客户端私钥 PEM 文件路径CA_CERT_PATH- 用于私有/内部 CA 的自定义 CA 证书 PEM 文件路径CLIENT_KEY_PASSPHRASE- 加密客户端私钥的密码REJECT_UNAUTHORIZED- 是否拒绝不受信任的服务器证书(默认值:true)SERVER_NAME- MCP 服务的名称(默认值:"mcp-openapi-server")SERVER_VERSION- 服务版本(默认值:"1.0.0")TRANSPORT_TYPE- 要使用的传输类型:"stdio" 或 "http"(默认值:"stdio")HTTP_PORT- HTTP 传输端口(默认值:3000)HTTP_HOST- HTTP 主机(默认值:"127.0.0.1")ENDPOINT_PATH- HTTP 传输的端点路径(默认值:"/mcp")TOOLS_MODE- 工具加载模式:"all"(加载所有基于端点的工具)、"dynamic"(仅加载元工具)或 "explicit"(仅加载 includeTools 中指定的工具)(默认值:"all")DISABLE_ABBREVIATION- 禁用名称优化(名称超过 64 个字符时可能会引发错误)VERBOSE- 启用操作日志(默认值为true;设置为false可抑制非必要日志)PROMPTS_PATH- 提示词 JSON/YAML 文件的路径或 URLPROMPTS_INLINE- 直接以 JSON 字符串形式提供提示词RESOURCES_PATH- 资源 JSON/YAML 文件的路径或 URLRESOURCES_INLINE- 直接以 JSON 字符串形式提供资源
命令行参数
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec https://api.example.com/openapi.json \
--headers "Authorization:Bearer token123,X-API-Key:your-api-key" \
--exclude-tag admin \
--client-cert ./certs/client.pem \
--client-key ./certs/client-key.pem \
--name "my-mcp-server" \
--server-version "1.0.0" \
--transport http \
--port 3000 \
--host 127.0.0.1 \
--path /mcp \
--disable-abbreviation true \
--verbose false
双向 TLS(mTLS)
如果上游 API 要求使用客户端证书进行身份验证,您可以将 TLS 凭据直接附加到出站请求。
npx @ivotoby/openapi-mcp-server \
--api-base-url https://secure-api.example.com \
--openapi-spec https://secure-api.example.com/openapi.json \
--client-cert ./certs/client.pem \
--client-key ./certs/client-key.pem \
--headers "Authorization:Bearer token123"
这与 HTTP 层身份验证相互独立,因此 mTLS 可以与静态标头或 AuthProvider 结合使用。
只有在 --api-base-url 使用 https:// 时,TLS 相关选项才会生效。
对于私有 CA 或加密密钥:
npx @ivotoby/openapi-mcp-server \
--api-base-url https://internal-api.example.com \
--openapi-spec ./openapi.yaml \
--client-cert ./certs/client.pem \
--client-key ./certs/client-key.pem \
--client-key-passphrase "$CLIENT_KEY_PASSPHRASE" \
--ca-cert ./certs/internal-ca.pem \
--reject-unauthorized false
--client-cert/CLIENT_CERT_PATH:客户端证书 PEM 文件--client-key/CLIENT_KEY_PATH:客户端私钥 PEM 文件--client-key-passphrase/CLIENT_KEY_PASSPHRASE:加密私钥的密码--ca-cert/CA_CERT_PATH:用于私有/内部证书颁发机构的自定义 CA 证书包--reject-unauthorized/REJECT_UNAUTHORIZED:仅当您有意允许自签名或其他不受信任的服务器证书时,才设为false
如果希望服务在脚本或嵌入式环境中保持静默,请设置 --verbose false 或 VERBOSE=false。
加载 OpenAPI 规范
MCP 服务支持多种 OpenAPI 规范加载方式,可灵活适用于不同的部署场景:
1. 从 URL 加载(默认)
从远程 URL 加载 OpenAPI 规范:
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec https://api.example.com/openapi.json
2. 从本地文件加载
从本地文件加载 OpenAPI 规范:
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec ./path/to/openapi.yaml
3. 从标准输入加载
从标准输入读取 OpenAPI 规范(适用于管道传输或容器化环境):
# Pipe from file
cat openapi.json | npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--spec-from-stdin
# Pipe from curl
curl -s https://api.example.com/openapi.json | npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--spec-from-stdin
# Using environment variable
export OPENAPI_SPEC_FROM_STDIN=true
echo '{"openapi": "3.0.0", ...}' | npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com
4. 内联规范
将 OpenAPI 规范内容直接作为命令行参数提供:
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--spec-inline '{"openapi": "3.0.0", "info": {"title": "My API", "version": "1.0.0"}, "paths": {}}'
# Using environment variable
export OPENAPI_SPEC_INLINE='{"openapi": "3.0.0", ...}'
npx @ivotoby/openapi-mcp-server --api-base-url https://api.example.com
支持的格式
所有加载方式均支持 JSON 和 YAML 格式。服务会自动检测格式并进行相应解析。
Docker 和容器用法
对于容器化部署,您可以挂载 OpenAPI 规范文件或使用标准输入:
# Mount local file
docker run -v /path/to/spec:/app/spec.json your-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec /app/spec.json
# Use stdin with docker
cat openapi.json | docker run -i your-mcp-server \
--api-base-url https://api.example.com \
--spec-from-stdin
错误处理
服务器会针对规范加载失败提供详细的错误消息:
- URL 加载:HTTP 状态码和网络错误
- 文件加载:文件系统错误(文件不存在、权限不足等)
- Stdin 加载:输入为空或读取错误
- 内联加载:缺少内容错误
- 解析错误:详细的 JSON/YAML 语法错误消息
验证
一次只能使用一个规范来源。服务器会验证以下来源中是否恰好提供了一个:
--openapi-spec(URL 或文件路径)--spec-from-stdin--spec-inline
如果指定了多个来源,服务器将退出并显示错误消息。
工具加载与筛选选项
根据 Stainless 的文章《将复杂 OpenAPI 规范转换为 MCP 服务的经验》(https://www.stainless.com/blog/what-we-learned-converting-complex-openapi-specs-to-mcp-servers),新增了以下标志,用于控制加载哪些 API 端点(工具):
--tools <all|dynamic|explicit>:选择工具加载模式:all(默认):加载 OpenAPI 规范中的所有工具,并应用指定的筛选条件dynamic:仅加载动态元工具(list-api-endpoints、get-api-endpoint-schema、invoke-api-endpoint)。--exclude-tag仍会应用于动态端点的发现和调用。explicit:仅加载通过--tool选项显式列出的工具,并忽略包含筛选条件。--exclude-tag仍会作为拒绝筛选条件应用。
--tool <toolId>:仅导入指定的工具 ID 或名称。可多次使用。在all模式下,此选项会绕过--tag、--resource和--operation,但不会绕过--exclude-tag。--tag <tag>:仅导入带有指定 OpenAPI 标签的工具。可多次使用。--exclude-tag <tag>:排除带有指定 OpenAPI 标签的工具。可多次使用。排除标签优先于--tool。--resource <resource>:仅导入指定资源路径前缀下的工具。可多次使用。--operation <method>:仅导入指定 HTTP 方法(get、post 等)对应的工具。可多次使用。
标签筛选用于控制工具的可见范围,而不是用于授权。请继续使用上游 API 的身份验证模型保护敏感端点。未标记的端点不受 --exclude-tag 影响。
示例:
# Load only dynamic meta-tools
npx @ivotoby/openapi-mcp-server --api-base-url https://api.example.com --openapi-spec https://api.example.com/openapi.json --tools dynamic
# Load only explicitly specified tools (ignores other filters)
npx @ivotoby/openapi-mcp-server --api-base-url https://api.example.com --openapi-spec https://api.example.com/openapi.json --tools explicit --tool GET::users --tool POST::users
# Load only the GET /users endpoint tool (using all mode with filtering)
npx @ivotoby/openapi-mcp-server --api-base-url https://api.example.com --openapi-spec https://api.example.com/openapi.json --tool GET-users
# Load tools tagged with "user" under the "/users" resource
npx @ivotoby/openapi-mcp-server --api-base-url https://api.example.com --openapi-spec https://api.example.com/openapi.json --tag user --resource users
# Exclude admin and internal endpoints from any tool loading mode
npx @ivotoby/openapi-mcp-server --api-base-url https://api.example.com --openapi-spec https://api.example.com/openapi.json --exclude-tag admin --exclude-tag internal
# Load only POST operations
npx @ivotoby/openapi-mcp-server --api-base-url https://api.example.com --openapi-spec https://api.example.com/openapi.json --operation post
提示词和资源
除了将 OpenAPI 端点作为工具公开之外,此服务器还可以通过 MCP 协议公开提示词(可重复使用的模板)和资源(静态内容)。
什么是提示词和资源?
| 功能 | 用途 | 使用场景 |
|---|---|---|
| 工具 | 供 AI 执行的 API 端点 | 发起 API 调用 |
| 提示词 | 支持参数替换的模板化消息 | 可重复使用的工作流模板 |
| 资源 | 只读内容,用于提供上下文 | API 文档、架构 |
加载提示词
可以从文件、URL 或内联 JSON 加载提示词:
# Load from local file
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec https://api.example.com/openapi.json \
--prompts ./prompts.json
# Load from URL
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec https://api.example.com/openapi.json \
--prompts https://example.com/mcp/prompts.json
# Inline JSON
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec https://api.example.com/openapi.json \
--prompts-inline '[{"name":"greet","title":"Greeting","template":"Hello {{name}}!"}]'
提示词文件格式(JSON):
[
{
"name": "api_request",
"title": "API Request Helper",
"description": "Helps generate API request templates",
"arguments": [
{ "name": "endpoint", "description": "API endpoint path", "required": true },
{ "name": "method", "description": "HTTP method", "required": false }
],
"template": "Create a {{method}} request to {{endpoint}} with proper parameters."
}
]
加载资源
可以从文件、URL 或内联 JSON 加载资源:
# Load from local file
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec https://api.example.com/openapi.json \
--mcp-resources ./resources.json
# Load from URL
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec https://api.example.com/openapi.json \
--mcp-resources https://example.com/mcp/resources.json
# Inline JSON
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec https://api.example.com/openapi.json \
--mcp-resources-inline '[{"uri":"docs://readme","name":"readme","text":"# Welcome"}]'
资源文件格式(JSON):
[
{
"uri": "docs://api/overview",
"name": "api-overview",
"title": "API Overview",
"description": "Overview of the API",
"mimeType": "text/markdown",
"text": "# API Overview\n\nThis API provides..."
}
]
组合工具、提示词和资源
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec https://api.example.com/openapi.json \
--prompts ./prompts.json \
--mcp-resources ./resources.json \
--transport http \
--port 3000
使用此配置时,服务器会公布这三种能力:
{
"capabilities": {
"tools": { "list": true, "execute": true },
"prompts": {},
"resources": {}
}
}
传输类型
Stdio 传输(默认)
Stdio 传输专为与 Claude Desktop 等 AI 系统直接集成而设计,这些系统通过标准输入/输出管理 MCP 连接。这是最简单的设置,无需网络配置。
适用场景:与 Claude Desktop 或其他支持基于 stdio 的 MCP 通信的系统集成时。
流式 HTTP 传输
HTTP 传输允许通过 HTTP 访问 MCP 服务,使 Web 应用和其他支持 HTTP 的客户端能够与 MCP 协议交互。它支持会话管理、流式响应和标准 HTTP 方法。
主要功能:
- 使用 Mcp-Session-Id 标头进行会话管理
initialize和tools/list请求的 HTTP 响应会在 POST 请求中同步发送。- 其他服务端到客户端的消息(例如
tools/execute结果、通知)会通过使用 Server-Sent Events(SSE)的 GET 连接进行流式传输。 - 支持 POST/GET/DELETE 方法
适用场景:需要向 Web 客户端或通过 HTTP 而非 stdio 通信的系统开放 MCP 服务时。
健康检查端点
使用 HTTP 传输时,可通过 /health 健康检查端点进行监控和服务发现:
# Check server health
curl http://localhost:3000/health
# Response:
# {
# "status": "healthy",
# "activeSessions": 2,
# "uptime": 3600
# }
健康状态响应字段:
status:服务运行时始终返回 "healthy"activeSessions:活跃 MCP 会话数uptime:服务运行时长,单位为秒
主要功能:
- 无需身份验证
- 支持任何 HTTP 方法(GET、POST 等)
- 适用于负载均衡器、Kubernetes 探针和监控系统
集成示例:
# Kubernetes liveness probe
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 3
periodSeconds: 10
# Docker healthcheck
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:3000/health || exit 1
安全注意事项
- HTTP 传输会验证 Origin 标头,以防止 DNS 重绑定攻击
- 默认情况下,HTTP 传输仅绑定到 localhost (127.0.0.1)
- 如果要向其他主机开放,请考虑实施额外的身份验证
调试
查看调试日志:
-
使用 stdio 传输和 Claude Desktop 时:
- 日志会显示在 Claude Desktop 日志中
-
使用 HTTP 传输时:
npx @ivotoby/openapi-mcp-server --transport http &2>debug.log
库的使用
本节面向希望将此软件包用作库来创建自定义 MCP 服务的开发者。
🚀 作为库使用
通过导入并配置 OpenAPIServer 类,为特定 API 创建专用 MCP 服务。此方式适用于:
- 自定义身份验证:使用
AuthProvider接口实现复杂的身份验证模式 - 针对 API 的优化:筛选端点、自定义错误处理,并针对特定用例进行优化
- 分发:将服务打包为独立的 npm 模块,以便轻松共享
- 集成:将服务嵌入到更大型的应用中,或添加自定义中间件
库的基本用法
import { OpenAPIServer } from "@ivotoby/openapi-mcp-server"
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
const config = {
name: "my-api-server",
version: "1.0.0",
apiBaseUrl: "https://api.example.com",
openApiSpec: "https://api.example.com/openapi.json",
specInputMethod: "url" as const,
headers: {
Authorization: "Bearer your-token",
"X-API-Key": "your-api-key",
},
transportType: "stdio" as const,
toolsMode: "all" as const, // Options: "all", "dynamic", "explicit"
}
const server = new OpenAPIServer(config)
const transport = new StdioServerTransport()
await server.start(transport)
工具加载模式
toolsMode 配置选项用于控制从 OpenAPI 规范加载哪些工具:
// Load all tools from the spec (default)
const config = {
// ... other config
toolsMode: "all" as const,
// Optional: Apply filters to control which tools are loaded
includeTools: ["GET::users", "POST::users"], // Only these tools
includeTags: ["public"], // Only tools with these tags
excludeTags: ["admin", "internal"], // Never expose tools with these tags
includeResources: ["users"], // Only tools under these resources
includeOperations: ["get", "post"], // Only these HTTP methods
}
// Load only dynamic meta-tools for API exploration
const config = {
// ... other config
toolsMode: "dynamic" as const,
// Provides: list-api-endpoints, get-api-endpoint-schema, invoke-api-endpoint
// excludeTags still hides matching operations from discovery and invocation
}
// Load only explicitly specified tools (include filters are ignored)
const config = {
// ... other config
toolsMode: "explicit" as const,
includeTools: ["GET::users", "POST::users"], // Only these exact tools
excludeTags: ["admin"], // Still applied as a deny filter
// includeTags, includeResources, includeOperations are ignored in explicit mode
}
配置提示词和资源
在 API 工具旁公开可重复使用的提示词和静态资源:
import { OpenAPIServer } from "@ivotoby/openapi-mcp-server"
const config = {
name: "my-api-server",
version: "1.0.0",
apiBaseUrl: "https://api.example.com",
openApiSpec: "https://api.example.com/openapi.json",
specInputMethod: "url" as const,
transportType: "stdio" as const,
toolsMode: "all" as const,
// Define prompts with argument templates
prompts: [
{
name: "api_request",
title: "API Request Helper",
description: "Helps generate API request templates",
arguments: [
{ name: "endpoint", description: "API endpoint path", required: true },
{ name: "method", description: "HTTP method", required: false },
],
template: "Create a {{method}} request to {{endpoint}} with proper parameters.",
},
],
// Define resources with static content
resources: [
{
uri: "docs://api/overview",
name: "api-overview",
title: "API Overview",
description: "Overview of the API capabilities",
mimeType: "text/markdown",
text: "# API Overview\n\nThis API provides...",
},
],
}
const server = new OpenAPIServer(config)
添加额外的自定义工具
你可以在根据 OpenAPI 规范生成的工具旁公开一些手动编写的 MCP 工具:
import { OpenAPIServer } from "@ivotoby/openapi-mcp-server"
const extraTools = [
{
id: "add",
tool: {
name: "add",
description: "Add two numbers",
inputSchema: {
type: "object",
properties: {
a: { type: "number" },
b: { type: "number" },
},
required: ["a", "b"],
},
},
handler: async (args) => {
const a = Number(args.a)
const b = Number(args.b)
const result = a + b
return {
content: [{ type: "text", text: JSON.stringify({ result }) }],
structuredContent: { result },
}
},
},
]
const server = new OpenAPIServer({
name: "my-api-server",
version: "1.0.0",
apiBaseUrl: "https://api.example.com",
openApiSpec: "https://api.example.com/openapi.json",
specInputMethod: "url",
transportType: "stdio",
toolsMode: "all",
extraTools,
})
注意:
- 在首个版本中,
extraTools仅供库使用;命令行没有用于函数处理程序的格式 - 自定义工具和根据 OpenAPI 生成的工具之间,额外工具 ID 和 MCP 工具名称必须唯一
- 额外工具处理程序应返回标准的 MCP
tools/call结果对象
动态管理提示词和资源
创建服务后,你也可以动态添加提示词和资源:
const server = new OpenAPIServer(config)
// Add prompts dynamically
const promptsManager = server.getPromptsManager()
if (promptsManager) {
promptsManager.addPrompt({
name: "debug_error",
title: "Error Debugger",
template: "Debug this API error: {{error_message}}",
})
}
// Add resources dynamically
const resourcesManager = server.getResourcesManager()
if (resourcesManager) {
resourcesManager.addResource({
uri: "docs://changelog",
name: "changelog",
title: "API Changelog",
mimeType: "text/markdown",
text: "# Changelog\n\n## v1.0.0\n- Initial release",
})
}
提示词定义格式
interface PromptDefinition {
name: string // Unique identifier
title?: string // Human-readable display title
description?: string // Description of the prompt
arguments?: {
// Template arguments
name: string
description?: string
required?: boolean
}[]
template: string // Template with {{argName}} placeholders
}
资源定义格式
interface ResourceDefinition {
uri: string // Unique URI identifier
name: string // Resource name
title?: string // Human-readable display title
description?: string // Description of the resource
mimeType?: string // Content MIME type
text?: string // Static text content
blob?: string // Static binary content (base64)
contentProvider?: () => Promise<string | { blob: string }> // Dynamic content
}
使用 AuthProvider 进行高级身份验证
对于具有令牌过期、刷新要求或复杂身份验证的 API:
import { OpenAPIServer, AuthProvider } from "@ivotoby/openapi-mcp-server"
import { AxiosError } from "axios"
class MyAuthProvider implements AuthProvider {
async getAuthHeaders(): Promise<Record<string, string>> {
// Called before each request - return fresh headers
if (this.isTokenExpired()) {
await this.refreshToken()
}
return { Authorization: `Bearer ${this.token}` }
}
async handleAuthError(error: AxiosError): Promise<boolean> {
// Called on 401/403 errors - return true to retry
if (error.response?.status === 401) {
await this.refreshToken()
return true // Retry the request
}
return false
}
}
const authProvider = new MyAuthProvider()
const config = {
// ... other config
authProvider: authProvider, // Use AuthProvider instead of static headers
}
📁 请参阅 examples/ 目录,了解完整且可运行的示例,包括:
- 使用静态身份验证的库基本用法
- 针对不同场景的 AuthProvider 实现
- 真实的 Beatport API 集成
- 可用于生产环境的打包模式
🔐 使用 AuthProvider 进行动态身份验证
AuthProvider 接口支持静态标头无法处理的复杂身份验证场景:
主要功能
- 动态标头:为每个请求提供最新的身份验证标头
- 令牌过期处理:自动检测并处理过期令牌
- 身份验证错误恢复:针对可恢复的身份验证失败进行重试
- 自定义错误消息:为用户提供清晰、可执行的指导
AuthProvider 接口
interface AuthProvider {
/**
* Get authentication headers for the current request
* Called before each API request to get fresh headers
*/
getAuthHeaders(): Promise<Record<string, string>>
/**
* Handle authentication errors from API responses
* Called when the API returns 401 or 403 errors
* Return true to retry the request, false otherwise
*/
handleAuthError(error: AxiosError): Promise<boolean>
}
常见模式
自动刷新令牌
class RefreshableAuthProvider implements AuthProvider {
async getAuthHeaders(): Promise<Record<string, string>> {
if (this.isTokenExpired()) {
await this.refreshToken()
}
return { Authorization: `Bearer ${this.accessToken}` }
}
async handleAuthError(error: AxiosError): Promise<boolean> {
if (error.response?.status === 401) {
await this.refreshToken()
return true // Retry with fresh token
}
return false
}
}
手动管理令牌(例如 Beatport)
class ManualTokenAuthProvider implements AuthProvider {
async getAuthHeaders(): Promise<Record<string, string>> {
if (!this.token || this.isTokenExpired()) {
throw new Error(
"Token expired. Please get a new token from your browser:\n" +
"1. Go to the API website and log in\n" +
"2. Open browser dev tools (F12)\n" +
"3. Copy the Authorization header from any API request\n" +
"4. Update your token using updateToken()",
)
}
return { Authorization: `Bearer ${this.token}` }
}
updateToken(token: string): void {
this.token = token
this.tokenExpiry = new Date(Date.now() + 3600000) // 1 hour
}
}
API 密钥身份验证
class ApiKeyAuthProvider implements AuthProvider {
constructor(private apiKey: string) {}
async getAuthHeaders(): Promise<Record<string, string>> {
return { "X-API-Key": this.apiKey }
}
async handleAuthError(error: AxiosError): Promise<boolean> {
throw new Error("API key authentication failed. Please check your key.")
}
}
📖 如需查看详细的 AuthProvider 文档和示例,请参阅 docs/auth-provider-guide.md
OpenAPI 架构处理
引用解析
此 MCP 服务实现了可靠的 OpenAPI 引用($ref)解析,以确保准确表示 API 架构:
- 参数引用:完整解析 OpenAPI 规范中指向参数组件的
$ref指针 - 架构引用:处理参数和请求正文中的嵌套架构引用
- 递归引用:通过检测并处理循环引用来防止无限循环
- 嵌套属性:保留复杂的嵌套对象和数组结构及其所有属性
输入架构组合
此服务会智能地将参数和请求正文合并为每个工具的统一输入架构:
- 参数与请求正文合并:将路径、查询和正文参数合并到单个架构中
- 冲突处理:通过为与参数名称冲突的正文属性添加前缀来解决命名冲突
- 类型保留:保留所有架构元素的原始类型信息
- 元数据保留:保留描述、格式、默认值、枚举值和其他架构属性
复杂架构支持
此 MCP 服务可处理各种 OpenAPI 架构的复杂情况:
- 基本类型正文:将非对象请求正文包装在
body属性中 - 对象正文:将对象属性展平到工具的输入架构中
- 数组正文:正确处理带有嵌套项定义的数组架构
- 必需属性:跟踪并保留哪些参数和属性为必需项
开发者信息
面向开发者
开发工具
npm run build- 构建 TypeScript 源代码npm run clean- 删除构建产物npm test- 运行 Vitest 测试套件npm run typecheck- 运行 TypeScript 类型检查npm run lint- 对src/**/*.ts运行类型感知的 ESLintnpm run dev- 监视源文件并在变更时重新构建npm run inspect-watch- 运行检查器,并在变更时自动重新加载
拉取请求前的验证
创建 PR 前,请运行完整的本地验证套件:
npm run build
npm test
npm run typecheck
npm run lint
npm run build 会更新 dist/,确保 CLI 执行测试使用最新代码。npm run lint 有意启用了类型感知检查,所有源文件都应通过检查。
开发工作流
- 克隆仓库
- 安装依赖:
npm install - 启动开发环境:
npm run inspect-watch - 修改
src/中的 TypeScript 文件 - 服务将自动重新构建并重启
贡献
- 复刻仓库
- 创建功能分支
- 进行修改
- 运行构建、测试、类型检查和代码检查:
npm run build && npm test && npm run typecheck && npm run lint - 提交拉取请求
📖 如需查看完整的开发者文档,请参阅 docs/developer-guide.md
常见问题解答
问:“工具”是什么?
答:工具对应于从 OpenAPI 规范中提取的单个 API 端点,并作为 MCP 资源公开。
问:如何在自己的项目中使用此软件包?
答:你可以导入 OpenAPIServer 类,并在自己的 Node.js 应用中将其用作库。这样,你就可以针对特定 API 创建专用 MCP 服务,并自定义身份验证、筛选和错误处理。完整实现请参阅 examples/ 目录。
问:使用 CLI 和将其用作库有什么区别?
答:CLI 适合快速设置和测试,而使用库的方式则允许你针对特定 API 创建专用软件包、通过 AuthProvider 实现自定义身份验证、添加自定义逻辑,并将服务作为独立的 npm 模块分发。
问:如何处理令牌会过期的 API?
答:请使用 AuthProvider 接口,而不是静态标头。AuthProvider 允许你实现动态身份验证,包括令牌刷新、过期处理和自定义错误恢复。不同模式的示例请参阅 AuthProvider 示例。
问:什么是 AuthProvider?我应该在什么时候使用它?
答:AuthProvider 是一种动态身份验证接口,可在每次请求前获取最新标头并处理身份验证错误。当你的 API 使用会过期的令牌、需要刷新令牌或需要静态标头无法实现的复杂身份验证逻辑时,请使用它。
问:如何筛选要加载的工具?
答:在 --tools all(默认值)模式下使用 --tool、--tag、--exclude-tag、--resource 和 --operation 标志;设置 --tools dynamic 可仅使用元工具;也可以使用 --tools explicit,仅加载通过 --tool 指定的工具。--exclude-tag 是拒绝筛选器,在动态模式和显式模式下仍会生效。
问:什么时候应该使用动态模式?
答:动态模式提供元工具(list-api-endpoints、get-api-endpoint-schema、invoke-api-endpoint),可在不预加载所有操作的情况下检查端点并与之交互,因此适用于大型或经常变化的 API。
问:什么是提示词和资源?
答:提示词是可重复使用的消息模板,其中包含参数占位符(例如 {{name}}),可通过 MCP 的 prompts/get 方法获取。资源是可通过 MCP 的 resources/read 方法读取的静态或动态内容(文本或二进制数据)。这两者都是可选功能,你可以与工具一并配置。
问:如何通过 CLI 暴露提示词和资源?
答:提示词使用 --prompts <path|url>,资源使用 --resources <path|url>。你也可以使用 --prompts-inline 和 --resources-inline 传入内联 JSON。详情请参阅《用户指南》中的“提示词和资源”部分。
问:如何为 API 请求指定自定义标头?
答:使用 --headers 标志或 API_HEADERS 环境变量,并以逗号分隔的 key:value 键值对指定标头,适用于 CLI 用法。使用库时,请使用 headers 配置选项,或实现 AuthProvider 来提供动态标头。
问:支持哪些传输方式? 答:服务支持 stdio 传输(默认),用于与 AI 系统集成;也支持 HTTP 传输(通过 SSE 实现流式传输),用于 Web 客户端。
问:服务如何处理包含引用的复杂 OpenAPI 架构?
答:服务会完整解析参数和架构中的 $ref 引用,并保留嵌套结构、默认值和其他属性。有关引用解析和架构组合的详情,请参阅“OpenAPI 架构处理”部分。
问:参数名称与请求体属性发生冲突时会怎样?
答:服务会检测名称冲突,并自动为请求体属性名称添加 body_ 前缀以避免冲突,确保所有属性均可访问。
问:我可以将 MCP 服务打包并分发吗?
答:可以!使用库的方式时,你可以为自己的 API 创建专用 npm 软件包。Beatport 示例展示了完整实现,可将其打包并作为 npx your-api-mcp-server 分发。
问:在哪里可以找到开发和贡献指南?
答:请参阅开发者指南,其中包含有关架构、关键概念、开发工作流和贡献指南的完整文档。
许可证
MIT
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。