viber-channel
v0.8.4
Published
Voice + text MCP channel between a Claude Code session and the Viber UI (https://viber.dgypx.dev). Push transcripts to Claude; send_message tool delivers text back to the UI.
Maintainers
Readme
viber-channel
Voice + text MCP channel that connects a Claude Code session to the Viber UI at https://viber.dgypx.dev.
When attached, transcripts spoken in the Viber browser tab are pushed into the Claude Code session as channel notifications, and Claude's send_message tool delivers text back to the UI (with edge-tts playback).
Prerequisites
- A Viber project + token. Open https://viber.dgypx.dev/projects, sign in with Google, create a project, click "Create connection", and paste the resulting
connect to viber: <url>line into your Claude Code session — Claude writes.viber/auth.jsonfor you. - bun on
PATH(used to run the TypeScript channel).
Wiring
Add this to your project's .mcp.json:
{
"mcpServers": {
"viber-channel": {
"command": "bunx",
"args": ["viber-channel@latest"],
"env": {
"VIBER_BASE_URL": "https://viber.dgypx.dev"
}
}
}
}Or register globally for the current user:
claude mcp add viber-channel --scope user \
--env VIBER_BASE_URL=https://viber.dgypx.dev \
-- bunx viber-channel@latestRestart Claude Code in the project directory. The channel acquires a single-instance lock under %APPDATA%/viber/ (or ~/.config/viber/ on Linux/macOS), mints a conversation against the Worker, and subscribes to the conversation-scoped SSE stream.
Codex bridge experiment
Issue #252 adds a Codex bridge as a sibling process to the Claude Code MCP channel. The bridge joins an existing Viber conversation as its own fresh Viber instance, listens to SSE events, forwards user/user_voice messages into a bridge-owned persistent codex app-server thread, and posts Codex's final reply back to Viber.
Launch it against a conversation that already exists:
bun run viber-codex-bridge.ts --conversation <conversation_id>Or via env fallback:
VIBER_TARGET_CONVERSATION_ID=<conversation_id> bun run viber-codex-bridge.tsFor one-shot validation, add --once; the bridge exits after the first Codex reply.
The bridge persists its Codex thread id in .viber/codex-bridge-threads.json by default, keyed by project/fingerprint/conversation. Restarting the bridge resumes that thread, so Codex context carries across Viber turns. To reset/respawn the bridge-owned Codex session, start with --new-thread.
Initial validation runs conservatively: sandbox=read-only, approvalPolicy=on-request, network disabled for turns, and developer instructions tell Codex not to run shell commands or read/write files. This is a validation posture, not a complete security boundary yet; hard permission enforcement must be designed before widening the bridge beyond read-only. Widen permissions only after the voice round-trip and memory test are validated.
By default the bridge registers a fresh instance and does not persist it into the shared auth file. This avoids rotating another live agent's per-membership conversation token. For diagnostics only, --reuse-auth-instance restores the shared-auth behavior.
For an agent-to-agent proof, add --include-agent-messages --echo-content. The bridge then reacts to non-user messages from other instances and replies with the exact content it received.
Configuration
| Env var | Default | Purpose |
|---|---|---|
| VIBER_BASE_URL | https://viber.dgypx.dev | Worker base URL (staging today; switch later if a separate prod hostname appears). |
| VIBER_CHANNEL_LABEL | folder basename | Human-readable name for the conversation in the UI. |
| VIBER_CODEX_BIN | codex | Codex executable used by viber-codex-bridge to spawn codex app-server. |
| VIBER_CODEX_BRIDGE_STATE | .viber/codex-bridge-threads.json | Optional path for the bridge-owned Codex thread state file. |
| VIBER_CF_CLIENT_ID / VIBER_CF_CLIENT_SECRET | unset | CF Access service-token headers (only needed when targeting a CF Access-protected hostname without a public bypass policy). |
Source
This package is built from viber-channel/ in the main Viber repo.
