Feishu frontend for local Claude CLI and Codex CLI execution
Forward Feishu bot messages to your local machine, execute them with Claude or Codex, and send the results back to Feishu.
A standalone Feishu bridge for local CLI agents.
The bridge opens a Feishu WebSocket connection using your bot app credentials, receives messages, stores short local history per conversation, calls either claude -p or codex exec, and sends the reply back to the same Feishu chat.
Core rule: one Feishu bot = one bridge process = one local execution environment.
Before starting, make sure the host machine has:
- Node.js 22 or newer
- A Feishu self-built app with bot access and valid
FEISHU_APP_ID/FEISHU_APP_SECRET - A locally installed and authenticated
claudeCLI orcodexCLI - Local filesystem access to the workspace you want the bot to operate on
| Feature | Description |
|---|---|
| Direct Feishu bridge | Receives im.message.receive_v1 over Feishu WebSocket |
| Selectable CLI backend | Runs either claude -p or codex exec on the machine that owns files and credentials |
| Session continuity | Per-session JSON history under data/sessions/ |
| Inbound media download | Feishu images/files are saved locally and exposed to the selected backend |
| Outbound media send | The backend can return [[image:/abs/path]] / [[file:/abs/path]] markers |
| Opt-in group delegation | Supports explicit protocol-marked delegated tasks in Feishu groups |
| Hosted group discussion | Supports host-led multi-bot discussion with bounded stance, cross-exam, and verdict phases |
| Dedicated bot profile | Separate env file and launcher for isolated bot deployments |
- Clone the repo and install dependencies:
git clone https://github.com/wwb1942/feishu-cli-bridge.git
cd feishu-cli-bridge
npm install-
Create a Feishu app in the Feishu Open Platform Developer Console, then copy the app credentials from the console. Enable the app's bot capability and subscribe to the
im.message.receive_v1event before starting the bridge. -
Prepare an env file:
cp .env.example .env.feishu-direct- Fill in the Feishu credentials and choose a backend:
FEISHU_APP_ID=...
FEISHU_APP_SECRET=...
BRIDGE_BACKEND=claudeTo enable group delegation and hosted multi-bot discussion:
FEISHU_GROUP_DELEGATION_ENABLED=trueSwitch to Codex backend:
BRIDGE_BACKEND=codex- Start the bridge:
node src/launcher.js .env.feishu-directOr use npm:
npm run start:feishuWindows PowerShell convenience wrapper:
./run-feishu-direct.ps1Unix/macOS convenience wrapper:
./run-feishu-direct.shGroup collaboration is opt-in. Enable it with:
FEISHU_GROUP_DELEGATION_ENABLED=trueOnce enabled:
- Human -> bot execution uses a real Feishu
@botmention in the group. - Bot -> bot delegation requires a leading
[delegate] [task:<id>]prefix and a real Feishu mention of the target bot. - Delegated bot results must start with
[task:<id>]so the origin or host bot can reconcile task state. - Only the elected host bot handles the original multi-bot discussion request.
- Non-host participants ignore the original human message and wait for delegated prompts from the host.
- Moderated discussion is host-led and bounded. It does not allow free bot-to-bot chatter.
- Task ids are used for reconciliation, timeout tracking, and out-of-order result recovery.
- The origin bot only posts a delegation confirmation, a send failure, or a wait-timeout notice.
- The delegated bot posts the final success or failure result in the group.
Host election for discussions is deterministic:
- If
FEISHU_DISCUSSION_HOST_BOT_OPEN_IDis set and that bot is mentioned, it becomes host. - Otherwise the first mentioned bot becomes host.
- If mention order is unavailable, the host falls back to lexicographic
open_idorder.
Discussion flow:
stance: the host asks each participant for an initial positioncross_exam: the host sends targeted follow-up challenges or questionsconvergence: the host narrows disagreements and prepares a conclusionverdict: the host posts one final group answer
Inbound:
- Feishu image/file messages are downloaded into the local
data/media/tree. - Image attachments are also passed into
codex execvia--imagewhen using the Codex backend. - Pure placeholder media events like
[image]are queued and merged with the next real text message from the same user. - Duplicate inbound Feishu events are deduplicated with persisted state plus per-event atomic claim files, so retries, short restarts, and accidental multi-process overlap do not replay the same user message.
- Assistant-originated
im.message.receive_v1events are ignored by default; when group delegation is enabled, only assistant messages with a valid leading protocol marker are forwarded. - Inbound event callbacks are acknowledged immediately and processed asynchronously in-process, reducing Feishu retries when attachment download or CLI execution is slow.
- Only one bridge process may hold the
DATA_DIR/bridge.lockinstance lock at a time. A second copy exits instead of double-consuming the same Feishu stream.
Outbound:
- If the backend wants to send media back, it should emit markers in the final text:
[[image:/absolute/path/to/image.png]]
[[file:/absolute/path/to/report.pdf]]
- Keep any normal user-facing text outside those marker lines.
- Media-heavy questions use a shorter retained history window to avoid long stalls.
FEISHU_APP_ID=...
FEISHU_APP_SECRET=...BRIDGE_BACKEND=claude
PROJECT_ROOT=/path/to/feishu-cli-bridge
DATA_DIR=/path/to/feishu-cli-bridge/data/defaultFEISHU_DOMAIN=feishu
FEISHU_ENCRYPT_KEY=
FEISHU_VERIFICATION_TOKEN=
FEISHU_GROUP_DELEGATION_ENABLED=false
FEISHU_BOT_OPEN_ID=
FEISHU_DELEGATE_TIMEOUT_MS=300000
FEISHU_DISCUSSION_HOST_BOT_OPEN_ID=
FEISHU_DISCUSSION_MAX_BOT_MESSAGES=20
FEISHU_DISCUSSION_MAX_DURATION_MS=900000
FEISHU_ACCOUNT_ID=custom-1
FEISHU_REPLY_CHUNK_CHARS=1400
FEISHU_MAX_INBOUND_BYTES=31457280
FEISHU_INBOUND_DEDUP_WINDOW_MS=12000
FEISHU_INBOUND_PROCESSING_TTL_MS=300000
FEISHU_INBOUND_REPLIED_TTL_MS=86400000CLAUDE_BIN=claude
CLAUDE_MODEL=
CLAUDE_EFFORT=
CLAUDE_WORKDIR=/path/to/your/workspace
CLAUDE_HISTORY_LIMIT=12
CLAUDE_IMAGE_HISTORY_LIMIT=4
CLAUDE_TIMEOUT_MS=240000
CLAUDE_ALLOWED_TOOLS=Read,Glob,Grep,Bash
CLAUDE_ADD_DIRS=
CLAUDE_BRIDGE_SYSTEM_PROMPT=You are Claude in a Feishu bot bridge running on the user machine. Reply concisely and helpfully in plain text. Reply with final user-facing text only. Do not mention skills, workflow, or internal process. If you want to return media, emit one marker per line: [[image:/absolute/path]] or [[file:/absolute/path]].CODEX_BIN=codex
CODEX_MODEL=gpt-5.4
CODEX_REASONING_EFFORT=low
CODEX_SANDBOX=workspace-write
CODEX_WORKDIR=/path/to/your/workspace
CODEX_HISTORY_LIMIT=12
CODEX_MAX_IMAGE_ATTACHMENTS=4
CODEX_IMAGE_HISTORY_LIMIT=4
CODEX_TIMEOUT_MS=180000
CODEX_MAX_IMAGE_DIMENSION=1280
CODEX_BRIDGE_SYSTEM_PROMPT=You are Codex in a Feishu bot bridge. Reply concisely and helpfully in plain text. If you want to return media, emit one marker per line: [[image:/absolute/path]] or [[file:/absolute/path]].Replace those path examples with real paths on your own machine. CLAUDE_WORKDIR and CODEX_WORKDIR are the default working directories for agent execution, while PROJECT_ROOT and DATA_DIR point at the bridge project and its local runtime data.
Notes:
BRIDGE_BACKEND=claudeexpects a working localclaudeCLI that is already authenticated and configured.BRIDGE_BACKEND=codexexpects a working localcodexCLI that is already authenticated and configured.CLAUDE_ALLOWED_TOOLSis the main switch that decides whether Claude can actually read files or run shell commands from Feishu requests.FEISHU_GROUP_DELEGATION_ENABLED=trueturns on both explicit group delegation and hosted multi-bot discussion.FEISHU_BOT_OPEN_IDis optional. If unset, the bridge tries to resolve the current bot identity at startup.FEISHU_DELEGATE_TIMEOUT_MScontrols how long the origin or host waits for a delegated result before posting a timeout notice.FEISHU_DISCUSSION_HOST_BOT_OPEN_IDoptionally pins the host bot when that bot is mentioned.FEISHU_DISCUSSION_MAX_BOT_MESSAGESandFEISHU_DISCUSSION_MAX_DURATION_MSbound discussion length.
Run Claude and Codex side-by-side safely:
- Use separate Feishu bot app credentials
- Use separate env files such as
.env.feishu-claudeand.env.feishu-codex - Use separate
FEISHU_ACCOUNT_IDvalues - Use separate
DATA_DIRvalues to avoid lock, session, and dedupe collisions - Run each profile as a separate process
| File | Purpose |
|---|---|
src/feishu-adapter.js |
Feishu WebSocket, media download/upload, and send/reply adapter |
src/bridge-app.js |
Bridge bootstrap, inbound dedupe, claim handling, and media merge flow |
src/bridge-runtime.js |
Route-aware runtime for direct chat, explicit delegation, and hosted discussion orchestration |
src/group-routing.js |
Group routing, protocol marker parsing, host election, and session-key construction |
src/launcher.js |
Cross-platform env-file loader and bridge launcher |
src/codex-runner.js |
Launches codex exec with rolling history and image attachments |
src/claude-runner.js |
Launches claude -p with explicit tool allowances and JSON parsing |
src/runner-utils.js |
Shared prompt builder and media marker parser |
src/pending-task-store.js |
JSON persistence for delegation/discussion task state and out-of-order result recovery |
src/session-store.js |
JSON storage for conversations, inbound claims, and process lock state |
src/config.js |
Environment/config loader |
src/index.js |
Process entrypoint and shutdown wiring |
run-feishu-direct.ps1 |
Windows PowerShell launcher for dedicated bot profiles |
run-feishu-direct.sh |
Unix/macOS launcher for dedicated bot profiles |
Issues and pull requests are welcome.
- Open an issue first for larger changes or behavior changes.
- Keep secrets, env files, and runtime data out of git.
- Run
npm testandnpm run checkbefore sending a PR.
Initial project framing and some README conventions were inspired by telegram-cli-bridge. This repository is implemented as a standalone Feishu bridge with a different runtime architecture and local CLI execution through claude -p or codex exec.
This project is released under the MIT License. See LICENSE.
- Never commit
.env.feishu-direct,.env.local, or any real credential file. - Keep bot credentials only in local env files or your process manager.
data/,node_modules/, and*.bak.*are excluded from git.- Before publishing, run a quick secret scan on the repo and verify only placeholder values remain in
.env.example.
- The bridge core is cross-platform at the Node.js level.
node src/launcher.js <env-file>is the recommended startup path on Linux, macOS, and Windows.- On Windows, defaults are
CODEX_BIN=codex.cmdandCLAUDE_BIN=claude.cmd; on Unix-like systems they default tocodexandclaude. run-feishu-direct.ps1is provided as a native PowerShell launcher for Windows.run-feishu-direct.shremains as a Unix convenience wrapper.- The previous Linux-only
/proclock dependency has been removed.