语音多路复用器

Claude Voice Multiplexer 是一个用于远程语音交互的插件和服务器,支持通过手机或浏览器与多个Claude会话进行语音控制。

  • by n33kos
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 n33kos/claude-voice-multiplexer

使用说明

克劳德语音多路复用器

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) vmux CLI和中继服务器发送命令。
  • 自动更新:每60秒轮询一次插件缓存。如果找到新版本,则复制守护程序文件并通过launchd重新启动。

会话注册(MCP插件)

每个Claude Code会话都通过捆绑的MCP插件和 SessionStart 挂钩:

  1. 钩子指向 /api/sessions/<id>/register 带有cwd和dir名称;中继跟踪会话并将其显示在web UI中
  2. 语音输入是通过将转录的文本注入tmux窗格(发送键)而不是通过阻止MCP呼叫传递给会话的
  3. 克劳德的回复文本被推回到中继(通过 relay_respond 或停止钩)并与Kokoro合成
  4. 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

这个:

  1. 安装必备组件(cmake、livekit、tmux,如果缺少)
  2. 使用Metal GPU加速从源代码编译whisper.cpp
  3. 在PyTorch MPS支持下建立Kokoro TTS
  4. 构建web应用程序
  5. 将守护程序文件复制到 ~/.claude/voice-multiplexer/daemon/
  6. 安装 vmux CLI到 ~/.local/bin/vmux
  7. 写入并加载launchd plist(com.vmux.daemon)
  8. 打印一次性配对代码,以便立即进行首次设置

数据目录

~/.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会话,请执行以下操作:

  1. 打开 http://localhost:3100
  2. 点击 + 会话列表中的按钮
  3. 输入工作目录路径
  4. 会话自动生成并连接

要连接到会话的终端(用于调试):

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:

  1. 副本 daemon/ 从缓存到 ~/.claude/voice-multiplexer/daemon/
  2. 将新版本写入 VERSION
  3. 设置关机事件→ 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升级:

  1. 在Claude Code中更新插件
  2. 守护进程的60秒轮询检测插件缓存中的新版本,并自动进行自我更新
  3. 守护进程重启后,服务将由launchd管理,无需手动 start.sh

现有的start.sh/stop.sh调用仍然有效(它们委托给 vmux 或回退到传统模式)。