个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Hands-free, two-way voice for your coding agent (Claude Code, Codex, Antigravity, Ollama) from your phone — free for noncommercial use, source-available, no ElevenLabs. Browser Web Speech + a tiny Node bridge over Tailscale HTTPS.
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
Hands-free, two-way voice for your coding agent from your phone — free, source-available, no ElevenLabs.
v0.8.2: Download the Mac host app DMG or Windows preview installer, choose
one workspace, start the bridge, verify Tailscale, and pair the native mobile
app by scanning the desktop QR code. Mac and Windows desktop preview builds are
validated in CI.
You speak or type on your phone, a coding agent (running on your Mac,
Windows PC, or Linux box) does the work, and the reply streams back as chat
and spoken audio — like a phone call with your agent, with a keyboard when
you want one.查看完整 README ↗Hands-free, two-way voice for your coding agent from your phone — free, source-available, no ElevenLabs.
v0.8.2: Download the Mac host app DMG or Windows preview installer, choose one workspace, start the bridge, verify Tailscale, and pair the native mobile app by scanning the desktop QR code. Mac and Windows desktop preview builds are validated in CI.
You speak or type on your phone, a coding agent (running on your Mac, Windows PC, or Linux box) does the work, and the reply streams back as chat and spoken audio — like a phone call with your agent, with a keyboard when you want one.
/ws) — connect multiple devices (phones, tablets, laptops) simultaneously; live turn streaming, approvals, and session updates sync across all connected clients in real-time..md) or JSON (.json) with native Web Share API and download fallback.STT_MODE=whisper) or streaming Whisper WebSocket transcriber (STT_MODE=whisper-stream); 🔊 text-to-speech stays in the browser — no per-minute voice cost.src/ (adapters, runners, services, routes) for high testability and reliability.Honest scope: for Claude/Codex/Antigravity/Aider/Gemini the model runs in its vendor's cloud (that's how those CLIs work); with the Ollama backend the model runs fully locally. voicebridge just removes the voice middleman (ElevenLabs) and its limits. Speech recognition on iOS uses Apple's free dictation service; text-to-speech is fully on-device.
Agent support: Claude Code, Codex, Antigravity, Ollama, Aider, and Gemini CLI are fully implemented, tested, and support session continuity. See docs/configuration.md for details.
Download the Apple Silicon DMG:
https://github.com/berkayturanci/voicebridge/releases/download/v0.8.1/voicebridge-0.2.1-arm64.dmg
Or download the Windows x64 preview installer:
Release checksums are published at:
https://github.com/berkayturanci/voicebridge/releases/download/v0.8.1/checksums.txt
Open it, choose your project folder and agent, set your Tailscale HTTPS URL, then scan the pairing QR from the iOS/Android app. The Network panel prepares the Tailscale Serve command and explains missing CLI, logged-out Tailscale, DNS/network failures, HTTP status, timeouts, and token mismatch. Full walkthrough: docs/mac-desktop-host.md and docs/windows-desktop-host.md.
git clone https://github.com/berkayturanci/voicebridge.git voicebridge && cd voicebridge && npm install
cp .env.example .env # set PROJECT_DIR + ACCESS_TOKEN
CLAUDE_BIN=$(which claude) npm start # prints a QR for your phone
tailscale serve --bg http://127.0.0.1:8787 # expose over HTTPS (separate terminal)
Then open the printed https://…ts.net URL in your phone's browser (Safari on
iOS) and tap 🎤 or just type. New to it? See Requirements,
Troubleshooting, and the step-by-step
mobile voice setup (why the mic needs HTTPS).
npm i -g @anthropic-ai/claude-code, then claude → /login).git clone https://github.com/berkayturanci/voicebridge.git voicebridge
cd voicebridge
npm install # qrcode-terminal (web-push is optional, for real push)
# Configure with a .env file (or plain env vars):
cp .env.example .env # then edit: PROJECT_DIR, ACCESS_TOKEN, …
# Start the bridge (binds to 127.0.0.1:8787 by default)
npm start
Any variable in .env is loaded at startup (real environment variables win).
On startup the bridge prints a QR code for the phone URL — scan it to open
the UI (and, when ACCESS_TOKEN/PUBLIC_URL are set, to authorize on open).
Web Speech needs a secure context (HTTPS) — over plain http://<lan-ip> a
phone's browser disables the mic. Tailscale gives your machine a real HTTPS cert
automatically:
tailscale serve --bg http://127.0.0.1:8787
tailscale serve status # shows the https://<your-machine>.<tailnet>.ts.net URL
The first time you run tailscale serve, you may have to enable the feature
once for your tailnet — it prints a login.tailscale.com/f/serve?node=… link;
open it and toggle Serve on. Full walkthrough (and the why) in
docs/mobile-voice-setup.md.
https://<your-machine>.<tailnet>.ts.net URL in Safari.That's it — talk, and Claude Code talks back. 🎧
| Env var | Default | Meaning |
|---|---|---|
PORT | 8787 | Port the bridge listens on |
HOST | 127.0.0.1 | Bind address (keep local; expose via tailscale serve) |
PUBLIC_URL | (none) | Public URL shown in the startup QR (e.g. your Tailscale https://…ts.net). Falls back to http://HOST:PORT. |
PROJECT_DIR | current directory | Default working directory for new sessions |
AGENT | claude | Default agent for the boot session (claude/codex/antigravity/ollama/aider/gemini) |
CLAUDE_BIN | claude | Path to the claude executable |
CODEX_BIN | codex | Path to the codex executable |
AGY_BIN | agy | Path to the Antigravity executable |
OLLAMA_BIN | ollama | Path to the Ollama executable |
OLLAMA_MODEL | llama3.2 | Default Ollama model |
OLLAMA_URL | http://127.0.0.1:11434 | Ollama HTTP endpoint |
AIDER_BIN | aider | Path to the Aider executable |
GEMINI_BIN | gemini | Path to the Google Gemini CLI executable |
ACCESS_TOKEN | (none) | If set, /api/* and /ws require authentication. The page prompts for it once and stores it. |
STT_MODE | browser | browser (Web Speech), whisper (local batch), or (local streaming) |
export ACCESS_TOKEN="$(openssl rand -hex 16)"
echo "$ACCESS_TOKEN" # type this into the phone once when prompted
npm start
Keeps transcription on your machine too (nothing goes to Apple). Needs ffmpeg
and a Whisper CLI (e.g. whisper.cpp's whisper-cli):
export STT_MODE=whisper
export STT_CMD='ffmpeg -nostdin -i {file} -ar 16000 -ac 1 -f wav - 2>/dev/null | whisper-cli -m ~/models/ggml-base.bin -nt -f - 2>/dev/null'
npm start
For real-time streaming speech-to-text, run whisper.cpp streaming transcriber:
export STT_MODE=whisper-stream
export STT_STREAM_URL='ws://127.0.0.1:8910/listen'
npm start
In whisper-stream mode the browser streams mic chunks in 250ms timeslices to /api/stt-stream; the
bridge proxies them to the local transcriber and relays partial/final transcript
JSON back to the UI.
/ws): all connected devices receive real-time
turn deltas, tool approvals, and session updates simultaneously..md) and JSON (.json) export via Web Share API or download.Each agent exposes modes that map to its CLI's approval/sandbox flags — pick a fuller-auto mode for true hands-free use:
| Agent | Modes (flag) |
|---|---|
| Claude | ask (standard prompt) · autoEdit (--permission-mode acceptEdits) · full (--dangerously-skip-permissions) |
| Codex | safe (-s read-only) · auto (-s workspace-write -c approval_policy="never") · full (--dangerously-bypass-approvals-and-sandbox) |
| Antigravity | safe (--sandbox) · full (--dangerously-skip-permissions) |
| Ollama | default (local LLM inference with session history) |
| Aider | code (standard coding) · architect (--chat-mode architect) · ask (--chat-mode ask) · auto (--auto-commits --chat-mode code) |
| Gemini | default (standard prompt) · yolo (--yolo auto-approve) · sandbox (--sandbox isolated mode) |
⚠️ Full-auto modes let the agent change files and run commands without prompting. Use them only on trusted projects over your private tailnet.
[ Phone / Tablet / Laptop ] [ Your Computer ]
mic ─Web Speech or Whisper STT─▶ text ──HTTPS/Tailscale──▶ voicebridge (src/ modular) ──spawn──▶ claude / aider / gemini / codex / agy
speaker ◀─speechSynthesis── reply ◀── WebSocket /ws ◀──── delta/activity/approvals ◀──── (agent CLI)
npm test # zero-dependency test suite (node:test): adapters, parser,
# session registry, streaming, modes, runners, push, and auth.
npm run smoke # end-to-end HTTP smoke test against a stub agent (no real CLI)
You don't need an agent CLI to see the bridge work end to end — point a *_BIN
env var at a stub that emits the expected output:
printf '#!/usr/bin/env node\nprocess.stdout.write(JSON.stringify({type:"assistant",message:{content:[{type:"text",text:"hello from the stub."}]}})+"\\n");\n' > /tmp/claude
chmod +x /tmp/claude
CLAUDE_BIN=/tmp/claude npm start # open the printed URL, type or speak
127.0.0.1 and is only reachable through your Tailscale
tailnet — it is not exposed to the public internet.ACCESS_TOKEN.| Symptom | Fix |
|---|---|
| Mic does nothing / "https required" | Web Speech needs HTTPS — open the tailscale serve URL, not http://…. |
| Mic button is greyed out / disabled on mobile | You're on a non-HTTPS origin (e.g. http://<lan-ip>). Open the https://…ts.net URL instead. See mobile voice setup. |
Serve is not enabled on your tailnet | One-time: open the printed login.tailscale.com/f/serve?node=… link and enable Serve in the admin console. |
| iOS mic doesn't work | Use the Safari tab, not an installed PWA (iOS blocks the mic in installed PWAs). |
| "Could not find 'claude'…" | Set CLAUDE_BIN to the agent's path (which claude) and make sure it's logged in. |
| 401 / keeps asking for a token | ACCESS_TOKEN is set — enter it once on the phone, or scan the QR (it carries the token). |
| Replies don't speak | TTS is unlocked on your first tap (mic/send) — interact once, then replies speak. Still silent? Check the voice/rate options and that the device isn't on silent. |
| Mic indicator stays on when idle | The recognizer is released on pause/mute/exit, when hands-free is off, and when the tab is backgrounded. iOS may show the dot for a second after release; if it persists, turn Eller serbest off (it listens between turns by design). |
| No notifications | Enable Bildirim and allow the permission; real push needs VAPID keys (see configuration). |
HOST=127.0.0.1); never expose it publicly.ACCESS_TOKEN (required if it's reachable beyond localhost — the bridge warns otherwise).Details in docs/security.md.
PolyForm Noncommercial License 1.0.0 — free to use, modify, and
share for any noncommercial purpose (personal, research, education,
nonprofit). Commercial use is not permitted, and the required copyright
notice (Copyright (c) 2026 Berkay Turancı) must be kept on copies. Want to use
voicebridge commercially? Contact the author for a separate license.
whisper-streamSTT_CMD | (none) | Whisper mode: shell command; {file} → recorded audio path; must print transcript to stdout |
STT_STREAM_URL | (none) | Whisper-stream mode: local WebSocket transcriber URL, e.g. ws://127.0.0.1:8910/listen |
STT_STREAM_CMD | (none) | Whisper-stream mode: local streaming subprocess command, e.g. whisper-stream -m ~/models/ggml-base.bin |