Company Feishu Codex 插件设计与使用说明

背景

这个插件的目标不是把飞书能力接进业务 App,也不是做一个 H5 授权页,而是让 Codex 在本机工作环境中拥有一套可调用的飞书工具能力。

核心需求可以归纳为一句话:

Codex 以某个公司飞书用户的身份,访问这个用户本来有权限访问的文件,并支持读取、新建和修改新版文档。

因此,插件的设计重点不是“全公司文档扫描”,而是“用户授权边界清晰”。用户能看到什么,Codex 才能看到什么;用户能编辑什么,Codex 才能编辑什么。

设计思想

只使用 user_access_token

插件刻意只使用 user_access_token,不把租户级 token 作为主链路。

这样做有三个好处:

  1. 权限边界天然贴合用户视角。
  2. Codex 不会获得超出当前授权用户的文件范围。
  3. 创建和修改文档时,失败原因也更符合用户直觉:没有编辑权限就不能改。

本地保存的是 OAuth 得到的用户 token 和 refresh token,不保存飞书账号密码。

插件、Skill、MCP 分层

插件由三层组成:

flowchart TD
    User[用户在 Codex 中发起请求]
    Skill[company-feishu-* Skills<br/>描述何时使用和如何使用]
    MCP[company-feishu-mcp<br/>提供可调用工具]
    Feishu[Feishu OpenAPI<br/>user_access_token]
    Token[本机 token 文件<br/>用户配置目录]

    User --> Skill
    Skill --> MCP
    MCP --> Token
    MCP --> Feishu

Skill 负责让 Codex 知道“什么时候应该使用飞书能力”,MCP 负责真正调用飞书 OpenAPI。这样可以把提示词逻辑和接口实现分开,后续扩展 sheet、wiki 或知识库能力时不会污染现有说明。

本地 marketplace

插件通过本地 marketplace 安装,当前 marketplace 名称为:

company-local

它不是线上 marketplace,也没有发布到公网。它只是本机 Codex 可识别的插件索引,指向本地插件目录。

产物结构

插件源码位于:

E:\Project\xxg\AIroles-programmer\plugin\feishu_plugin

主要结构如下:

feishu_plugin/
  .codex-plugin/
    plugin.json
  .mcp.json
  mcp/
    company-feishu-mcp/
      server.mjs
  skills/
    company-feishu-auth/
      SKILL.md
    company-feishu-drive/
      SKILL.md
    company-feishu-docx/
      SKILL.md

本地 marketplace 位于:

E:\Project\xxg\AIroles-programmer\.agents\plugins\marketplace.json

Codex 安装后的缓存路径类似:

C:\Users\<USER>\.codex\plugins\cache\company-local\feishu_plugin\1.0.0

Skill 设计

插件拆成三个 Skill,而不是做成一个大 Skill。

company-feishu-auth

负责登录、检查登录状态、刷新或清理本地授权。

典型触发语句:

使用 company-feishu-auth 登录我的公司飞书账号

它会引导 Codex 调用:

company_feishu_auth_status
company_feishu_get_login_url
company_feishu_exchange_code
company_feishu_logout

company-feishu-drive

负责文件发现能力,包括搜索、列文件夹和查询文件元信息。

典型触发语句:

搜索我飞书里关于设备帮助的文档

它会引导 Codex 调用:

company_feishu_search_files
company_feishu_list_folder
company_feishu_get_file_meta

company-feishu-docx

负责新版文档读写能力,包括读取、新建、追加和替换。

典型触发语句:

新建一篇飞书文档,把这次总结写进去

它会引导 Codex 调用:

company_feishu_read_docx
company_feishu_create_docx
company_feishu_update_docx

MCP 工具设计

MCP server 名称是:

company-feishu-mcp

对外暴露的工具统一使用 company_feishu_ 前缀:

company_feishu_auth_status
company_feishu_get_login_url
company_feishu_exchange_code
company_feishu_logout
company_feishu_search_files
company_feishu_list_folder
company_feishu_get_file_meta
company_feishu_read_docx
company_feishu_create_docx
company_feishu_update_docx

第一版 MCP server 使用单文件实现:

mcp/company-feishu-mcp/server.mjs

这样做的目的是降低安装成本。当前实现不依赖额外 npm 包,只要求本机 Node.js 支持 fetch,也就是建议使用 Node.js 18 或更高版本。

实现步骤

1. 创建插件清单

.codex-plugin/plugin.json 描述插件元信息、Skill 目录和 MCP 配置入口。

关键配置示意如下:

{
  "name": "feishu_plugin",
  "version": "1.0.0",
  "skills": "./skills/",
  "mcpServers": "./.mcp.json",
  "interface": {
    "displayName": "Company Feishu",
    "capabilities": ["Read", "Write"]
  }
}

2. 配置 MCP server

.mcp.json 指向本地 Node 脚本,并注入非敏感默认配置。

{
  "mcpServers": {
    "company-feishu-mcp": {
      "command": "node",
      "args": ["./mcp/company-feishu-mcp/server.mjs"],
      "env": {
        "COMPANY_FEISHU_APP_ID": "YOUR_APP_ID",
        "COMPANY_FEISHU_REDIRECT_URI": "http://localhost:3000/callback",
        "COMPANY_FEISHU_BASE_URL": "https://open.feishu.cn"
      }
    }
  }
}

注意:COMPANY_FEISHU_APP_SECRET 不写入插件文件,只放在用户本机环境变量中。

3. 实现 OAuth 登录

登录过程如下:

sequenceDiagram
    participant User as 用户
    participant Codex as Codex
    participant MCP as company-feishu-mcp
    participant Feishu as Feishu OAuth

    User->>Codex: 请求登录公司飞书
    Codex->>MCP: company_feishu_get_login_url
    MCP->>MCP: 启动 localhost callback
    MCP-->>Codex: 返回授权 URL
    User->>Feishu: 浏览器打开授权 URL
    Feishu-->>MCP: callback 携带 code
    MCP->>Feishu: code 换 user_access_token
    MCP->>MCP: 保存 token 到用户配置目录

token 默认保存到:

Windows: %APPDATA%\company-feishu\tokens.json
macOS/Linux: ~/.config/company-feishu/tokens.json

4. 实现文件发现

文件发现能力包括:

搜索当前用户可见的云文档
列出指定 folder_token 下的文件
批量查询文件元信息

这些能力都通过用户 token 调用。搜索结果不是公司全量结果,而是当前登录用户有权限看到的结果。

5. 实现文档读写

新版文档能力分三类:

read_docx     读取 docx 为 Markdown
create_docx   创建新版文档,可选写入 Markdown/HTML
update_docx   append 或 replace

写入内容时,插件会先把 Markdown 或 HTML 转换成飞书文档 blocks,再插入到目标文档中。

update_docx 的策略:

append   默认推荐,用于追加总结、说明、版本记录
replace  仅在用户明确要求覆盖全文时使用

安装方法

1. 注册本地 marketplace

codex plugin marketplace add E:\Project\xxg\AIroles-programmer

查看 marketplace:

codex plugin marketplace list

应该能看到:

company-local  E:\Project\xxg\AIroles-programmer

2. 安装插件

codex plugin add feishu_plugin@company-local

查看插件:

codex plugin list

应该能看到:

feishu_plugin@company-local  installed, enabled

3. 配置本机密钥

只设置本机环境变量,不提交到仓库。

setx COMPANY_FEISHU_APP_SECRET "YOUR_APP_SECRET"

如果需要覆盖 App ID,也可以设置:

setx COMPANY_FEISHU_APP_ID "YOUR_APP_ID"

设置后重新打开终端或重启 Codex。

使用方法

登录

在 Codex 中输入:

使用 company-feishu-auth 登录我的公司飞书账号

Codex 会调用 MCP 返回登录 URL。用户在浏览器里完成飞书授权后,MCP 会把 token 保存到本机。

检查登录状态

检查 Company Feishu 登录状态

搜索文件

搜索我飞书里关于“设备帮助”的文档

列文件夹

列出这个飞书文件夹下的文件:folder_token=YOUR_FOLDER_TOKEN

读取文档

读取这个飞书文档并总结:docx_token=YOUR_DOCX_TOKEN

新建文档

新建一篇飞书文档,标题是“接口重构说明”,内容使用这次总结

追加文档

把这段内容追加到这个飞书文档末尾:docx_token=YOUR_DOCX_TOKEN

替换文档

替换这个飞书文档内容,使用下面的 Markdown

替换是高风险操作,除非用户明确说“覆盖全文”或“替换内容”,否则优先使用追加。

验证方式

插件开发完成后,做了三类验证:

node --check E:\Project\xxg\AIroles-programmer\plugin\feishu_plugin\mcp\company-feishu-mcp\server.mjs
python E:\Project\xxg\AIroles-programmer\skills\.system\plugin-creator\scripts\validate_plugin.py E:\Project\xxg\AIroles-programmer\plugin\feishu_plugin
codex plugin list

并用 JSON-RPC 手动验证了 MCP 初始化和 company_feishu_auth_status 返回。

安全注意事项

  1. 不要把 COMPANY_FEISHU_APP_SECRET 写入插件文件、博客、日志或仓库。
  2. 不要保存飞书账号密码。
  3. token 文件只保存在用户本机配置目录。
  4. 如果密钥曾在聊天、截图或文档里暴露,应到飞书开放平台重置。
  5. 搜索和读取结果只代表当前登录用户的可见范围,不代表公司全量文档。

后续扩展

下一阶段可以考虑:

支持 sheet 读取
支持 wiki 节点解析
支持指定资料库范围搜索
支持更精细的 docx 局部修改
支持 token 加密存储
支持插件版本自动升级流程

当前版本先把最关键链路打通:登录、搜索、读取、新建和修改。