Skip to main content

LingTai WeChat MCP server

Project description

lingtai-wechat

LingTai WeChat MCP server — iLink Bot API client with QR-code login, multi-modal messaging, and LICC inbox callback.

This is the canonical setup, configuration, and troubleshooting doc for the lingtai-wechat MCP. It is fetched by LingTai agents (or anyone else) when they need to install or configure this server.

MCP / LICC contract spec: see the lingtai-anatomy skill, reference/mcp-protocol.md, for the canonical specification of the catalog → registry → activation chain, environment-variable injection, and the LICC v1 inbox callback protocol. The reference client implementation is src/lingtai_wechat/licc.py in this repo (vendored verbatim into all first-party LingTai MCP repos — copy it if you're writing your own).

Tools

One omnibus MCP tool: wechat(action=...). Actions: send, check, read, reply, search, contacts, add_contact, remove_contact. Supports text, images, voice, video, and files (auto-detected from media_path extension).

Inbound messages (LICC)

Inbound WeChat messages flow into the host agent's inbox via the LingTai Inbox Callback Contract. Each new message is delivered as a LICC event with:

  • from — contact alias (or raw wxid_... if no contact saved).
  • subject"wechat message from <name>".
  • body — a ~300 char preview, including bracketed media references like [Image: /path], [Voice: /path], [Video: /path].
  • metadata.message_id — for reply.
  • metadata.from_user_id — raw wxid_....
  • metadata.item_types — list of message item types (text, image, voice, video, file).

Session expiry events are also delivered via LICC with metadata.event_type: "session_expired" so the agent knows to ask for re-login.

Install

# Into the LingTai agent's venv (typically ~/.lingtai-tui/runtime/venv/)
pip install git+https://github.com/Lingtai-AI/lingtai-wechat.git

After install, python -m lingtai_wechat (or the lingtai-wechat script) starts the MCP server over stdio.

QR-code login (one-time, before first use)

WeChat doesn't issue static bot tokens. Authenticate by scanning a QR code with the WeChat mobile app.

The login QR is admin-only — do not share it. Scanning it logs a WeChat account in as the bot's backend identity. If a friend or end user scans it instead of you, their account binds in place of yours and your credentials are replaced. This is not a contact / group / customer-service QR — those are shared from inside WeChat after login, and are how users actually chat with the bot.

Recommended: browser bootstrap

lingtai-wechat-bootstrap .secrets/wechat

This is the preferred first-time setup. It:

  1. Creates .secrets/wechat/config.json with defaults if missing.
  2. Renders the QR as an SVG inside a self-contained HTML page (with an admin-only warning banner) and opens it in your default browser.
  3. Polls iLink for confirmation, auto-refreshing the QR if it expires.
  4. Writes credentials.json (chmod 600) and tells you to refresh the MCP.

The page auto-refreshes every 3s and prints a clear admin-only warning so the scanner cannot mistake it for a chat QR.

Headless fallback: terminal QR

If the host has no browser or you're connecting over SSH without X-forwarding:

python -c "from lingtai_wechat.login import cli_login; cli_login('.secrets/wechat')"

This prints an ASCII QR directly to the terminal. Scan it with WeChat. On success, credentials.json is written into the directory you passed.

After login

credentials.json contains bot_token, user_id, and base_url. Sessions expire periodically (typically ~30 days). When expired, you'll see a LICC event with metadata.event_type: "session_expired" — re-run the bootstrap.

Configure

The server reads two files from the directory pointed at by LINGTAI_WECHAT_CONFIG:

  • config.json — user-controlled options.
  • credentials.json — written by lingtai-wechat-bootstrap (or the cli_login fallback). Don't edit by hand.

config.json schema

{
  "poll_interval": 1.0,
  "allowed_users": ["wxid_abc123"],
  "cdn_base_url": "https://..."
}
  • poll_interval — seconds between iLink long-polls (default 1.0).
  • allowed_users — optional allow-list of WeChat user IDs. When set, messages from other senders are silently ignored. Omit to accept any sender.
  • cdn_base_url — usually omit; the default works.

Activation in LingTai

{
  "addons": ["wechat"],
  "mcp": {
    "wechat": {
      "type": "stdio",
      "command": "/path/to/your/python",
      "args": ["-m", "lingtai_wechat"],
      "env": {
        "LINGTAI_WECHAT_CONFIG": ".secrets/wechat/config.json"
      }
    }
  }
}

Then run system(action="refresh") from the agent. The MCP subprocess starts, the iLink long-poll begins, and the omnibus wechat tool becomes available.

Troubleshooting

  • LINGTAI_WECHAT_CONFIG env var not set — your init.json mcp.wechat.env entry is missing the LINGTAI_WECHAT_CONFIG key.
  • WeChat config not found — the path resolves but no file exists. Relative paths are resolved against LINGTAI_AGENT_DIR.
  • WeChat credentials not found — config exists but credentials.json doesn't. Run the QR-code login flow above.
  • WeChat session expired event in agent inbox — re-run the QR-code login flow.
  • All connection attempts failed in stderr — usually a stale base_url in credentials. Re-run login.
  • MCP server failed to start — usually the command path in init.json doesn't have lingtai_wechat installed. Confirm with <command> -m lingtai_wechat --help from a shell.
  • Tool calls return WeChat manager not initialized — server boot failed (missing config or expired creds). Check stderr.

Multiple pollers after upgrading

iLink's getUpdates is a single-consumer long-poll: two processes holding the same bot_token race over inbound messages and each one gets a different subset. To prevent this, every lingtai-wechat poller takes an exclusive fcntl.flock on ~/.lingtai-wechat/locks/poller-<sha256(bot_token)[:16]>.lock at startup. If a second poller starts for the same account, it refuses with a PollerLockBusy error that includes the holder's PID.

After upgrading to a lingtai-wechat version with the lock, the new process may refuse to start because a pre-upgrade poller from another LingTai project is still running. Diagnose and stop it:

# 1. Find every lingtai_wechat poller currently running.
pgrep -af 'python.*lingtai_wechat'

# 2. The PollerLockBusy error names the holder PID. Inspect it:
ps -p <pid> -o pid,command
lsof -p <pid> 2>/dev/null | grep cwd   # which working dir launched it

# 3. Stop the old poller (refresh that project's MCP after).
kill -TERM <pid>

Notes:

  • Lockfiles in ~/.lingtai-wechat/locks/ are intentionally left on disk after process exit — the flock kernel state is what's authoritative, not the file's presence. A leftover lockfile from a dead process is harmless; a new poller will reacquire the lock cleanly.
  • The lock is keyed on sha256(bot_token), so two accounts produce different lockfiles and don't conflict. Multiple LingTai projects sharing one account is the case the lock prevents.
  • On Windows, fcntl is unavailable; lingtai-wechat will refuse to start with UnsupportedPlatformError rather than silently re-introducing the race.

License

MIT.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lingtai_wechat-0.1.2.tar.gz (30.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lingtai_wechat-0.1.2-py3-none-any.whl (35.6 kB view details)

Uploaded Python 3

File details

Details for the file lingtai_wechat-0.1.2.tar.gz.

File metadata

  • Download URL: lingtai_wechat-0.1.2.tar.gz
  • Upload date:
  • Size: 30.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for lingtai_wechat-0.1.2.tar.gz
Algorithm Hash digest
SHA256 0ce0998a683a25d27ec6d148f11eada44e8bf4fbf7bb5d2950bde3c697f2d79b
MD5 4efec1af334616fb148cc955cc8a5e93
BLAKE2b-256 fcfe423dda277d8a9fea67e9c2daefeadc537c2bdbadd80e077c7c69a62661bf

See more details on using hashes here.

File details

Details for the file lingtai_wechat-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: lingtai_wechat-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 35.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for lingtai_wechat-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0e9dc9d8d09100c4f2f1e551d6fb0711a6697f1efed60d765662eb1b68f488b9
MD5 73a99119028f0e96b2cf45407695a7ce
BLAKE2b-256 4bbb3066b3fd0487223014b013f4d86da5065a5141974b2dac21433c0c85fd47

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page