Skip to main content
Glama
README.md
# 飞书 MCP 使用指南(feishu-wiki-mcp)

本项目是**面向 MCP 客户端的飞书服务网关**,运行时通过飞书开放平台 API 提供标准化工具调用。

- 运行时:Node.js >= 20 + stdio transport(`@modelcontextprotocol/sdk`)
- 入口:`build/index.js`
- 当前版本:`1.3.1`
- 包名:`@akaknele/feishu-wiki-mcp`
- 当前可用 Tool:36 个

## 一、部署与启动方式

### 1. 开发构建与本地运行

```bash
npm install
npm run build
npm start -- --app-id <APP_ID> --app-secret <APP_SECRET>
```

### 2. OAuth 模式(用于用户授权)

适用于需要用户级权限(`user token`)的场景:

```bash
npm start -- --app-id <APP_ID> --app-secret <APP_SECRET> --oauth --port 3001
```

### 2b. 预置 Token 模式(无浏览器,适合第三方 MCP 客户端)

当第三方应用(Claude Desktop、Cursor 等)安装 MCP 无法弹出浏览器时,可提前获取 user token 后通过参数或环境变量传入,完全跳过 OAuth 授权流程:

```bash
# 命令行参数
feishu-wiki-mcp --app-id <APP_ID> --app-secret <APP_SECRET> \
  --user-token <USER_ACCESS_TOKEN> \
  --refresh-token <REFRESH_TOKEN>

# 或环境变量(推荐)
FEISHU_APP_ID=cli_xxx \
FEISHU_APP_SECRET=secret_xxx \
FEISHU_USER_TOKEN=u-xxx \
FEISHU_REFRESH_TOKEN=ur-xxx \
feishu-wiki-mcp
```

MCP 客户端配置示例:

```json
{
  "mcpServers": {
    "feishu-wiki-mcp": {
      "command": "feishu-wiki-mcp",
      "args": ["--app-id", "<APP_ID>", "--app-secret", "<APP_SECRET>"],
      "env": {
        "FEISHU_USER_TOKEN": "<USER_ACCESS_TOKEN>",
        "FEISHU_REFRESH_TOKEN": "<REFRESH_TOKEN>"
      }
    }
  }
}
```

> token 过期后会自动用 `refresh_token` 刷新;refresh_token 也过期则报错,需重新获取。

### 2c. 如何获取 User Token

预置模式需要提前拿到 `user_access_token` 和 `refresh_token`,有以下三种方式:

#### 方式一:运行一次 `--oauth`,从缓存文件提取(推荐)

在**有浏览器的机器**上完成一次授权:

```bash
feishu-wiki-mcp --app-id cli_xxx --app-secret xxx --oauth --port 3001
```

授权成功后读取缓存文件:

```bash
cat ~/.feishu-wiki-mcp-token.json
```

输出示例:

```json
{
  "access_token": "u-xxx...",
  "refresh_token": "ur-xxx...",
  "expires_at": 1234567890000,
  "refresh_expires_at": 9876543210000
}
```

将 `access_token` 和 `refresh_token` 填入环境变量即可。`refresh_token` 有效期约 30 天,MCP 会自动续期 `access_token`,正常使用无感知。

#### 方式二:飞书开放平台 API 调试台(无需写代码)

1. 打开 [open.feishu.cn](https://open.feishu.cn) → 进入你的应用
2. 左侧菜单选择 **"开发工具 → API 调试台"**
3. 右上角鉴权方式选择 **"用户身份(user_access_token)"**,点击授权登录
4. 授权完成后,调试台会自动填入 token,复制即可

#### 方式三:手动 OAuth 换 token(Shell 脚本)

适合自动化脚本场景,需要一个可访问的回调地址(本地 localhost 即可):

```bash
# 替换为你的 App ID / Secret
APP_ID="cli_xxx"
APP_SECRET="xxx"
PORT=3001

# Step 1:用浏览器打开授权 URL,完成后从地址栏取 code 参数
SCOPES="wiki:wiki docx:document drive:drive bitable:bitable im:message contact:user.id:readonly"
echo "请用浏览器访问以下地址完成授权:"
echo "https://open.feishu.cn/open-apis/authen/v1/index?app_id=${APP_ID}&redirect_uri=http%3A%2F%2Flocalhost%3A${PORT}%2Fcallback&scope=$(python3 -c "import urllib.parse; print(urllib.parse.quote('${SCOPES}'))")"
echo ""
read -p "粘贴回调 URL 中的 code 参数值: " CODE

# Step 2:获取 app_access_token
APP_TOKEN=$(curl -s -X POST "https://open.feishu.cn/open-apis/auth/v3/app_access_token/internal" \
  -H "Content-Type: application/json" \
  -d "{\"app_id\":\"${APP_ID}\",\"app_secret\":\"${APP_SECRET}\"}" | jq -r .app_access_token)

# Step 3:用 code 换 user_access_token + refresh_token
curl -s -X POST "https://open.feishu.cn/open-apis/authen/v1/oidc/access_token" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${APP_TOKEN}" \
  -d "{\"grant_type\":\"authorization_code\",\"code\":\"${CODE}\"}" | jq '{access_token: .data.access_token, refresh_token: .data.refresh_token}'
```

运行后输出的 `access_token` 和 `refresh_token` 即可填入环境变量。

#### Token 有效期说明

| Token | 有效期 | 过期行为 |
|-------|--------|---------|
| `user_access_token` | ~2 小时 | MCP 自动用 refresh_token 续期 |
| `refresh_token` | ~30 天 | 需重新走上述任一方式获取 |

### 3. 安装后直接运行

```bash
npm install -g @akaknele/feishu-wiki-mcp@1.3.1
feishu-wiki-mcp --app-id <APP_ID> --app-secret <APP_SECRET>
```

或使用 npx:

```bash
npx @akaknele/feishu-wiki-mcp@1.3.1 --app-id <APP_ID> --app-secret <APP_SECRET>
```

### 4. MCP 客户端接入(示例)

```json
{
  "mcpServers": {
    "feishu-wiki-mcp": {
      "command": "feishu-wiki-mcp",
      "args": ["--app-id", "<APP_ID>", "--app-secret", "<APP_SECRET>"]
    }
  }
}
```

OAuth 模式示例:

```json
{
  "mcpServers": {
    "feishu-wiki-mcp": {
      "command": "feishu-wiki-mcp",
      "args": ["--app-id", "<APP_ID>", "--app-secret", "<APP_SECRET>", "--oauth", "--port", "3001"]
    }
  }
}
```

## 二、外网网络(OAuth)要求

若在企业内网/防火墙下运行,需要放行:

- `https://open.feishu.cn`
- `https://openapi.*.feishu.cn`(飞书 API 域名)

OAuth 回调地址默认为:

- `http://localhost:3001/callback`

因此对应机器的 `3001` 端口需要可访问(对本机浏览器即可),并且回调 URL 能回传到该本机实例。

## 三、核心流程

1. 启动服务并通过参数选择 tenant 模式或 OAuth 模式
2. MCP 客户端请求对应 tool
3. 服务器内部自动获取并刷新 token(`~/.feishu-wiki-mcp-token.json`)
4. 使用 token 调用飞书接口并返回结构化 JSON

## 四、工具清单(36)

### 工具清单质量说明

每个工具都以 MCP tool schema 的实际参数定义为准,`返回值`默认为飞书 API 的 `JSON` 响应文本。

### 知识库(Wiki)

| 工具 | 用途 | 必填参数 | 可选参数 |
| --- | --- | --- | --- |
| `wiki_list_spaces` | 列出当前用户可见知识库 | 无 | `page_size`(1-50), `page_token` |
| `wiki_get_space` | 获取知识库详情 | `space_id` | 无 |
| `wiki_list_nodes` | 列出知识库子节点(默认顶层) | `space_id` | `parent_node_token`, `page_size`(1-50), `page_token` |
| `wiki_get_node` | 通过 wiki token 或文档 token 获取节点 | `token` | `obj_type`(doc/docx/sheet/mindnote/bitable/file/slides/wiki) |
| `wiki_create_node` | 创建知识库节点(文档/表格等) | `space_id`, `obj_type` | `parent_node_token`, `node_type`(origin/shortcut, 默认 origin), `title` |
| `wiki_move_node` | 在知识库内移动节点 | `space_id`, `node_token` | `target_parent_token`, `target_space_id` |
| `wiki_move_docs_to_wiki` | 将云空间文档移动进知识库 | `space_id`, `obj_type`, `obj_token` | `parent_wiki_token` |
| `wiki_update_title` | 更新节点标题 | `space_id`, `node_token`, `title` | 无 |
| `wiki_copy_node` | 复制节点(可跨库) | `space_id`, `node_token` | `target_parent_token`, `target_space_id`, `title` |
| `wiki_search` | 搜索知识库节点 | `query` | `space_id`, `page_size`, `page_token` |
| `wiki_create_node_with_markdown` | **🆕** 一步创建带 Markdown 内容的 wiki 文档(上传→转换→移入知识库) | `space_id`, `markdown` | `title`(<=27 字符), `parent_node_token` |

### 文档(Docx)

| 工具 | 用途 | 必填参数 | 可选参数 |
| --- | --- | --- | --- |
| `doc_get_raw_content` | 获取文档纯文本内容 | `document_id` | 无 |
| `doc_search` | 搜索云文档 | `search_key` | `count`(0-50), `offset`, `owner_ids`, `docs_types` |
| `doc_import` | 导入 Markdown 创建飞书文档(自动上传 → 转换 docx)。**🆕 v1.3**: 可选传入 `space_id` 直接写入知识库 | `markdown` | `file_name`(<=27 字符), `folder_token`, `space_id`(传入后自动移入知识库), `parent_wiki_token` |
| `doc_list_blocks` | 列出文档所有块 | `document_id` | `page_size`(1-500), `page_token`, `document_revision_id` |
| `doc_get_block` | 获取指定块详情 | `document_id`, `block_id` | `document_revision_id` |
| `doc_create_blocks` | 在指定父块下插入子块。**🆕 v1.3**: 补全所有 block_type 文档 + 客户端参数校验 | `document_id`, `block_id`, `children` | `index`(插入位置,默认追加) |
| `doc_update_block` | 更新指定块内容(PATCH) | `document_id`, `block_id`, `update` | 无 |
| `doc_delete_blocks` | 删除父块下指定区间的子块 | `document_id`, `block_id`, `start_index`, `end_index` | 无 |

### 多维表格(Bitable)

| 工具 | 用途 | 必填参数 | 可选参数 |
| --- | --- | --- | --- |
| `bitable_create_app` | 创建多维表格应用 | 无 | `name`, `folder_token` |
| `bitable_list_tables` | 列出应用内表 | `app_token` | `page_size`, `page_token` |
| `bitable_create_table` | 创建数据表 | `app_token`, `name` | `default_view_name`, `fields`(字段列表) |
| `bitable_list_fields` | 列出表字段 | `app_token`, `table_id` | `page_size`, `page_token` |
| `bitable_search_records` | 条件筛选记录 | `app_token`, `table_id` | `field_names`, `filter`(`conjunction`+`conditions`), `sort`, `page_size`(<=500), `page_token` |
| `bitable_create_record` | 新增记录 | `app_token`, `table_id`, `fields` | 无 |
| `bitable_update_record` | 更新记录 | `app_token`, `table_id`, `record_id`, `fields` | 无 |

### IM 与联系人

| 工具 | 用途 | 必填参数 | 可选参数 |
| --- | --- | --- | --- |
| `im_send_message` | 发送消息(文本/卡片等) | `receive_id`, `receive_id_type`, `msg_type`, `content` | 无 |
| `im_list_messages` | 获取聊天历史 | `container_id` | `container_id_type`(chat/thread,默认 chat), `start_time`, `end_time`, `sort_type`, `page_size`, `page_token` |
| `im_list_chats` | 获取用户/机器人群聊列表 | 无 | `page_size`, `page_token`, `sort_type` |
| `im_create_chat` | 创建群聊 | 无 | `name`, `description`, `chat_type`(private/public), `user_id_list`, `owner_id` |
| `im_get_chat_members` | 获取群成员 | `chat_id` | `page_size`, `page_token` |
| `contact_batch_get_user_id` | 批量通过邮箱/手机号查用户 ID | 无 | `emails`(每项 string, 最多 50), `mobiles`(每项 string, 最多 50) |

### 权限与删除

| 工具 | 用途 | 必填参数 | 可选参数 |
| --- | --- | --- | --- |
| `drive_add_permission` | 为云文档添加协作者权限 | `token`, `type`, `member_id`, `member_type`, `perm` | 无 |
| `wiki_delete_node` | 将 wiki 节点移出到云空间根目录(第一步);之后用 `drive_delete_file` 彻底删除(飞书无公开 wiki 删除 API) | `space_id`, `node_token`(wiki node token,非 obj_token) | 无 |
| `drive_upload_file` | **🆕** 上传文件到云空间(base64),获取 `file_token` 用于插入图片等 | `file_name`, `base64` | `parent_type`(默认 explorer), `parent_node` |
| `drive_delete_file` | 删除云空间文件(移至回收站) | `file_token`, `type` | 无 |

### 说明
- `fields`(Bitable 相关)通常使用字段名/系统键映射值;建议先用 `bitable_list_fields` 明确 schema 后再写入。
- `im_send_message` 的 `content` 按对应 `msg_type` 要求传入 JSON 字符串。
- `doc_import`:先上传 md 文件获取 `file_token`,再创建导入任务转换为 docx,轮询等待最多 30 秒。v1.3 新增 `space_id` + `parent_wiki_token` 参数,导入后可自动移入知识库。
- `wiki_create_node_with_markdown`:一步到位创建带内容的 wiki 文档。内部自动完成:上传 Markdown → 转换为 docx → 移入知识库。适合 AI Agent 快速创建结构化文档。
- `doc_create_blocks`:v1.3 新增客户端参数校验,block_type 与字段名不匹配时会返回明确错误提示(如 `block_type=4 需要字段 "heading2"`),避免飞书 API 返回笼统的 `invalid param`。支持的 block_type:2=text, 3-9=heading1-7, 11=bullet, 12=ordered, 14=code, 15=quote, 22=divider, 27=image, 31=table, 34=callout。
- `drive_upload_file`:上传 base64 编码的文件到云空间,返回 `file_token`,可配合 `doc_create_blocks` 的 image block(block_type=27)在文档中插入图片。
- `wiki_delete_node`:飞书无公开 wiki 删除 API。本工具将节点移出 wiki 至云空间根目录(step1),之后需通过 `drive_delete_file` 删除底层文件(step2)。需要 wiki node token,可从 `wiki_list_nodes` 返回的 `node_token` 字段获取。

## 五、安全与生产部署

### 最小可运行参数清单

### 启动参数(必备)

- `--app-id`:飞书应用 ID(必填,可用 `FEISHU_APP_ID` 环境变量代替)
- `--app-secret`:飞书应用 Secret(必填,可用 `FEISHU_APP_SECRET` 代替)
- `--oauth`:启动浏览器 OAuth 授权模式(可选)
- `--port`:OAuth 回调端口(可选,默认 `3001`)
- `--user-token`:预置用户 access token,跳过浏览器授权(可选,可用 `FEISHU_USER_TOKEN` 代替)
- `--refresh-token`:预置 refresh token,token 过期时自动刷新(可选,可用 `FEISHU_REFRESH_TOKEN` 代替)

### 推荐环境变量

- `FEISHU_APP_ID`
- `FEISHU_APP_SECRET`
- `FEISHU_USER_TOKEN`(预置模式,无需浏览器)
- `FEISHU_REFRESH_TOKEN`(配合 user token 自动续期)
- `FEISHU_OAUTH=true/false`(已废弃,建议改用 user token 模式)

#### 示例 `.env`

```bash
FEISHU_APP_ID=cli_xxx
FEISHU_APP_SECRET=secret_xxx
FEISHU_OAUTH=true
FEISHU_MCP_PORT=3001
```

#### 示例启动脚本(避免在命令行直接暴露明文)

```bash
set -a
source .env
set +a

if [ "${FEISHU_OAUTH}" = "true" ]; then
  feishu-wiki-mcp --app-id "$FEISHU_APP_ID" --app-secret "$FEISHU_APP_SECRET" --oauth --port "${FEISHU_MCP_PORT:-3001}"
else
  feishu-wiki-mcp --app-id "$FEISHU_APP_ID" --app-secret "$FEISHU_APP_SECRET"
fi
```

### 版本与发布一致性

- 当前代码版本:`1.3.1`(`package.json` 中 `version`)
- MCP 运行主文件:`build/index.js`
- 发布示例(建议保持一致):

```bash
npm version patch                      # 或 npm version 1.0.7
npm run build                          # 确保生成 build/index.js
npm publish --access public

# 标签建议与版本一致
git tag v1.0.7
git push --tags
```

### 安全与生产环境建议

#### 端口访问控制

- OAuth 回调默认地址固定为 `http://localhost:${port}/callback`(当前实现不支持自定义 callback host/path)。
- 生产部署中建议只对内网开放 `3001`,并通过反向代理对外暴露时加 IP 白名单/鉴权。
- 避免将该端口放到公开网段;如需公网访问,建议使用 VPN 或 SSH 隧道到内网服务端。

#### token 文件权限

- 用户 token 缓存在 `~/.feishu-wiki-mcp-token.json`。
- 建议设置严格权限:

```bash
chmod 600 ~/.feishu-wiki-mcp-token.json
chown "$USER" ~/.feishu-wiki-mcp-token.json
```

- 建议使用独立运行用户,避免多人共享 HOME 目录。
- 需要强制重新登录时,删除该文件可清除会话缓存。

#### 日志脱敏

- 运行时禁止在 shell 中开启 `set -x`,避免把 `APP_SECRET` 打印到日志。
- 当前日志仅输出错误描述,不应泄露 token 明文;如你接入统一日志系统,请开启敏感字段脱敏(如 `app_secret`、`token`)。

#### 回调地址与 HTTPS 要求

- 本地开发/单机场景:`http://localhost:<port>/callback` 是可用的。
- 生产场景若通过反向代理对外网开放,建议使用 HTTPS 并把代理层回调地址映射为该本机回调,同时在飞书应用配置中放行对应可访问域名。
- 若需自定义公网 callback(非 localhost),需修改 `doOAuthFlow` 中 `redirectUri` 逻辑并重新构建发布。

## 六、发布(如需维护 npm)

```bash
npm version patch # 或指定版本号
npm login --registry https://registry.npmjs.org
npm publish --access public
git tag v1.0.7
git push --tags
```

## 七、故障排查

- `feishu-wiki-mcp` 命令未找到:先确认全局安装成功,`npm bin -g` 在 `PATH`
- 启动报 token 错误:检查 APP_ID / APP_SECRET 是否正确、应用是否开通对应权限
- OAuth 首次无效:检查 callback URL 是否可达、端口放行是否正常、浏览器可打开授权链接
- Token 缓存文件:`~/.feishu-wiki-mcp-token.json`(每个用户一份,按需清理可强制重新登录)

## 八、当前版本行为边界

- 当前实现基于 `@modelcontextprotocol/sdk` 的 stdio transport,适配本地/远程 MCP 客户端调用
- 已实现 36 个工具,按需在服务端扩展后可追加

## 九、Changelog

### v1.3.0
- **新增 `wiki_create_node_with_markdown`**:一步到位在知识库中创建带 Markdown 内容的文档节点。内部自动完成:上传 Markdown → 转换为 docx → 移入知识库指定位置。AI Agent 只需一次调用即可完成之前需要 3 步(create_node → list_blocks → create_blocks)的操作。
- **新增 `drive_upload_file`**:支持 base64 编码文件上传到飞书云空间,返回 `file_token`,可用于在文档中插入图片等场景。
- **增强 `doc_import`**:新增 `space_id` + `parent_wiki_token` 可选参数,导入 Markdown 后自动将文档移入知识库,省去手动调用 `wiki_move_docs_to_wiki`。
- **增强 `doc_create_blocks`**:
  - 补全所有 block_type 文档:新增 11=bullet、12=ordered、15=quote、22=divider 等类型的完整 JSON 示例
  - 新增客户端参数校验:block_type 与字段名不匹配时返回明确错误提示(如 `block_type=4 需要字段 "heading2"`),不再依赖飞书 API 笼统的 `invalid param` 错误

### v1.2.0
- **bugfix `doc_import`**:修复创建空文档的问题。现在正确实现三步流程:① 上传 md 文件获取 `file_token` → ② 创建导入任务(md→docx)→ ③ 轮询等待,内容完整导入。
- **bugfix `wiki_delete_node`**:飞书无公开 wiki 删除端点(DELETE 返回 404)。改为两步删除工作流:本工具先将节点移出 wiki 至云空间根目录,再配合 `drive_delete_file` 彻底删除底层文件。

### v1.1.0
- 新增 5 个 Docx Blocks 操作工具:`doc_list_blocks`、`doc_get_block`、`doc_create_blocks`、`doc_update_block`、`doc_delete_blocks`,支持对飞书文档内容的完整 CRUD
- 新增 `wiki_delete_node`、`drive_delete_file` 删除工具
- OAuth 改进:支持 `--user-token` / `--refresh-token` 参数和 `FEISHU_USER_TOKEN` / `FEISHU_REFRESH_TOKEN` 环境变量,第三方 MCP 客户端无需浏览器即可授权
- 环境变量支持 `FEISHU_APP_ID` / `FEISHU_APP_SECRET`

### v1.0.7
- 初始版本,27 个工具(Wiki、Bitable、IM、权限)

TDQS

B3.1/5.0

Scored across 36 tools

Disambiguation3/5

Most tools have distinct domain+resource targets, but wiki_create_node_with_markdown and doc_import overlap significantly (both import Markdown to wiki), and wiki_create_node vs wiki_create_node_with_markdown could confuse. The detailed descriptions help, but some boundary ambiguity remains.

Naming Consistency5/5

All tools follow a consistent domain_verb_noun pattern in snake_case (e.g., bitable_create_app, wiki_list_nodes, im_send_message). Even longer names like wiki_move_docs_to_wiki retain the predictable prefix structure, with no mixed conventions.

Tool Count2/5

With 36 tools, the set is heavy and exceeds the 25-tool threshold for appropriate count. The server is named wiki-mcp but includes many unrelated tools for IM, contacts, and bitable, making it feel over-scoped and broad rather than focused.

Completeness3/5

The core wiki lifecycle is well covered (list, get, create, move, copy, update title, delete), and document block operations add depth. However, there are notable gaps: no bitable delete record, no wiki node content update beyond title, and no full-document replacement, leaving some workflows incomplete.

Maintenance

ActivityInactive
ResponsivenessNo issues