Claude Code channel plugin for Feishu/Lark — chat with Claude through Feishu with local-file memory and scheduled jobs
$git clone https://github.com/is908/claude-lark-pluginInstalls into the current project.
Install claude-lark-plugin by running `git clone https://github.com/is908/claude-lark-plugin`, then use it for the current task and follow its documentation at https://github.com/is908/claude-lark-plugin.
| 1 | # Claude Lark Plugin |
| 2 | |
| 3 | [](README_CN.md) |
| 4 | [](package.json) |
| 5 | [](LICENSE) |
| 6 | |
| 7 | Chat with Claude Code in real time through Feishu (Lark). Local-file memory, scheduled jobs, rich media support. |
| 8 | |
| 9 | --- |
| 10 | |
| 11 | ## How It Works |
| 12 | |
| 13 | ``` |
| 14 | Feishu User ──> Feishu Open Platform ──WebSocket──> claude-lark-plugin (MCP Server) ──> Claude Code |
| 15 | <── reply / edit / react ──< |
| 16 | ``` |
| 17 | |
| 18 | The plugin connects to Feishu via the Lark SDK WebSocket client, receives messages in real time, enriches them with memory context, and forwards them to Claude Code as an MCP channel. Claude's responses are sent back through the Feishu IM API. |
| 19 | |
| 20 | --- |
| 21 | |
| 22 | ## Features |
| 23 | |
| 24 | ### Messaging |
| 25 | |
| 26 | - Direct messages (P2P) and group chats (responds to @bot mentions) |
| 27 | - Rich message types: text, post (rich text), image, file, audio, video, interactive cards |
| 28 | - **Image auto-download**: images are downloaded to a local inbox so Claude can see them directly |
| 29 | - Quoted reply support with automatic parent message fetching |
| 30 | - Attachment extraction (image, file, audio, video) with type-aware download |
| 31 | - **Reaction events**: user emoji reactions on bot messages are forwarded to Claude |
| 32 | |
| 33 | ### Responding |
| 34 | |
| 35 | - Text replies with automatic chunking for long messages (configurable limit) |
| 36 | - **Card rendering**: long or markdown-rich replies (headings, code blocks, tables, lists, bold, or > 500 chars) auto-render as Feishu cards. Pass `format='card'` to force card, `format='text'` to force plain. Optional `footer` footnote supported |
| 37 | - **Ack reaction**: bot automatically reacts with an emoji (default: MeMeMe) on receive, removes it after replying |
| 38 | - Image and file uploads (images up to 10 MB, files up to 30 MB) |
| 39 | - Message editing (plain text and card markdown) |
| 40 | - Emoji reactions on any message |
| 41 | - Auto-chunking splits at paragraph, line, or word boundaries |
| 42 | |
| 43 | ### Memory |
| 44 | |
| 45 | - Three-layer architecture: Buffer, Episodic, and Semantic memory |
| 46 | - Auto-flush distillation from conversation buffer to episodic memory |
| 47 | - Local markdown-file storage under `~/.claude/channels/lark/memories/` |
| 48 | - User profiles (tiered public/private since v0.10.0), chat episodes, thread episodes, and global skills |
| 49 | - Memory-enriched context injection on every incoming message, filtered by caller identity |
| 50 | |
| 51 | ### Privacy & Security (v0.9.0+) |
| 52 | |
| 53 | - **Server-derived caller identity**: sensitive tools (`save_memory`, `create_job`, `list_jobs`, `update_job`, `delete_job`, `what_do_you_know`, `forget_memory`) resolve the calling user from the authenticated Feishu event stream, not from tool arguments — socially-engineered prompts cannot act on behalf of another user |
| 54 | - **Memory transparency (v0.11.0+)**: `what_do_you_know` lists what the bot has stored about the caller (filtered by current-chat visibility); `forget_memory` removes a specific line by hash. Optional `promote_to_rule` feeds corrections into `privacy-rules.md` — a self-learning loop that makes future misclassifications less likely |
| 55 | - **Append-only audit log (v0.11.0+)**: `~/.claude/channels/lark/audit.log` records every sensitive-tool invocation (timestamp / tool / caller / outcome / redacted args) so the operator can retrospectively inspect what was accessed on their machine |
| 56 | - **Terminal skills default to redacted output (v0.11.0+)**: `/lark:jobs` hides prompt bodies by default; verbose opt-in is required. Destructive operations require interactive confirmation |
| 57 | - **Tiered profile memory (v0.10.0+)**: each user's profile is split into `public.md` (visible to anyone who @mentions the user) and `private.md` (owner-only). Private-chat preferences no longer leak into groups via @mention injection |
| 58 | - **L1/L2/L3 classification** (v0.10.0+): hardcoded regex + keyword rules catch phones / credentials / sensitive Chinese keywords. Email is intentionally NOT in L1 — the plugin targets **work-chat use cases** where emails are commonly shared via signatures/directories; personal deployments can add their own "Always private" email rule to `privacy-rules.md`. User-editable `privacy-rules.md` covers personal/org-specific cases; LLM handles the nuance. `parseTieredProfile` applies an L1 safety net over LLM output so misclassified credentials get forced to private |
| 59 | - **Legacy-profile migration respects L2 rules (v0.11.1+)**: if the operator authors `privacy-rules.md` before (or during) the upgrade, `## Always private` phrases are applied as case-insensitive substring matches during migration — org-specific codenames, client names, and people mentions get routed to `private.md` even though L1 alone wouldn't flag them |
| 60 | - **`list_jobs` visibility filter**: in a group chat, members only see jobs whose `target_chat_id` matches that group (with prompt bodies redacted for non-owners); in a private chat, the caller sees their own jobs. Group members can no longer inspect each other's |