SwaggerWatcher MCP Server
An MCP server that dynamically reads OpenAPI specs and registers every endpoint as an LLM-callable tool with automatic change detection and hot reload.
README
SwaggerWatcher MCP Server
<div align="center">
Give AI agents real-time access to your APIs via Swagger/OpenAPI — with automatic change detection and hot reload.
</div>
SwaggerWatcher is an MCP server that dynamically reads OpenAPI (Swagger) specifications and registers every endpoint as an LLM-callable tool. Point it at your API docs, and the AI can discover, understand, and call your APIs without any manual configuration.
Why This Exists
Problem: To let AI agents (Cursor, Claude, WorkBuddy, etc.) call your backend APIs, you typically need to manually register every endpoint as a tool. When your API changes, you must update the tool definitions — a maintenance burden that doesn't scale.
Solution: SwaggerWatcher acts as an MCP gateway — it reads your OpenAPI spec once and keeps itself in sync:
Write OpenAPI docs → SwaggerWatcher reads them
↓
API changes on backend → Polling detects the diff
↓
AI gets updated tools ← Hot-reload notification
Zero manual registration. Zero drift between docs and tools.
Features
- Auto-discovery — Drop an OpenAPI URL or file path; every endpoint becomes a tool
- Change detection — Polls your spec at a configurable interval; detects additions, removals, and schema changes
- Hot reload — On spec change, updates the tool list and notifies connected MCP clients (
send_tool_list_changed) - Automatic diff logging — Logs exactly what changed:
+ added,- removed,~ changed $refresolution — Resolves JSON References inline so LLMs see full object schemas- Full parameter support — Path params, query strings, headers, and request bodies
- Configurable auth — Per-spec headers for loading protected docs, per-API headers for making authenticated calls
- Dynamic mode — AI self-manages tool groups via
_list_groups/_activate_groupsto stay within model limits - Tag filtering —
include_tags,exclude_tags, ormax_tools(auto-select by popularity) - Tag discovery —
--list-tagsCLI flag prints all tag groups with endpoint counts - Multi-API ready — Config supports multiple servers in one instance
- Lightweight — Python 3.11+, two dependencies (
mcp,httpx,pyyaml)
Quick Start
1. Install
pip install git+https://github.com/huixiaheyu/swagger-mcp.git
Or from source:
git clone https://github.com/huixiaheyu/swagger-mcp.git
cd swagger-mcp
pip install -e .
2. Configure
Create config.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 # seconds between checks
3. Run
swagger-mcp config.yaml
4. (Optional) Discover tags
swagger-mcp config.yaml --list-tags
Prints all OpenAPI tags with endpoint counts — useful when configuring filters.
Configuration Reference
config.yaml
servers:
- name: my-api # Server name (used as tool name prefix)
openapi_url: "https://..." # Remote OpenAPI spec URL
# openapi_file: "./spec.yaml" # Or local file path
base_url: "https://..." # Base URL for API calls
mode: dynamic # Operation mode: static (default) | dynamic
# --- Filter options (all optional) ---
max_tools: 150 # Auto-select top tags by endpoint count
# include_tags: # Whitelist: only these tags
# - sys-user
# exclude_tags: # Blacklist: skip these tags
# - gen-controller
spec_headers: # Headers for fetching the spec
Authorization: "Bearer xxx"
api_headers: # Headers injected into every API call
api-key: "sk-xxx"
poll_interval: 300 # Change detection interval (seconds)
| Field | Required | Default | Description |
|---|---|---|---|
name |
Yes | — | Used as tool name prefix |
openapi_url |
No* | — | URL to OpenAPI spec (JSON or YAML) |
openapi_file |
No* | — | Local path to OpenAPI spec |
base_url |
Yes | — | Base URL for outgoing API requests |
mode |
No | static |
Operation mode: static (fixed tools) or dynamic (AI switches groups) |
max_tools |
No | 0 (unlimited) | Auto-select top N tag groups by endpoint count |
include_tags |
No | — | Whitelist: only register endpoints with these tags |
exclude_tags |
No | — | Blacklist: skip endpoints with these tags |
spec_headers |
No | {} |
HTTP headers for fetching the spec |
api_headers |
No | {} |
HTTP headers injected into every API call |
poll_interval |
No | 300 |
Polling interval in seconds (0 to disable) |
*One of openapi_url or openapi_file is required.
Environment variable
SWAGGER_MCP_CONFIG— Path to config file (default:config.yaml)
Dynamic Mode
When your API has hundreds of endpoints exceeding model tool limits, set mode: dynamic so the AI manages its own tool context:
servers:
- name: my-api
openapi_url: "https://..."
mode: dynamic
The server exposes two control tools that are always available:
| Tool | Purpose |
|---|---|
_list_groups |
List all OpenAPI tags with endpoint counts |
_activate_groups |
Switch to specific tag groups, triggers tool_list_changed |
How it works:
User: "Find user admin"
AI:
1. Sees current tools don't cover user management
2. Calls `_list_groups()` → sees sys-user-controller(14), auth-controller(7)
3. Calls `_activate_groups(["sys-user-controller"])`
4. Receives tool_list_changed → tool list refreshes
5. Calls the actual API: ruoyi_list({...}) → returns user data
Key benefits:
- Starts with a single tag group (~10-30 tools), avoiding the initial limit
- AI autonomously switches modules as needed — zero manual config
- Single process, no need for multiple MCP server instances
- In
staticmode,max_tools/include_tags/exclude_tagsare still available
MCP Client Integration
Cursor / Windsurf / Claude Desktop
Add to your MCP config:
{
"mcpServers": {
"swagger-mcp": {
"command": "python",
"args": ["-m", "swagger_mcp", "/path/to/config.yaml"]
}
}
}
Note:
swagger-mcpis not available on PyPI yet. Install via:pip install git+https://github.com/huixiaheyu/swagger-mcp.git
WorkBuddy
Add to ~/.workbuddy/mcp.json:
{
"mcpServers": {
"swagger-mcp": {
"command": "/path/to/venv/bin/python",
"args": ["-m", "swagger_mcp", "/path/to/config.yaml"]
}
}
}
Any MCP client
Run via stdio:
# If installed from GitHub
python -m swagger_mcp /path/to/config.yaml
# If running from source
python -m swagger_mcp /path/to/config.yaml
Architecture
┌──────────┐ ┌──────────────────────────────────────┐
│ MCP │ │ SwaggerWatcher Server │
│ Client │────▶│ │
│ (Cursor, │ │ ┌─────────┐ ┌──────────┐ │
│ WorkBuddy│ │ │ Spec │──▶ Tools │ │
│ etc.) │ │ │ Loader │ │ Registry │ │
│ │ │ │(URL/File)│ │($ref □) │ │
│ │ │ └────┬────┘ └────┬─────┘ │
│ │ │ │ │ │
│ │ │ ┌────▼────────────▼──────┐ │
│ │ │ │ Change Detector │ │
│ │ │ │ (SHA-256 hash, diff) │ │
│ │ │ └───────────┬────────────┘ │
│ │ │ │ hot reload │
│ │ │ ┌───────────▼──────────┐ │
│ │ │ │ API Proxy │ │
│ │◀────│ │ (httpx → backend) │ │
└──────────┘ │ └──────────────────────┘ │
└──────────────────────────────────────┘
- Spec Loader — Fetches OpenAPI specs from URL or local file (JSON/YAML auto-detect)
- Tool Registry — Parses every
paths.{path}.{method}→ MCPTooldefinition with full JSON Schema (including$refresolution) - Change Detector — Background poll loop computes SHA-256 hash of normalized spec; on mismatch, increments the diff and calls
send_tool_list_changed() - API Proxy — When the LLM calls a tool, reconstructs the HTTP request (path interpolation, query params, headers, body) and returns the response
How Tool Names Are Generated
Tools follow <server>_<operationId> (preferred) or <server>_<method>__<path_segments>:
| OpenAPI | MCP Tool Name |
|---|---|
operationId: getPetById |
petstore_getPetById |
operationId: updatePet (POST /pet) |
petstore_updatePet |
No operationId, GET /pet/{petId} |
petstore_get__pet__petId |
Change Detection Example
[+] added tools: petstore_createUser, petstore_deleteOrder
[-] removed tools: petstore_deprecatedMethod
[~] changed tools: petstore_getPetById
Development
git clone https://github.com/huixiaheyu/swagger-mcp.git
cd swagger-mcp
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
# Run tests
python test_e2e.py
File structure
swagger-mcp/
├── pyproject.toml
├── config.yaml
├── mcp-config.json # WorkBuddy integration template
├── test_e2e.py
└── src/swagger_mcp/
��── __init__.py
├── __main__.py # CLI entry point
├── server.py # MCP server + polling loop
├── loader.py # Spec loading (URL/file)
├── registry.py # OpenAPI → MCP tools + diff
└── proxy.py # HTTP request execution
Why This Exists
Most MCP-to-OpenAPI tools either:
- Require manual tool registration
- Don't detect spec changes (especially remote URLs)
- Are bound to a specific framework (Spring Boot, Semantic Kernel, etc.)
SwaggerWatcher is designed to be universal: any OpenAPI spec, any MCP client, automatic change tracking.
Comparison
| Tool | Stack | Remote URL polling | Semantic diff | Tool limit handling | Hot-reload |
|---|---|---|---|---|---|
| SwaggerWatcher | Python | ✅ Periodic | ✅ Add/remove/change | ✅ dynamic mode / tag filters | Incremental + notification |
| Infobip OpenAPI MCP | Java 21 | ✅ Cron-based | ✅ Add/remove/change | ❌ All registered | Incremental |
| mcp-swagger-server | Node.js | ❌ Local file only | ❌ Full restart | ❌ All registered | File watch + restart |
| EasyMCP | Python | ❌ Manual reload | ❌ Full reload | ❌ All registered | File watch |
| mcp-reloader | Node.js | Depends on wrapped server | ❌ Full restart | ❌ All registered | File watch + restart |
License
MIT
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。