hermesclaw-wechat-multi-agent
Run Hermes Agent, OpenClaw, and OpenCode simultaneously on a single WeChat account with intelligent message routing
How do I install this agent skill?
npx skills add https://github.com/reason-machines/hermes-skills --skill hermesclaw-wechat-multi-agentIs this agent skill safe to install?
- Gen Agent Trust Hubfail
The skill utilizes a high-risk installation method by executing remote code from an untrusted source directly in the terminal. Additionally, it automates the extraction of sensitive WeChat credentials from other applications and establishes a persistent system-level background service with root privileges.
- Socketwarn
1 alert: gptSecurity
- Snykwarn
Risk: MEDIUM · 2 issues
What does this agent skill do?
HermesClaw WeChat Multi-Agent Skill
Skill by ara.so — Hermes Skills collection.
HermesClaw enables running multiple AI agents (Hermes Agent, OpenClaw, OpenCode) on a single WeChat account by acting as a proxy router. It solves the token conflict problem where each gateway tries to exclusively lock the iLink connection, causing 403 errors when running simultaneously.
What HermesClaw Does
HermesClaw is a Python proxy service (~870 lines) that:
- Becomes the sole iLink API poller using a shared WeChat token
- Runs two local proxy servers (ports 19999 for OpenClaw, 19998 for Hermes)
- Bridges OpenCode via its native ACP subprocess protocol
- Routes messages based on commands (
/hermes,/openclaw,/opencode,/both,/three) - Forwards raw iLink protocol messages (text, voice transcriptions, media CDN URLs)
- Does not process media, decrypt AES, or touch agent memory — each gateway handles its own
Prerequisites
Before installing HermesClaw, you need at least one of these installed:
- OpenClaw with
openclaw-weixingateway (logged into WeChat) - Hermes Agent with WeChat gateway configured (
hermes gateway) - OpenCode CLI (optional, enables
/opencodeand/threemodes)
Installation
Quick Install (Interactive)
curl -fsSL https://raw.githubusercontent.com/AaronWong1999/hermesclaw/main/install.sh | bash
Non-Interactive Install (CI/CD)
curl -fsSL https://raw.githubusercontent.com/AaronWong1999/hermesclaw/main/install.sh | HERMESCLAW_YES=1 bash
# Or with the script directly:
# bash install.sh -y
What the Installer Does
- Detects installed gateways (Hermes, OpenClaw)
- Extracts iLink token from gateway account files
- Patches OpenClaw
baseUrl→http://127.0.0.1:19999 - Patches Hermes
WEIXIN_BASE_URL→http://127.0.0.1:19998 - Detects OpenCode CLI at
~/.npm-global/bin/opencodeor viacommand -v opencode - Installs Python deps:
requests,python-dotenv - Creates OpenClaw media symlink (handles path mismatch)
- Sets up systemd service
hermesclaw
Manual Installation Steps
If you need to install manually:
# 1. Clone the repo
cd ~
git clone https://github.com/AaronWong1999/hermesclaw.git
cd hermesclaw
# 2. Install dependencies
pip3 install requests python-dotenv
# 3. Configure .env
cat > .env << 'EOF'
ILINK_TOKEN=your_ilink_token_here
HERMES_PROXY_PORT=19998
OPENCLAW_PROXY_PORT=19999
OPENCODE_CMD=/path/to/opencode
OPENCODE_MODEL=opencode/minimax-m2.5-free
EOF
# 4. Create systemd service
sudo tee /etc/systemd/system/hermesclaw.service > /dev/null << 'EOF'
[Unit]
Description=HermesClaw WeChat Multi-Agent Router
After=network.target
[Service]
Type=simple
User=$USER
WorkingDirectory=$HOME/hermesclaw
ExecStart=/usr/bin/python3 $HOME/hermesclaw/hermesclaw.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
# 5. Enable and start
sudo systemctl daemon-reload
sudo systemctl enable hermesclaw
sudo systemctl start hermesclaw
Configuration
Environment Variables (.env)
# Required: iLink API token (extracted from gateway account files)
ILINK_TOKEN=your_token_here
# Proxy ports (defaults shown)
HERMES_PROXY_PORT=19998
OPENCLAW_PROXY_PORT=19999
# OpenCode integration (optional)
OPENCODE_CMD=/home/user/.npm-global/bin/opencode
OPENCODE_MODEL=opencode/minimax-m2.5-free # Free, no API key needed
# Other free models: opencode/deepseek-free, opencode/qwen-free, opencode/glm-free
# Logging
LOG_LEVEL=INFO # DEBUG for verbose output
Gateway Configuration
OpenClaw (~/.openclaw/openclaw-weixin/accounts/*.json):
{
"baseUrl": "http://127.0.0.1:19999",
"token": "your_token"
}
Hermes (~/.hermes/.env):
WEIXIN_BASE_URL=http://127.0.0.1:19998
WEIXIN_TOKEN=your_token
Optional: Fix Hermes Message Splitting
Hermes by default splits long messages by newlines. To send as single messages:
cd ~/hermesclaw
bash fix_hermes_splitting.sh
This patches ~/.hermes/hermesagent/gateways/weixin.py to disable paragraph splitting.
Commands
In-WeChat Commands
Send these in any WeChat conversation with the bot:
/hermes # Route to Hermes Agent only
/openclaw # Route to OpenClaw only
/opencode # Route to OpenCode only (voice coding)
/both # Route to Hermes + OpenClaw (both reply)
/three # Route to all three agents
/whoami # Show current routing mode and status
Default mode is Hermes. In /both or /three modes, replies are prefixed:
[Hermes Agent][OpenClaw][OpenCode]
Service Management
# Check status
sudo systemctl status hermesclaw
# View logs
journalctl -u hermesclaw -f
# Restart
sudo systemctl restart hermesclaw
# Stop
sudo systemctl stop hermesclaw
Code Examples
Routing Logic (Python)
# hermesclaw.py core routing
class HermesClawRouter:
def __init__(self, token):
self.token = token
self.route_mode = "hermes" # default
self.hermes_proxy = ProxyServer(19998, token)
self.openclaw_proxy = ProxyServer(19999, token)
self.opencode_bridge = ACPBridge()
def handle_message(self, msg):
text = msg.get("content", "").strip()
# Route switching commands
if text == "/hermes":
self.route_mode = "hermes"
return self.send_reply(msg, "Switched to Hermes Agent")
elif text == "/openclaw":
self.route_mode = "openclaw"
return self.send_reply(msg, "Switched to OpenClaw")
elif text == "/opencode":
self.route_mode = "opencode"
return self.send_reply(msg, "Switched to OpenCode")
elif text == "/both":
self.route_mode = "both"
return self.send_reply(msg, "Switched to dual-agent mode")
elif text == "/three":
self.route_mode = "three"
return self.send_reply(msg, "Switched to triple-agent mode")
# Forward to active agent(s)
if self.route_mode == "hermes":
self.hermes_proxy.queue_message(msg)
elif self.route_mode == "openclaw":
self.openclaw_proxy.queue_message(msg)
elif self.route_mode == "opencode":
self.opencode_bridge.send_message(msg)
elif self.route_mode == "both":
self.hermes_proxy.queue_message(msg)
self.openclaw_proxy.queue_message(msg)
elif self.route_mode == "three":
self.hermes_proxy.queue_message(msg)
self.openclaw_proxy.queue_message(msg)
self.opencode_bridge.send_message(msg)
Proxy Server Implementation
class ProxyServer:
def __init__(self, port, token):
self.port = port
self.token = token
self.message_queue = queue.Queue()
def run(self):
app = Flask(__name__)
@app.route("/v1/weixinbot/getupdate", methods=["POST"])
def get_update():
# Pop from queue and return to gateway
try:
msg = self.message_queue.get(timeout=25)
return jsonify(msg)
except queue.Empty:
return jsonify({"type": "heartbeat"})
@app.route("/v1/weixinbot/sendmessage", methods=["POST"])
def send_message():
# Forward to real iLink API
data = request.json
response = requests.post(
"https://ilinkai.weixin.qq.com/v1/weixinbot/sendmessage",
json=data,
headers={"Authorization": f"Bearer {self.token}"}
)
return response.json()
app.run(host="127.0.0.1", port=self.port)
OpenCode ACP Bridge
class ACPBridge:
def __init__(self, cmd, model):
self.cmd = cmd # Path to opencode CLI
self.model = model
self.process = None
def start(self):
self.process = subprocess.Popen(
[self.cmd, "acp", "--model", self.model],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
bufsize=1
)
def send_message(self, msg):
# Format as ACP protocol
acp_msg = {
"type": "user_message",
"content": msg.get("content", ""),
"context": {
"from": msg.get("from_wxid"),
"chat_id": msg.get("room_wxid", msg.get("from_wxid"))
}
}
self.process.stdin.write(json.dumps(acp_msg) + "\n")
self.process.stdin.flush()
def read_response(self):
while True:
line = self.process.stdout.readline()
if not line:
break
response = json.loads(line)
if response.get("type") == "assistant_message":
return response.get("content")
Common Patterns
Pattern 1: Voice to OpenCode
OpenCode excels at voice-based coding. Route voice messages:
User: /opencode
User: [voice message: "Create a Python script that reads CSV and generates a bar chart"]
OpenCode: [creates chart.py with pandas and matplotlib]
Pattern 2: Dual-Agent Comparison
Get different perspectives on the same question:
User: /both
User: What's the best way to handle rate limiting in a REST API?
[Hermes Agent]: Use exponential backoff with jitter...
[OpenClaw]: Implement a token bucket algorithm...
Pattern 3: Seamless Switching
Switch contexts without losing conversation history:
User: /hermes
User: Explain async/await in Python
[Hermes responds]
User: /openclaw
User: Now write an example with aiohttp
[OpenClaw responds with code]
Pattern 4: Media Forwarding
HermesClaw forwards raw iLink messages, so each gateway handles media natively:
# Voice message flow:
# 1. iLink sends voice with transcription
# 2. HermesClaw forwards raw message to active gateway(s)
# 3. Gateway extracts transcription or downloads/decrypts audio
# 4. Gateway processes and replies
# Image flow:
# 1. iLink sends CDN URL + AES key
# 2. HermesClaw forwards raw message
# 3. Gateway downloads and decrypts using its native logic
# 4. Gateway processes image (OCR, vision model, etc.)
Troubleshooting
Problem: 403 Token Conflict
Symptom: One gateway works, the other gets 403 errors or no messages.
Solution:
# 1. Verify HermesClaw is running
sudo systemctl status hermesclaw
# 2. Check both gateways point to proxies
grep baseUrl ~/.openclaw/openclaw-weixin/accounts/*.json
# Should show: http://127.0.0.1:19999
grep WEIXIN_BASE_URL ~/.hermes/.env
# Should show: http://127.0.0.1:19998
# 3. Restart all services
sudo systemctl restart hermesclaw
# Restart Hermes gateway
# Restart OpenClaw gateway
Problem: Messages Not Routed
Symptom: /hermes or /openclaw commands don't switch mode.
Solution:
# Check HermesClaw logs
journalctl -u hermesclaw -n 100
# Verify message reception
curl -X POST http://127.0.0.1:19998/v1/weixinbot/getupdate \
-H "Content-Type: application/json" \
-d '{}'
# Should return queued message or heartbeat
Problem: OpenCode Not Found
Symptom: /opencode or /three commands don't work.
Solution:
# Install OpenCode
npm install -g opencode-ai
# Verify installation
command -v opencode
# Should print: /home/user/.npm-global/bin/opencode
# Update .env
cd ~/hermesclaw
echo "OPENCODE_CMD=$(command -v opencode)" >> .env
# Restart HermesClaw
sudo systemctl restart hermesclaw
Problem: Media Path Errors
Symptom: OpenClaw can't find media files.
Solution:
# HermesClaw installer creates this symlink automatically
ln -sf ~/.openclaw/openclaw-weixin/files ~/hermesclaw/openclaw-weixin-files
# If missing, create manually and restart
sudo systemctl restart hermesclaw
Problem: Long Messages Split
Symptom: Hermes sends replies as multiple short messages.
Solution:
cd ~/hermesclaw
bash fix_hermes_splitting.sh
# This patches ~/.hermes/hermesagent/gateways/weixin.py
# to send long replies as single messages
Problem: Token Extraction Failed
Symptom: Installer can't find iLink token.
Manual extraction:
# For OpenClaw:
grep -r "token" ~/.openclaw/openclaw-weixin/accounts/*.json
# For Hermes:
grep WEIXIN_TOKEN ~/.hermes/.env
# Add to ~/hermesclaw/.env:
echo "ILINK_TOKEN=your_extracted_token" >> ~/hermesclaw/.env
Architecture Overview
┌─────────────────────────────────────┐
│ iLink API (WeChat) │
│ ilinkai.weixin.qq.com │
└──────────────┬──────────────────────┘
│
(sole poller)
│
┌──────────────▼──────────────────────┐
│ HermesClaw Router │
│ - Routes by /hermes /openclaw │
│ - Queues raw iLink messages │
│ - Prefix replies in multi-mode │
├─────────┬─────────┬─────────────────┤
│ Proxy A │ Proxy B │ ACP Bridge │
│ :19999 │ :19998 │ (subprocess) │
└────┬────┴────┬────┴────┬────────────┘
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│OpenClaw │ │ Hermes │ │OpenCode │
│ gateway │ │ gateway │ │ CLI │
└─────────┘ └─────────┘ └─────────┘
Uninstallation
Quick Uninstall
sudo systemctl stop hermesclaw
sudo systemctl disable hermesclaw
sudo rm -f /etc/systemd/system/hermesclaw.service
sudo systemctl daemon-reload
# Restore OpenClaw configs
find "$HOME" -maxdepth 5 -name "*.json.bak" -path "*/openclaw-weixin/accounts/*" \
-exec sh -c 'for f; do cp "$f" "${f%.bak}"; done' sh {} +
# Restore Hermes .env
[ -f "$HOME/.hermes/.env.bak" ] && cp "$HOME/.hermes/.env.bak" "$HOME/.hermes/.env"
# Remove HermesClaw directory (optional)
rm -rf "$HOME/hermesclaw"
Testing
HermesClaw includes 82 pytest tests covering core routing, proxy servers, ACP bridge, and recovery scenarios:
cd ~/hermesclaw
pip3 install pytest pytest-mock
python3 -m pytest tests/ -v
Key test files:
tests/test_core.py— Routing logic, mode switchingtests/test_proxy.py— Proxy server message queuingtests/test_acp.py— OpenCode bridge protocoltests/test_recovery.py— Connection failures, retries
Advanced Usage
Custom OpenCode Models
Edit .env to use different free models:
# MiniMax M2.5 (default, recommended)
OPENCODE_MODEL=opencode/minimax-m2.5-free
# DeepSeek (coding-focused)
OPENCODE_MODEL=opencode/deepseek-free
# Qwen (multilingual)
OPENCODE_MODEL=opencode/qwen-free
# GLM (ChatGLM)
OPENCODE_MODEL=opencode/glm-free
All models are free and require no API keys.
Programmatic Control
Control HermesClaw from other scripts:
import requests
# Switch to dual-agent mode
requests.post("http://127.0.0.1:19998/control", json={
"action": "set_mode",
"mode": "both"
})
# Get current status
status = requests.get("http://127.0.0.1:19998/status").json()
print(f"Current mode: {status['mode']}")
print(f"Queued messages: {status['queue_size']}")
Debug Logging
Enable verbose logging:
# Edit .env
echo "LOG_LEVEL=DEBUG" >> ~/hermesclaw/.env
# Restart and tail logs
sudo systemctl restart hermesclaw
journalctl -u hermesclaw -f
References
- GitHub: https://github.com/AaronWong1999/hermesclaw
- Hermes Agent: https://github.com/NousResearch/hermes-agent
- OpenClaw: https://github.com/openclaw/openclaw
- OpenCode: https://github.com/sst/opencode
- iLink API: WeChat gateway protocol (proprietary)
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/reason-machines/hermes-skills/hermesclaw-wechat-multi-agent">View hermesclaw-wechat-multi-agent on skillZs</a>