A Lark (Feishu) bot that bridges group chat conversations to Claude Code, giving your team an AI assistant that can search the web, read chat history, and even generate and share files — all from within Lark.
- Python 3.10+
- Claude Code CLI installed and authenticated (
claudemust be in your PATH) - A Lark app with bot capabilities enabled — create one at the Lark Developer Console (or Feishu Developer Console for Feishu)
- Go to the Developer Console and create a new app
- Under Bot, enable the bot capability
Navigate to Permissions & Scopes and add:
| Permission | Purpose |
|---|---|
im:message or im:message:send_as_bot |
Send and reply to messages |
im:message:readonly |
Read chat history for context |
im:resource |
Upload images and files |
- Go to Events & Callbacks
- Under Event Subscriptions, add the
im.message.receive_v1event - For the subscription method, select WebSocket (long connection)
Create a new version and publish the app. If your organization requires admin approval, request it.
Invite your bot into any Lark group chat where you want it available.
git clone git@github.com:lorabit110/claude-code-gateway.git
cd claude-code-gateway
python -m venv venv
source venv/bin/activate # on Windows: venv\Scripts\activate
pip install -r requirements.txtcp .env.example .envEdit .env and fill in your Lark app credentials:
LARK_APP_ID=cli_xxxxxxxxxx
LARK_APP_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
| Variable | Default | Description |
|---|---|---|
CLAUDE_MODEL |
claude-opus-4-6 |
Claude model to use |
CLAUDE_MAX_TURNS |
10 |
Max agentic turns per invocation |
CLAUDE_TIMEOUT |
120 |
Subprocess timeout in seconds |
LARK_DOMAIN |
https://open.larksuite.com |
Use https://open.feishu.cn for Feishu |
python main.pyThe bot connects to Lark via WebSocket and starts listening for messages. You should see:
Bot identity: name=YourBot, open_id=ou_xxxxxx
Starting WebSocket connection...
- In a group chat — @mention the bot followed by your question
- In a DM — message the bot directly (no @mention needed)
- Images and files — send an image or file to the bot and it will view and analyze it
- File generation — ask the bot to write a script, generate an image, etc. It will send the file as an attachment in the chat
/new— reset the conversation session and start fresh/stop— interrupt a running request
- The bot receives messages via Lark's WebSocket event stream
- On @mention (or DM), it builds a prompt with recent conversation context
- It invokes
claude -p --output-format stream-jsonas a subprocess with MCP tools - A live-updating card shows progress (tool usage and intermediate text) as Claude works
- When Claude finishes, the card is replaced with the final response
- Any files Claude generated in the workspace are uploaded and sent to the chat
- Each chat maintains a persistent Claude session (stored on disk) for multi-turn conversations
The system prompt is loaded from system_prompt.txt at runtime — edit it without changing code. Each chat can also have a WORKSPACE.md in its workspace directory (workspaces/<chat_id>/) that is appended to the system prompt automatically. Claude can create and update this file to persist notes across sessions.
main.py Entry point
config.py Configuration from environment variables
system_prompt.txt System prompt (editable at runtime)
bot/
event_handler.py WebSocket event handling, streaming progress, bot commands
message_formatter.py Response formatting as interactive markdown cards
message_parser.py Lark message parsing and @mention stripping
claude_integration/
invoker.py Claude Code CLI subprocess with streaming and session management
prompt_builder.py Prompt construction with conversation context
lark_client/
client.py Lark API client factory
message_api.py Message send/reply/update, reactions, file/image upload/download
mcp_tools/
lark_server.py MCP server exposing Lark read and download tools to Claude
| Problem | Fix |
|---|---|
Claude Code CLI not found |
Make sure claude is installed and in your PATH |
| Bot doesn't respond in group | Verify the bot is @mentioned and has im:message:readonly permission |
| File uploads fail | Add the im:resource permission and re-publish the app |
Get bot info failed |
Check LARK_APP_ID and LARK_APP_SECRET in .env |
| Timeout errors | Increase CLAUDE_TIMEOUT for complex queries |
| Session lost after restart | Sessions are now persisted in workspaces/<chat_id>/session.json |