# mcp-weaver **Repository Path**: fushoujiang/mcp-weaver ## Basic Information - **Project Name**: mcp-weaver - **Description**: mcp-weaver 是基于 Spring Boot 的 MCP(Model Context Protocol)网关:只靠配置就能把普通 REST API 变成 MCP 工具。每个业务域拥有独立的 Stateless Streamable HTTP MCP 端点,全部运行时管理——新增工具秒级生效,无需重建、无需重启。 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-09-21 - **Last Updated**: 2026-09-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: MCP, AI, AI网关 ## README # mcp-weaver

真实控制台、真实调用:选中 MySQL 支撑的织入工具 → 控制台试调用(92ms)→ 调用落审计(脱敏)。录制脚本见 docs/record-demo.mjs。
## 为什么选 mcp-weaver —— 一份诚实的对比 | | **mcp-weaver** | Higress | Spring AI Alibaba MCP | IBM ContextForge | |---|---|---|---|---| | 运行时 / 部署 | **单个 Spring Boot fat jar**,有 Java 就能跑 | Go + Envoy + Wasm(K8s 原生) | Spring Boot,以 Nacos 为中心 | Python,多服务组合 | | HTTP REST → MCP | ✅ OpenAPI 3 声明 + 批量导入 | ✅ | ✅ | ✅ | | **Dubbo → MCP** | ✅ **泛化调用,无需提供方 JAR**(2.7 / 3.x) | — | — | — | | 存量 MCP server 挂为**受治理上游** | ✅ stdio / Streamable HTTP / SSE,连接池 + 退避 + 自愈 | ✅ mcp-server 插件 | — | ✅ federation | | 管理控制台 | ✅ **内置零构建、中/英双语**,试调用、审计查看一体 | 独立 console 组件 | — | ✅ Admin UI | | 客户端认证 | ✅ API Key + JWT、scopes、**按 server 覆盖** | ✅ 插件化 | 基础能力 | ✅ | | 客户端限流 / 配额 | ✅ QPS + 并发在途 + 日配额,超限 429 + 审计事件 | ✅ | — | ✅ | | **审计追踪** | ✅ 调用 / 注册 / 凭证全事件,脱敏 + Token 哈希,MySQL / Langfuse,CSV 导出 | 偏 metrics / tracing | — | ✅ | | 配置存储 | ✅ MySQL **与** Nacos 可组合,SPI 可扩展 | Nacos / K8s CRD | Nacos | 可插拔 DB | | 热更新 | ✅ **事件驱动,写入毫秒级生效** | ✅ xDS | ✅ Nacos 推送 | ✅ | | 最适合谁 | 有存量 Spring / Dubbo / Nacos 系统的 Java 企业 | K8s 原生流量入口 | Spring AI Alibaba 用户 | Python 技术栈平台团队 | 「—」= 截至 2026-09 公开文档未见支持;如有出入,欢迎 PR 指正。 一句话:技术栈是 Java + Dubbo + Nacos 的组织,mcp-weaver 是按你的体质造的。 ## 60 秒一键体验 ```bash docker compose -f docker/docker-compose.demo.yml up ``` 自包含、零外网依赖:种子含 MySQL + 演示订单库 + 4 个织入的 MySQL 工具,调用在网关内部自环。 - **控制台** → `http://localhost:8080`,登录 `demo-admin` / `mwsec-demo-admin-key`(演示凭证,仅限本地体验) - **MCP 端点** → `http://localhost:8080/mysql-demo/mcp`,API Key `mcp-demo-agent-key`,Cursor / Claude / 任意 MCP 客户端直连 - 8080 被占?`MW_DEMO_PORT=18081 docker compose -f docker/docker-compose.demo.yml up` 更多搭建方式(手动播种 MySQL、普通 compose)见下方[快速开始](#快速开始)。 ## 特性 - **零代码织入工具** —— OpenAPI 3 规范声明(`in` / `schema` / `requestBody` / `responses`),自动生成 MCP schema 并代理调用 - **上游 MCP 聚合** —— 把存量 MCP server(stdio / Streamable HTTP / 旧 SSE)挂为上游,工具经网关代理输出:live-mount 自动派生到服务,或导入为持久化工具,详见 [docs/example-mcp-upstream.md](docs/example-mcp-upstream.md) - **三协议织入:HTTP + Dubbo + MCP** —— 工具声明 `protocol: dubbo` 经泛化调用接入 Dubbo 2.7/3.x 服务(**无需提供方 JAR**),声明 `protocol: mcp` 即代理已挂的上游 server,详见 [docs/example-dubbo.md](docs/example-dubbo.md) - **多端点** —— 每个配置的 server 暴露独立 `/{name}/mcp` Streamable HTTP 端点 - **热更新** —— 配置变更事件驱动:控制台 / REST 写入**立即生效**;直改表 ≤2 秒轮询感知。带字段级变更摘要 - **控制台 AI 助手** —— 登录后全页面悬浮球(可拖拽、位置记忆),点开即对话:回答项目问题与实时实例状态;LLM 配置三种改法(对话里发「设置 api-key …」、设置页卡片、env 兜底),存 `mcp_weaver_setting` 表**运行时生效**;未配置时本地兜底照常答实例状态 - **演进路线页** —— 控制台侧栏「演进路线」:时间线展示项目从 HTTP 织入起点到上游聚合 / 事件驱动 / 智能控制台的每一步(双语),以及进行中与规划中的方向 - **可插拔配置存储(SPI)** —— 默认 **MySQL**(规范化表),可选 Nacos,实现 `ConfigStore` 接口即可自定义 - **只保留标准认证** —— `api_key` / `jwt` / `none`,**按 server 独立配置**可组合;客户端凭证 + scopes 权限(`tool:read|write|execute`、`admin`);RFC 9728 / RFC 8414 OAuth 元数据端点、JWKS - **网关身份标识头** —— 每次下游调用携带 `X-Call-Source: mcp-weaver` + 防伪造的 `X-Mcp-Caller`(网关解析的调用方身份),后端无需解析凭证 - **审计** —— 工具调用/结果、工具注册变更、Server 配置变更(新增/更新/删除)与生命周期、客户端凭证操作(Key/Secret 分配、重置、明文查看)与认证签发(Token/API Key,含失败尝试)落 MySQL 和/或 Langfuse(OpenTelemetry),脱敏 + Token 哈希;每条管理类事件携带操作人(operator 为「来源/操作人」,如 `api:jwt/demo-admin`,控制台按列展示);Key 仅以掩码入审计,Secret 永不落审计;保留期可配(`mcp.weaver.audit.retention-days`,默认永久保留,启用后按 cron 分批清理过期事件) - **SSRF 防护** —— 私有网段拦截 + CIDR 白名单、禁用重定向跟随、query 参数强制编码 - **客户端限流配额** —— 每客户端 QPS / 并发在途 / 日配额三维限额(全部 0 = 不限),MCP 端点请求粒度生效,超限 429(JSON-RPC `-32063`)并落审计(AUTH / RATE_LIMITED);控制台客户端弹窗直接编辑,MySQL 需执行 `docs/sql/migration-client-rate-limit.sql`(可选,缺列时不限流) - **工具调用韧性** —— 每工具并发在途上限(`maxConcurrent`,0 = 不限)+ 连续失败熔断(默认 5 次跳闸、30s 冷静期后半开探测,异常或错误信封均计失败,与指标口径一致);拒绝零排队快速失败,以 `error.type=circuit_open / concurrency_limit` 落指标 - **OpenAPI 批量导入** —— 粘贴或抓取 OpenAPI v3 文档(JSON / YAML),本地 `$ref` 递归内联,每个操作生成一个 HTTP 工具(operationId 命名、query/path 参数转 inputSchema、requestBody/responses 透传),控制台先预览后导入;URL 抓取经网关 SSRF 策略,不另开门 - **安全默认值(2026-09 收口)** —— 审计敏感值掩码与 SSRF 防护默认开启(`MCP_WEAVER_AUDIT_MASK_ENABLED` / `MCP_WEAVER_SSRF_ENABLED`,默认 true);显式关闭时启动即打 WARN 并给出恢复路径;内网后端请用 `allowed-internal-cidrs` 白名单收敛而非整体关闭 - **控制台试调用** —— 工具详情「试调用」以网关身份真实执行一次(走 ToolExecutor 全链路:守卫 / 指标 / 审计漏斗不变,指标 client 维度记 `console/<操作者>`),参数 JSON 即填即跑,结果原文回显并标错误信封;ADMIN 权限 - **文件上传工具** —— MCP 参数 Base64 文件(`contentEncoding: base64`)转 multipart 转发 - **内置管理控制台** —— 登录、概览、服务/工具/客户端管理、审计追踪、配置文档、系统设置(零前端构建依赖) - **可选 Nacos MCP Registry 同步** —— REF 模式 + Naming 实例注册(`McpRegistrySync` SPI) ## 模块 | 模块 | 职责 | |---|---| | `mcp-weaver-core` | 引擎:多 Server 启动器、动态工具注册、工具执行器(SSRF 安全 HTTP 客户端)、安全、审计、管理 REST API、`ConfigStore` / `McpRegistrySync` SPI | | `mcp-weaver-store-mysql` | 默认存储:规范化表(`mcp_weaver_server` / `mcp_weaver_tool` / `mcp_weaver_client` / `mcp_weaver_setting`),server/工具/客户端各一行,checksum CAS 写入 + 行级轮询感知外部变更 | | `mcp-weaver-store-nacos` | 可选存储:Nacos 配置中心(推送)+ Nacos MCP Registry 同步 | | `mcp-weaver-invoker-dubbo` | 可选协议执行器:Dubbo 泛化调用(`protocol: dubbo` 的工具走此模块,含引用缓存与安全白名单) | | `mcp-weaver-server` | Spring Boot 组装件:内置管理控制台,默认 MySQL,一个配置切到 Nacos | ## 快速开始 ### 一键体验(推荐,自包含无外网依赖) ```bash docker compose -f docker/docker-compose.demo.yml up ``` 起来后浏览器开 `http://localhost:8080`,登录 **`demo-admin` / `mwsec-demo-admin-key`**;MCP 客户端连 `http://localhost:8080/mysql-demo/mcp`(API Key `mcp-demo-agent-key`)。种子内容:演示订单库 + 4 个 MySQL 工具(查询/列表/统计/创建),工具调用在网关内部自环(网关 → 内置 demo REST → MySQL),零外部依赖;SSRF 默认开,compose 里只放行了容器回环段。8080 被占就 `MW_DEMO_PORT=18081 docker compose -f docker/docker-compose.demo.yml up`。演示凭证仅限本地体验。 ### 预构建镜像(免构建,国内匿名可拉) ```bash docker pull crpi-p53lyu34f0g6x20q.cn-beijing.personal.cr.aliyuncs.com/fushoujiang/mcp-weaver:1.0.0 ``` 运行所需环境变量(MySQL 连接 + JWT 密钥)参照 [docker/docker-compose.yml](docker/docker-compose.yml)。Java 构件同步发布在 Maven Central,groupId `io.gitee.fushoujiang`。 ### 手动搭建(了解各部件) ```bash # 1. 启动 MySQL + 初始化表 docker run -d --name mcp-weaver-mysql -e MYSQL_ROOT_PASSWORD=root \ -e MYSQL_DATABASE=mcp_weaver -p 3306:3306 mysql:8 mysql -h127.0.0.1 -uroot -proot mcp_weaver < docs/sql/mysql-schema.sql # 2. 种子数据:一个 server + 一个工具 + 一个客户端凭证(行级存储) mysql -h127.0.0.1 -uroot -proot mcp_weaver <<'SQL' INSERT INTO mcp_weaver_server (name, config_key, instructions, auth_type, sort_order) VALUES ('demo-service', 'demo-service-tools', 'Demo service', 'none', 0); INSERT INTO mcp_weaver_tool (config_key, tool_name, definition, sort_order) VALUES ('demo-service-tools', 'hello', '{"name":"hello","description":"Say hello","apiEndpoint":"https://httpbin.org/get","httpMethod":"get","parameters":[{"name":"name","in":"query","required":true,"description":"Your name","schema":{"type":"string"}}]}', 0); INSERT INTO mcp_weaver_client (client_id, client_secret, name, allowed_scopes, sort_order) VALUES ('my-admin', 'change-me-secret', 'Admin', '["tool:read","tool:write","admin"]', 0); SQL # 3. 运行 export MCP_WEAVER_DATASOURCE_PASSWORD=root export MCP_WEAVER_JWT_SECRET=$(openssl rand -hex 32) mvn -pl mcp-weaver-server spring-boot:run # 4. 打开控制台(登录:my-admin / change-me-secret) open http://localhost:8080/ # 5. MCP 客户端连接 http://localhost:8080/demo-service/mcp ``` 变更传播是**事件驱动**的:控制台 / REST API 的写入**立即生效**(上层统一在每次写入成功后发布 `ConfigStoreChangedEvent` Spring 事件,对所有存储实现一视同仁);直接改表(裸 `INSERT INTO mcp_weaver_tool`、其他节点的写入)由行级轮询在 `mcp.weaver.store.mysql.poll-interval-ms`(默认 2 秒)内感知热生效。存储实现会抑制自身写入的回声通知——一次写入只触发一轮重载。 ### 性能基线(M1 单机,Apple ab) | 路径 | c=50 RPS | c=50 P99 | |---|---:|---:| | 裸框架 health | 14,628 | 13ms | | MCP ping(认证 + JSON-RPC) | 7,880 | 44ms | | tools/list | 5,986 | 54ms | | tools/call 全环(含内环 HTTP + SQL,实例总负载≈2×压力) | 756 | 1.9s* | 治理链路全开下协议开销 ~1ms/请求;完整织入调用网关净增 ~2.6ms;HTTP invoker 已换 HttpClient5 连接池(2026-09-26 复测:c=50 P99 从 ~1.9s 收敛到 ~0.1-0.3s,吞吐 2-3 倍,单线程成本无回归,详见 benchmark.md 复测节)。方法与复跑脚本见 [docs/benchmark.md](docs/benchmark.md) / [benchmark.sh](docs/benchmark.sh)。 或 `docker compose -f docker/docker-compose.yml up --build`。 ### 认证接入 ```bash # 签发 Token(clientId + clientSecret) curl -X POST http://localhost:8080/api/auth/token \ -H 'Content-Type: application/json' \ -d '{"clientId":"my-agent","clientSecret":"xxx"}' # API Key 模式(?key= 或 X-API-Key) curl -H 'X-API-Key: mcp-xxxx' http://localhost:8080/demo-service/mcp ``` 客户端凭证存于 `clients` 文档(`mcp_weaver_config_doc` 表 `doc_key='clients'`): ```json { "clients": [{ "clientId": "my-agent", "clientSecret": "xxx", "name": "My Agent", "tokenType": "CLI", "allowedScopes": ["tool:read", "tool:execute"], "allowedServers": [], "enabled": true, "apiKeys": [ { "key": "mcp-aaaa", "remark": "Cursor-工作电脑" }, { "key": "mcp-bbbb", "remark": "生产网关-01" } ] }] } ``` > 一个客户端可配置**多把 API Key**(各带备注),任一把均可通过 `?key=` / `X-API-Key` 认证; > 控制台「客户端 → Key 管理」支持逐把新增(填备注)/ 查看 / 重置 / 删除。 > 兼容旧格式:仅有 `apiKey` 单字段时视为一把无备注 Key;MySQL 存储使用子表 > `mcp_weaver_client_api_key`(见 `docs/sql/migration-client-api-keys.sql`)。 ### REST API 总览 | 方法 | 路径 | 权限 | 说明 | |------|------|------|------| | GET/POST/PUT/DELETE | `/api/servers` | `tool:read` / `admin` | Server 配置管理(支持 checksum 乐观锁 `X-Expected-Md5`) | | GET/POST/DELETE | `/api/tools/servers/{name}/tools` | `tool:read` / `tool:write` | 工具管理 | | GET/POST/DELETE | `/api/clients` | `admin` | 客户端凭证管理 / 吊销(更新时 Secret 可留空保持不变,Key 列表以存储为准) | | GET/POST | `/api/clients/{id}/api-keys` | `admin` | 查看全部 Key(含备注)/ 新增一把(带备注) | | POST | `/api/clients/{id}/api-keys/{key}/regenerate` | `admin` | 按把重置(旧 Key 立即失效) | | DELETE | `/api/clients/{id}/api-keys/{key}` | `admin` | 按把删除 | | POST | `/api/clients/{id}/regenerate-secret` | `admin` | 重置 Secret(旧 Secret 立即失效,新值仅返回一次) | | POST | `/api/auth/token` `/api/auth/apikey` `/api/auth/refresh` | 公开 | Token 签发 / API Key(返回第一把)/ 刷新 | | GET | `/api/audit/logs` | 需认证 | 审计日志分页查询 | | GET | `/.well-known/*` | 公开 | OAuth 元数据 / JWKS | ### 切换到 Nacos 存储 ```yaml mcp: weaver: store: type: nacos nacos: servers-data-id: mcp-servers-config.json clients-data-id: mcp-clients.json spring: ai: alibaba: mcp: nacos: server-addr: localhost:8848 namespace: your-ns username: nacos password: nacos ``` 工具文档的 dataId = server 配置中的 `configDataId`(可选,默认自动派生为 `{serverName}-tools`),格式与 MySQL 存储一致;同时自动启用 Nacos MCP Registry 同步(REF 模式 + Naming 实例注册)。 ### 案例:MySQL 变 MCP 工具 见 [docs/example-mysql.md](docs/example-mysql.md)——业务表 → REST → MCP 工具全流程(查询/列表/统计/创建),含热更新演示与 curl/Python 接入示例。 ### 案例:存量 MCP server 聚合 见 [docs/example-mcp-upstream.md](docs/example-mcp-upstream.md)——stdio / Streamable HTTP / 旧 SSE 三种上游挂载,live-mount 自动派生与 import-mcp 导入两条路,防环、退避自愈与白名单治理一应俱全。 ### 复合存储(一个项目同时用 MySQL + Nacos) 路由型组合——**每个文档唯一归属一个存储**(按文档键前缀路由,绝不双写合并,CAS 语义在每个存储内保持完整): ```yaml mcp: weaver: store: type: composite stores: mysql: { enabled: true } # 平台侧:servers / clients / 默认工具 nacos: { enabled: true } # 业务侧:需配置 Nacos 连接 store: composite: default-store: mysql routes: - doc-prefix: "tools:order" # configKey 以 order 开头的工具组归 Nacos store: nacos ``` 典型分工:平台在 MySQL 管理 server 注册与客户端凭证;各业务团队在 Nacos 自管自己的工具配置(推送秒级生效)。控制台「配置文档」页联合展示两个存储的文档,并**按文档标注归属存储**(MySQL / Nacos 徽章);概览页显示当前存储组合。 完整实战案例见 [docs/example-composite.md](docs/example-composite.md)——MySQL 注册 + Nacos 工具发布 + 启动配置 + 热推送演示 + 配置参考与排错清单。 ### 自定义存储 实现两个接口即可接入任意配置源(Git / etcd / Apollo / 文件……): ```java public interface ConfigStore { String loadServersDoc(); // servers 文档 JSON boolean saveServersDoc(String json, String expectedChecksum); Set