Xiaozhi Desktop MCP
# Xiaozhi Desktop MCP
把小智、MCP Client 和本机 Mac 工作流连接起来的安全桌面工具层。
`xiaozhi-desktop-mcp` 是一个运行在本机的 MCP Server。它把 Obsidian 记忆、App 控制、Claude Code / Codex 会话、Xcode、浏览器、Finder、剪贴板等桌面能力封装成可控工具,让语音助手或 AI Client 能安全地调用本机能力。
它不是新的小智后端,也不是任意 shell 执行器。这个项目的核心是:用 MCP / HTTP 接口暴露能力,同时用白名单、路径限制、待确认动作、鉴权和可观测日志把桌面自动化收进安全边界。
[API](docs/api.md) · [Desktop Control Roadmap](docs/desktop-control-roadmap.md) · [4.0 Upgrade Plan](docs/upgrade-plan-v4.md) · [4.0 Migration](docs/migration-v4.md) · [macOS E2E](docs/macos-e2e.md) · [3.0 Migration](docs/migration-v3.md) · [Client Examples](docs/clients.md) · [Operations](docs/operations.md) · [Security](docs/security.md) · [Xiaozhi Integration](docs/xiaozhi-integration.md)
License: MIT · Version: 4.0.0 · Python · FastMCP · FastAPI
---
## What It Does
```mermaid
flowchart LR
U["Voice / MCP Client / HTTP Client"]
T["Transport Layer<br/>stdio / Streamable HTTP / HTTP API"]
R["Intent & Dispatch<br/>desktop_intent / api_v1"]
S["Safety Boundary<br/>allowlists / path checks / pending actions"]
W["Mac Workflow<br/>Obsidian / Apps / Codex / Xcode / Browser"]
U --> T --> R --> S --> W
```
典型场景:
- “小智,记一下...” -> 写入 Obsidian vault
- “打开这个项目的 Claude Code” -> 在允许项目里启动可见会话
- “让 cc 检查 README” -> 创建或发送受控任务
- “打开 Xcode 并构建” -> 只操作白名单项目
- “搜索 Obsidian / 打开浏览器 / 控制音乐 / 读写剪贴板” -> 通过统一桌面意图执行
---
## Why This Exists
语音助手和 LLM 真正接入桌面时,难点不是“能不能调用命令”,而是“能不能安全、稳定、可追踪地调用本机能力”。
这个项目把桌面自动化里的风险收束成明确规则:
- App、项目、Xcode、Obsidian 都有白名单或路径边界
- 中风险动作先进入 pending action,再由用户确认
- MCP Client 可以走标准协议,普通程序可以走 HTTP API
- 每次请求都有 request id,方便从客户端追到工具调用
- HTTP 暴露到非 localhost 时必须开启 token 鉴权
---
## Transports
| 入口 | 命令 | 默认地址 | 适合场景 |
| --- | --- | --- | --- |
| MCP stdio | `xiaozhi-desktop-mcp` | 标准输入输出 | Claude Desktop、小智 bridge、本机 MCP client |
| MCP Streamable HTTP | `xiaozhi-desktop-mcp-streamable` | `http://127.0.0.1:8766/mcp` | 支持 MCP over HTTP 的客户端 |
| HTTP API v1 | `xiaozhi-desktop-http` | `http://127.0.0.1:8765/api/v1` | Java / Python / Go / 稳定客户端 |
| HTTP API v2 | `xiaozhi-desktop-http` | `http://127.0.0.1:8765/api/v2` | schema 校验、策略、审计、工作流 |
如果你接的是标准 MCP Client,优先使用 `stdio` 或 `Streamable HTTP`。
如果你只是从普通程序里调用桌面能力,使用 `/api/v1/dispatch`。
如果你在做新客户端,可以先读 `/api/v2/actions` 获取参数 schema 和策略说明,再按需调用 `/api/v2/dispatch`。
---
## Capabilities
| 能力 | 说明 |
| --- | --- |
| Obsidian | 保存记忆、创建/打开/追加笔记、每日笔记、搜索、最近记忆 |
| Claude Code / Codex | 打开项目、发送指令、slash 命令、切模型、状态查询、继续、聚焦、停止 |
| Project Alias | 从 `CC_ALLOWED_PROJECTS` 生成安全项目别名 |
| Apps | 打开、关闭、聚焦或查询 `ALLOWED_APPS` 白名单内的 macOS App |
| Xcode | 打开项目、build、test、clean、查看最近错误 |
| Browser / Finder / Clipboard | 标签页读取与控制、打开搜索、Finder 定位、剪贴板读写 |
| Desktop Perception | 全屏/窗口截图、macOS Vision OCR、MCP 图像内容 |
| Accessibility UI | UI 树、元素状态,以及确认后的点击、输入、滚动、拖拽、菜单和文件选择 |
| Verified Execution | 短期 Observation、窗口/目标重校验、幂等动作和操作后自动验证 |
| Music | Apple Music 状态/音量控制、网易云播放和客户端内搜索 |
| Pending Actions | SQLite 持久化、TTL、原子确认、防重复执行 |
| Workflows | 多步骤计划、暂停确认、重启恢复、继续和取消 |
| Dynamic Workflows | 只读重试、受限等待、条件分支和显式安全补偿 |
| Audit | SQLite 脱敏审计,只保存参数名,不保存参数值 |
| Diagnostics | 健康检查、配置摘要、工具目录、会话清理 |
| Observability | `X-Request-Id`、请求日志、工具调用耗时、错误追踪 |
---
## Quick Start
```bash
git clone git@github.com:jijiutong/xiaozhi-desktop-mcp.git
cd xiaozhi-desktop-mcp
python3 -m venv .venv
. .venv/bin/activate
pip install -e .
cp .env.example .env
```
编辑 `.env`,至少确认这些配置:
```env
OBSIDIAN_VAULT=/path/to/your/obsidian-vault
DESKTOP_MCP_CONFIG=desktop-mcp.yaml
DEFAULT_PROJECT_ROOT=/path/to/your/project
CC_ALLOWED_PROJECTS=/path/to/your/project
XCODE_ALLOWED_PROJECTS=/path/to/your/project
ALLOWED_APPS=Obsidian,Xcode,Google Chrome,Safari,Music,Finder,Terminal
APP_ALIASES=chrome=Google Chrome,netease=网易云音乐,网易云=网易云音乐
APP_PROCESS_ALIASES=网易云音乐=网易云音乐|NetEaseMusic|NeteaseMusic
APP_AUTOMATION_ALIASES=网易云音乐=NeteaseMusic
DESKTOP_MCP_STATE_DB=~/.local/share/xiaozhi-desktop-mcp/state.db
DESKTOP_MCP_PENDING_TTL_SECONDS=600
DESKTOP_MCP_OBSERVATION_TTL_SECONDS=120
DESKTOP_MCP_WORKFLOW_LEASE_SECONDS=300
DESKTOP_MCP_AUDIT_ENABLED=true
DESKTOP_MCP_BROWSER_CONTROL_ENABLED=true
# 留空允许任意 http(s) 域名;生产环境可配置 example.com,docs.example.com
DESKTOP_MCP_BROWSER_ALLOWED_DOMAINS=
```
启动普通 HTTP API:
```bash
xiaozhi-desktop-http
```
检查服务:
```bash
curl http://127.0.0.1:8765/api/v1/health
curl http://127.0.0.1:8765/api/v1/actions
curl http://127.0.0.1:8765/api/v2/actions
```
启动标准 MCP Streamable HTTP:
```bash
xiaozhi-desktop-mcp-streamable
```
默认 endpoint:
```text
http://127.0.0.1:8766/mcp
```
---
## HTTP Dispatch
普通客户端推荐统一调用:
```text
POST /api/v1/dispatch
```
请求示例:
```json
{
"request_id": "client-001",
"action": "desktop_intent",
"params": {
"category": "docs",
"intent": "search",
"params": {
"query": "desktop mcp"
}
}
}
```
响应示例:
```json
{
"success": true,
"request_id": "client-001",
"action": "desktop_intent",
"spoken_message": "找到了 3 条相关笔记。",
"error_spoken_message": "",
"error": "",
"data": {}
}
```
客户端建议:
- 成功时读 `spoken_message`
- 失败时读 `error_spoken_message`
- 调试和结构化数据读 `data`
- 日志串联使用 `request_id`
更多 Java / Python / Go 示例见 [Client Examples](docs/clients.md)。
---
## Common Actions
| 任务 | Action |
| --- | --- |
| 通用桌面意图 | `desktop_intent` |
| 截图 / 窗口截图 / OCR | `desktop_screenshot` / `desktop_window_screenshot` / `desktop_ocr` |
| 创建短期桌面观察 | `desktop_observe` |
| 重校验、执行一次并验证 | `desktop_execute_step` |
| UI 能力 / UI 树 / UI 操作 | `accessibility_capabilities` / `accessibility_tree` / `accessibility_action` |
| 查看分类能力 | `category_registry` |
| 保存一条记忆 | `remember` |
| 搜索 Obsidian | `search_obsidian` |
| 新建 / 打开 / 追加笔记 | `create_note` / `open_note` / `append_daily_note` |
| 列出允许项目 | `list_projects` |
| 按项目名交给 Claude Code | `ask_cc_project` |
| 查看 Claude Code 状态 | `check_cc` |
| 让 Claude Code 继续 / 停止 | `continue_cc` / `stop_cc` |
| 发送 slash 命令 / 切模型 | `cc_send_slash_command` / `cc_switch_model` |
| 打开 / 关闭 App | `app_open` / `app_close` |
| 聚焦 / 查询 App | `app_focus` / `app_status` |
| 浏览器打开 / 搜索 | `browser_open` / `browser_search` |
| 浏览器标签页 / 当前页 | `browser_tabs` / `browser_current` |
| 浏览器控制 / 能力 | `browser_control` / `browser_capabilities` |
| 音乐控制 / 状态 / 音量 | `music_control` / `music_status` / `music_set_volume` |
| 网易云客户端搜索 | `music_search_app` |
| App Driver 能力 | `app_capabilities` |
| 工作流计划 / 执行 / 查询 / 取消 | `workflow_plan` / `workflow_execute` / `workflow_get` / `workflow_cancel` |
| 审计记录 | `audit_list` |
| Xcode 构建 / 测试 / 清理 | `xcode_build` / `xcode_test` / `xcode_clean` |
| 查看 Xcode 最近错误 | `xcode_last_errors` |
| 创建 / 确认待执行动作 | `pending_create` / `pending_confirm` |
| 桌面环境自检 | `health` |
| 查看工具目录 | `tool_catalog` |
---
## Voice Examples
```text
小智,记一下:这个项目先做成桌面 MCP。
小智,打开这个项目的 Claude Code。
小智,把这个任务交给 cc:检查 README 是否清楚。
小智,让 cc 执行 /status。
小智,看看 cc 现在卡在哪。
小智,搜索 Obsidian 里关于桌面 MCP 的笔记。
小智,打开 Xcode 项目并构建。
小智,音乐下一首。
小智,用浏览器搜索 desktop mcp。
小智,列出 Chrome 的标签页。
小智,切到 Chrome 第二个标签页。
小智,看看 Apple Music 正在播放什么。
小智,在网易云音乐客户端搜索周杰伦。
小智,把这段话复制到剪贴板。
```
---
## Security Model
| 边界 | 策略 |
| --- | --- |
| 任意 shell | 不提供 |
| App | 只能操作 `ALLOWED_APPS` |
| 项目 | 只能进入 `CC_ALLOWED_PROJECTS` |
| Xcode | 只能操作 `XCODE_ALLOWED_PROJECTS` |
| Obsidian | 只能访问 `OBSIDIAN_VAULT` |
| Finder | 只能打开 Obsidian、任务目录、允许项目内路径 |
| Accessibility | 窗口/UI 目标必须是白名单 App;UI 写操作必须单独确认 |
| 中风险动作 | 先创建 pending action,确认后执行 |
| HTTP 鉴权 | 非 localhost 绑定必须设置 `DESKTOP_MCP_AUTH_TOKEN` |
| HTTP Token 权限 | 用 `DESKTOP_MCP_AUTH_SCOPES` 限制 `screen:read`、`state:read`、`desktop:control` |
| 工作流恢复 | 租约防止并发 owner;崩溃后只读步骤可恢复,未知写操作结果会停机 |
| 可观测性 | 请求和工具调用记录 request id、状态、耗时,不打印 token |
HTTP API 和 Streamable HTTP 都支持:
```text
Authorization: Bearer <token>
X-Desktop-Mcp-Token: <token>
```
更多细节见 [Security Model](docs/security.md)。
---
## Project Structure
| 路径 | 作用 |
| --- | --- |
| `src/xiaozhi_desktop_mcp/server.py` | 标准 MCP stdio / Streamable HTTP 工具入口 |
| `src/xiaozhi_desktop_mcp/http_server.py` | FastAPI HTTP 服务 |
| `src/xiaozhi_desktop_mcp/api_v1.py` | 多语言统一 dispatch API |
| `src/xiaozhi_desktop_mcp/api_v2.py` | Schema、策略、错误码和审计执行入口 |
| `src/xiaozhi_desktop_mcp/storage.py` | pending、workflow、audit SQLite 状态库 |
| `src/xiaozhi_desktop_mcp/workflows_v2.py` | 可恢复多步骤工作流 |
| `src/xiaozhi_desktop_mcp/tools/` | Obsidian、App、cc、项目、Xcode、pending actions 等工具 |
| `desktop-mcp.yaml` | 通用桌面 category registry 配置 |
| `docs/api.md` | HTTP API 协议 |
| `docs/clients.md` | Java / Python / Go 示例 |
| `docs/operations.md` | 启动、检查和排障 |
| `docs/security.md` | 安全模型 |
---
## Development
```bash
. .venv/bin/activate
pytest
ruff check src tests
```
---
## Documentation
| 文档 | 内容 |
| --- | --- |
| [API](docs/api.md) | HTTP API 协议、鉴权、请求响应 |
| [Client Examples](docs/clients.md) | Java / Python / Go 接入示例 |
| [Operations](docs/operations.md) | 启动、健康检查、常见排障 |
| [Security](docs/security.md) | 白名单、路径限制、鉴权和日志 |
| [Desktop Control Roadmap](docs/desktop-control-roadmap.md) | 完整 LLM 桌面操控差距、当前进度和后续闭环路线 |
| [macOS E2E](docs/macos-e2e.md) | 真实 App smoke 矩阵、运行条件和最近一次结果 |
| [Xiaozhi Integration](docs/xiaozhi-integration.md) | 小智服务和 MCP bridge 接入 |
| [Changelog](CHANGELOG.md) | 版本变化 |
## License
MIT
TDQS
Scored across 48 tools
Many tools have overlapping purposes, especially among 'cc_' and 'desktop_' prefixes (e.g., cc_open_claude_code, cc_start_session, desktop_open_cc_project, desktop_open_cc_project_named). An agent could easily misselect which tool to use for launching or managing Claude Code sessions.
Tool names follow a consistent verb_noun pattern within each subsystem (app_, cc_, obsidian_, xcode_), but the overall mix of prefixes and some near-duplicate names (e.g., cc_open_claude_code vs cc_open_visible_session) cause minor confusion.
With 48 tools, the set is quite large but covers a broad domain (desktop automation, Claude Code, Obsidian, Xcode). However, many tools serve very similar functions, suggesting some could be consolidated.
The tool set provides comprehensive coverage for its intended domain: app management, Claude Code lifecycle, Obsidian note operations, pending actions, and Xcode build/test. Minor gaps exist (e.g., lack of file system operations), but core workflows are well-supported.