npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

openbird

v3.1.0

Published

Feishu infrastructure service — relay mode or MCP server mode

Downloads

2,081

Readme

OpenBird

飞书(Lark)非官方基础设施服务,运行在本地,通过浏览器 cookie 连接飞书,提供两个显式运行模式:

  1. Relay 模式 — 连接飞书 WebSocket,将消息标准化后 POST 到你提供的 webhook 地址
  2. MCP 模式 — 通过 stdio 暴露多个飞书 API 工具,供 AI Agent 调用

快速开始

# 克隆并安装
git clone https://github.com/ztxtxwd/openbird.git
cd openbird
pnpm install

# 配置
cp .env.example .env
# 编辑 .env,粘贴你从浏览器 DevTools 复制的飞书 cookie

MCP 模式

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 mcp
  • node 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-node
import { 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/webhook

MCP 工具

通过 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