Skip to main content
Glama
README.md
# Feishu Access Bridge

[![Python 3.11+](https://img.shields.io/badge/Python-3.11%2B-blue)](https://www.python.org/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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