Skip to main content
Glama
README.md
# MOSS 小智 MCP 服务器

> 为 **DIY MOSS(ESP32)** 智能助手提供视觉识别与 PTZ 云台控制能力的 MCP 服务器。

本项目通过 WebSocket 管道连接小智云端平台(`api.xiaozhi.me`),让云端 AI 能够调用本地摄像头能力,实现远程视觉感知与交互。

---

## 快速开始

### 前置要求

- Docker 和 Docker Compose(推荐)
- 或 Python 3.10+
- 一个已注册的 [小智](https://xiaozhi.me) 设备与 JWT Token
- **摄像头取帧服务** `chenqizhi1992/camera-service`(详见下方说明)

### 摄像头取帧服务

本项目的视觉识别功能依赖于 **camera-service** 镜像(`chenqizhi1992/camera-service`),该服务负责从摄像头实时取帧并提供 HTTP REST API。

> 该镜像仓库地址:https://hub.docker.com/r/chenqizhi1992/camera-service

在你的 `docker-compose.yml` 中添加该服务(或单独运行):

```yaml
services:
  camera-service:
    image: chenqizhi1992/camera-service:latest
    container_name: camera-service
    restart: unless-stopped
    ports:
      - "18080:18080"       # 取帧 HTTP API 端口
    volumes:
      - /dev:/dev           # 挂载摄像头设备
    privileged: true        # 需要访问硬件设备
    environment:
      - CAMERA_INDEX=0      # 摄像头设备索引
```

或者直接运行:

```bash
docker run -d \
  --name camera-service \
  --restart unless-stopped \
  --privileged \
  -p 18080:18080 \
  -v /dev:/dev \
  chenqizhi1992/camera-service:latest
```

启动后通过 `http://<host_ip>:18080` 访问取帧 API。

### 使用 Docker(推荐)

#### 1. 配置环境变量

复制 `.env` 文件并按实际情况修改:

```bash
# MCP 端点地址(从小智平台获取,含 JWT Token)
MCP_ENDPOINT=wss://api.xiaozhi.me/mcp/?token=your_jwt_token_here

# 摄像头配置(指向 camera-service 的地址)
ENABLED_IP_CAMERA=true
CAMERA_SERVICE_URL=http://192.168.1.1:18080   # 改成 camera-service 的实际地址
ONVIF_CAMERA_PTZ_ENABLED=true
```

#### 2. 启动 MCP 服务

```bash
docker compose up -d
```

查看日志:

```bash
docker compose logs -f
```

#### 3. 停止服务

```bash
docker compose down
```

### 使用 Python 直接运行

```bash
# 1. 安装依赖
pip install -r requirements.txt

# 2. 配置环境变量(复制 .env 并修改)
# 编辑 .env 文件...

# 3. 启动 MCP 服务器
python mcp_pipe.py yo_mcp.py
```

---

## 环境变量说明

| 变量 | 默认值 | 说明 |
|------|--------|------|
| `MCP_ENDPOINT` | — | **必填** WebSocket 端点地址,从小智平台获取(含 JWT Token) |
| `ENABLED_IP_CAMERA` | `false` | 是否启用 IP 摄像头工具 |
| `CAMERA_SERVICE_URL` | `http://192.168.1.1:18080` | 摄像头 HTTP 服务地址 |
| `ONVIF_CAMERA_PTZ_ENABLED` | `true` | 是否启用 ONVIF PTZ 云台控制 |
| `PYTHONUNBUFFERED` | `1` | Python 日志实时输出 |

---

## 架构说明

```
┌──────────────────────────────────────────────────────────────┐
│                      本地运行环境(Docker)                    │
│                                                              │
│  ┌─────────────────────────────────────────────────────┐     │
│  │  moss-xiaozhi-mcp (mcp-pipe 容器)                   │     │
│  │  ┌─────────────┐        ┌──────────────────────┐   │     │
│  │  │  yo_mcp.py  │ stdio │    mcp_pipe.py        │   │     │
│  │  │ (MCP Server)│◄─────►│  (WebSocket Bridge)   │   │     │
│  │  │             │        │                      │   │     │
│  │  │ camera_tool │        │ 指数退避重连          │   │     │
│  │  │  ├ 视觉识别  │        │ 双向数据管道          │   │     │
│  │  │  └ PTZ控制  │        └──────────┬───────────┘   │     │
│  │  └──────┬──────┘                   │               │     │
│  └─────────┼──────────────────────────┼───────────────┘     │
│            │ HTTP REST                │ WebSocket (wss)     │
│            ▼                          ▼                     │
│  ┌──────────────────┐      ┌──────────────────────┐        │
│  │ camera-service   │      │  api.xiaozhi.me      │        │
│  │ (取帧 Docker 容器) │      │  小智云端平台         │        │
│  │ :18080           │      └──────────────────────┘        │
│  └────────┬─────────┘                                      │
│           │ USB / 串口                                      │
│           ▼                                                 │
│  ┌──────────────────────────────────────┐                  │
│  │  ESP32 设备(DIY MOSS)               │                  │
│  │  ├─ 运行 MOSS 固件 / 驱动外设         │                  │
│  │  ├─ 摄像头模块 + 云台电机控制         │                  │
│  │  └─ USB 连接上位机                   │                  │
│  └──────────────────────────────────────┘                  │
└──────────────────────────────────────────────────────────────┘
```

### 核心组件

| 组件 | 文件 | 职责 |
|------|------|------|
| **MCP 服务器** | `yo_mcp.py` | 基于 FastMCP 框架,自动注册 `tools/` 下的工具模块 |
| **WebSocket 桥接** | `mcp_pipe.py` | 将 stdio 传输桥接到云端 WebSocket,支持自动重连 |
| **相机工具** | `tools/camera_tool.py` | 提供视觉识别与 PTZ 云台控制 MCP Tool |

### 自动重连机制

`mcp_pipe.py` 内置指数退避重连策略:
- 初始等待:1 秒
- 最大等待:60 秒
- 每次重连:等待时间 × 2 + 随机抖动(0~10%)

---

## 可用工具

| 工具名 | 功能 | 参数 |
|--------|------|------|
| `camera_tool` | 拍照并分析照片内容 | `question`: 关于照片的问题 |
| `adjust_the_camera_view_tool` | 调整摄像头云台角度 | `direction`: up/down/left/right, `angle`: -360~360° |

> **注意**:PTZ 控制当前适配天地伟业摄像头,其他品牌需根据 ONVIF 协议自行适配。

---

## 构建与发布 Docker 镜像

### 构建镜像

```bash
docker build -t chenqizhi1992/moss-xiaozhi-mcp:latest .
```

### 推送到 Docker Hub

```bash
# 登录
docker login

# 推送
docker push chenqizhi1992/moss-xiaozhi-mcp:latest
```

---

## 项目结构

```
moss-xiaozhi-mcp/
├── yo_mcp.py              # MCP 服务器主入口
├── mcp_pipe.py            # WebSocket 管道桥接
├── tools/
│   └── camera_tool.py     # 相机工具(视觉 + PTZ)
├── Dockerfile             # Docker 构建文件
├── docker-compose.yml     # Docker Compose 编排
├── requirements.txt       # Python 依赖
├── .env                   # 环境变量配置
├── .dockerignore          # Docker 构建忽略
├── .gitignore             # Git 忽略规则
└── PROJECT_ANALYSIS.md    # 项目分析文档
```

---

## 依赖

| 依赖 | 版本 | 用途 |
|------|------|------|
| `mcp` | ≥ 0.9.1 | FastMCP 服务器框架 |
| `websockets` | 12.0 | WebSocket 客户端 |
| `python-dotenv` | 1.0.1 | 环境变量加载 |
| `requests` | 2.31.0 | HTTP 请求 |

---

## 开发

### 添加新工具

在 `tools/` 目录下创建新的 `.py` 文件,实现 `register_tool(mcp)` 函数即可自动注册:

```python
# tools/example_tool.py
def register_tool(mcp):
    @mcp.tool()
    def example_tool(param: str) -> dict:
        """工具说明"""
        return {"result": f"Hello, {param}"}
```

---

## 许可证

MIT