Skip to main content
Glama
hxhy00

SwaggerWatcher MCP Server

by hxhy00
README.md
# 👁️ SwaggerWatcher

**给你的 AI Agent 装上实时 API 感知能力——自动发现 OpenAPI 文档,所有接口即时变成可调用的 MCP 工具。**

[![Python 3.11+](https://img.shields.io/badge/Python-3.11+-3776AB?style=for-the-badge&logo=python&logoColor=white)](https://python.org)
[![MCP Server](https://img.shields.io/badge/MCP-Server-5C3EE8?style=for-the-badge)](https://modelcontextprotocol.io)
[![MIT License](https://img.shields.io/badge/License-MIT-blue?style=for-the-badge)](LICENSE)
[![GitHub Stars](https://img.shields.io/github/stars/huixiaheyu/swagger-mcp?style=for-the-badge)](https://github.com/huixiaheyu/swagger-mcp/stargazers)

[English](README.en.md) · [快速开始](#快速开始) · [能力一览](#能力一览) · [动态模式](#动态模式) · [设计理念](#设计理念) · [配置参考](#配置参考) · [对比](#与现有方案对比)

---

## 💡 为什么需要 SwaggerWatcher?

**问题**:AI Agent 要调用你的后端 API,通常需要手动把每个接口注册成工具。接口一改,工具定义就得同步更新。在快速迭代的项目里,这几乎不可维护。

**方案**:SwaggerWatcher 充当一个 **MCP 网关**——读取你的 OpenAPI/Swagger 文档,把所有接口自动注册为 AI 可调用的工具。配置一次,后续接口变更自动同步:

```
你写 OpenAPI 文档           →    SwaggerWatcher 自动读取
                                  ↓
后端新增/修改接口            →    轮询检测到变更 + 增量 Diff
                                  ↓
AI Agent 自动获得新工具      ←    热重载通知
```

### ✅ 在你用之前,你可能想知道

- 🤔 **"我没用过 MCP,能用吗?"** → 能。SwaggerWatcher 是标准 MCP Server,支持所有 MCP 客户端(Cursor、Claude Desktop、WorkBuddy、Windsurf 等)。只需配好 `config.yaml`,一行命令启动。
- 🔒 **"API 有认证怎么办?"** → 支持 Bearer Token、API Key、自定义 Header。拉文档的认证和调接口的认证分开配置。
- 📊 **"接口太多了(几百个)怎么办?"** → `dynamic` 模式让 AI 自己按需切换工具组;或用 `include_tags` / `exclude_tags` 精确过滤;或用 `max_tools` 自动按热度筛选。

---

## ✨ 能力一览

| 能力 | 说明 |
|------|------|
| **自动发现** | 给个 OpenAPI URL 或文件路径,所有 endpoint 自动变成 MCP Tool |
| **变更检测** | 定时轮询,SHA-256 哈希比对,发现增/删/改 |
| **热重载** | 变更后自动更新工具列表,通知已连接的 MCP 客户端 |
| **语义 Diff** | 日志清晰输出:`+ 新增`、`- 移除`、`~ 变更` |
| **\$ref 解析** | 递归展开 JSON Reference,AI 看到完整参数结构 |
| **参数全支持** | 路径参数 / 查询参数 / 请求头 / 请求体 |
| **认证隔离** | 拉取文档的认证 vs 调用 API 的认证分开配置 |
| **动态模式** | AI 通过 `_list_groups` / `_activate_groups` 自主切换工具组 |
| **标签过滤** | 白名单 / 黑名单 / 自动按接口热度筛选 |
| **多 API 聚合** | 一个实例同时监听多个后端 |
| **轻量** | Python 3.11+,仅三个依赖(mcp + httpx + pyyaml) |

---

## 🚀 快速开始

### 1️⃣ 安装

```bash
pip install git+https://github.com/huixiaheyu/swagger-mcp.git
```

或从源码:

```bash
git clone https://github.com/huixiaheyu/swagger-mcp.git
cd swagger-mcp
pip install -e .
```

### 2️⃣ 配置

创建 `config.yaml`:

```yaml
servers:
  - name: petstore
    openapi_url: "https://petstore3.swagger.io/api/v3/openapi.json"
    base_url: "https://petstore3.swagger.io/api/v3"
    poll_interval: 300  # 秒
```

### 3️⃣ 运行

```bash
swagger-mcp config.yaml
# 或通过环境变量
export SWAGGER_MCP_CONFIG=config.yaml
swagger-mcp
```

看到 `Loaded 19 tools from 'petstore'` 即启动成功。

### 4️⃣ (可选)查看标签组

```bash
swagger-mcp config.yaml --list-tags
```

> 💡 **默认 5 分钟轮询一次**。接口变了不需要重启,SwaggerWatcher 自动检测、增量更新、通知 AI 客户端。

---

## 🔧 配置参考

<details>
<summary><b>config.yaml</b> 完整字段(点击展开)</summary>

```yaml
servers:
  - name: my-api                # 服务名(工具名前缀)
    openapi_url: "https://..."  # OpenAPI 文档 URL
    # openapi_file: "./spec.yaml"  # 或本地文件路径
    base_url: "https://..."     # API 调用基础 URL
    mode: dynamic               # static(默认)| dynamic
    # --- 过滤选项(全部可选) ---
    max_tools: 150              # 自动选接口最多的标签组,不超过此数
    # include_tags:             # 白名单
    #   - sys-user
    # exclude_tags:             # 黑名单
    #   - gen-controller
    spec_headers:               # 拉取文档时的认证头
      Authorization: "Bearer xxx"
    api_headers:                # 每次 API 调用自动注入
      api-key: "sk-xxx"
      X-Tenant-Id: "tenant-01"
    poll_interval: 300          # 轮询间隔(秒),0 关闭
```

| 字段 | 必需 | 默认值 | 说明 |
|------|------|--------|------|
| `name` | 是 | — | 服务标识,用于工具名前缀 |
| `openapi_url` | 否* | — | OpenAPI 文档 URL |
| `openapi_file` | 否* | — | 本地文件路径 |
| `base_url` | 是 | — | API 请求的 Base URL |
| `mode` | 否 | `static` | 运行模式 |
| `max_tools` | 否 | 0(不限) | 自动保留热度最高的 N 个标签组 |
| `include_tags` | 否 | — | 白名单 |
| `exclude_tags` | 否 | — | 黑名单 |
| `spec_headers` | 否 | `{}` | 拉取文档的 HTTP 头 |
| `api_headers` | 否 | `{}` | API 调用的 HTTP 头 |
| `poll_interval` | 否 | `300` | 轮询间隔(秒) |

*\* `openapi_url` 和 `openapi_file` 至少填一个。*
</details>

### 环境变量

- `SWAGGER_MCP_CONFIG` — 配置文件路径(默认 `config.yaml`)

---

## 🤖 动态模式

当 API 接口超过模型限制(通常 200+),设置 `mode: dynamic` 让 AI 自己管理工具上下文:

```yaml
servers:
  - name: ruoyi
    openapi_url: "https://..."
    mode: dynamic
```

启动后,AI 看到两个额外的控制工具:

| 工具 | 作用 |
|------|------|
| `_list_groups` | 列出所有 OpenAPI 标签组及接口数量 |
| `_activate_groups` | 切换到指定标签组,触发工具列表刷新 |

**工作流程**:

```
你:查一下 admin 这个用户
AI:
  1. 看到当前工具不覆盖用户管理模块
  2. 调用 _list_groups() → sys-user-controller(14), auth-controller(7)
  3. 调用 _activate_groups(["sys-user-controller"])
  4. 收到 tool_list_changed → 工具列表刷新
  5. 调用 ruoyi_list({...}) → 查到用户信息
```

**关键特性**:
- 启动时只加载最大标签组(通常 10-30 个工具),避免直接超限
- AI 自主按需切换模块,不需要人工配置
- 单进程实现,不依赖多 MCP Server 实例
- `static` 模式下同样支持 `max_tools` / `include_tags` / `exclude_tags`

---

## 🔌 MCP 客户端集成

### Cursor / Windsurf / Claude Desktop

```json
{
  "mcpServers": {
    "swagger-mcp": {
      "command": "python",
      "args": ["-m", "swagger_mcp", "/path/to/config.yaml"]
    }
  }
}
```

> **注意**:尚未发布到 PyPI,通过 GitHub 安装:`pip install git+https://github.com/huixiaheyu/swagger-mcp.git`

### WorkBuddy

加到 `~/.workbuddy/mcp.json`:

```json
{
  "mcpServers": {
    "swagger-mcp": {
      "command": "/path/to/venv/bin/python",
      "args": ["-m", "swagger_mcp", "/path/to/config.yaml"]
    }
  }
}
```

### 任意 MCP 客户端

```bash
python -m swagger_mcp /path/to/config.yaml
```

---

## 🏗️ 架构说明

```
┌──────────┐     ┌──────────────────────────────────────┐
│   MCP    │     │          SwaggerWatcher              │
│  Client  │────▶│                                      │
│ (Cursor, │     │  ┌─────────┐  ┌──────────┐          │
│  AI IDE) │     │  │  Spec   │──▶  Tools   │          │
│          │     │  │ Loader  │  │ Registry │          │
│          │     │  │(URL/文件)│  │($ref 展开)│         │
│          │     │  └────┬────┘  └────┬─────┘          │
│          │     │       │            │                 │
│          │     │  ┌────▼────────────▼──────┐          │
│          │     │  │    Change Detector      │          │
│          │     │  │  (SHA-256 哈希 + Diff)   │          │
│          │     │  └───────────┬────────────┘          │
│          │     │              │ 热重载通知             │
│          │     │  ┌───────────▼──────────┐            │
│          │     │  │     API Proxy        │            │
│          │◀────│  │  (httpx → 后端)      │            │
└──────────┘     └──────────────────────────────────────┘
```

四个核心组件:

1. **Spec Loader** — 从 URL 或本地文件拉取 OpenAPI 文档,自动识别 JSON/YAML
2. **Tool Registry** — 遍历 `paths.{path}.{method}` 生成 MCP Tool 定义,递归展开 `$ref`
3. **Change Detector** — 后台定时轮询 SHA-256 哈希,发现变更做增量 diff
4. **API Proxy** — LLM 调用工具时重构 HTTP 请求,代理到后端

### 工具命名规则

优先 `operationId`,没有时自动生成:

```
<服务名>_<operationId>
<服务名>_<方法>__<路径分段>
```

| OpenAPI | 生成的工具名 |
|---------|-------------|
| `operationId: getPetById` | `petstore_getPetById` |
| `operationId: updatePet` | `petstore_updatePet` |
| 无 operationId,`GET /pet/{petId}` | `petstore_get__pet__petId` |

### 变更检测示例

```
[INFO] + added tools: petstore_createUser, petstore_deleteOrder
[INFO] - removed tools: petstore_deprecatedMethod
[INFO] ~ changed tools: petstore_getPetById
```

---

## 🎯 设计理念

1. **配置即文档** — OpenAPI 本身就是最权威的接口文档,不需要再维护一套工具定义
2. **实时同步** — 后端接口变了,AI 应该立刻知道,不需要人工介入
3. **认证隔离** — 获取文档的权限 ≠ 调用 API 的权限,分开配置
4. **增量优先** — 变了一个接口,只更新那一个,不是全量重启
5. **零信任代理** — 所有请求走代理层,鉴权、限流、审计在这一层集中治理
6. **AI 自主管理工具上下文** — 接口超限时,AI 自己决定需要哪些模块

---

## 📦 开发指南

```bash
git clone https://github.com/huixiaheyu/swagger-mcp.git
cd swagger-mcp
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

# 端到端测试
python test_e2e.py
```

### 项目结构

```
swagger-mcp/
├── pyproject.toml              # 项目元信息 + 依赖
├── config.yaml                 # 默认配置示例
├── config.local.yaml           # 本地开发配置(不进 Git)
├── mcp-config.json             # WorkBuddy 集成模板
├── test_e2e.py                 # 端到端测试
├── README.md                   # 本文档
├── README.en.md                # 英文文档
└── src/swagger_mcp/
    ├── __init__.py
    ├── __main__.py             # CLI 入口
    ├── server.py               # MCP 服务器 + 轮询
    ├── loader.py               # 文档加载器
    ├── registry.py             # OpenAPI → MCP 工具 + Diff
    └── proxy.py                # HTTP 代理
```

---

## ⚖️ 与现有方案对比

| 方案 | 技术栈 | 远程 URL 检测 | 变更 diff | 工具超限处理 | 热重载 |
|------|--------|:------------:|:---------:|:-----------:|--------|
| **SwaggerWatcher** | Python | ✅ 定时轮询 | ✅ 增/删/改 | ✅ dynamic / 标签过滤 | 增量 + 通知 |
| Infobip OpenAPI MCP | Java 21 | ✅ cron 轮询 | ✅ 增/删/改 | ❌ 全注册 | 增量 |
| mcp-swagger-server | Node.js | ❌ 仅本地 | ❌ 全量重启 | ❌ 全注册 | File watch |
| EasyMCP | Python | ❌ 手动 reload | ❌ 全量重载 | ❌ 全注册 | File watch |
| mcp-reloader | Node.js | 取决于 wrapped | ❌ 全量重启 | ❌ 全注册 | File watch |

**SwaggerWatcher 是目前唯一同时满足以下四点的轻量方案**:
- ✅ 不绑定 Java/Spring 生态
- ✅ 远程 OpenAPI URL 自动变更检测
- ✅ 增/删/改语义 diff + 热重载通知
- ✅ 工具超限处理:dynamic / 标签过滤 / 热度筛选

---

## License

MIT