Skip to content

dorokuma/wechatbridge

Repository files navigation

WeChatBridge

English | 简体中文

license python

WeChatBridge connects a WeChat bot to agentic coding CLIs (Google's agy / Antigravity, or xAI's Grok Build). From WeChat you can send text, images, files, and voice-as-text to the active CLI, get replies back, and receive certain generated files over the WeChat CDN. Switch backends per user with /backend — no restart.

WeChat (phone)  ⇄  iLink bot API  ⇄  WeChatBridge  ⇄  agy / grok CLI
                                     (this project)    (runs tools)

The bridge process stays up and long-polls iLink. For prompts that go to a CLI, it spawns one agy or grok child (-p single-turn) and exits that child when done — the child does not stay resident. Many slash commands (/help, /backend, /persona, …) are handled inside the bridge and never start a CLI. Only artifacts the bridge can detect under the user's allowed session paths are pushed back via CDN.

Features

  • Text, image, file, and voice (WeChat server-side transcription only) go to the active backend (agy or grok)
  • Detected CLI artifacts under the per-user allowed tree can be sent back (size-capped); not every file the CLI touches
  • Each WeChat user gets an isolated workspace; model / effort / mode are remembered per backend
  • Runtime backend switch: /backend agy or /backend grok (clears the “continue session” flag so the next CLI turn starts without -c / --continue; does not immediately wipe history files on disk)
  • Slash commands for model, session reset, persona, and more (see below)
  • Dangerous-prompt gate: a keyword list of concrete destructive patterns asks for confirmation before run
  • Sender whitelist (WECHATBRIDGE_ALLOWED_SENDERS; empty = allow all)
  • /mcp returns short usage text; /agent rewrites into a natural-language subagent prompt for the CLI (not a native MCP bridge)
  • Media over WeChat CDN with AES-128-ECB encrypt/decrypt
  • Multi-instance: one codebase, set WECHATBRIDGE_INSTANCE per process (state / session / QR paths derive from it)
  • Deploy templates: systemd (Linux), launchd (macOS), Task Scheduler notes (Windows)

Platform Support

  • Linux — primary (systemd unit included)
  • macOS — supported (launchd plist included)
  • Windows — supported (Task Scheduler guide included)

Default data paths expand from ~ (e.g. ~/.local/share/wechatbridge/<instance>/).

CLI Backends

  • agy (default) — Google Antigravity CLI
  • grok — xAI Grok Build CLI

Per-user switch: /backend agy or /backend grok. Each backend keeps its own model / effort / mode memory and persona file layout. Global default is WECHATBRIDGE_BACKEND.

Prerequisites

  • At least one CLI installed and signed in:
    • agy on PATH, or set AGY_BIN_PATH
    • and/or grok on PATH, or set GROK_BIN_PATH
    • Antigravity is Google's terminal agentic coding CLI (successor to Gemini CLI). Grok Build is xAI's counterpart.
  • A WeChat account with a ClawBot / iLink bot (QR bind on first run)
  • Python 3.10+

Install

The recommended way is with pipx (Python >= 3.10 required):

pipx install wechatbridge-cli

After installation, verify:

wechatbridge --version

Install pipx

Debian / Ubuntu:

sudo apt install pipx

Other systems (or to get the latest version):

python3 -m pip install --user pipx && python3 -m pipx ensurepath

Then start a new shell or re-source your shell config so pipx is on PATH.

Developers

If you want to hack on the source:

git clone https://github.com/dorokuma/wechatbridge.git
cd wechatbridge
pip install -e .

Configure

Configuration is loaded from the first location found:

  1. $WECHATBRIDGE_ENV_FILE — explicit path
  2. $XDG_CONFIG_HOME/wechatbridge/<instance>.env (defaults to ~/.config/wechatbridge/<instance>.env)
  3. $XDG_CONFIG_HOME/wechatbridge/.env (defaults to ~/.config/wechatbridge/.env)
  4. .env in the repository root — deprecated (prints a warning on startup)

The instance name defaults to default; override with WECHATBRIDGE_INSTANCE.

Get the example config:

mkdir -p ~/.config/wechatbridge
curl -o ~/.config/wechatbridge/.env https://raw.githubusercontent.com/dorokuma/wechatbridge/main/deploy/wechatbridge.env.example

Then edit ~/.config/wechatbridge/.env with your settings.

Key variables (all have defaults):

Variable Default Purpose
AGY_BIN_PATH agy path to the agy binary
GROK_BIN_PATH grok path to the grok binary
WECHATBRIDGE_BACKEND agy global default backend (agy / grok; overridable per user via /backend)
WECHATBRIDGE_INSTANCE default instance name; state / session / QR paths derive from it
WECHATBRIDGE_ALLOWED_SENDERS empty comma-separated WeChat IDs (empty = allow all)
AGY_TIMEOUT 600 CLI run timeout in seconds (both backends)
WECHATBRIDGE_MAX_OUTBOUND_BYTES 104857600 max file size sent back to WeChat (100 MB)
WECHATBRIDGE_MAX_INBOUND_BYTES 20971520 max inbound image/file after download (20 MB)
WECHATBRIDGE_MAX_CONCURRENT 4 global concurrent handlers; extras get a busy reply
WECHATBRIDGE_CONFIRM_TOKEN y reply this token to approve a gated dangerous prompt
WECHATBRIDGE_ENABLE_MCP true enable the /mcp help text command
WECHATBRIDGE_ENABLE_SUBAGENT true enable the /agent prompt-rewrite command
WECHATBRIDGE_ADMINS empty comma-separated wxid list; admins receive WeChat notification when a new version is detected
WECHATBRIDGE_UPDATE_CHECK true check PyPI for new versions on startup and every 24h; failures are silent
WECHATBRIDGE_UPDATE_CHECK_INTERVAL 86400 update check interval in seconds

Full list: deploy/wechatbridge.env.example.

Why the new config location? With pipx the package is installed globally, so a .env next to the source no longer makes sense. The XDG base directory layout keeps your config separate and instance-aware.

Run

wechatbridge

On first run the bridge prints a QR code (and saves PNG under the instance data dir). Scan with WeChat to bind, then it long-polls for messages.

Upgrading

pipx upgrade wechatbridge-cli
sudo systemctl restart wechatbridge

Or run the upgrade script (no clone needed — fetch it with curl):

curl -fsSL https://raw.githubusercontent.com/dorokuma/wechatbridge/main/deploy/update.sh | sudo bash

The script upgrades the pipx installation and restarts the service. If the service runs as a dedicated system user (e.g. wechatbridge), running as root automatically runs pipx as that user (override with WECHATBRIDGE_USER=<user>).

Data lives under ~/.local/share/wechatbridge/<instance>/ (sessions, SQLite history, QR codes, login state) and is not touched during upgrade — your bots stay logged in and conversations are preserved.

Before upgrading a major or minor version (e.g. 1.2 → 1.3), check the corresponding section in CHANGELOG.md for breaking changes and migration steps.

Deploy

Linux (systemd)

First, install the bridge under the wechatbridge system user:

sudo -u wechatbridge pipx install wechatbridge-cli

Then deploy the service unit:

sudo cp deploy/wechatbridge.service /etc/systemd/system/
sudo systemctl enable --now wechatbridge

Multi-instance: copy the template deploy/wechatbridge@.service and enable instances:

sudo cp deploy/wechatbridge@.service /etc/systemd/system/
sudo systemctl enable --now wechatbridge@bot2
sudo systemctl enable --now wechatbridge@bot3

Each instance reads its own config file (~/.config/wechatbridge/bot2.env) and keeps state under its own data directory (~/.local/share/wechatbridge/bot2/).

macOS (launchd)

cp deploy/wechatbridge.plist ~/Library/LaunchAgents/com.wechatbridge.plist
# edit WorkingDirectory and ProgramArguments in the plist
launchctl load ~/Library/LaunchAgents/com.wechatbridge.plist

Windows (Task Scheduler)

See deploy/wechatbridge-windows.md.

Slash commands

Command Action
/help list supported commands for the active backend
/backend <agy|grok> switch CLI backend for this WeChat user (on real change: drop continue flag; history files may remain until retention cleanup)
/clear or /new drop continue flag so the next CLI turn is a new conversation (does not instantly delete history files)
/model <name> set model (validated against the backend's model list; see /models)
/models list models from the active CLI
/fast set low reasoning effort (on only — not a toggle; no “off” command)
/planning set planning mode (on only — not a toggle)
/add-dir <path> agy: pass --add-dir on later runs if path is allowed. grok: recorded only; not passed to the CLI yet
/agents list agents via the active CLI
/persona <text> set persona (show / clear / reset subcommands)
/version show current version, instance name, and backend; if a newer version is available, show upgrade hint
/mcp short MCP usage hint text (can disable with WECHATBRIDGE_ENABLE_MCP)
/agent <name> <task> craft a "invoke subagent …" prompt and run the CLI (can disable with WECHATBRIDGE_ENABLE_SUBAGENT)

Other /… commands are either rejected (e.g. /exit), reported as unsupported on WeChat (TUI-only panels), or passed through to the active CLI.

/add-dir only accepts paths under the user's session directory or roots listed in WECHATBRIDGE_ADD_DIR_ROOTS.

Ops & security (what the bridge actually enforces)

  • Whitelist first. Empty WECHATBRIDGE_ALLOWED_SENDERS means anyone who can message the bot can use it.
  • Auto-approve CLIs. agy runs with --dangerously-skip-permissions; grok with --always-approve (unless planning mode). Treat this as trusted-user tooling, not a multi-tenant sandbox.
  • Danger gate is keyword-based, not full intent understanding. Defaults target concrete patterns (rm -rf /, pipe-to-shell, mkfs, format c:, a few heavy Chinese phrases, …). Everyday wording like bare “delete” is not gated. Override list via WECHATBRIDGE_CONFIRM_KEYWORDS; approve with WECHATBRIDGE_CONFIRM_TOKEN (default y), TTL WECHATBRIDGE_PENDING_TTL.
  • Inbound media is size-capped (default 20 MB), streamed, and CDN hosts are allowlisted. Missing aes_key returns a clear error.
  • Outbound artifacts only leave the allowed per-user tree (agy: session scratch; grok: under session dir), after realpath checks, and only if under WECHATBRIDGE_MAX_OUTBOUND_BYTES.
  • Concurrency: global cap (WECHATBRIDGE_MAX_CONCURRENT, default 4); same user is serialized, different users can run in parallel.
  • Long replies are split into chunks (WECHATBRIDGE_MESSAGE_CHUNK, default 2000 characters).
  • Data layout: instance data under ~/.local/share/wechatbridge/<instance>/ (override with env). Runtime dirs prefer 0700; token/QR files prefer 0600 (Unix; Windows relies on NTFS ACLs).
  • Retention: session temps vs dialogue history use separate TTLs (WECHATBRIDGE_SESSION_RETENTION_DAYS, WECHATBRIDGE_HISTORY_RETENTION_DAYS). Prefs/auth are kept.
  • Child env is sanitized (strips common secret-style variable names) and points HOME (and USERPROFILE on Windows) at the per-user session dir.

Limitations

  • Not a standalone agent — requires agy and/or grok.
  • Voice is WeChat speech-to-text only; no local ASR; empty transcript → “type instead”.
  • No video send/receive; no native WeChat voice-bubble replies (no silk encode).
  • One WeChat binding per process; multiple accounts need multiple instances (WECHATBRIDGE_INSTANCE).
  • Artifact send-back is best-effort detection under allowed paths, not “every file the CLI created anywhere”.
  • /mcp / /agent do not implement MCP protocol or spawn process supervisors inside the bridge — they only guide or rephrase for the CLI.
  • Deploy only for trusted users behind a whitelist when possible.

Contributing

See CONTRIBUTING.md. Semantic Versioning from 1.0.0; record changes in CHANGELOG.md.

License

MIT. See LICENSE.

About

Bridge WeChat messages to agy CLI - text/image/file/voice in, agy replies and generated files back.

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages