v2.1.0 | 通用AI工具接入平台,支持多AI系统通过适配器统一接入,管理 MCP(Model Context Protocol)服务,实现工具的热插拔、动态路由和统一管理。
| 特性 | 说明 |
|---|---|
| 热插拔支持 | 动态添加/移除 MCP 服务,无需重启主服务 |
| 多AI适配 | 支持小智AI、OpenAI GPT、豆包等多种AI系统 |
| 统一协议 | 适配器模式统一不同AI的调用协议 |
| 可视化管理 | Web 控制台管理所有 MCP 服务(Outfit 字体 + 设计 Token 系统) |
| 进程管理 | 自动管理 MCP 子进程生命周期 |
| 智能路由 | 工具名称自动路由到对应 MCP 服务 |
| WebSocket支持 | 实时双向通信,流式响应 |
| 健康监控 | 服务状态自动检测和恢复 |
| 分布式集群 | Redis pub/sub 节点通信、服务调度、故障转移 |
| 多租户治理 | 租户 CRUD、组织模型、资源配额、Fernet 密钥管理 |
| 可观测性 | 分布式追踪、SLI/SLO 仪表盘、告警体系、Prometheus 指标 |
| 服务市场 | .mcpkg 打包/发布/安装/升级/回滚、联邦同步 |
| AI 能力增强 | 调用缓存、按工具限流、重试策略、SSE 流式响应 |
| 安全合规 | JWT + RBAC 三角色、操作审计、子进程沙箱、ed25519 签名验签 |
| SDK 与 CLI | Python/TypeScript SDK + CLI 脚手架 + 服务模板 |
┌─────────────────────────────────────────────────────────────┐
│ MCPilot 平台 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 小智AI │ │ OpenAI │ │ 豆包AI │ │
│ │ (WebSocket) │ │ GPT │ │ (更多AI...) │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ └──────────────────┼──────────────────┘ │
│ ┌───────▼───────┐ │
│ │ 多AI网关层 │ │
│ │ MultiAIGateway│ │
│ └───────┬───────┘ │
│ ┌────────────────────┼────────────────────┐ │
│ ┌─────▼──────┐ ┌─────▼──────┐ ┌────▼───────┐ │
│ │ 适配器层 │ │ 服务路由层 │ │ 进程管理层 │ │
│ └────────────┘ └────────────┘ └─────────────┘ │
│ ┌──────────▼───────────┐ │
│ │ MCP 服务池 │ │
│ │ [音乐] [新闻] [家居] │ │
│ └───────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
mcpilot/
├── backend/ # FastAPI 后端
│ ├── app/
│ │ ├── main.py # 应用入口
│ │ ├── config.py # 配置管理
│ │ ├── core/ # 核心业务逻辑
│ │ │ ├── process_manager.py # 进程管理器
│ │ │ ├── router.py # 工具路由引擎
│ │ │ ├── hotplug.py # 热插拔管理器
│ │ │ ├── auth.py # 认证与 RBAC
│ │ │ ├── audit.py # 操作审计
│ │ │ ├── metrics.py # Prometheus 指标
│ │ │ ├── marketplace.py # 服务市场
│ │ │ └── redis_client.py # Redis 分布式支持
│ │ ├── adapters/ # AI 适配器
│ │ │ ├── base.py # 适配器基类
│ │ │ ├── factory.py # 适配器工厂
│ │ │ ├── xiaozhi.py # 小智 AI 适配器
│ │ │ └── openai.py # OpenAI 适配器
│ │ ├── gateway/ # WebSocket 网关
│ │ │ ├── server.py # 连接管理
│ │ │ └── protocol.py # JSON-RPC 协议实现
│ │ ├── api/ # REST API
│ │ │ ├── services.py # 服务管理 API
│ │ │ ├── tools.py # 工具调用 API
│ │ │ ├── adapters.py # 适配器查询 API
│ │ │ ├── system.py # 系统管理 API
│ │ │ ├── auth.py # 认证 API
│ │ │ ├── audit.py # 审计查询 API
│ │ │ └── marketplace.py # 服务市场 API
│ │ ├── models/ # 数据模型
│ │ │ ├── schemas.py # Pydantic 请求/响应模型
│ │ │ └── database.py # SQLAlchemy ORM 模型
│ │ └── db/ # 数据库(PostgreSQL)
│ │ ├── base.py # 数据库连接(asyncpg + NullPool)
│ │ └── repository.py # 数据访问层
│ ├── configs/ # 配置文件目录
│ │ ├── config.yaml # 主配置
│ │ ├── config.example.yaml # 示例配置
│ │ └── mcp-services/ # MCP 服务配置目录
│ ├── scripts/ # 后端脚本
│ │ ├── echo_service.py # Echo MCP 服务
│ │ ├── datetime_service.py # DateTime MCP 服务
│ │ ├── fs_service.py # 文件系统 MCP 服务
│ │ ├── http_service.py # HTTP 代理 MCP 服务
│ │ └── init_database.sql # 数据库初始化 SQL
│ ├── tests/ # 测试目录
│ │ ├── unit/ # 单元测试
│ │ ├── integration/ # 集成测试
│ │ ├── performance/ # 性能测试
│ │ └── manual/ # 手工验证脚本(需服务已启动,不参与 pytest 收集)
│ ├── pyproject.toml # Python 依赖配置
│ ├── requirements.txt # pip 依赖清单
│ ├── main.py # 后端启动入口
│ └── Dockerfile # 后端 Dockerfile
│
├── frontend/ # Vue3 前端
│ ├── src/
│ │ ├── views/ # 页面组件
│ │ ├── components/ # 公共组件
│ │ ├── api/ # API 客户端
│ │ ├── router/ # 路由配置
│ │ ├── styles/ # 全局样式
│ │ └── types/ # TypeScript 类型定义
│ ├── package.json
│ ├── vite.config.ts
│ └── Dockerfile # 前端 Dockerfile
│
├── docker-compose.yml # 一键启动
├── samples/ # 核心示例代码
│ ├── adapters/ # AI 适配器示例
│ └── gateway/
│ └── multi_ai_gateway.py # 多 AI 统一网关
├── docs/ # 文档目录
│ ├── 用户手册.md # 安装部署与功能指南
│ ├── 系统设计.md # 系统设计文档
│ ├── 开发计划.md # 开发计划(4阶段14周)
│ ├── 路线图.md # 需求规划与路线图
│ ├── API参考.md # API 参考文档(108+ 端点)
│ ├── 开发者指南.md # 开发者指南(9章节)
│ ├── 部署指南.md # 部署指南
│ └── 发布说明.md # 发布说明
├── AGENT.md # AI 上下文记忆
└── README.md # 项目说明
- Python 3.11+
- Node.js 18+(前端)
- PostgreSQL 17+
- Redis 7+(可选,分布式部署时启用)
- pip 或 poetry
# 1. 创建数据库
psql -h 192.168.31.210 -U postgres -c "CREATE DATABASE mcpilot;"
# 2. 初始化表结构
python -c "import psycopg2; conn=psycopg2.connect(host='192.168.31.210',port=5432,user='postgres',password='abc123',dbname='mcpilot'); cur=conn.cursor(); f=open('scripts/init_database.sql','r',encoding='utf-8'); cur.execute(f.read()); f.close(); conn.commit(); conn.close(); print('Done')"
# 或应用启动时自动建表(并自动标记 Alembic 版本)数据库初始化三条路径等价(产物完全一致,均标记版本 0000_v2_1_0_baseline):
| 路径 | 命令 | 适用场景 |
|---|---|---|
| 初始化脚本 | 执行 backend/scripts/init_database.sql |
无 Python 环境的服务器 |
| 应用启动 | 启动后端(自动 create_all + 自动 stamp) |
开发/快速体验 |
| Alembic | cd backend && alembic upgrade head |
生产/版本化迁移 |
全量脚本与单一基线迁移
backend/migrations/versions/0000_v2_1_0_baseline.py等价; 后续增量变更请通过alembic revision新增迁移,并同步更新 init_database.sql。
连接参数(默认配置):
| 参数 | 值 |
|---|---|
| Host | 192.168.31.210 |
| Port | 5432 |
| 用户名 | postgres |
| 密码 | abc123 |
| 数据库 | mcpilot |
| 连接串 | postgresql+asyncpg://postgres:abc123@192.168.31.210:5432/mcpilot |
cd backend
pip install -r requirements.txt
mkdir -p logs
cp configs/config.example.yaml configs/config.yaml
# 编辑 config.yaml 确认数据库连接参数
python main.py
# 应用启动时自动创建所有表结构(create_tables)cd frontend
npm install
npm run dev# Docker Compose 包含 PostgreSQL 17 + Redis 7 + 后端 + 前端
docker-compose up -d --build
# 服务编排:
# - postgres: PostgreSQL 17-alpine,数据持久化到 postgres_data 卷
# - redis: Redis 7-alpine(分布式模式)
# - backend: FastAPI 应用,依赖 postgres 和 redis 健康检查
# - frontend: Nginx 托管 Vue 静态资源,反向代理 API 和 WebSocket单容器同时运行 Nginx(前端 + API/WebSocket 反代)与 Uvicorn 后端,适合快速部署。
也可使用编排文件一键起全套:docker compose -f docker-compose.fullstack.yml up -d --build。
# 在项目根目录执行(构建上下文必须是根目录)
docker build -t mcpilot:latest .
# 可选:前端启用登录开关(默认 false,修改后需重新构建)
docker build --build-arg VITE_AUTH_ENABLED=true -t mcpilot:latest .# 创建独立网络(容器间通过名称互访)
docker network create mcpilot-net
# PostgreSQL 17
docker run -d --name mcpilot-postgres --network mcpilot-net \
--restart unless-stopped \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=abc123 \
-e POSTGRES_DB=mcpilot \
-v mcpilot-postgres:/var/lib/postgresql/data \
postgres:17-alpine
# Redis 7
docker run -d --name mcpilot-redis --network mcpilot-net \
--restart unless-stopped \
-v mcpilot-redis:/data \
redis:7-alpinedocker run -d --name mcpilot \
--network mcpilot-net \
--restart unless-stopped \
-p 3000:80 \
-p 8000:8000 \
-v mcpilot-music:/data/music \
-e DATABASE__URL="postgresql+asyncpg://postgres:abc123@mcpilot-postgres:5432/mcpilot" \
-e REDIS__ENABLED=true \
-e REDIS__URL="redis://mcpilot-redis:6379/0" \
-e AUTH__ENABLED=true \
-e AUTH__JWT_SECRET="change-this-to-a-secure-secret" \
-e AUTH__BOOTSTRAP_ADMIN_PASSWORD="change-this-in-production" \
-e SERVER__TOKEN="change-this-token-in-production" \
-e MUSIC_HOST="192.168.31.210" \
-e MUSIC_PORT=8000 \
mcpilot:latest
-e MUSIC_HOST填宿主机局域网 IP(或域名):bridge 网络下容器内自动探测到的是容器 IP, 小智设备无法访问;需外部直连映射的 8000 端口,MUSIC_PORT与对外映射端口保持一致。- 音乐目录改挂宿主目录:
-v /path/to/music:/data/music。- 单机部署不需要 Redis 时:删掉 redis 容器和两行
-e REDIS__*,并显式传-e REDIS__ENABLED=false(镜像默认值为 true)。
# 容器直接使用宿主机网络栈,小智设备点歌无需注入 MUSIC_HOST
docker run -d --name mcpilot \
--network host \
--restart unless-stopped \
-v /path/to/music:/data/music \
-e DATABASE__URL="postgresql+asyncpg://postgres:abc123@127.0.0.1:5432/mcpilot" \
-e REDIS__ENABLED=false \
-e MUSIC_PORT=8000 \
mcpilot:latesthost 模式下端口映射(
-p)无效:Web 控制台为宿主机 80 端口,后端直连为 8000; 数据库/Redis 连接串需指向127.0.0.1或实际地址。
| 端口(宿主:容器) | 用途 |
|---|---|
3000:80 |
Web 控制台(Nginx:前端页面 + /api、/docs、/subsonic、/music 反代 + WebSocket 升级) |
8000:8000 |
后端直连(API 文档 /docs、Subsonic 流媒体、MCP WebSocket、小智设备点歌) |
| 挂载(容器路径) | 用途 |
|---|---|
/data/music |
本地音乐曲库(VOLUME 已声明,未挂载则用匿名卷) |
/app/configs/mcp-services |
MCP 服务配置目录(可选,支持热插拔;挂载整个 /app/configs 会覆盖容器内置 config.yaml,慎用) |
/app/logs |
应用日志目录(可选) |
注入格式为 Pydantic Settings 嵌套分隔符 SECTION__FIELD,下表为全部可覆盖变量及镜像内置默认值:
| 环境变量 | 默认值 | 说明 |
|---|---|---|
DATABASE__URL |
postgresql+asyncpg://postgres:abc123@postgres:5432/mcpilot |
PostgreSQL 连接串(asyncpg 驱动,必需) |
DATABASE__TIMEZONE |
Asia/Shanghai |
会话时区(影响时间戳列) |
DATABASE__ECHO |
false |
SQL 回显调试 |
DATABASE__POOL_SIZE |
5 |
连接池大小 |
DATABASE__MAX_OVERFLOW |
10 |
连接池溢出上限 |
REDIS__ENABLED |
true |
Redis 开关,单机部署传 false |
REDIS__URL |
redis://redis:6379/0 |
Redis 连接串 |
REDIS__KEY_PREFIX |
mcpilot: |
Redis 键前缀 |
REDIS__LOCK_TIMEOUT |
30 |
分布式锁超时(秒) |
AUTH__ENABLED |
true |
登录认证开关 |
AUTH__JWT_SECRET |
change-this-to-a-secure-secret-in-production |
JWT 签名密钥(生产必改) |
AUTH__JWT_EXPIRE_MINUTES |
1440 |
Token 有效期(分钟) |
AUTH__BOOTSTRAP_ADMIN_PASSWORD |
admin123 |
首次启动管理员初始密码(生产必改) |
SERVER__HTTP_HOST |
0.0.0.0 |
后端监听地址 |
SERVER__HTTP_PORT |
8000 |
后端监听端口(Nginx 反代固定指向 8000,一般不改) |
SERVER__TOKEN |
change-this-token-in-production |
MCP 网关认证 token(生产必改) |
SERVER__DEBUG |
false |
调试模式 |
LOGGING__LEVEL |
INFO |
日志级别(DEBUG/INFO/WARNING/ERROR) |
LOGGING__FORMAT |
json |
日志格式(json/console) |
MUSIC_DIR |
/data/music |
音乐目录(容器内路径,配合挂载使用) |
MUSIC_HOST |
(空) | 小智设备可访问的主机地址(宿主机 IP/域名);空=自动探测(bridge 网络下探测到容器 IP,设备不可达) |
MUSIC_PORT |
8000 |
小智设备实际访问的流媒体端口(与对外映射的后端端口一致) |
TZ |
Asia/Shanghai |
容器时区 |
环境变量优先级:
docker run -e> 镜像内置默认值;若挂载自定义config.yaml到/app/configs/config.yaml,文件中的同名键优先于环境变量(Pydantic Settings 行为)。
# 查看容器日志(后端 + Nginx 已合并输出到 stdout/stderr)
docker logs -f mcpilot
# 查看内置健康检查状态(后端 /health + Nginx 首页双探测)
docker inspect --format '{{.State.Health.Status}}' mcpilot
# 快速验证
curl http://localhost:3000/ # 前端页面
curl http://localhost:8000/health # 后端健康检查- Web 控制台: http://localhost:3000
- API 文档: http://localhost:8000/docs
- Prometheus 指标: http://localhost:8000/api/v1/metrics
| AI 类型 | 状态 | 适配器 | 协议 |
|---|---|---|---|
| 小智AI | 已实现 | XiaoZhiAdapter | JSON-RPC 2.0 |
| OpenAI GPT | 已实现 | OpenAIAdapter | Function Calling |
| 豆包AI | 待实现 | DoubaoAdapter | Function Calling |
| 通义千问 | 待实现 | QwenAdapter | Function Calling |
| 文心一言 | 待实现 | WenxinAdapter | Function Calling |
| Claude | 待实现 | ClaudeAdapter | Tool Use |
配合本平台的音乐 MCP 服务,可将小智 AI 音箱固件升级为本地曲库点歌机。固件仓库:smart-open/xiaozhi-esp32-music-player(基于 78/xiaozhi-esp32 v2.2.3+ 二次开发,适配细节见仓库内《小智音乐Fork说明文档.md》)。
固件采用「云端 MCP 查歌 + 设备播放 URL」模式,无需烧录任何服务器地址:
语音"播放江南"
→ 小智云端调用 MCPilot 音乐服务(music_search,拼音/容错/相关度检索)
→ 服务返回自动适配局域网 IP 的流式播放地址(url 字段)
→ 云端调用设备工具 self.music.play_url(传入 url)
→ 固件从 URL 运行时推导服务器地址 → 流式解码播放 + 歌词逐行同步显示
服务器换机、IP 变更均无需重新烧录固件。
| 步骤 | 说明 |
|---|---|
| 1. 准备环境 | 安装 ESP-IDF v5.5.x + ESP-ADF(需能编译 pipeline_http_mp3 示例) |
| 2. 获取固件 | git clone https://github.com/smart-open/xiaozhi-esp32-music-player.git |
| 3. 编译 | 运行 build_mcpilot.bat(脚本内 ESP-IDF 路径按本机环境修改) |
| 4. 烧录 | 运行 flash_mcpilot.bat(默认 COM6,按实际串口修改) |
| 5. 验证 | python monitor_serial.py <秒数> <输出文件> 抓取串口日志,观察启动/播放/唤醒词状态 |
- 目标硬件:ESP32-S3(16MB Flash / 8MB PSRAM),板型已在
sdkconfig.defaults锁定为bread-compact-wifi - 播放地址格式:
http://<MUSIC_HOST 或自动探测IP>:<MUSIC_PORT>/subsonic/rest/stream.view?...&id=<URL编码文件名>;Docker 部署时通过MUSIC_HOST环境变量注入宿主机局域网 IP(bridge 网络下自动探测到的是容器 IP,设备无法访问) - 服务端前置条件:启动 MCPilot 后端并运行 music-service,Subsonic 兼容层(
/subsonic/rest/*)随后端自动提供,设备与服务器需处于同一局域网
| 文档 | 说明 |
|---|---|
| 用户手册 | 安装部署、快速开始、功能指南、API速查、运维指南 |
| 系统设计 | 完整架构设计、核心模块、数据流、安全、测试策略 |
| 开发计划 | 4阶段14周开发计划、任务分解、风险应对 |
| 路线图 | 需求规划、验收标准、技术决策 |
| API参考 | REST API 和 WebSocket 接口说明(108+ 端点) |
| 开发者指南 | 快速开始、架构、SDK/CLI、适配器/MCP服务开发教程 |
| 部署指南 | 本地/Docker/K8s部署方案、Prometheus/Grafana 监控 |
| 发布说明 | 版本发布记录与变更日志 |
const ws = new WebSocket(
'ws://localhost:8000/mcp/ws?ai_type=xiaozhi&token=your_token'
);
ws.send(JSON.stringify({
jsonrpc: '2.0',
id: '1',
method: 'tools/call',
params: {
name: 'music.search',
arguments: { keyword: '周杰伦' }
}
}));
ws.onmessage = (event) => {
const response = JSON.parse(event.data);
console.log('Result:', response.result);
};const ws = new WebSocket('ws://localhost:8000/mcp/ws?ai_type=openai');
ws.send(JSON.stringify({
request_id: 'call_123',
tool_name: 'music.search',
arguments: { keyword: '周杰伦' }
}));- 单节点支持 100+ 并发 MCP 服务
- WebSocket 连接数 10,000+
- 工具调用平均延迟 < 100ms
- 配置更新生效时间 < 1s
MIT License
- Fork 本项目
- 创建特性分支 (
git checkout -b feature/fooBar) - 提交更改 (
git commit -am 'Add some fooBar') - 推送到分支 (
git push origin feature/fooBar) - 创建 Pull Request

