Skip to main content
Glama
TuanLdv

mcp-openapi-server

by TuanLdv

OpenAPI MCP Server

一个模型上下文协议(MCP)服务器,将 OpenAPI 端点暴露为 MCP 工具,并可选支持 MCP 提示词和资源。该服务器允许大语言模型通过 MCP 协议发现由 OpenAPI 规范定义的 REST API 并与之交互。

📖 文档

  • 用户指南 - 面向希望将本 MCP 服务器与 Claude Desktop、Cursor 或其他 MCP 客户端一起使用的用户

  • 库用法 - 面向希望将此包作为库来创建自定义 MCP 服务器的开发者

  • 开发者指南 - 面向在代码库上工作的贡献者和开发者

  • AuthProvider 指南 - 详细的认证模式和示例


用户指南

本节介绍如何以最终用户身份,在 Claude Desktop、Cursor 或其他兼容 MCP 的工具中使用该 MCP 服务器。

Related MCP server: cod-api MCP Server

概述

该 MCP 服务器可以通过两种方式使用:

  1. CLI 工具:直接使用 npx @ivotoby/openapi-mcp-server 配合命令行参数进行快速设置

  2. 库:在自己的 Node.js 应用程序中导入并使用 OpenAPIServer 类来实现自定义部署

该服务器支持两种传输方式:

  1. Stdio 传输(默认):用于与 Claude Desktop 等通过标准输入/输出管理 MCP 连接的 AI 系统直接集成。

  2. 可流式 HTTP 传输:用于通过 HTTP 连接服务器,使 Web 客户端和其他支持 HTTP 的系统能够使用 MCP 协议。

用户快速入门

选项 1:与 Claude Desktop 一起使用(Stdio 传输)

无需克隆此仓库。只需配置 Claude Desktop 使用该 MCP 服务器:

  1. 找到或创建你的 Claude Desktop 配置文件:

    • 在 macOS 上:~/Library/Application Support/Claude/claude_desktop_config.json

  2. 添加以下配置:

{
  "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"
      }
    }
  }
}
  1. 用你实际的 API 配置替换环境变量:

    • API_BASE_URL:你的 API 的基础 URL

    • OPENAPI_SPEC_PATH:你的 OpenAPI 规范的 URL 或路径

    • API_HEADERS:API 认证标头的逗号分隔 key:value 对

选项 2:与 HTTP 客户端一起使用(HTTP 传输)

要通过 HTTP 客户端使用该服务器:

  1. 无需安装!使用 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
  1. 使用 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 端点的基础 URL

  • OPENAPI_SPEC_PATH - OpenAPI 规范的路径或 URL

  • OPENAPI_SPEC_FROM_STDIN - 设置为 "true" 以从标准输入读取 OpenAPI 规范

  • OPENAPI_SPEC_INLINE - 直接以字符串形式提供 OpenAPI 规范内容

  • API_HEADERS - API 标头的逗号分隔 key:value 对

  • 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 文件的路径或 URL

  • PROMPTS_INLINE - 直接以 JSON 字符串形式提供提示词

  • RESOURCES_PATH - 资源 JSON/YAML 文件的路径或 URL

  • RESOURCES_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 结合使用。

TLS 相关选项仅在 --api-base-url 使用 https:// 时生效。

对于私有 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 规范或使用 stdin:

# 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 的文章“What We Learned Converting Complex OpenAPI Specs to MCP Servers”(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 等通过标准输入/输出管理 MCP 连接的 AI 系统直接集成而设计。这是最简单的设置,不需要网络配置。

适用场景:与 Claude Desktop 或其他支持基于 stdio 的 MCP 通信的系统集成时。

可流式 HTTP 传输

HTTP 传输允许通过 HTTP 访问 MCP 服务器,使 Web 应用程序和其他支持 HTTP 的客户端能够与 MCP 协议交互。它支持会话管理、流式响应和标准 HTTP 方法。

主要特性:

  • 使用 Mcp-Session-Id 标头进行会话管理

  • 对 initialize 和 tools/list 请求的 HTTP 响应会在 POST 上同步发送。

  • 其他从服务器到客户端的消息(例如 tools/execute 的结果、通知)会通过 GET 连接使用服务器发送事件(SSE)进行流式传输。

  • 支持 POST/GET/DELETE 方法

适用场景:当你需要向通过 HTTP 而非 stdio 通信的 Web 客户端或系统开放 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)

  • 如果向其他主机开放,请考虑实施额外的认证

调试

要查看调试日志:

  1. 将 stdio 传输与 Claude Desktop 一起使用时:

    • 日志会出现在 Claude Desktop 日志中

  2. 使用 HTTP 传输时:

    npx @ivotoby/openapi-mcp-server --transport http &2>debug.log

库用法

🚀 作为库使用

通过导入和配置 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 仅限库使用;没有针对函数处理器的 CLI 格式

  • 额外工具 ID 和 MCP 工具名称必须在自定义工具和 OpenAPI 生成的工具之间保持唯一

  • 额外工具处理器应返回正常的 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 Schema 处理

引用解析

该 MCP 服务器实现了健壮的 OpenAPI 引用($ref)解析,以确保 API Schema 的准确表示:

  • 参数引用:完全解析 OpenAPI 规范中指向参数组件的 $ref 指针

  • Schema 引用:处理参数和请求体中的嵌套 Schema 引用

  • 递归引用:通过检测和处理循环引用来防止无限循环

  • 嵌套属性:保留复杂的嵌套对象和数组结构及其所有属性

输入 Schema 组合

服务器会将参数和请求体智能合并为每个工具的统一输入 Schema:

  • 参数 + 请求体合并:将路径、查询和主体参数组合为单一 Schema

  • 冲突处理:通过为与参数名称冲突的主体属性添加前缀来解决命名冲突

  • 类型保留:维护所有 Schema 元素的原始类型信息

  • 元数据保留:保留描述、格式、默认值、枚举和其他 Schema 属性

复杂 Schema 支持

MCP 服务器可处理各种 OpenAPI Schema 的复杂性:

  • 原始类型主体:将非对象请求体包装在 "body" 属性中

  • 对象主体:将对象属性扁平化到工具的输入 Schema 中

  • 数组主体:正确处理数组 Schema 及其嵌套项定义

  • 必需属性:跟踪并保留哪些参数和属性是必需的


开发者信息

面向开发者

开发工具

  • npm run build - 构建 TypeScript 源代码

  • npm run clean - 移除构建产物

  • npm test - 运行 Vitest 测试套件

  • npm run typecheck - 运行 TypeScript 类型检查

  • npm run lint - 对 src/**/*.ts 运行类型感知的 ESLint 检查

  • npm 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 特意采用类型感知检查,所有源文件都应无警告通过。

开发工作流程

  1. 克隆仓库

  2. 安装依赖:npm install

  3. 启动开发环境:npm run inspect-watch

  4. 修改 src/ 中的 TypeScript 文件

  5. 服务器将自动重新构建并重启

参与贡献

  1. Fork 仓库

  2. 创建功能分支

  3. 进行您的修改

  4. 运行构建、测试、类型检查和代码检查:npm run build && npm test && npm run typecheck && npm run lint

  5. 提交拉取请求

📖 有关全面的开发者文档,请参阅 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 具有过期令牌、需要刷新令牌,或需要静态标头无法处理的复杂认证逻辑时,请使用它。

问:如何过滤要加载的工具? 答:使用 --tool、--tag、--exclude-tag、--resource 和 --operation 标志配合 --tools all(默认值);设置 --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 请求指定自定义标头? 答:对于 CLI 用法,使用 --headers 标志或 API_HEADERS 环境变量,以逗号分隔的 key:value 对。对于库用法,使用 headers 配置选项,或实现 AuthProvider 以提供动态标头。

问:支持哪些传输方法? 答:服务器支持用于与 AI 系统集成的 stdio 传输(默认)以及用于 Web 客户端的 HTTP 传输(通过 SSE 进行流式传输)。

问:服务器如何处理带有引用的复杂 OpenAPI Schema? 答:服务器会完全解析参数和 Schema 中的 $ref 引用,保留嵌套结构、默认值和其他属性。有关引用解析和 Schema 组合的详细信息,请参阅"OpenAPI Schema 处理"部分。

问:当参数名称与请求体属性冲突时会发生什么? 答:服务器会检测命名冲突,并自动为请求体属性名称添加 body_ 前缀以避免冲突,确保所有属性都可访问。

问:我可以打包我的 MCP 服务器进行分发吗? 答:可以!使用库方式时,您可以为您的 API 创建专用的 npm 包。有关完整实现,请参阅 Beatport 示例,该示例可打包并作为 npx your-api-mcp-server 分发。

问:在哪里可以找到开发和贡献指南? 答:请参阅 开发者指南,其中包含有关架构、关键概念、开发工作流程和贡献指南的全面文档。

许可证

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Exposes REST API endpoints defined in an OpenAPI Specification as MCP tools, allowing AI models to call them via the ModelContext Protocol.
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Exposes any REST API as MCP tools, enabling AI agents to discover and call existing HTTP endpoints without modifying the original API.
    -