openbird
v3.1.0
Published
Feishu infrastructure service — relay mode or MCP server mode
Downloads
2,081
Maintainers
Readme
OpenBird
飞书(Lark)非官方基础设施服务,运行在本地,通过浏览器 cookie 连接飞书,提供两个显式运行模式:
- Relay 模式 — 连接飞书 WebSocket,将消息标准化后 POST 到你提供的 webhook 地址
- MCP 模式 — 通过 stdio 暴露多个飞书 API 工具,供 AI Agent 调用
快速开始
# 克隆并安装
git clone https://github.com/ztxtxwd/openbird.git
cd openbird
pnpm install
# 配置
cp .env.example .env
# 编辑 .env,粘贴你从浏览器 DevTools 复制的飞书 cookieMCP 模式
OPENBIRD_COOKIE="your_cookie_here" node bin/openbird.js mcp仅启动 MCP Server(stdio),不连接 WebSocket,不转发事件。
Relay 模式
OPENBIRD_COOKIE="your_cookie_here" \
node bin/openbird.js relay http://localhost:3000/webhook连接飞书 WebSocket 并将所有事件转发到你提供的 webhook 地址。
运行示例
node examples/basic-usage.mjs该示例以 MCP 模式启动 OpenBird,并演示如何通过 stdio 连接 MCP 客户端。
配置
| 环境变量 | 必填 | 说明 |
|---|---|---|
| OPENBIRD_COOKIE | 是 | 飞书浏览器 cookie 字符串 |
| OPENBIRD_DEBUG | 否 | 设为 true 开启调试日志 |
| OPENBIRD_ENRICH | 否 | Relay 模式下设为 false 可关闭事件富化 |
支持 .env 文件配置。
迁移说明
旧版本通过 OPENBIRD_WEBHOOK_URL 是否存在来隐式决定是否同时启动 webhook 转发。现在改为显式命令:
node bin/openbird.js mcpnode bin/openbird.js relay <webhook-url>
Relay 模式不再自动启动 MCP server。
Webhook 事件
OpenBird 将飞书 WebSocket 消息标准化为稳定的事件格式:
{
"type": "im.message.receive_v1",
"event_id": "evt_7604769001905884091",
"timestamp": 1739347200000,
"data": {
"id": "7604769001905884091",
"conversation": {
"id": "7599271773103737795",
"type": "group"
},
"sender": {
"id": "7128839302827827201",
"type": "user"
},
"content": {
"type": "text",
"text": "hello"
},
"thread_id": null
}
}im.thread.reply_count_v1 示例:
{
"type": "im.thread.reply_count_v1",
"event_id": "evt_123",
"timestamp": 1712023530000,
"semantic": {
"entity": "thread",
"action": "activity_detected",
"kind": "state_signal",
"consumable": false,
"requires_hydration": "fetch_thread_messages",
"dedupe_key": "thread:thread_1:reply_count:12",
"dedupe_strategy": "drop_exact_match",
"routing_hints": ["thread", "activity"]
},
"data": {
"chatId": "chat_1",
"threadId": "thread_1",
"replyCount": 12,
"updateTime": 1712023530000
}
}当前仅 im.thread.reply_count_v1 会携带 semantic 字段。其他 webhook 事件仍保持现有结构。
事件类型
| 类型 | 说明 |
|---|---|
| im.message.receive_v1 | 聊天消息(文本、富文本、图片、卡片等) |
| im.message.reaction_v1 | 表情回应 |
| im.message.read_count_v1 | 消息阅读数变更 |
| im.message.preview_v1 | 消息预览 |
| im.message.urgent_v1 | 加急通知 |
| im.message.urgent_ack_v1 | 加急确认 |
| im.reaction.user_v1 | 用户表情反应配置变更 |
| im.reaction.user_mru_v1 | 用户最近使用表情反应变更 |
| im.chat.read_state_v1 | 会话已读状态 |
| im.chat.tabs_v1 | 会话 Tab 变更 |
| im.chat.top_notice_v1 | 会话置顶通知 |
| im.thread.reply_count_v1 | 话题回复数 |
| im.thread.read_state_v1 | 话题已读状态 |
| im.thread.updated_v1 | 话题更新 |
| feed.cards_v1 | Feed 卡片 |
| calendar.event.sync_v1 | 日历事件同步 |
| system.device.status_v1 | 设备状态 |
| system.event.unknown | 未识别的推送事件 |
消息内容类型
| 类型值 | 名称 | 说明 | |---|---|---| | 2 | rich | 富文本 | | 3 | file | 文件 | | 4 | text | 纯文本 | | 5 | image | 图片 | | 6 | system | 系统消息 | | 7 | audio | 音频 | | 9 | share_group_chat | 群聊分享 | | 10 | sticker | 表情贴纸 | | 11 | merge_forward | 合并转发 | | 12 | calendar | 日历事件 | | 14 | card | 卡片(交互式) | | 15 | media | 媒体文件 | | 23 | share_user_card | 用户名片分享 | | 24 | todo | 待办任务 |
交付语义
- 通过 HTTP POST 发送 JSON body
event_id全局唯一,可用于幂等判断- 非 2xx 响应会指数退避重试,最多 5 次
接收事件
使用 openbird-webhook-node 接收事件:
pnpm add openbird-webhook-nodeimport { createServer } from 'openbird-webhook-node'
createServer({
port: 3000,
onMessage(event) {
console.log(event.data.sender.id, event.data.content.text)
},
})然后用 Relay 模式启动 OpenBird:
OPENBIRD_COOKIE="your_cookie_here" \
node bin/openbird.js relay http://localhost:3000/webhookMCP 工具
通过 Model Context Protocol 提供多个工具(stdio 通信)。
消息
| 工具 | 说明 |
|---|---|
| send_message | 发送消息(支持 Markdown) |
| send_mention_message | 发送 @提及 消息 |
| send_reply | 回复指定消息(引用回复) |
| put_message_link | 生成消息链接 |
| get_message_link_permission | 查询消息链接预览权限 |
| add_reaction | 添加表情回应 |
| remove_reaction | 移除表情回应 |
会话
| 工具 | 说明 |
|---|---|
| get_chat_history | 获取聊天历史消息 |
| get_chat_meta | 获取会话元信息(最后消息位置、已读位置等) |
| create_chat | 创建一对一会话 |
| search | 搜索用户和群组 |
| search_in_chat | 在指定会话中搜索消息 |
| mark_chat_read | 标记会话已读 |
| pin_session | 置顶会话 |
| unpin_session | 取消置顶会话 |
| mark_session | 标记会话为重要 |
| unmark_session | 取消标记会话 |
用户
| 工具 | 说明 |
|---|---|
| get_user_info | 根据用户 ID 获取信息 |
| get_user_profile_card | 获取用户名片(头像、签名等) |
| set_user_signature | 设置当前用户签名 |
| get_user_relation | 查询与目标用户的关系 |
| get_user_presence | 获取用户在线状态 |
机器人
| 工具 | 说明 |
|---|---|
| create_webhook_bot | 在指定会话中创建 webhook 机器人 |
| get_webhook_bot_info | 获取 webhook 机器人的 webhook 地址和配置信息 |
| send_webhook_bot_text | 通过 webhook URL 发送文本消息 |
| send_webhook_bot_post | 通过 webhook URL 发送富文本 post 消息 |
| send_webhook_bot_image | 通过 webhook URL 使用已有 image_key 发送图片消息 |
| send_webhook_bot_share_chat | 通过 webhook URL 发送群名片消息 |
| send_webhook_bot_card | 通过 webhook URL 发送交互式卡片消息 |
| send_webhook_bot_message | 通过 webhook URL 发送原始 webhook payload |
通讯录
| 工具 | 说明 |
|---|---|
| save_contact_alias | 保存联系人备注名和备忘 |
| sync_contact_info | 同步联系人信息 |
日历
| 工具 | 说明 |
|---|---|
| get_calendar_events | 获取日历事件列表 |
| calendar_rsvp | 回复日历邀请(接受/拒绝/待定) |
话题
| 工具 | 说明 |
|---|---|
| create_thread | 从消息创建话题 |
加急
| 工具 | 说明 |
|---|---|
| send_urgent | 发送加急通知 |
| get_urgent_ack_status | 查询加急确认状态 |
配置
| 工具 | 说明 |
|---|---|
| get_config | 获取飞书配置项 |
| get_feature_flags | 获取 Feature Flags |
媒体
| 工具 | 说明 |
|---|---|
| download_image | 下载图片 |
| download_file | 下载消息附件到本地临时文件并返回路径 |
使用 MCP Inspector 测试
npx @modelcontextprotocol/inspector node bin/openbird.js mcp项目结构
openbird/
├── bin/openbird.js # CLI 入口
├── src/
│ ├── index.js # 模式分发与共享启动逻辑
│ ├── logger.js # 日志(全部写 stderr,stdout 留给 MCP)
│ ├── core/ # 飞书协议实现
│ │ ├── api.js # HTTP API 客户端(34 个方法)
│ │ ├── auth.js # Cookie 认证
│ │ ├── websocket.js # WebSocket 客户端
│ │ ├── builders/ # Protobuf 请求/响应构建
│ │ ├── proto/ # .proto 定义及生成代码
│ │ └── utils/ # Cookie、加密、varint 工具
│ ├── webhook/
│ │ ├── normalizer.js # WebSocket 消息 -> OpenBird 事件
│ │ └── dispatcher.js # HTTP POST 转发(含重试)
│ └── mcp/
│ └── server.js # MCP Server(多个工具)
├── examples/
│ └── basic-usage.mjs # MCP 示例
└── docs/
└── plans/ # 设计文档开发
# 安装依赖
pnpm install
# 运行测试
pnpm test
# 测试覆盖率
pnpm test:coverage
# 修改 proto.proto 后重新生成代码
pnpm generate:proto
# 启动 MCP 模式
node bin/openbird.js mcp
# 启动 Relay 模式
node bin/openbird.js relay http://localhost:3000/webhook测试
项目使用 Vitest 作为测试框架,当前有 324 个测试覆盖所有核心模块:
| 模块 | 测试数 | |---|---| | cookie, time, varint, encryption | 56 | | header, params, richtext, proto | 103 | | auth, api, websocket | 137 | | normalizer, dispatcher | 23 | | logger | 5 |
pnpm test # 运行所有测试
pnpm test:watch # 监听模式
pnpm test:coverage # 覆盖率报告工作原理
OpenBird 逆向了飞书网页版的 WebSocket 协议和 HTTP API,使用你的浏览器 cookie 以你的用户身份认证——和浏览器使用的是同一个会话。
获取 cookie:打开飞书网页版(feishu.cn),打开浏览器开发者工具,从任意 *.feishu.cn 请求中复制完整的 Cookie 请求头的值。
注意:这是非官方工具。飞书可能随时修改协议,使用风险自负。
License
MIT
