使用说明
克劳德语音多路复用器
Claude Code MCP插件和中继服务器,用于与多个Claude Code会话进行远程语音交互。从任何地方与正在运行的Claude会话交谈——在它们之间切换,查看它们的输出,并通过手机或任何浏览器的语音控制它们。
v3.0:技术支持 vmuxd,一个持久的守护进程,管理所有服务,并根据web应用程序的需求生成Claude会话。现在有了会话间消息传递、交互式终端和改进的按键可靠性。
建筑
Phone / Browser Mac (all local)
┌──────────────────────┐ ┌──────────────────────────────────────────┐
│ │ │ │
│ React Web App │◄─LiveKit─► Relay Server (:3100) │
│ (mic/speaker/UI) │ WebRTC │ ├── LiveKit Agent (embedded) │
│ │ │ │ ├── VAD + audio buffering │
│ Features: │ │ │ ├── Whisper STT │
│ - Voice I/O │ │ │ └── Kokoro TTS │
│ - Session list │ │ ├── WebSocket hub │
│ - New session spawn │ │ ├── Session registry │
│ - Session controls │ │ └── LiveKit token server │
│ - Text transcript │ │ │
│ - Agent status │ │ vmuxd daemon (launchd) │
│ │ │ ├── Service manager │
└──────────────────────┘ │ │ ├── vmux-whisper (auto-restart) │
│ │ ├── vmux-kokoro (auto-restart) │
│ │ ├── vmux-livekit (auto-restart) │
│ │ └── vmux-relay (auto-restart) │
│ ├── Session manager │
│ │ ├── vmux-session-<name> (tmux) │
│ │ └── ... │
│ └── Unix socket IPC (/tmp/vmuxd.sock) │
└──────────────────────────────────────────┘
For remote access: expose relay server via tunnel (Cloudflare/ngrok/Tailscale)
运作原理
守护进程(vmuxd)
vmuxd 是一个持久的macOS launchd代理,拥有所有服务的整个生命周期:
- 服务经理:启动Whisper、Kokoro、LiveKit和中继服务器。通过健康检查和指数回退在崩溃时自动重启来监控每个。
- 会话管理器:在命名的tmux窗口中生成Claude Code会话。每个会话运行
claude --permission-mode auto并立即向中继服务器注册。 - Unix套接字IPC:暴露
/tmp/vmuxd.sock(模式0600)vmuxCLI和中继服务器发送命令。 - 自动更新:每60秒轮询一次插件缓存。如果找到新版本,则复制守护程序文件并通过launchd重新启动。
会话注册(MCP插件)
每个Claude Code会话都通过捆绑的MCP插件和 SessionStart 挂钩:
- 钩子指向
/api/sessions/<id>/register带有cwd和dir名称;中继跟踪会话并将其显示在web UI中 - 语音输入是通过将转录的文本注入tmux窗格(发送键)而不是通过阻止MCP呼叫传递给会话的
- 克劳德的回复文本被推回到中继(通过
relay_respond或停止钩)并与Kokoro合成 - Kokoro音频通过LiveKit流式传输回客户端
会话产卵流
Web app "New Session" → POST /api/sessions/spawn {"cwd": "/path/to/project"}
→ relay server → vmux IPC (Unix socket)
→ vmuxd session manager
→ tmux new-session -s "vmux-project-a3f2" -c /path/to/project
→ send-keys: claude --permission-mode auto
→ poll relay /api/sessions until session appears (up to 60s)
→ session visible in web UI → auto-connect
音频流
Phone mic → LiveKit (WebRTC) → Relay Server (LiveKit Agent)
→ VAD detects end-of-speech
→ Whisper (local STT) → transcribed text
→ WebSocket → MCP plugin in Claude session
→ Claude processes, generates response text
→ WebSocket → Relay Server
→ Kokoro (local TTS) → PCM audio
→ LiveKit (WebRTC) → Phone speaker
代理状态框架
代理将其状态作为结构化状态对象进行跟踪:
{state: "thinking", activity: "Transcribing speech..."}
{state: "speaking", activity: null}
{state: "idle", activity: null}
{state: "error", activity: "Speech-to-text failed. Is Whisper running?"}
会话运行状况
守护进程每30秒监视一次生成的会话:
| 状态 | 含义 |
|---|---|
standby |
已注册且处于空闲状态,可进行语音输入 |
active |
Claude正在处理请求 |
zombie |
tmux会话活动,但中继心跳停止>90秒 |
dead |
tmux会话已退出 |
无论运行状况如何,每个会话都始终可见“终止”和“重新启动”按钮。
组件
1. vmuxd 守护进程(daemon/)
| 文件 | 描述 |
|---|---|
vmuxd.py |
主守护进程(asyncio、launchd入口点) |
service_manager.py |
基础设施服务生命周期+自动重启 |
session_manager.py |
tmux会话生成、跟踪、健康监控 |
ipc_server.py |
Unix套接字IPC服务器(换行符分隔的JSON) |
vmux |
CLI包装器--通过套接字向守护进程发送命令 |
VERSION |
已安装版本(用于自动更新比较) |
2. vmux 命令行界面
vmux status # show daemon + service + session status
vmux spawn /path/to/project # spawn new Claude session
vmux kill <session-id> # kill a session
vmux attach <session-id> # attach to tmux terminal (for debugging)
vmux sessions # list active sessions
vmux restart <session-id> # kill + respawn a session
vmux restart kokoro # restart an infrastructure service
vmux interrupt <session-id> # send Ctrl-C to a session
vmux hard-interrupt <session-id># Ctrl-C + MCP reconnect
vmux send <id-or-path> <text> # send a text message to a session's voice queue
vmux send-keys <id> <keys> # send literal keystrokes to a session's tmux pane
vmux send-key <id> <key> # send a special key (Enter, C-c, Tab, etc.)
vmux auth-code # generate a one-time pairing code
vmux update-if-newer # apply update from plugin cache
vmux shutdown # stop daemon and all services
3.MCP工具(relay-server/mcp_tools.py)
FastMCP工具嵌入在中继服务器中,通过SSE提供服务 /mcp/sse.
| 工具 | 说明 |
|---|---|
relay_respond |
将Claude的响应文本发送回中继器进行TTS合成。 |
relay_activity |
用Claude的当前活动更新web客户端。 |
relay_disconnect |
从中继中注销此会话。 |
relay_status |
显示当前继电器连接状态。 |
relay_notify |
在网络成绩单上发布后台代理完成通知。 |
relay_code_block |
将代码片段或差异推送到成绩单上。 |
relay_file |
将文件直接转发到web应用程序(无令牌成本)。 |
relay_image |
将图像直接转发到web应用程序。 |
generate_auth_code |
生成一个6位配对码,用于授权新设备。 |
4.中继服务器(relay-server/)
连接web客户端、Claude会话和本地AI服务的Python服务器(FastAPI+Uvicorn)。
终点:
| 端点 | 类型 | 描述 |
|---|---|---|
POST /api/sessions/spawn |
HTTP | 通过守护进程生成Claude会话(需要身份验证) |
DELETE /api/sessions/<id> |
HTTP | 通过守护进程终止会话(需要身份验证) |
POST /api/sessions/<id>/interrupt |
HTTP | 通过守护进程进行硬中断(需要身份验证) |
POST /api/sessions/<id>/restart |
HTTP | 通过守护进程杀死+重生(需要身份验证) |
POST /api/sessions/<id>/message |
HTTP | 向会话的语音队列发送文本消息 |
双向通信 terminal_input 消息 (v3.0):客户端WebSocket现在接受 terminal_input 消息与 {keys, special_key} 字段,通过守护进程转发到会话的tmux窗格。
5.React Web应用程序(web/)
- “+”按钮 在会话列表标题中--打开一个对话框,按目录生成新的Claude会话
- 健康徽章 在会话卡上——琥珀色“僵尸”,红色“死亡”
- 终止/重启/硬中断 会话上下文菜单中的菜单项(用于守护进程管理的会话)
- 交互式终端叠加 (v3.0)——点击成绩单中的终端图标,打开双向终端视图。包括命令输入栏、快捷键(^C、Esc、Tab、,↑, ↓),以及自动刷新终端快照。通过WebSocket直接向Claude Code TUI发送按键→ 守护进程→ tmux.
- 授权:承载头 --auth令牌存储在localStorage中,并作为
Authorization: Bearer <jwt>在所有REST请求上
6.技能(skills/)
| 技能 | 描述 |
|---|---|
install |
运行完整的安装程序(构建deps,设置launchd守护进程) |
start-services |
如果未运行,则通过launchctl启动守护程序 |
stop-services |
通过以下方式停止所有服务 vmux shutdown |
service-status |
通过以下方式检查状态 vmux status |
auth-code |
通过以下方式生成设备配对代码 vmux auth-code |
7.基础设施
服务由以下人员启动和监督 vmuxd:
| 服务 | 端口 | 描述 |
|---|---|---|
| Whisper服务器 | :8100 |
本地STT(whisper.cpp,使用Metal GPU从源代码编译) |
| Kokoro服务器 | :8101 |
本地TTS(kokoro fastapi,带MPS加速的PyTorch) |
| LiveKit服务器 | :7880 |
用于音频传输的WebRTC媒体服务器 |
| 中继服务器 | :3100 |
核心集线器(FastAPI+WebSocket) |
| MCP工具 | /mcp |
嵌入中继服务器,通过SSE提供服务 /mcp/sse |
配置
所有设置均通过配置 ~/.claude/voice-multiplexer/voice-multiplexer.env,由安装脚本生成。
关键设置:
| 变量 | 默认值 | 描述 |
|---|---|---|
RELAY_HOST |
0.0.0.0 |
中继服务器绑定地址 |
RELAY_PORT |
3100 |
中继服务器端口 |
WHISPER_URL |
http://127.0.0.1:8100/v1 |
Whisper STT端点 |
KOKORO_URL |
http://127.0.0.1:8101/v1 |
Kokoro TTS端点 |
KOKORO_VOICE |
af_heart |
TTS语音 |
LIVEKIT_URL |
ws://localhost:7880 |
LiveKit服务器URL |
LIVEKIT_API_KEY |
LiveKit API密钥 | |
LIVEKIT_API_SECRET |
LiveKit API机密 | |
SESSION_TIMEOUT |
600 |
会话心跳超时(秒) |
AUTH_SECRET |
(自动生成) | JWT签名密钥 |
AUTH_TOKEN_TTL_DAYS |
90 |
设备授权令牌持续多长时间 |
VMUX_DAEMON_SECRET |
(自动生成) | 守护进程的内部机密→中继通信 |
安装
先决条件
- macOS与Homebrew
- Xcode命令行工具(
xcode-select --install) - Python 3.10+
uv(curl -LsSf https://astral.sh/uv/install.sh | sh) - Node.js 20+与npm
通过技能安装(推荐)
在Claude Code中安装插件后,只需在任何Claude会话中运行安装技能:
/voice-multiplexer:install
Claude将与您确认,然后运行安装程序并在完成后报告配对代码。
安装脚本(手动)
# Install with defaults (base Whisper model, ~142 MB)
./scripts/install.sh
# Install with a larger, more accurate Whisper model
./scripts/install.sh --whisper-model small
# Force reinstall
./scripts/install.sh --force
这个:
- 安装必备组件(cmake、livekit、tmux,如果缺少)
- 使用Metal GPU加速从源代码编译whisper.cpp
- 在PyTorch MPS支持下建立Kokoro TTS
- 构建web应用程序
- 将守护程序文件复制到
~/.claude/voice-multiplexer/daemon/ - 安装
vmuxCLI到~/.local/bin/vmux - 写入并加载launchd plist(
com.vmux.daemon) - 打印一次性配对代码,以便立即进行首次设置
数据目录
~/.claude/voice-multiplexer/
├── daemon/
│ ├── vmuxd.py # Installed daemon (updated by auto-update)
│ ├── service_manager.py
│ ├── session_manager.py
│ ├── ipc_server.py
│ ├── vmux # CLI wrapper
│ └── VERSION # Installed version
├── whisper/
│ ├── whisper.cpp/ # Compiled binary + source
│ └── models/
│ └── ggml-{model}.bin
├── kokoro/
│ └── kokoro-fastapi/ # Python venv + TTS model
├── logs/
│ ├── daemon.log # vmuxd daemon logs
│ ├── daemon-error.log # vmuxd stderr
│ ├── whisper.log
│ └── kokoro.log
├── daemon.secret # Internal daemon↔relay shared secret (0600)
├── daemon.state # Live PID/session state (updated every 10s)
├── devices.json # Authorized devices
└── voice-multiplexer.env # Service config
已启动集成
守护进程作为macOS launchd代理运行:
- 属性列表:
~/Library/LaunchAgents/com.vmux.daemon.plist - 自动启动:从登录时开始(
RunAtLoad: true) - 自动重启:launchd在崩溃时重新启动(
KeepAlive: true) - 节流:重新启动之间至少10秒
# Control daemon lifecycle
launchctl start com.vmux.daemon # start now
launchctl stop com.vmux.daemon # stop (launchd restarts automatically)
launchctl unload ~/Library/LaunchAgents/com.vmux.daemon.plist # disable auto-start
launchctl load ~/Library/LaunchAgents/com.vmux.daemon.plist # re-enable auto-start
卸载
# Remove everything
./scripts/uninstall.sh
# Keep downloaded models (faster reinstall)
./scripts/uninstall.sh --keep-models
卸载之前,请停止守护进程:
launchctl unload ~/Library/LaunchAgents/com.vmux.daemon.plist
入门指南
加载插件
来自n33kos市场:
/plugin install n33kos/voice-multiplexer
从本地目录(开发):
alias claude='command claude --plugin-dir /path/to/claude-voice-multiplexer'
首次设置
./scripts/install.sh
安装脚本设置所有内容,启动守护进程,并打印一次性配对代码。打开 http://localhost:3100 并输入代码以授权您的设备。就这样
日常使用
后台进程在以下情况下自动运行 install.sh。您不需要手动启动或停止服务。
要在任何Claude会话中使用语音:
语音注册是自动的—— SessionStart 钩子在启动时向中继注册会话,守护进程在预装插件的情况下生成会话。只需打开 http://localhost:3100 会话出现在列表中。
要从web应用程序生成新的Claude会话,请执行以下操作:
- 打开
http://localhost:3100 - 点击
+会话列表中的按钮 - 输入工作目录路径
- 会话自动生成并连接
要连接到会话的终端(用于调试):
vmux sessions # list active sessions
vmux attach <session-id> # open tmux terminal
远程访问(隧道)
要从本地网络外部访问语音多路复用器:
ngrok http 3100
LiveKit流量通过位于以下位置的中继服务器进行代理 /livekit/*,因此只需要对一个端口进行隧道传输。令牌端点根据请求主机自动返回正确的WebSocket URL。
安全:
- JWT设备身份验证保护所有端点
- 配对代码只能从本地主机或通过以下方式生成
vmux auth-code - 配对尝试有速率限制(每个IP 5/60s)
- 守护进程↔中继通道使用单独的共享密钥(
X-Daemon-Secret)
Daemon架构详细信息
IPC协议
Unix套接字位于 /tmp/vmuxd.sock (模式0600)接受换行符分隔的JSON:
{"cmd": "spawn", "cwd": "/path/to/project"}
→ {"ok": true, "session_id": "abc123", "tmux_session": "vmux-project-a3f2", "daemon_id": "d4f1a2b3"}
{"cmd": "kill", "session_id": "abc123"}
→ {"ok": true}
{"cmd": "restart-session", "session_id": "abc123"}
→ {"ok": true, "session_id": "def456", "tmux_session": "vmux-project-e5c7"}
{"cmd": "hard-interrupt", "session_id": "abc123"}
→ {"ok": true}
{"cmd": "restart", "service": "kokoro"}
→ {"ok": true}
{"cmd": "status"}
→ {"ok": true, "daemon_pid": 1234, "services": {...}, "sessions": [...]}
{"cmd": "send-keys", "session_id": "abc123", "keys": "hello world"}
→ {"ok": true}
{"cmd": "send-keys", "session_id": "abc123", "special_key": "Enter"}
→ {"ok": true}
{"cmd": "send-message", "session_id": "abc123", "text": "Please summarize..."}
→ {"ok": true}
{"cmd": "shutdown"}
→ {"ok": true}
服务重启策略
每个服务在出现故障时都会以指数级回退重新启动:
- 尝试1:2s延迟
- 尝试2:延迟4秒
- 尝试3:8秒延迟
- ...
- 最大延迟:60秒
- 最大尝试次数:5次(然后放弃——日志显示“已达到最大重启次数”)
继电器重启恢复
当中继服务器重新启动(崩溃或自动更新)时,现有会话将在下一个用户提示时重新连接 UserPromptSubmit 如果需要,hook会向中继重新注册会话。不需要守护进程端恢复舞蹈;语音输入继续工作,因为它通过tmux发送密钥而不是长寿命的MCP传输进行路由。
自动更新流程
守护进程每60秒检查一次插件缓存:
~/.claude/plugins/cache/n33kos/voice-multiplexer/<version>/plugin.json
如果 version > installed VERSION:
- 副本
daemon/从缓存到~/.claude/voice-multiplexer/daemon/ - 将新版本写入
VERSION - 设置关机事件→ launchd通过KeepAlive重新启动
项目结构
claude-voice-multiplexer/
├── .claude-plugin/
│ └── plugin.json # Plugin manifest (v3.0.0)
├── .mcp.json # Bundled MCP server definition
├── README.md
├── daemon/
│ ├── vmuxd.py # Main daemon process
│ ├── service_manager.py # Service lifecycle + auto-restart
│ ├── session_manager.py # tmux session spawning + tracking
│ ├── ipc_server.py # Unix socket IPC server
│ ├── vmux # CLI wrapper (Python, executable)
│ └── VERSION # Installed daemon version
├── skills/
│ ├── install/SKILL.md
│ ├── start-services/SKILL.md
│ ├── stop-services/SKILL.md
│ ├── service-status/SKILL.md
│ └── auth-code/SKILL.md
├── relay-server/
│ ├── server.py # FastAPI server + session control endpoints
│ ├── mcp_tools.py # FastMCP tools over SSE
│ ├── livekit_agent.py # LiveKit agent (VAD, STT, TTS)
│ ├── audio.py # Whisper/Kokoro clients
│ ├── registry.py # Session registry
│ ├── auth.py # JWT auth + device management
│ ├── config.py # Configuration (env vars)
│ └── requirements.txt
├── web/
│ └── src/
│ ├── hooks/
│ │ ├── useRelay.ts # WebSocket + session control
│ │ ├── useAuth.ts # Auth with Bearer header
│ │ └── ...
│ └── components/
│ ├── SessionList/ # Session drawer + New Session button
│ ├── TerminalOverlay/ # Interactive terminal with keystroke input
│ └── ...
└── scripts/
├── install.sh # Full install + daemon setup + launchd
├── start.sh # Compatibility wrapper (delegates to vmux)
├── stop.sh # Compatibility wrapper (delegates to vmux)
├── status.sh # Compatibility wrapper (delegates to vmux)
└── uninstall.sh
会话间消息传递(v3.0)
这 vmux send 命令启用会话之间的程序化消息传递,解锁一个编排器模式,其中一个AI协调多个Claude会话。
# Send by session ID
vmux send abc123 "Please summarize the recent changes"
# Send by directory path (auto-computes session ID from path hash)
vmux send ~/projects/my-app "Run the test suite and report back"
# Pipe from stdin
echo "Deploy to staging" | vmux send abc123 -
消息是通过将文本直接注入目标会话的tmux窗格来传递的,与web UI文本输入和语音转录的路径相同。
流量: vmux send → 守护进程IPC→ POST /api/sessions/{id}/message → 接力→ 守护进程 inject_text → tmux发送密钥+Enter。
从v1迁移
如果你从v1.x升级:
- 在Claude Code中更新插件
- 守护进程的60秒轮询检测插件缓存中的新版本,并自动进行自我更新
- 守护进程重启后,服务将由launchd管理,无需手动
start.sh
现有的start.sh/stop.sh调用仍然有效(它们委托给 vmux 或回退到传统模式)。