HTTP API转MCP工具桥接器

一个配置驱动的CLI工具,无需编码即可将外部HTTP API暴露为MCP工具,支持多种认证方式和响应转换。

  • by future-fantasy-org
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 future-fantasy-org/mcp-live-bridge

使用说明

mcp活桥

配置驱动的CLI,将外部HTTP API作为MCP工具公开。

mcp live bridge读取描述HTTP端点的配置文件,并自动将其公开为 模型上下文协议(MCP) 通过Streamable HTTP传输工具。不需要per-API编码-在YAML/JSON/TOML中定义您的端点,它们将成为可调用的MCP工具。

特性

  • 零代码工具创建 --在配置中定义HTTP端点,立即获取MCP工具
  • 灵活的身份验证系统 --内置Form和OAuth2提供程序,以及自定义提供程序支持
  • 模板引擎 --基于Handlebars的URL、查询、正文和标头的参数映射
  • 响应转换 --JSONPath提取和Handlebars模板格式化
  • 多格式配置 --YAML、JSON或TOML
  • 身份验证生命周期管理 --401上的自动令牌刷新、轮询验证和重试
  • 每次会话传输 --每个MCP客户端都有自己的传输实例,支持多个同时连接
  • 调试日志 --可配置的日志级别(quiet, default, verbose, debug)具有请求/响应详细信息跟踪功能
  • OpenAPI导入 --根据OpenAPI/Swagger规范生成网桥配置
  • 交互式初始化 --引导式配置生成向导
  • 可流式HTTP传输 --使用带有流式HTTP的官方MCP SDK
  • CLI接口 — start, validate, list, init,以及 import 命令

快速开始

安装

npm install -g mcp-live-bridge

或者从源代码构建:

git clone https://github.com/<your-org>/mcp-live-bridge.git
cd mcp-live-bridge
npm install
npm run build

创建配置文件

# bridge-config.yaml
name: my-api-bridge
server:
  port: 8090

auth:
  provider: form
  config:
    login_url: https://api.example.com/login
    username: your-username
    password: your-password

tools:
  - name: list_users
    description: "List all users"
    url: https://api.example.com/users
    method: GET

  - name: get_user
    description: "Get a user by ID"
    url: https://api.example.com/users/{{params.id}}
    method: GET
    parameters:
      id:
        type: integer
        required: true
        description: "User ID"
        location: path

启动服务器

mcp-live-bridge start -c bridge-config.yaml

MCP服务器现在正在侦听 http://localhost:8090.

使用克劳德桌面/IDE进行配置

添加到您的MCP客户端配置中(例如,Claude Desktop claude_desktop_config.json):

{
  "mcpServers": {
    "my-api-bridge": {
      "url": "http://localhost:8090/mcp",
      "headers": {}
    }
  }
}

CLI命令

# Start the MCP server
mcp-live-bridge start -c <config-file> [options]

Options:
  -p, --port <number>   Override server port
  --verbose             Verbose logging (can also be set via server.log_level in config)
  --quiet               Errors only

# Validate config file without starting
mcp-live-bridge validate -c <config-file>

# List all tools defined in config
mcp-live-bridge list -c <config-file>

# Interactive config generation wizard
mcp-live-bridge init

# Specify output file
mcp-live-bridge init -o my-config.yaml

# Import from OpenAPI spec
mcp-live-bridge import -u https://api.example.com/openapi.json -n my-bridge

# Import from local file
mcp-live-bridge import -f ./openapi.yaml -n my-bridge -o config.yaml

配置参考

完整配置架构

name: bridge-name                    # Required: Bridge instance name
version: "1.0"                      # Optional: Config format version (default: "1.0")

server:                             # Optional: Server settings
  host: 0.0.0.0                     # Default: 0.0.0.0
  port: 8080                        # Default: 8080
  cors_origin: "*"                  # Default: "*"
  cors_allow_headers:               # Default: Content-Type, Authorization, MCP-Session-Id, Mcp-Protocol-Version
    - Content-Type
    - Authorization
    - MCP-Session-Id
    - Mcp-Protocol-Version
  cors_allow_methods:               # Default: GET, POST, DELETE, OPTIONS
    - GET
    - POST
    - DELETE
    - OPTIONS
  cors_expose_headers:              # Default: MCP-Session-Id, Mcp-Protocol-Version
    - MCP-Session-Id
    - Mcp-Protocol-Version
  timeout: 30000                    # Request timeout in ms (default: 30000)
  log_level: default                # "quiet" | "default" | "verbose" | "debug" (default: "default")

auth:                               # Required: Authentication config
  provider: form                    # Built-in: "form" | "oauth2" | path to custom .mjs
  config: {}                        # Provider-specific config
  validation: {}                    # Optional: Auth validation
  refresh: {}                       # Optional: Refresh strategy

headers:                            # Optional: Global default headers
  Content-Type: application/json

tools:                              # Required: Array of tool definitions
  - name: tool_name                 # Required: Tool name (unique)
    description: "Tool description" # Required: Tool description
    url: https://api.example.com    # Required: Full endpoint URL
    method: GET                     # Required: HTTP method
    headers: {}                     # Optional: Tool-level headers (merged with global)
    body: ""                        # Optional: Request body template (string or object)
    content_type: ""                # Optional: Content-Type override
    parameters: {}                  # Optional: Parameter definitions
    response: {}                    # Optional: Response transformation

刀具参数

每个参数都支持以下字段:

字段 类型 必填 描述
type string 是 string, number, integer, boolean, array, object
required boolean 否 参数是否为必填项(默认值:推断自 default)
default any 否 默认值
description string 否 参数说明
location string 是 path, query, body, header
enum string[] 否 允许的值

参数通过以下方式注入模板 {{params.<name>}}.

请求正文

这个 body 字段支持两种格式:

字符串模板 (原始,仍受支持):

body: '{"username": "{{params.username}}", "email": "{{params.email}}"}'

对象定义 (推荐):

body:
  username: "{{params.username}}"
  email: "{{params.email}}"
  role: admin          # Static values are preserved as-is
  count: "{{params.n}}" # Rendered as string

对象基于以下内容进行序列化 content_type:

content_type 序列化
application/json (默认) JSON.stringify
application/x-www-form-urlencoded key=value&key2=value2

URL编码示例:

content_type: application/x-www-form-urlencoded
body:
  username: "{{params.username}}"
  password: "{{params.password}}"

JSON支持嵌套对象,URL编码时会自动展开嵌套对象:

body:
  user:
    name: "{{params.name}}"
    email: "{{params.email}}"

响应转换

tools:
  - name: search
    url: https://api.example.com/search?q={{params.query}}
    method: GET
    response:
      extract: "$.results[*]"         # JSONPath expression to extract data
      template: "{{#each this}}{{name}}: {{url}}\n{{/each}}"  # Handlebars template
  • 提取:JSONPath表达式,用于提取响应的子集
  • 模板:Handlebars模板,用于格式化提取的数据

如果省略,则返回原始JSON响应。

自定义处理程序工具

对于单个工具需要调用多个HTTP端点的场景,您可以使用 type: handler 要定义自定义处理程序脚本,请执行以下操作:

tools:
  # Standard HTTP tool (default)
  - name: get_user
    url: https://api.example.com/users/{{params.id}}
    method: GET

  # Custom handler tool
  - name: create_user_and_profile
    type: handler
    handler: ./tools/create-user-and-profile.mjs
    description: "Create a user and fetch their profile"
    parameters:
      username:
        type: string
        required: true
        description: "Username for the new account"
        location: handler
      email:
        type: string
        required: true
        description: "Email for the new account"
        location: handler
      password:
        type: string
        required: true
        description: "Password for the new account"
        location: handler

处理程序是一个具有默认导出功能的ESM模块。它接收 params 和一个 context 对象:

// tools/create-user-and-profile.mjs
export default async function(params, ctx) {
  const { http, auth, logger } = ctx;

  // Step 1: Create user
  const user = await http.post('https://api.example.com/users', {
    headers: auth,
    body: { username: params.username, email: params.email, password: params.password },
  });

  // Step 2: Fetch profile using the returned ID
  const profile = await http.get(`https://api.example.com/users/${user.id}/profile`, {
    headers: auth,
  });

  return { user, profile };
}

可用上下文属性:

属性 描述
http.get(url, opts?) GET请求,自动解析JSON响应
http.post(url, opts?) POST请求;主体通过以下方式转换为字符串 String(),自动解析JSON响应
http.put(url, opts?) PUT请求;主体通过以下方式转换为字符串 String(),自动解析JSON响应
http.delete(url, opts?) DELETE请求,自动解析JSON响应
http.request(req) 原始请求(返回 { status, body, headers })
auth 当前认证报头(例如。, { Authorization: "Bearer ..." })
config auth.config 配置文件中的值
logger 记录器实例(info, debug, warn, error)

全部 http.* 方法接受选项对象: { headers?, body?, params? }The params 字段将查询参数附加到URL body 字段接受任何类型,并通过以下方式转换为字符串 String() 在发送之前。这个 Content-Type 标题是 不 自动设置——您必须通过以下方式自行设置 headers 并适当地对主体进行序列化。

更多示例:

// Form-encoded POST
export default async function(params, ctx) {
  const result = await ctx.http.post('https://api.example.com/login', {
    headers: { 'Content-Type': 'application/x-www-form-urlencoded', ...ctx.auth },
    body: `username=${encodeURIComponent(params.username)}&password=${encodeURIComponent(params.password)}`,
  });
  return result;
}
// JSON POST (explicit serialization and Content-Type)
export default async function(params, ctx) {
  const result = await ctx.http.post('https://api.example.com/users', {
    headers: { 'Content-Type': 'application/json', ...ctx.auth },
    body: JSON.stringify({ name: params.name, email: params.email }),
  });
  return result;
}
// Paginated fetching
export default async function(params, ctx) {
  const { http, auth, logger } = ctx;
  let page = 1;
  const allResults = [];
  while (true) {
    const res = await http.get('https://api.example.com/search', { headers: auth, params: { q: params.query, page } });
    allResults.push(...res.results);
    if (res.results.length < 20) break;
    page++;
  }
  return { total: allResults.length, results: allResults };
}

认证

内置:表单提供者

基于Cookie的身份验证(发布凭据,从中提取Cookie Set-Cookie 头球

auth:
  provider: form
  config:
    login_url: https://api.example.com/login
    login_method: POST               # Default: POST
    login_body: '{"user":"{{username}}","pass":"{{password}}"}'  # Optional: JSON body template
    login_headers: {}                # Optional: Extra login headers
    username: your-username
    password: your-password

如果 login_body 省略,凭据将以以下方式发送 application/x-www-form-urlencoded.

内置:OAuth2提供程序

auth:
  provider: oauth2
  config:
    token_url: https://api.example.com/oauth/token
    client_id: your-client-id
    client_secret: your-client-secret
    grant_type: client_credentials   # "authorization_code" | "client_credentials"
    # For authorization_code:
    authorization_url: https://api.example.com/oauth/authorize
    redirect_uri: http://localhost:8090/callback
    scopes:
      - read
      - write

自定义身份验证提供程序

编写一个ESM模块,使用以下方法导出一个类:

// my-auth-provider.mjs
export default class MyAuthProvider {
  async init(config) { /* Called with auth.config */ }
  async getAuthHeaders() { /* Return headers object, e.g., { Authorization: "Bearer ..." } */ }
  async isValid() { /* Return boolean */ }
  async refresh() { /* Re-authenticate */ }
  async dispose() { /* Cleanup */ }
  async getAuthContext() { /* Optional: return auth metadata */ }
}

然后在配置中引用它:

auth:
  provider: ./my-auth-provider.mjs
  config:
    token_url: https://api.example.com/token
    api_key: your-api-key

看 examples/jwt-auth-provider.mjs 查看完整的JWT示例。

身份验证和刷新

身份验证系统提供了两种机制来保持凭据有效:

  1. 主动轮询 --定期调用验证端点以检查凭据是否仍然有效,并在过期前主动刷新
  2. 反应式刷新 --当工具调用收到401响应时,会自动刷新凭据并重试请求
auth:
  provider: form
  config:
    login_url: https://api.example.com/login
    username: user
    password: pass

  validation:                        # Optional: Auth health check endpoint
    check_url: https://api.example.com/me
    check_method: GET                # Default: GET (or POST if check_body is set)
    check_headers: {}                # Optional: Extra headers for the check request
    check_body: ""                   # Optional: Request body (switches method to POST)
    valid_when:
      status: 200                    # Expected HTTP status code
      # jsonpath_not_exists: "$.expired"   # Optional: JSONPath that must not exist
      # jsonpath_equals:               # Optional: JSONPath value assertions
      #   "$.active": true
      # json_match:                    # Optional: Regex match on response body
      #   pattern: ".*ok.*"

  refresh:                           # Refresh behavior
    on_failure: true                 # Auto-refresh on 401 (default: true)
    retry_count: 3                   # Max retries on refresh failure (default: 3)
    retry_delay: 5                   # Seconds between retries (default: 5)
    poll_interval: 300               # Proactive: validate every N seconds (optional, disabled by default)

它是如何工作的:

触发器 行为
poll_interval 已设置 每N秒调用一次 validation.check_url 使用当前身份验证标头。如果检查失败,则触发 refresh()
工具调用返回401 自动调用 refresh() 并重试请求(最多 retry_count + 1 时间)
没有 validation defined 返回到 provider.isValid() 投票(如果 poll_interval 已设置)
没有 poll_interval 投票功能已禁用;刷新仅在401上被动发生

例子

请参阅 examples/ 完整工作示例目录:

建筑

┌──────────────────────────────────────────────────────┐
│                    mcp-live-bridge                   │
│                                                      │
│  ┌──────────┐   ┌──────────────┐   ┌──────────────┐ │
│  │  Config   │──>│ Tool Registry │──>│ MCP Server   │ │
│  │  Loader   │   │              │   │ (per-session)│ │
│  └──────────┘   └──────┬───────┘   └──────┬───────┘ │
│                        │                    │        │
│                        v                    v        │
│  ┌─────────────────────────────────────────────────┐ │
│  │              Request Pipeline                   │ │
│  │  Auth Headers -> Template -> HTTP -> Transform  │ │
│  └─────────────────────────────────────────────────┘ │
│                                                      │
│  ┌─────────────────────────────────────────────────┐ │
│  │           Auth Lifecycle Manager                │ │
│  │  Init -> Poll Validate -> Refresh on 401/fail  │ │
│  └─────────────────────────────────────────────────┘ │
│                                                      │
│  ┌─────────────────────────────────────────────────┐ │
│  │  Session Manager (per-client transport)         │ │
│  │  New transport per session -> route by session  │ │
│  └─────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────┘

发展

# Install dependencies
npm install

# Build
npm run build

# Run in watch mode
npm run dev

# Run tests
npm test

# Validate a config file
node dist/index.js validate -c examples/jwt-service-config.yaml

# List tools in a config
node dist/index.js list -c examples/jwt-service-config.yaml

需求

  • Node.js>=20

许可证

麻省理工学院