内容
# 一切皆可用的MCP(egmcp)
> [模型上下文协议](https://modelcontextprotocol.io) 的管理层面。将其指向任何中间件 — MySQL、PostgreSQL、S3/MinIO、阿里云OSS、本机文件系统、Swagger API — 几秒钟后,您就拥有了一个符合标准的MCP服务器,您的LLM客户端可以与其通信。
**状态:** M0(工程骨架)。后端启动,`/healthz` 返回200,单镜像构建有效。详见 [设计文档](docs/superpowers/specs/2026-07-02-egmcp-design.md) 和 [里程碑计划](docs/superpowers/specs/2026-07-02-egmcp-plan.md)。
---
## 快速开始(Docker)
```bash
docker build -t egmcp:dev .
docker run --rm -p 8080:8080 -v egmcp-data:/data --name egmcp-dev egmcp:dev
# 在另一个终端中
curl -s http://localhost:8080/healthz
# {"instance_id":"/data","status":"ok","uptime":"1s"}
```
首次启动时,平台会:
1. 创建 `/data/configs/admin.yaml` 并附带安全默认值。
2. 生成一个随机管理员密码和JWT签名密钥。
3. 只在容器日志中打印一次密码。
使用以下命令查找:
```bash
docker logs egmcp-dev | grep first-boot
```
在 `http://localhost:8080/` 打开仪表盘(M1将添加登录表单;M0返回静态占位符)。
## 快速开始(本地开发)
前提条件:Go 1.22+,Node 18+。
```bash
make web-install # 安装前端依赖
make web-build # 构建 web/dist(在 `make build` 之前必须执行)
make build # 编译后端到 bin/egmcp
make run # 从 ./configs/admin.yaml 运行
# 或:
make docker-build # 构建镜像,即使没有本地Go
```
## 项目布局
```text
cmd/egmcp/ # 入口点
internal/
config/ # YAML加载,ENV替换,首次启动引导
log/ # zap包装器(JSON到stdout)
core/ # 路由器,实例注册表(M0:存根)
server/ # HTTP多路复用器,中间件,静态回退
auth/ # (M1)JWT,bcrypt
store/ # (M1)YAML实例存储 + fsnotify
connectors/builtin/ # (M2+)文件系统,mysql,postgres,oss,s3,swagger
audit/ # (M8)请求审计日志
pkg/connector/ # 连接器SDK(插件作者的稳定API)
web/ # Vite + React + TS + AntD 管理控制台
plugins/ # 第三方.so/.dll连接器
configs/ # admin.yaml + 实例示例
deploy/docker/ # Dockerfile + 入口点
docs/superpowers/specs/ # 设计 + 计划文档
```
## 里程碑
| ID | 标题 | 状态 |
| --- | --- | --- |
| M0 | 工程骨架 | ✅ |
| M1 | 配置层 + 认证 + UI框架 | ✅ |
| M2 | MCP协议 + 文件系统连接器 | ✅ |
| M3 | MySQL / PostgreSQL | ✅ |
| M4 | OSS / S3 (MinIO) | ⏳ |
| M5 | Swagger / OpenAPI | ⏳ |
| M6 | Go插件加载器 | ⏳ |
| M7 | 研究驱动的额外功能(Git,Fetch,…) | ⏳ |
| M8 | 审计,指标,文档,GA | ⏳ |
## M2 演练
平台现在支持 [模型上下文协议](https://modelcontextprotocol.io)。
在创建文件系统连接器类型的实例后,将任何MCP兼容的客户端(Claude Desktop,Cursor,Cline,…)指向:
```text
http://<host>:8080/mcp/<slug>
```
…使用 `Authorization: Bearer <admin JWT>` (或通过 `X-Instance-Key: <key>` / `?key=<key>` 的每个实例API密钥)。
MCP层在 `internal/mcp` 上实现,基于 [`modelcontextprotocol/go-sdk`](https://github.com/modelcontextprotocol/go-sdk):
- **可流式HTTP** 在 `/mcp/{slug}` (2025-03-26传输)。
- **传统SSE** 在 `/mcp/{slug}/sse` + `/mcp/{slug}/messages`。
- **OpenAPI 3.1** 导出在 `/mcp/{slug}/openapi.json`。
文件系统连接器公开:
| 工具 | 描述 |
| --- | --- |
| `filesystem__read_file` | 读取UTF-8文本文件 |
| `filesystem__write_file` | 写入UTF-8文本文件(禁用读取) |
| `filesystem__list_dir` | 列出目录子项(带有可选隐藏文件) |
| `filesystem__delete_file` | 删除文件或空目录(破坏性) |
| `filesystem__search` | 递归名称搜索(不区分大小写) |
另外还有一个资源 `fs://tree` 以JSON形式返回目录树。
**沙盒**:每个传入路径都使用 `filepath.Clean("/") + p` 进行规范化,并与配置的根目录连接;符号链接被解析,如果它们指向根目录之外,则会被拒绝。路径遍历、绝对路径和符号链接逃逸都会关闭。
通过嵌入式二进制文件验证端到端():
| 步骤 | 结果 |
| --- | --- |
| `POST /mcp/sandbox` 初始化 | 200 + `Mcp-Session-Id` |
| `notifications/initialized` | 202 |
| `tools/list` | 5种工具,带有完整的JSON模式 |
| `tools/call filesystem__read_file` | 返回文件内容 |
| `tools/call filesystem__read_file ../etc/passwd` | `isError: true` |
| `GET /mcp/sandbox/openapi.json` | 有效的OpenAPI 3.1 |
## M3 演练
两种新的SQL连接器,**mysql** 和 **postgres**,共享一个 `pkg/sqlconn` 包,该包在驱动程序上统一强制执行平台的安全策略:
- **只读模式** (默认 `true` )拒绝任何其第一个重要关键字不是 `SELECT`/`WITH`/`SHOW`/`EXPLAIN`/`DESCRIBE`/`TABLE`/`VALUES` 的语句。
- **语句超时** (默认30s)限制任何单个查询。
- **行上限** 截断超大结果集并标记 `truncated`。
- **表允许列表** :当非空时,查询引用表外的集合会失败并关闭。检查使用基于正则表达式的小型解析器(足以应对典型查询;不是完整的SQL语法)。
工具表面(适用于两个驱动程序):
| 工具 | 描述 |
| --- | --- |
| `sql_query` | 运行语句,返回行作为JSON |
| `list_databases` / `list_schemas` | 列出可见数据库/模式 |
| `list_tables` | 列出配置的数据库/模式中的表 |
| `describe_table` | 表的列元数据 |
启动本地夹具进行端到端测试:
```bash
docker compose -f deploy/docker/docker-compose.dev.yml up -d
```
然后将mysql连接器指向 `user:pass@tcp(localhost:3306)/egmcp_test`,将postgres连接器指向 `postgres://egmcp:egmcp@localhost:5432/egmcp_test?sslmode=disable`。
查看 [计划](docs/superpowers/specs/2026-07-02-egmcp-plan.md) 以获取每个里程碑的任务和验收标准。
## M1 演练
`docker run` 后,打开 `http://localhost:8080/`:
1. **登录** 使用容器日志中打印的管理员凭证。
2. **创建实例** (`新建实例`):
- 步骤1:选择一个slug(变为 `/mcp/{slug}`)。
- 步骤2:选择连接器类型(内置连接器在M2+注册)。
- 步骤3:连接器的模式驱动表单从连接器的 `Manifest.ConfigSchema` 自动生成。
3. **管理** 实例在列表视图中:刷新,测试,删除。每个实例页面显示连接器配置和“复制JSON”按钮,该按钮生成一个 `mcpServers` 代码段,准备粘贴到Claude Desktop / Cursor中。
REST 接口(都在 `/api/v1` 下):
| 方法 & 路径 | 用途 |
| --- | --- |
| `POST /auth/login` | 公共;返回JWT |
| `GET /me` | 管理员配置文件 |
| `GET /connectors/builtin` | 列出已注册的连接器类型 |
| `GET/POST /instances` | 列出 / 创建 |
| `GET/PUT/DELETE /instances/{slug}` | 读取 / 替换 / 删除 |
| `POST /instances/{slug}/test` | 每个连接器的健康检查 |
| `POST /instances/{slug}/rotate-key` | 发出新的API密钥 |
| `GET /plugins` | 插件列表(直到M6为空) |
| `GET /healthz` / `/readyz` | 运行状况 |
## 配置
`admin.yaml` (首次启动时自动创建):
```yaml
server:
listen: ":8080"
auth:
admin_username: admin
admin_password_hash: "$2a$..." # bcrypt; 首次启动值自动生成
jwt_secret: "..." # 64-hex; 首次启动值自动生成
jwt_ttl: 12h
data_dir: ./data
instances_dir: ./data/instances
plugins_dir: ./data/plugins
log_level: info
```
在启动时解析秘密引用(`${VAR}` 和 `${VAR:-default}`)。
## 许可证
待定