From wechat
Sets up WeChat channel for Claude Code: generates terminal QR code for login scan, polls API for confirmation, stores credentials, checks status and access.
npx claudepluginhub lc2panda/claude-plugin-wechat --plugin wechatThis skill is limited to using the following tools:
Manages WeChat iLink Bot login and credential storage. Credentials live in
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Generates original PNG/PDF visual art via design philosophy manifestos for posters, graphics, and static designs on user request.
Manages WeChat iLink Bot login and credential storage. Credentials live in
~/.claude/channels/wechat/credentials.json.
Arguments passed: $ARGUMENTS
Read both state files and give the user a complete picture:
Credentials — check ~/.claude/channels/wechat/credentials.json for
token and baseUrl. Show set/not-set; if set, show token first 6 chars
masked.
Access — read ~/.claude/channels/wechat/access.json (missing file
= defaults: dmPolicy: "pairing", empty allowlist). Show:
What next — concrete next step based on state:
/wechat:configure login to scan QR code and connect."/wechat:access pair <code>."login — QR code loginThis is a TWO-STEP process. The scripts are in the plugin install directory.
Find the plugin root by looking for the channels/wechat/login-qr.ts file:
~/.claude/plugins/cache/lc2panda-plugins/wechat/*/channels/wechat/login-qr.ts
Use ls to resolve the wildcard and get the actual path.
Step 1: Fetch and display QR code
bun <plugin-root>/channels/wechat/login-qr.ts
This script:
https://ilinkai.weixin.qq.com/npx qrcode-terminal{"qrcode":"...","url":"..."}Wait for the user after showing the QR code. Tell them: "用微信扫描二维码,或在微信中打开上面的链接。扫码完成后告诉我。"
Extract the qrcode value from the last line of output — you'll need it
for step 2.
Step 2: Poll for scan result
After the user says they've scanned (or just proceed after showing the QR):
bun <plugin-root>/channels/wechat/login-poll.ts <qrcode>
This script polls the WeChat API for scan status. It outputs one line:
scaned — user scanned, waiting for confirmation on phoneexpired — QR expired (exit code 1). Offer to re-run step 1.timeout — timed out (exit code 1). Offer to re-run step 1.{"token":"...","baseUrl":"...","accountId":"...","userId":"..."} — success!
Credentials saved and scanner added to allowlist. (exit code 0)On success, tell the user:
On scaned, tell the user "已扫码,请在微信上点击确认..." and note
the poll script is still running.
clear — remove credentialsDelete ~/.claude/channels/wechat/credentials.json.
baseurl <url> — set custom API base URLFor testing or alternative iLink endpoints. Read existing credentials.json,
update baseUrl, write back.
access.json is re-read on every inbound message — policy changes via
/wechat:access take effect immediately, no restart.https://ilinkai.weixin.qq.com/.Q: 通过 Task 工具派出的 sub-agent 调用 reply 时报错 "cannot send to WeChat" 或 "session timeout",但主会话直接发就成功,为什么?
A: 这是 MCP 协议的物理限制,不是 bug。Sub-agent 运行在独立的隔离上下文中,没有 MCP 传输句柄,无法直接调用 reply 工具。即使 sub-agent 拿到了 context_token,那也是任务派发时刻的字符串字面量,工作几分钟后已经过期。
正确做法:让 sub-agent 把要发送的内容作为返回值交还给主会话,由主会话调用 reply 工具。这样可以避免一次失败重试,节省 token 与时间。
新版插件(v2.1.3+)的 reply 工具已将 context_token 改为可选:主会话不传也能发送,服务端会自动取该用户最新缓存的 token。仅当用户从未发过消息(缓存为空)时才会要求"先让用户发一条 WeChat 消息"。
Q: 为什么不能直接在 sub-agent 里向 iLink HTTP API 发送消息?
A: 即使 sub-agent 直接 POST 到 iLink 后端的 sendmessage 端点,也需要有效的 context_token。该协议采用 last-wins 模型——服务端按用户缓存最新一个 token,旧 token 在用户发新消息后就不再保证可用。Sub-agent 手上的 token 来自任务派发时刻,几分钟后通常已不是最新。统一由主会话发送可以彻底规避这一时序问题。