by op7418
Bridge Claude Code / Codex to IM platforms — chat with AI coding agents from Telegram, Discord, or Feishu/Lark.
# Add to your Claude Code skills
git clone https://github.com/op7418/Claude-to-IM-skillname: claude-to-im description: | Bridge THIS Claude Code or Codex session to Telegram, Discord, Feishu/Lark, QQ, or WeChat so the user can chat with Claude from their phone. Use for: setting up, starting, stopping, or diagnosing the claude-to-im bridge daemon; forwarding Claude replies to a messaging app; any phrase like "claude-to-im", "bridge", "消息推送", "消息转发", "桥接", "连上飞书", "手机上看claude", "启动后台服务", "诊断", "查看日志", "配置". Subcommands: setup, start, stop, status, logs, reconfigure, doctor. Do NOT use for: building standalone bots, webhook integrations, or coding with IM platform SDKs — those are regular programming tasks. argument-hint: "setup | start | stop | status | logs [N] | reconfigure | doctor" allowed-tools:
You are managing the Claude-to-IM bridge.
User data is stored at ~/.claude-to-im/.
The skill directory (SKILL_DIR) is at ~/.claude/skills/claude-to-im.
In Codex installs it may instead be ~/.codex/skills/Claude-to-IM-skill.
If neither path exists, fall back to Glob with pattern **/skills/**/claude-to-im/SKILL.md or **/skills/**/Claude-to-IM-skill/SKILL.md and derive the root from the result.
Parse the user's intent from $ARGUMENTS into one of these subcommands:
| User says (examples) | Subcommand |
|---|---|
| setup, configure, 配置, 我想在飞书上用 Claude, 帮我连接 Telegram, 帮我接微信 | setup |
| start, start bridge, 启动, 启动桥接 | start |
| stop, stop bridge, 停止, 停止桥接 | stop |
| status, bridge status, 状态, 运行状态, 怎么看桥接的运行状态 | status |
| logs, logs 200, 查看日志, 查看日志 200 | logs |
| reconfigure, 修改配置, 帮我改一下 token, 换个 bot | reconfigure |
| doctor, diagnose, 诊断, 挂了, 没反应了, bot 没反应, 出问题了 | doctor |
Disambiguation: status vs doctor — Use status when the user just wants to check if the bridge is running (informational). Use doctor when the user reports a problem or suspects something is broken (diagnostic). When in doubt and the user describes a symptom (e.g., "没反应了", "挂了"), prefer doctor.
Extract optional numeric argument for logs (default 50).
Before asking users for any platform credentials, read SKILL_DIR/references/setup-guides.md internally so you know where to find each credential. Do NOT dump the full guide to the user upfront — only mention the specific next step they need to do (e.g., "Go to https://open.feishu.cn → your app → Credentials to find the App ID"). If the user says they don't know how, then show the relevant section of the guide.
Before executing any subcommand, detect which environment you are running in:
AskUserQuestion tool is available. Use it for interactive setup wizards.AskUserQuestion is NOT available. Fall back to non-interactive guidance: explain the steps, show SKILL_DIR/config.env.example, and ask the user to create ~/.claude-to-im/config.env manually.You can test this by checking if AskUserQuestion is in your available tools list.
start, stop, status, logs, reconfigure, doctor)Before running any subcommand other than setup, check if ~/.claude-to-im/config.env exists:
setup wizard using AskUserQuestion.~/.claude-to-im/config.env based on the example:" then show the contents of SKILL_DIR/config.env.example and stop. Don't attempt to start the daemon — without config.env the process will crash on startup and leave behind a stale PID file that blocks future starts.setupRun an interactive setup wizard. This subcommand requires AskUserQuestion. If it is not available (Codex environment), instead show the contents of SKILL_DIR/config.env.example with field-by-field explanations and instruct the user to create the config file manually.
When AskUserQuestion IS available, collect input one field at a time. After each answer, confirm the value back to the user (masking secrets to last 4 chars only) before moving to the next question.
Step 1 — Choose channels
Ask which channels to enable (telegram, discord, feishu, qq, weixin). Accept comma-separated input. Briefly describe each:
/perm ... commands./perm ... commands or quick 1/2/3 replies. Voice messages only use WeChat's own speech-to-text text; raw voice audio is not transcribed by the bridge.Step 2 — Collect tokens per channel
For each enabled channel, collect one credential at a time. Tell the user where to find each value in one sentence. Only show the full guide section (from SKILL_DIR/references/setup-guides.md) if the user asks for help or says they don't know how:
/claude-to-im start, (E) configure events (im.message.receive_v1) and callback (card.action.trigger) with long connection mode, (F) publish second version + admin approve.user_openid, NOT QQ number. If the user doesn't have openid yet, they can leave it empty.cd SKILL_DIR && npm run weixin:login~/.claude-to-im/runtime/weixin-login.html and tries to open it automatically in the local browser.~/.claude-to-im/data/weixin-accounts.json. Running the helper again replaces the previously linked account.CTI_WEIXIN_MEDIA_ENABLED only controls inbound image/file/video downloads. For voice messages, the bridge only accepts the text returned by WeChat's built-in speech-to-text. If WeChat does not provide a transcript, the bridge replies with an error instead of downloading/transcribing raw audio.Step 3 — General settings
Ask for runtime, default working directory, model, and mode:
claude (default), codex, auto
claude — uses Claude Code CLI + Claude Agent SDK (requires claude CLI installed)codex — uses OpenAI Codex SDK (requires codex CLI; auth via codex auth login or OPENAI_API_KEY)auto — tries Claude first, falls back to Codex if Claude CLI not found$CWDcode (default), plan, askStep 4 — Write config and validate
mkdir -p ~/.claude-to-im/{data,logs,runtime,data/messages}~/.claude-to-im/config.env with all settings in KEY=VALUE formatchmod 600 ~/.claude-to-im/config.envSKILL_DIR/references/token-validation.md for the exact commands and expected responses for each platform. This catches typos and wrong credentials before the user tries to start the daemon. For Weixin, a successful QR login already counts as validation./claude-to-im start to start the bridge."startPre-check: Verify ~/.claude-to-im/config.env exists (see "Config check" above). Without it, the daemon will crash immediately and leave a stale PID file.
Run: bash "SKILL_DIR/scripts/daemon.sh" start
Show the output to the user. If it fails, tell the user:
doctor to diagnose: /claude-to-im doctor/claude-to-im logsstopRun: bash "SKILL_DIR/scripts/daemon.sh" stop
statusRun: bash "SKILL_DIR/scripts/daemon.sh" status
logsExtract optional line count N from arguments (default 50).
Run: bash "SKILL_DIR/scripts/daemon.sh" logs N
reconfigure~/.claude-to-im/config.envSKILL_DIR/references/setup-guides.md if they ask for help/claude-to-im stop then /claude-to-im start to apply the changes."If the user wants to switch Weixin accounts during reconfigure, run cd SKILL_DIR && npm run weixin:login again. Each successful scan replaces the previously linked local account.
doctorRun: bash "SKILL_DIR/scripts/doctor.sh"
Show results and suggest fixes for any failures. Common fixes:
cd SKILL_DIR && npm installcd SKILL_DIR && npm run buildsetupcd SKILL_DIR && npm run weixin:loginFor more complex issues (messages not received, permission timeouts, high memory, stale PID files), read SKILL_DIR/references/troubleshooting.md for detailed diagnosis steps.
Feishu upgrade note: If the user upgraded from an older version of this skill and Feishu is returning permission errors (e.g. streaming cards not working, typing indicators failing, permission buttons unresponsive), the root cause is almost certainly missing permissions or callbacks in the Feishu backend. Refer the user to the "Upgrading from a previous version" section in SKILL_DIR/references/setup-guides.md — they need to add new scopes (cardkit:card:write, cardkit:card:read, im:message:update, im:message.reactions:read, im:message.reactions:write_only), add the card.action.trigger callback, and re-publish the app. The upgrade requires two publish cycles because adding the callback needs an active WebSocket connection (bridge must be running).
~/.claude-to-im/config.env — survives across sessions.Bridge Claude Code / Codex to IM platforms — chat with AI coding agents from Telegram, Discord, Feishu/Lark, QQ, or WeChat.
Want a desktop GUI instead? Check out CodePilot — a full-featured desktop app with visual chat interface, session management, file tree preview, permission controls, and more. This skill was extracted from CodePilot's IM bridge module for users who prefer a lightweight, CLI-only setup.
This skill runs a background daemon that connects your IM bots to Claude Code or Codex sessions. Messages from IM are forwarded to the AI coding agent, and responses (including tool use, permission requests, streaming previews) are sent back to your chat.
You (Telegram/Discord/Feishu/QQ/WeChat)
↕ Bot API
Background Daemon (Node.js)
↕ Claude Agent SDK or Codex SDK (configurable via CTI_RUNTIME)
Claude Code / Codex → reads/writes your codebase
/perm commands / quick 1/2/3 replies (Feishu/QQ/WeChat)chmod 600, auto-redacted in all logs/claude-to-im setup, or tell Codex claude-to-im setupCTI_RUNTIME=claude or auto) — installed and authenticated (claude command available)CTI_RUNTIME=codex or auto) — npm install -g @openai/codex. Auth: run codex auth login, or set OPENAI_API_KEY (optional, for API mode)Choose the section that matches the AI agent product you actually use.
npx skillsnpx skills add op7418/Claude-to-IM-skill
After installation, tell Claude Code:
/claude-to-im setup
If you want WeChat specifically, you can also say:
帮我接微信
git clone https://github.com/op7418/Claude-to-IM-skill.git ~/.claude/skills/claude-to-im
Claude Code discovers it automatically.
git clone https://github.com/op7418/Claude-to-IM-skill.git ~/code/Claude-to-IM-skill
mkdir -p ~/.claude/skills
ln -s ~/code/Claude-to-IM-skill ~/.claude/skills/claude-to-im
git clone https://github.com/op7418/Claude-to-IM-skill.git ~/code/Claude-to-IM-skill
bash ~/code/Claude-to-IM-skill/scripts/install-codex.sh
For local development with a live checkout:
bash ~/code/Claude-to-IM-skill/scripts/install-codex.sh --link
The install script places the skill under ~/.codex/skills/claude-to-im, installs dependencies, and builds the daemon.
After installation, tell Codex:
claude-to-im setup
If you want WeChat specifically, you can also say:
帮我接微信桥接
git clone https://github.com/op7418/Claude-to-IM-skill.git ~/.codex/skills/claude-to-im
cd ~/.codex/skills/claude-to-im
npm install
npm run build
Claude Code: Start a new session and type / — you should see claude-to-im in the skill list. Or ask Claude: "What skills are available?"
Codex: Start a new session and say claude-to-im setup, start bridge, or 帮我接微信桥接.
Choose the update flow that matches both your AI agent product and your installation method.
If you installed with npx skills, re-run:
npx skills add op7418/Claude-to-IM-skill
If you installed via git clone or symlink:
cd ~/.claude/skills/claude-to-im
git pull
npm install
npm run build
Then tell Claude Code:
/claude-to-im doctor
/claude-to-im start
If you installed with the Codex install script in copy mode:
rm -rf ~/.codex/skills/claude-to-im
bash ~/code/Claude-to-IM-skill/scripts/install-codex.sh
If you installed with --link or cloned directly into the Codex skills directory:
cd ~/.codex/skills/claude-to-im
git pull
npm install
npm run build
Then tell Codex:
claude-to-im doctor
start bridge
Claude Code
/claude-to-im setup
Codex
claude-to-im setup
The wizard will guide you through:
Claude Code
/claude-to-im start
Codex
start bridge
The daemon starts in the background. You can close the terminal — it keeps running.
Open your IM app and send a message to your bot. Claude Code / Codex will respond through the bridge.
When Claude needs to use a tool (edit a file, run a command), you'll see a permission prompt with Allow / Deny buttons right in the chat (Telegram/Discord), or a text /perm command prompt / quick 1/2/3 replies (Feishu/QQ/WeChat).
All commands are run inside Claude Code or Codex:
| Claude Code | Codex (natural language) | Description |
|---|---|---|
| /claude-to-im setup | "claude-to-im setup" / "配置" | Interactive setup wizard |
| /claude-to-im start | "start bridge" / "启动桥接" | Start the bridge daemon |
| /claude-to-im stop | "stop bridge" / "停止桥接" | Stop the bridge daemon |
| /claude-to-im status | "bridge status" / "状态" | Show daemon status |
| /claude-to-im logs | "查看日志" | Show last 50 log lines |
| /claude-to-im logs 200 | "logs 200" | Show last 200 log lines |
| /claude-to-im reconfigure | "reconfigure" / "修改配置" | Update config interactively |
| /claude-to-im doctor | "doctor" / "诊断" | Diagnose issues |
The setup wizard provides inline guidance for every step. Here's a summary:
@BotFather on Telegram → /newbot → follow prompts123456789:AABbCc...)/setprivacy → Disable (for group use)@userinfobotbot → permissions: Send Messages, Read Message History, View Channels → copy invite URLsetup wizard provides the exact JSON)im.message.receive_v1 eventQQ currently supports C2C private chat only. No group/channel support, no inline permission buttons, no streaming preview. Permissions use text
/perm ...commands. Image inbound only (no image replies).
CTI_QQ_ALLOWED_USERS takes user_openid values (not QQ numbers) — can be left empty initiallyCTI_QQ_IMAGE_ENABLED=false if the underlying provider doesn't support image inputWeChat currently uses QR login, single-account mode, text-based permissions, and no streaming preview.
cd ~/.claude/skills/claude-to-im && npm run weixin:logincd ~/.codex/skills/claude-to-im && npm run weixin:login~/.claude-to-im/runtime/weixin-login.html and tries to open it in your browser automatically~/.claude-to-im/data/weixin-accounts.jsonAdditional notes:
CTI_WEIXIN_MEDIA_ENABLED controls inbound image/file/video downloads onlyvoice_item.text, the bridge replies with an error instead of downloading/transcribing raw voice audio/perm ... commands or quick 1/2/3 replies~/.claude-to-im/
├── config.env ← Credentials & settings (chmod 600)
├── data/ ← Persistent JSON storage
│ ├── sessions.json
│ ├── bindings.json
│ ├── permissions.json
│ └── messages/ ← Per-session message history
├── logs/
│ └── bridge.log ← Auto-rotated, secrets redacted
└── runtime/
├── bridge.pid ← Daemon PID file
└── statu
No comments yet. Be the first to share your thoughts!