Viber Server
БесплатноНе проверенEnables an AI assistant to send and read Viber messages by automating the Viber Desktop app on macOS through UI automation and OCR.
Описание
Enables an AI assistant to send and read Viber messages by automating the Viber Desktop app on macOS through UI automation and OCR.
README
An MCP server that lets an AI assistant (e.g. Claude) send and read Viber messages by driving your already-running, signed-in Viber Desktop app on macOS.
Viber has no local/public API and its message database is encrypted, so this works entirely through UI automation:
- Send — open the chat via the
viber://URL scheme, paste the text, and click the send button. - Receive — capture the visible Viber window and OCR it with Apple's Vision framework.
⚠️ Unofficial. Not affiliated with, endorsed by, or supported by Viber / Rakuten. It automates the desktop UI on your own machine and account. UI automation is inherently version-sensitive and may break when Viber updates. Use at your own risk and review your account's terms of service.
Why it works this way
Three hard constraints shaped the design (all verified on Viber v28.2.0):
- The message DB is unreadable.
~/Library/Application Support/ViberPC/<number>/viber.dbis encrypted with a Botan page codec (random header, notSQLite format 3), with no public key-derivation recipe. So history can't be read from disk. - The accessibility tree is unusable. Viber is a Qt app; AX queries hang, so there's no element tree to read or click.
- Qt ignores ordinary synthetic input. Every click/keystroke must be generated from a real HID
event source (
CGEventSourceCreate(kCGEventSourceStateHIDSystemState)) — plainCGEvents and System Events keystrokes are silently dropped by Qt's input widgets.
What's left — and what this uses — is the viber:// URL scheme, HID-sourced input, and screen OCR.
Tools
| Tool | Description |
|---|---|
send_message(to, text, dry_run=False) |
Open the chat for to, confirm it, paste text, click send, and OCR-verify it landed. dry_run pastes into the box but doesn't send. |
reply(text) |
Send text into the currently-open chat — no navigation. Pair with read_open_chat. |
open_chat(to) |
Bring a conversation to the foreground without sending. |
open_and_read(to) |
Open a conversation and return its visible text in one step. |
read_open_chat() |
OCR the currently-visible Viber window and return its text. |
save_to_my_notes(text) |
Save a note to Viber's private "My Notes" self-chat (opens it via search, then sends). |
open_my_notes() |
Open the "My Notes" self-chat without saving. |
list_chats() |
List the sidebar chats (names, previews, times, unread counts) via OCR — a quick inbox overview. |
put_draft(text) |
Paste text into the currently-open chat's compose box — no navigation, no send. For drafting a reply to review. |
search_and_open(name) |
Search Viber by name and open the best-matching contact/chat (exact/prefix beats substring). Returns matched + low_confidence; verify before sending if low_confidence. |
list_contacts() |
Return the name → number aliases from contacts.json. |
to is either an E.164 number (+639171234567) or a name defined in contacts.json.
Unknown names error out rather than guess a recipient. send_message returns verified: true when
the sent message is confirmed on screen (false = not seen, null = couldn't check).
Requirements
- macOS (tested on macOS 15/26, Apple Silicon)
- Viber Desktop installed, running, and signed in
- uv (Python is managed by
uv)
Install
git clone <your-fork-url> viber-mcp
cd viber-mcp
uv sync
cp contacts.example.json contacts.json # then edit with your real contacts
macOS permissions (required)
Grant these to the app that launches the server (your terminal — iTerm/Terminal — or Claude), in System Settings → Privacy & Security:
- Accessibility — synthetic clicks/keystrokes (sending).
- Screen Recording — window capture (reading + send verification).
The first send/read fails with a clear message until these are granted. After granting, fully quit and reopen the host app so the permission binds.
If you get
not allowed to send keystrokes(error 1002) while the toggle already looks on, reset the stuck TCC entry and relaunch:tccutil reset Accessibility <your-terminal-bundle-id>(e.g.com.googlecode.iterm2,com.apple.Terminal).
Configure contacts
contacts.json maps friendly names to E.164 numbers (it is git-ignored — it holds real numbers):
{
"Me": "+639171234567",
"Mom": "+639181234567"
}
Names that aren't in the file must be given as full E.164 numbers.
Use it from Claude Code
Register the server (user scope):
claude mcp add --transport stdio --scope user viber -- \
uv --directory "$(pwd)" run server.py
Check with claude mcp list (should show viber … ✓ Connected). After editing the server code,
reconnect so Claude reloads it (/mcp → reconnect viber, or restart Claude Code). Remove with
claude mcp remove viber.
/viber-reply slash command (optional convenience)
Copy commands/viber-reply.md into ~/.claude/commands/ (user scope) or your project's
.claude/commands/. It reads the open chat, drafts a reply in your voice, and pastes it into the
compose box without sending — you review and send.
/viber-reply
/viber-reply keep it short and warm; say I'll call tonight
Use it standalone (no Claude)
A small MCP client is included for testing:
uv run client.py list # advertise tools
uv run client.py contacts # show alias map
uv run client.py open "Mom" # open a chat
uv run client.py send "Mom" "hello" --dry-run # fill box, don't send
uv run client.py send "Mom" "hello" # actually send
uv run client.py draft "a reply to review" # drop draft in open chat (not sent)
uv run client.py read # OCR the open chat
How it works (details)
- Send:
open viber://chat?number=<E164>opens the chat (desktop navigation takes a few seconds, so the window is polled via OCR until the recipient's chat is confirmed — and the send is refused if the number "isn't on Viber"). Then: click the compose box, clear any draft, paste the clipboard text (emoji/unicode/newlines survive), click the send button, and OCR-verify the bubble appeared. The clipboard is saved and restored around the paste. - Receive: the largest on-screen window owned by "Rakuten Viber" is captured with
screencapture -l <id>and OCR'd byVNRecognizeTextRequest. It only sees what's on screen.
Automation constraints
Because there's no API — only synthetic input + OCR against a Qt app — a few non-obvious rules make
or break reliability. Keep these in mind when running the tools or editing viber_send.py:
- Synthetic input must use a real HID event source. Qt silently drops plain
CGEvents and System Events keystrokes; the code posts every click/keystroke fromCGEventSourceCreate(kCGEventSourceStateHIDSystemState). - Sidebar, search box, send button, and panel-close ✕ are targeted by fixed PIXEL offsets from the window edges — not fractions. The sidebar and side panels have fixed pixel widths, so fraction-based clicks miss on wide/maximized windows.
- Any right-side panel (chat-info or sticker "Settings") must be closed before sending — it shifts the send button. The code detects and closes it automatically.
- Sending clicks the send button; it does not press Return ("Send message on Enter" may be off).
viber://chat navigation is slow and mobile-first — the code polls via OCR until the target chat is confirmed, and refuses to send if the number "isn't on Viber". You cannot message your own number ("cannot add yourself"); My Notes is a separate chat.- Keep Viber in a normal window on the main desktop — not macOS fullscreen. Fullscreen puts it on a separate Space, causing window-ID churn and blank captures. Don't resize it mid-operation, and prefer keeping side panels closed.
- OCR sees only on-screen text and can garble small/emoji text or interleave the sidebar with the
open conversation; the returned
verifiedflag is best-effort (false negatives are common).
Project layout
| File | Purpose |
|---|---|
server.py |
FastMCP stdio server; defines the tools |
viber_send.py |
platform-neutral recipient resolution, send pipeline, search scoring |
viber_ocr.py |
platform-neutral formatting of OCR observations into read results |
backends/base.py |
Backend interface (semantic: observe, clicks, keys, clipboard) + OCRError |
backends/macos.py |
macOS backend — the only file with OS APIs (Quartz/Vision/AppKit) + Viber layout |
backends/__init__.py |
get_backend() selects a backend by platform |
client.py |
standalone MCP client for testing |
contacts.json |
your name → number map (git-ignored) |
contacts.example.json |
template to copy |
commands/viber-reply.md |
optional Claude Code slash command |
Porting: add backends/<os>.py implementing Backend, wire it into get_backend(), and
re-tune that platform's UI-element locations. All domain logic and tools are shared. (Windows can
likely target elements via UI Automation instead of coordinates; Linux/Wayland restricts capture and
synthetic input, so X11 is easier.)
Limitations & caveats
- OCR sees only on-screen text — scroll to bring older messages into view; it can garble text or interleave the sidebar's chat previews with the conversation.
- No message history from disk (encrypted DB).
- Names resolve from
contacts.json— Viber's own contact list can't be read. - Version-sensitive: a Viber UI/layout change can require small coordinate tweaks.
- Messaging your own number is blocked by Viber ("cannot add yourself"); "My Notes" is separate.
Privacy & security
- Runs entirely locally; it does not send your messages or contacts anywhere except into Viber.
contacts.jsonis git-ignored so real numbers don't get committed.- Requires powerful macOS permissions (Accessibility, Screen Recording) for the host app — grant only if you understand and trust that.
License
MIT — see LICENSE.
Установка Viber Server
У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.
▸ github.com/wawimundo/viber-mcpFAQ
Viber Server MCP бесплатный?
Да, Viber Server MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для Viber Server?
Нет, Viber Server работает без API-ключей и переменных окружения.
Viber Server — hosted или self-hosted?
Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.
Как установить Viber Server в Claude Desktop, Claude Code или Cursor?
Открой Viber Server на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
LibreOffice Tools
Enables AI agents to read, write, and edit Office documents via LibreOffice with token-efficient design. Supports multiple formats including DOCX, XLSX, PPTX, a
автор: passerbyflutterdannote/figma-use
Full Figma control: create shapes, text, components, set styles, auto-layout, variables, export. 80+ tools.
автор: dannoteLogo.dev
Search and retrieve company logos by brand or domain. Customize size, format, and theme to match your design needs. Accelerate design, prototyping, and content
автор: NOVA-3951PIX4Dmatic
Enables GUI automation for controlling PIX4Dmatic on Windows through MCP. Supports launching, focusing, capturing screenshots, sending hotkeys, clicking UI elem
автор: jangjo123Compare Viber Server with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории design
