feishu-access-bridge
README.md
# Feishu Access Bridge
[](https://www.python.org/)
[](LICENSE)
一个轻量、无第三方 Python 依赖的飞书内容读取工具。通过同一套 CLI 和 MCP 接口读取飞书 Wiki、文档、电子表格及多维表格,可在三种访问方式之间按需选择:
- **用户 OAuth**:继承登录用户本人的文档权限,适合个人知识库和私有文档。
- **企业自建应用**:使用应用身份,适合服务端、机器人和无人值守任务。
- **浏览器会话**:复用 `agent-browser` 的持久化登录状态,适合 API 暂不支持的页面。
适用于 Codex、OpenCode、Claude Desktop 等支持本地 stdio MCP 的客户端,也可以独立作为命令行工具使用。
## 功能
- 自动识别 `/wiki/`、`/docx/`、`/sheets/`、`/base/` 链接。
- Wiki 节点自动解析真实资源类型与 `obj_token`。
- OAuth access token 过期后自动刷新,并保存飞书返回的新 refresh token。
- 令牌以 `0600` 权限原子写入本机,不会输出到 MCP 状态信息。
- 浏览器 Profile 持久化,正常情况下首次扫码后可复用登录状态。
- 同时提供 `feishu-bridge` CLI 与 `feishu-bridge-mcp` MCP Server。
- Python 标准库实现,核心功能零运行时依赖。
## 支持范围
| 资源 | 链接形式 | API 返回内容 |
| --- | --- | --- |
| Wiki | `/wiki/<node_token>` | 自动解析后读取实际文档或表格 |
| 新版文档 | `/docx/<document_id>` | 文档纯文本内容 |
| 电子表格 | `/sheets/<spreadsheet_token>` | 每个工作表前 200 行、前 26 列 |
| 多维表格 | `/base/<app_token>` | 所有数据表及分页记录 |
目前不处理旧版 `/docs/` 文档、附件下载、评论、图片 OCR 和写入操作。电子表格行列上限可在代码中调整。
## 快速安装
### 方式一:使用 pipx(推荐普通用户)
需要 Python 3.11 或更高版本:
```bash
git clone https://github.com/xashfh1234-oss/feishu-access-bridge.git
cd feishu-access-bridge
pipx install .
feishu-bridge --help
```
升级:
```bash
cd feishu-access-bridge
git pull
pipx install --force .
```
### 方式二:使用 uv
```bash
git clone https://github.com/xashfh1234-oss/feishu-access-bridge.git
cd feishu-access-bridge
uv tool install .
feishu-bridge --help
```
### 方式三:项目虚拟环境(适合开发)
```bash
git clone https://github.com/xashfh1234-oss/feishu-access-bridge.git
cd feishu-access-bridge
python3 -m venv .venv
.venv/bin/pip install -e .
.venv/bin/feishu-bridge --help
```
如果 Debian/Ubuntu 提示缺少 `ensurepip`,可安装系统的 `python3-venv`,或直接使用 `uv venv && uv pip install -e .`。
## 选择访问方式
| 模式 | 是否需要飞书应用 | 是否需要用户授权 | 是否需要 agent-browser | 推荐场景 |
| --- | --- | --- | --- | --- |
| `user` | 是 | 是 | 否 | 读取“我能看到”的私有内容 |
| `tenant` | 是 | 否 | 否 | 服务端自动化、共享给应用的内容 |
| `browser` | 否 | 浏览器登录 | 是 | API 无法覆盖或临时访问 |
| `auto` | 是 | 可选 | 否 | 优先用户 OAuth,缺失时使用应用身份 |
## 路径 A:用户 OAuth(推荐)
### 1. 创建飞书自建应用
进入[飞书开放平台](https://open.feishu.cn/),创建一个企业自建应用。在“凭证与基础信息”中取得:
- App ID
- App Secret
不要把 App Secret 提交到 Git、截图或粘贴到公开日志。
### 2. 添加权限
在应用的“权限管理”中添加以下用户身份权限:
```text
offline_access
wiki:wiki:readonly
docs:document.content:read
sheets:spreadsheet:readonly
bitable:app:readonly
```
只读某一种资源时可以只申请对应权限,但 `offline_access` 必须保留,否则不能持续刷新授权。
### 3. 配置 OAuth 重定向 URL
在应用安全设置中添加完整地址:
```text
http://127.0.0.1:8765/callback
```
必须与配置完全一致,包括协议、IP、端口和路径。出现飞书错误 `20029` 通常表示重定向 URL 不匹配;`20027` 且提示 `offline_access`,表示权限尚未添加或新版应用尚未发布。
### 4. 发布应用版本
新增权限或重定向地址后,创建并发布一个新版本。组织管理员可能需要审核。仅在开发后台保存配置但没有发布,用户授权页不会获得最新权限。
### 5. 配置本地凭证
环境变量方式:
```bash
export FEISHU_APP_ID='cli_xxxxxxxxxxxxxxxx'
export FEISHU_APP_SECRET='replace-with-your-secret'
```
或者保存为 `~/.feishu_config.json`:
```json
{
"app_id": "cli_xxxxxxxxxxxxxxxx",
"app_secret": "replace-with-your-secret"
}
```
建议限制文件权限:
```bash
chmod 600 ~/.feishu_config.json
```
也可以通过 `FEISHU_CONFIG_PATH` 指向其他配置文件。
### 6. 完成一次用户授权
```bash
feishu-bridge oauth-login
```
终端会打印一个授权链接,同时在 `127.0.0.1:8765` 临时监听回调。用浏览器打开链接并同意授权,成功后可以关闭页面。令牌默认保存在:
```text
~/.feishu_user_token.json
```
正常情况下不需要每次登录。access token 会用 refresh token 自动更新;用户撤销授权、refresh token 到期或应用权限改变时,才需要重新运行 OAuth 登录。
### 7. 读取文档
```bash
feishu-bridge read 'https://example.feishu.cn/wiki/YourWikiToken' --mode user --pretty
```
## 路径 B:企业应用身份
企业应用身份不需要用户 OAuth,但目标资源必须允许该应用访问。配置同一组 `FEISHU_APP_ID` 和 `FEISHU_APP_SECRET`,并在开放平台给应用添加所需的应用身份只读权限,然后运行:
```bash
feishu-bridge read 'https://example.feishu.cn/docx/DocumentId' --mode tenant --pretty
```
如果接口返回权限不足,请检查:应用版本是否已发布、所需权限是“应用身份”还是“用户身份”、目标知识空间或文档是否已向应用开放。
## 路径 C:浏览器登录态
浏览器模式不要求飞书 App ID/Secret,但需要先安装 [agent-browser](https://github.com/vercel-labs/agent-browser):
```bash
npm install -g agent-browser
agent-browser install
```
首次以可见窗口打开飞书并完成扫码:
```bash
feishu-bridge browser-login 'https://www.feishu.cn/'
```
默认 Profile 保存在 `~/.agent-browser/profiles/feishu`。之后读取时会复用该 Profile:
```bash
feishu-bridge read 'https://example.feishu.cn/wiki/YourWikiToken' --mode browser --pretty
```
飞书主动让会话失效、扫码设备退出、Cookie 过期或风控触发时,仍可能需要再次扫码。不要共享或提交浏览器 Profile。
## CLI 使用
检查本机配置状态(不会展示密钥或令牌):
```bash
feishu-bridge status
```
自动模式先尝试用户 OAuth,用户授权不存在或失效时再尝试应用身份:
```bash
feishu-bridge read 'https://example.feishu.cn/wiki/YourWikiToken' --mode auto --pretty
```
直接传 token 时,默认按 Wiki token 处理。可用 `--kind` 指定类型:
```bash
feishu-bridge read 'DocumentId' --kind docx --mode user
feishu-bridge read 'SpreadsheetToken' --kind sheet --mode tenant
feishu-bridge read 'AppToken' --kind bitable --mode user
```
`auto` 不会在接口返回“权限不足”后悄悄切换身份,以免隐藏授权边界;这时应明确选择 `--mode user` 或 `--mode tenant`。
## MCP 接入
MCP Server 使用 stdio 通信:
```bash
feishu-bridge-mcp
```
暴露两个工具:
- `feishu_read_resource`:读取支持的飞书 URL,参数 `mode` 可选 `auto`、`user`、`tenant`、`browser`。
- `feishu_auth_status`:返回可用访问路径,不泄露凭证。
### Codex
如果使用 pipx/uv 全局安装,先用 `command -v feishu-bridge-mcp` 找到绝对路径,然后写入 Codex 配置:
```toml
[mcp_servers.feishu-access]
command = "/absolute/path/to/feishu-bridge-mcp"
```
如果使用仓库虚拟环境:
```toml
[mcp_servers.feishu-access]
command = "/absolute/path/to/feishu-access-bridge/.venv/bin/feishu-bridge-mcp"
```
### OpenCode
```json
{
"mcp": {
"feishu-access": {
"type": "local",
"command": ["/absolute/path/to/feishu-bridge-mcp"],
"enabled": true
}
}
}
```
修改 MCP 配置后重启客户端。MCP 子进程需要能够读取你的环境变量或 `~/.feishu_config.json`。
## 配置项
| 环境变量 | 默认值 | 说明 |
| --- | --- | --- |
| `FEISHU_APP_ID` | 空 | 飞书应用 App ID |
| `FEISHU_APP_SECRET` | 空 | 飞书应用 App Secret |
| `FEISHU_CONFIG_PATH` | `~/.feishu_config.json` | JSON 凭证文件 |
| `FEISHU_TOKEN_PATH` | `~/.feishu_user_token.json` | OAuth 令牌文件 |
| `FEISHU_REDIRECT_URI` | `http://127.0.0.1:8765/callback` | OAuth 回调地址 |
| `FEISHU_BROWSER_PROFILE` | `~/.agent-browser/profiles/feishu` | 浏览器 Profile 目录 |
## 常见问题
### 为什么浏览器已经登录,API 还是没有权限?
浏览器 Cookie、用户 OAuth token 和 tenant token 是三套独立身份。网页能打开并不意味着开放平台 API 自动拥有相同权限。希望继承个人文档权限时请选择 `user` 模式。
### 为什么 OpenCode 似乎不需要登录?
常见原因是它复用了已有浏览器 Profile、系统 Cookie、环境变量,或已配置好的 MCP 服务。不是飞书绕过了登录,而是凭证已经存在于本机进程可访问的位置。
### 每次都需要扫码吗?
不需要。浏览器模式会保存 Profile,OAuth 模式会自动刷新令牌。但飞书会话或授权被撤销、过期、触发安全校验时需要重新登录。
### OAuth 回调端口被占用怎么办?
设置新的回调地址,并在飞书后台添加同一个地址:
```bash
export FEISHU_REDIRECT_URI='http://127.0.0.1:9876/callback'
feishu-bridge oauth-login
```
### 为什么电子表格只有 200 行或 26 列?
这是当前版本为避免单次 MCP 输出过大设置的读取上限,不是飞书数据丢失。可在 `ResourceReader._read_sheet` 调整,后续版本会增加分页和范围参数。
## 安全说明
- 不要提交 App Secret、OAuth token、Cookie 或浏览器 Profile。
- OAuth `state` 使用安全随机数并在回调时校验。
- OAuth 回调仅允许绑定 `127.0.0.1` 或 `localhost`。
- token 文件以临时文件写入后原子替换,权限为 `0600`。
- 浏览器模式拥有登录用户的网页权限,只应用于可信 URL。
- 项目的 `.gitignore` 已忽略常见凭证与构建目录,但提交前仍应检查 `git diff --cached`。
## 开发与测试
```bash
git clone https://github.com/xashfh1234-oss/feishu-access-bridge.git
cd feishu-access-bridge
uv venv
uv pip install -e .
.venv/bin/python -m unittest discover -s tests -v
```
测试是离线的,不会读取真实飞书凭证。真实环境冒烟测试可使用你有权访问的测试文档:
```bash
.venv/bin/feishu-bridge read 'YOUR_FEISHU_URL' --mode user
```
欢迎提交 Issue 和 Pull Request。请勿在 Issue 中粘贴 App Secret、完整 access token 或包含敏感业务数据的接口响应。
## License
[MIT](LICENSE)
TDQS
B3.4/5.0
Scored across 2 tools
Disambiguation5/5
The two tools serve distinct purposes: one reads Feishu resources, the other checks authentication status. There is no overlap, so an agent can easily distinguish them.
Naming Consistency4/5
Both tools share the 'feishu_' prefix, but 'read_resource' follows a verb_noun pattern while 'auth_status' is more of a noun phrase. The inconsistency is minor given the small set.
Tool Count3/5
With only two tools, the set is at the lower boundary of acceptable size. It is enough for basic read and status checks but feels thin for a general access bridge.
Completeness2/5
The set lacks crucial operations like listing available resources, writing/updating, or searching. It covers only reading by URL and auth status, leaving significant gaps for a Feishu integration.
Maintenance
ActivitySlowing
ResponsivenessNo issues