feishu-bridge
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@feishu-bridgeHelp me prepare for this week's team meeting"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Feishu Bridge
A PoC exploring how collaboration tools should be redesigned for the AI Agent era.

One core. Two surfaces (CLI + MCP). Real Feishu data, real meeting brief — in 30 seconds.
What is this
A small TypeScript library that lets AI tools (Claude Desktop, Cursor, Claude Code...) use Feishu in a natural way.
Same business core, two surfaces:
CLI form —
feishu-bridge ..., callable from any AI that can spawn a shellMCP form — exposes the same capabilities as MCP tools
Both share the same AI Friendly design philosophy.
Related MCP server: lark-mcp
Why two forms
I was using Claude Code and noticed something: even when GitHub MCP exists, Claude often falls back to invoking gh CLI for GitHub tasks. CLI was already installed, already authenticated, zero config.
That reframed my mental model of AI Friendly:
AI Friendly is not about which protocol you pick. It's about whether AI can use your product smoothly — through whatever surface is available.
So this PoC implements the same capabilities twice — as a CLI and as an MCP server — to prove the underlying design philosophy is what matters, not the protocol.
The full demo narrative
The user types into Claude Desktop:
"Help me prepare for this week's team meeting."
Behind the scenes:
Step 1 — feishu_search_events(query="周会")
Claude calls the search-events tool. The bot's tenant_access_token can only see the bot's own primary calendar (empty) — but search-events gracefully degrades: it queries /calendar/v4/freebusy/list for the user's busy windows (which tenant_access_token CAN read), and returns a composite payload:
{
"events": [], // bot doesn't have detail access
"busy_windows": [ // …but it can see WHEN the user is busy
{ "human_label": "周三 14:00-14:30", "duration_minutes": 30, ... },
{ "human_label": "周四 15:00-16:00", "duration_minutes": 60, ... },
{ "human_label": "周五 16:00-17:00", "duration_minutes": 60, ... }
],
"source_diagnostics": {
"root_cause": "app_identity_vs_user_identity: bot is authenticated as
application identity ou_6687… and sees only its OWN primary calendar
via tenant_access_token. The user has 10 busy windows visible via
/freebusy/list, but Feishu's freebusy protocol intentionally omits
summaries. Detailed event read requires either (a) the bot is added
as an attendee, (b) the user shares the calendar via ACL, or (c) the
app uses user_access_token (OAuth) instead."
},
"recovery_hints": [
{ "id": "use_busy_windows", "actor": "mcp-caller", ... },
{ "id": "switch_to_user_access_token", "actor": "app-developer", ... }
]
}Claude reads the description contract ("don't fabricate titles when only busy_windows are present") and responds:
"I see you're busy 周三 14:00-14:30 and 周四 15:00-16:00. Which one did you mean?"
Step 2 — feishu_user_recent_work(user_id="ou_3de3...")
Once the user confirms, Claude calls the recent-work aggregator. One composite call pulls all 5 project-tracker rows from a real Bitable, normalizes the schema (Feishu Bitable encodes person fields as arrays of {name, email}, dates as ms timestamps, etc.), and returns:
{
"user": { "open_id": "ou_3de3…", "name": "胡奕舟" },
"bitable_updates": [
{ "title": "权限模块设计", "status": "进行中", "updated_at_human": "2026-05-23", ... },
{ "title": "登录组件重构", "status": "已完成", "updated_at_human": "2026-05-22", ... },
{ "title": "移动端适配", "status": "进行中", "updated_at_human": "2026-05-20", ... },
{ "title": "监控大盘搭建", "status": "阻塞", "updated_at_human": "2026-05-18", ... },
{ "title": "文档同步工具", "status": "已完成", "updated_at_human": "2026-05-15", ... }
],
"source_diagnostics": { "docx": "Skipped: drive scope not yet granted — see OBSERVATIONS.md" }
}Step 3 — Claude composes the brief
Claude reads the JSON and writes:
# 前端团队周会 预读
## 本周完成 (2)
- ✅ 登录组件重构 (2026-05-22) — OAuth 2.1 改造,接入 Device Flow
- ✅ 文档同步工具 (2026-05-15) — 已上线 v1.0,日均同步 2000+ 文档
## 本周进行中 (2)
- 🔄 权限模块设计 (2026-05-23) — RBAC 方案评审中,本周完成 PRD
- 🔄 移动端适配 (2026-05-20) — iOS/Android/H5 三端兼容验证
## 风险项 (1)
- 🚧 监控大盘搭建 【阻塞】(2026-05-18) — 等运维资源A task that takes a human ~1 hour. AI does it in ~10 seconds.
See examples-meeting-brief.md for the actual generated output.
Five AI Friendly principles this PoC embodies
Tool descriptions are written for the LLM, not for human developers — see how
feishu_search_events's description explicitly says "DO NOT invent event titles — say 'the user has a 30-min block at 周三 14:00'" (src/mcp/server.ts)Errors carry structured recovery hints (
error_code,recovery_hint,is_retryable, plus actor-taggedrecovery_hints[]) so the LLM can self-correct or surface the dev-side fixComposite operations over fine-grained APIs —
feishu_user_recent_workis one call that internally fans out across Bitable / (future) Docx / IMTools collaborate — each description explicitly names the next tool to chain into (
search_events → get_attendees → user_recent_work)Graceful degradation with self-explanation — when the bot lacks visibility,
source_diagnosticsandrecovery_hintstell the LLM exactly why and what to try next, instead of returningevents: []
Repository layout
src/
core/
client.ts # Feishu API client (token cache + freebusy + calendar + bitable)
load-env.ts # zero-dep .env loader (auto-loaded by CLI and MCP)
types.ts
tools/ # the 3 capability functions, single source of truth
search-events.ts # composite: bot events + user freebusy + diagnostics
user-recent-work.ts# composite: bitable rows + (future) docx
get-attendees.ts # event attendees enriched with user profile
cli/index.ts # CLI surface (commander)
mcp/server.ts # MCP surface (@modelcontextprotocol/sdk)
assets/
demo.gif # the 30-second demo GIF
demo.tape # vhs source — `vhs assets/demo.tape` to re-recordQuick start
# 1. install
npm install
# 2. configure (one-time) — auto-loaded by both CLI and MCP
cp .env.example .env
# Fill in:
# FEISHU_APP_ID
# FEISHU_APP_SECRET
# FEISHU_PROJECT_BITABLE_APP_TOKEN (required for user-recent-work)
# FEISHU_PROJECT_BITABLE_TABLE_ID
# FEISHU_USER_OPEN_ID (optional — fallback for search-events)
# 3. build
npm run build
# 4. smoke test
node dist/cli/index.js ping
# => {"ok":true,"message":"feishu-bridge CLI is alive","version":"0.2.0"}
# 5. real query — composite call returns 5 bitable rows
node dist/cli/index.js user-recent-work --user-id ou_xxxxxxxxxxxxxxxx --days 14
# 6. search-events with freebusy fallback — see source_diagnostics
node dist/cli/index.js search-events --query 周会 --user-id ou_xxxxxxxxxxxxxxxxWire up to Claude Desktop (MCP)
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"feishu-bridge": {
"command": "node",
"args": ["/absolute/path/to/feishu-bridge-poc/dist/mcp/server.js"],
"env": {
"FEISHU_APP_ID": "cli_xxxxxxxxxxxxxxxx",
"FEISHU_APP_SECRET": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"FEISHU_PROJECT_BITABLE_APP_TOKEN": "xxxxxxxxxxxxxxxxxx",
"FEISHU_PROJECT_BITABLE_TABLE_ID": "tblxxxxxxxxxxxxxxx"
}
}
}
}Restart Claude Desktop. You should see feishu_search_events, feishu_get_attendees, feishu_user_recent_work, and feishu_ping available.
Status (v0.2.0)
Surface | What works today |
Core | token cache · 7 verified endpoints · zero-dep .env loader |
CLI |
|
MCP |
|
End-to-end | Bitable: ✅ 5 real records · Calendar: ✅ 10 real freebusy windows via fallback |
What this PoC is intentionally not
See ROADMAP.md → "Explicitly out of scope". Notably: docx writeback, full Feishu API surface coverage, OAuth/user_access_token (would unlock event titles — captured as a recovery_hint).
Companion docs
DESIGN_PHILOSOPHY.md— the five principles, expandedGAPS.md— 7 concrete OpenAPI-level gaps observed while building this PoC (with workarounds and production fixes)OBSERVATIONS.md— ecosystem-level notes on the Feishu AI Friendly landscape (lark-cli / lark-openapi-mcp / peer MCP servers / MCP spec)ROADMAP.md— stages, exit criteria, out-of-scope list
License
MIT
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/zhengjs1225/feishu-bridge-poc'
If you have feedback or need assistance with the MCP directory API, please join our Discord server