关于 feishu-inout
feishu-inout 用于操作 Feishu/Lark 文档、消息、日历、会议、多维表格和群组。它结合官方远程 MCP 服务与 Open API,并提供凭据配置指引。
主要功能
- 01读取和编辑文档
- 02搜索文档和消息
- 03管理日历与会议
- 04操作多维表格
- 05管理群聊
- 06引导配置凭据与 OAuth
适用场景
- 01查找或更新 Feishu/Lark 文档
- 02发送消息并查看聊天记录
- 03管理日程与会议安排
- 04读取或更新多维表格记录
MCP 相关
通过 `https://mcp.feishu.cn/mcp` 上的官方远程 MCP 服务处理消息等操作;日历、多维表格和群组管理使用 Open API。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ joe960913/ feishu-inout --skill feishu-inout安装后在 Claude Code 中输入/feishu-inout确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSE.gitignoreREADME.mdREADME_CN.mdscripts/feishu_mcp.py详细介绍
飞书 InOut - 飞书/Lark 文档、消息、日历、多维表格与群组操作
通过官方飞书/Lark Remote MCP 服务(https://mcp.feishu.cn/mcp)和开放 API,操作云文档、发送/搜索消息、管理日历事件和会议、使用多维表格,以及管理群聊。零依赖,纯 Python。
安全:凭据处理规则
重要——请始终遵守以下规则:
- 绝不在任何 shell 命令中直接填入
FEISHU_APP_ID或FEISHU_APP_SECRET的值 - 绝不回显、打印或输出 App Secret 的值
- 运行任何脚本命令前,确保已加载环境变量:如果
echo $FEISHU_APP_ID返回空值,先运行source ~/.zshrc(或source ~/.bashrc) - 脚本会自动从环境变量读取凭据——无需将其作为参数传入
快速检查:用户是否已完成配置?
检查以下两项:
- 是否已设置环境变量
FEISHU_APP_ID和FEISHU_APP_SECRET?(运行echo $FEISHU_APP_ID——如果为空,先运行source ~/.zshrc) - 是否存在有效的 UAT 令牌?(运行脚本的
whoami命令)
如果两项都已就绪 → 跳转到使用方法。 如果任一项缺失 → 引导用户完成首次设置。
首次设置
告诉用户:“设置大约需要 5 分钟。我会一步步引导你操作——按步骤进行,并在每一步完成后告诉我。”
开始前,询问用户:
你需要哪些功能?
- 只读(搜索、阅读、浏览)——权限最少,设置最快
- 读写(+ 创建、编辑、评论)——推荐,可满足大多数场景
- 全部功能(+ 发送/搜索消息、日历/会议、多维表格、群组管理)——消息功能通过 MCP 使用用户身份(UAT),日历/多维表格/群组使用开放 API
根据用户的选择,在步骤 2 中显示对应的权限字符串。请注意,步骤 6(机器人能力)对于所有选项都是可选的。
必须显示与用户选择相对应的权限字符串:
选项 1(只读):
docx:document:readonly,search:docs:read,wiki:wiki:readonly,im:chat:read,task:task:read
选项 2(读写,推荐):
docx:document:readonly,search:docs:read,wiki:wiki:readonly,im:chat:read,task:task:read,docx:document,docx:document:create,docx:document:write_only,docs:document.media:upload,docs:document.media:download,wiki:node:read,wiki:node:create,docs:document.comment:read,docs:document.comment:create,contact:user:search,contact:contact.base:readonly,contact:user.base:readonly,board:whiteboard:node:read,drive:drive
选项 3(全部功能):
docx:document:readonly,search:docs:read,wiki:wiki:readonly,im:chat:read,task:task:read,docx:document,docx:document:create,docx:document:write_only,docs:document.media:upload,docs:document.media:download,wiki:node:read,wiki:node:create,docs:document.comment:read,docs:document.comment:create,contact:user:search,contact:contact.base:readonly,contact:user.base:readonly,board:whiteboard:node:read,drive:drive,im:message,im:message:send_as_bot,im:chat,search:message,im:message.send_as_user,im:message.p2p_msg:get_as_user,im:message.group_msg:get_as_user,calendar:calendar:readonly,calendar:calendar,bitable:app:readonly,bitable:app,im:chat:create
建议用户一次性启用所有权限(选项 3),以免日后需要更多功能时重新授权。如果用户倾向于最小权限,则显示对应的选项。
引导用户将字符串粘贴到开放平台 → 权限管理 → 批量导入/导出。
重要:批量导入后,提醒用户,部分权限(在下表中标记为“需要审批”),例如 im:message.send_as_user、search:message、im:message.p2p_msg:get_as_user、im:message.group_msg:get_as_user,需要管理员审批。等待审批期间,其他功能均可正常使用——用户可以立即开始使用文档、评论、日历和多维表格。
总共 6 个步骤。每完成一步后,都要确认用户已完成,再进入下一步。
步骤 1:创建飞书/Lark 应用
- 前往 Lark 开放平台(中国大陆:open.feishu.cn)并登录
- 点击右上角的创建企业自建应用
- 输入应用名称(任意名称,例如“My Doc Assistant”)和描述
- 创建完成后,前往应用详情页
- 在凭证与基础信息页面,记下:
- App ID(格式:
cli_xxxxxxxxxxxxxxxx) - App Secret(字母数字字符串)
- App ID(格式:
提醒用户将这些信息设为环境变量(见步骤 4)。不要让用户将 App Secret 发给你或粘贴到对话中。
步骤 2:启用 API 权限
进入应用 → 权限管理 → 批量导入/导出,粘贴与上方用户选择相对应的权限字符串。
或者逐项启用:
核心(必需):
| 权限范围 | 描述 | 授权类型 |
|---|---|---|
docx:document:readonly | 查看文档 | 应用 |
search:docs:read | 搜索文档 | 用户 |
wiki:wiki:readonly | 查看知识库 | 用户 + 应用 |
im:chat:read | 查看聊天信息 | 应用 |
task:task:read | 查看任务 | 应用 |
写入/编辑(追加、替换、插入、覆盖、删除、创建文档):
| 权限范围 | 描述 | 授权类型 |
|---|---|---|
docx:document | 查看和编辑文档 | 应用 |
docx:document:create | 创建文档 | 应用 |
docx:document:write_only | 写入文档 | 应用 |
docs:document.media:upload | 上传图片 | 应用 |
wiki:node:read | 查看知识库节点 | 应用 |
wiki:node:create | 创建知识库节点 | 应用 |
评论(get-comments、add-comments):
| 权限范围 | 描述 | 授权类型 |
|---|---|---|
docs:document.comment:read | 读取评论 | 应用 |
docs:document.comment:create | 创建评论 | 应用 |
用户(search-user、get-user):
| 权限范围 | 描述 | 授权类型 |
|---|---|---|
contact:user:search | 搜索用户 | 用户 |
contact:contact.base:readonly | 联系人信息 | 应用 |
contact:user.base:readonly | 用户信息 | 应用 |
文件(fetch-file):
| 权限范围 | 描述 | 授权类型 |
|---|---|---|
docs:document.media:download | 下载图片/附件 | 应用 |
board:whiteboard:node:read | 查看白板 | 应用 |
drive:drive | 管理云盘文件 | 应用 |
消息(send-msg、reply、get-msgs、search-msgs 等):
| 权限范围 | 描述 | 授权类型 |
|---|---|---|
im:message | 管理消息 | 应用 |
im:message:send_as_bot | 以机器人身份发送 | 应用 |
im:chat | 管理聊天 | 应用 |
search:message | 搜索消息 | 用户(需审批) |
im:message.send_as_user | 以用户身份发送 | 用户(需审批) |
im:message.p2p_msg:get_as_user | 读取私聊历史记录 | 用户(需审批) |
im:message.group_msg:get_as_user | 以用户身份读取群聊消息 | 用户(需审批) |
日历/会议(create-event、list-events):
| 权限范围 | 描述 | 授权类型 |
|---|---|---|
calendar:calendar:readonly | 查看日历 | 用户 |
calendar:calendar | 管理日历和活动 | 用户 |
多维表格(list-tables、list-records、create-record、update-record):
| 权限范围 | 描述 | 授权类型 |
|---|---|---|
bitable:app:readonly | 查看多维表格数据 | 用户 |
bitable:app | 管理多维表格数据 | 用户 |
群组管理(create-group、add-members、list-groups):
| 权限范围 | 描述 | 授权类型 |
|---|---|---|
im:chat:create | 创建群组 | 应用 |
注意:仅当用户选择“所有功能”时,才需要启用消息、日历、多维表格和群组管理权限。消息功能通过使用 UAT(用户身份)的官方 MCP 实现——机器人能力为可选项,并非必需。日历、多维表格和群组管理使用 Open API。
启用后,“用户”类型权限显示“与用户权限范围一致”属于正常情况。“应用”类型显示“-”也属于正常情况。
确认所有权限均显示 ✅ 已启用。
步骤 3:添加重定向 URL(用于 OAuth)
进入应用 → 安全设置 → 重定向 URL → 添加:
http://localhost:9876/callback
这是用于获取 User Access Token(UAT)的 OAuth 回调 URL。
第 4 步:设置环境变量
引导用户自行设置凭据。不要让用户向你发送 App Secret,也不要在对话中输出或复述凭据值。
根据用户的操作系统:
macOS / Linux:
echo 'export FEISHU_APP_ID="your_app_id"' >> ~/.zshrc
echo 'export FEISHU_APP_SECRET="your_app_secret"' >> ~/.zshrc
source ~/.zshrc
Windows(PowerShell):
[System.Environment]::SetEnvironmentVariable('FEISHU_APP_ID', 'your_app_id', 'User')
[System.Environment]::SetEnvironmentVariable('FEISHU_APP_SECRET', 'your_app_secret', 'User')
设置后重启终端或 IDE。
验证(仅验证 App ID,绝不输出 Secret):
- macOS/Linux:
echo $FEISHU_APP_ID - Windows:
echo $env:FEISHU_APP_ID
第 5 步:通过 OAuth 登录以获取 UAT
运行登录命令:
python3 ~/.claude/skills/feishu-inout/scripts/feishu_mcp.py login
流程:
- 脚本会在浏览器中打开飞书/Lark 授权页面
- 如果显示“权限不足”,浏览器会列出确切缺少的权限——在开放平台启用这些权限,然后点击“重试”,无需一次性启用所有权限
- 用户在浏览器中点击授权
- 浏览器显示“授权成功!你可以关闭此页面。”
- 终端显示
UAT saved!——完成
令牌将在 2 小时后过期;脚本会通过 refresh_token 自动刷新。如果令牌过期太久,请重新运行 login。
验证所有内容均已就绪:
python3 ~/.claude/skills/feishu-inout/scripts/feishu_mcp.py whoami
python3 ~/.claude/skills/feishu-inout/scripts/feishu_mcp.py search-doc "test"
第 6 步:机器人能力(可选)
通过 MCP 收发消息使用 UAT(用户身份),因此发送或读取消息不需要机器人能力。send-message MCP 工具会以已认证用户的身份发送消息,而不是以机器人的身份发送。
不过,如果用户需要机器人身份(例如,以机器人身份发送自动通知),可以选择启用:
- 前往应用 → 添加能力 → 启用 机器人
- 前往版本管理与发布 → 创建版本 → 提交审核
- 审核通过后,将机器人添加到目标群组
此步骤完全可选。如果用户只需要以自己的身份发送消息,请跳过。
设置完成!
完成所有步骤后,祝贺用户,并建议尝试以下操作来验证一切正常:
一切就绪!试试以下任一操作,开始使用:
- “显示我的飞书/Lark 文档”
- “搜索关于[主题]的文档”
- “创建一个名为[标题]的新文档”
- “我今天有哪些会议?”
- “给[姓名]发条消息:你好!”
只需自然地交流——其余的交给我来处理。
身份验证
脚本会自动选择最合适的令牌:
- UAT(用户访问令牌)——首选。支持搜索文档、访问个人文档及其他用户级操作
- TAT(租户访问令牌)——UAT 不可用时的后备选项。功能有限:无法搜索,只能访问已授权给应用的文档
这两种令牌使用不同的 MCP 请求头:
- UAT →
X-Lark-MCP-UAT - TAT →
X-Lark-MCP-TAT
检查当前状态:
python3 ~/.claude/skills/feishu-inout/scripts/feishu_mcp.py whoami
重新登录(令牌过期时):
python3 ~/.claude/skills/feishu-inout/scripts/feishu_mcp.py login
提取文档 ID
从飞书/Lark URL 中提取 docID:
https://xxx.feishu.cn/docx/ABC123def → docID = ABC123def
https://xxx.larksuite.com/docx/ABC123def → docID = ABC123def
https://xxx.feishu.cn/wiki/XYZ789abc → docID = XYZ789abc
https://xxx.feishu.cn/docs/doccn123c → docID = doccn123c
规则:docID 是 /docx/、/wiki/ 或 /docs/ 后面的最后一个路径段。
用法
所有操作均使用 scripts/feishu_mcp.py 脚本($S = 下方的完整路径):
S=~/.claude/skills/feishu-inout/scripts/feishu_mcp.py
# Auth
python3 $S login # OAuth login to get UAT
python3 $S whoami # Show current token status
# Read documents
python3 $S fetch-doc <docID> # Read full document
python3 $S fetch-doc <docID> 0 5000 # Paginated read (offset, limit)
# Search
python3 $S search-doc <keyword> # Search documents (needs UAT)
python3 $S search-user <keyword> # Search users
# Browse
python3 $S list-docs # List "My Library"
python3 $S list-docs <docID> # List child docs
python3 $S get-user # Get current user info
python3 $S get-user <open_id> # Get specific user info
# Create document (one step, with markdown content)
python3 $S create-doc <title> '<markdown>'
python3 $S create-doc <title> '<markdown>' '{"wiki_space":"my_library"}'
python3 $S create-doc <title> '<markdown>' '{"folder_token":"fldcnXXX"}'
# Update document (7 modes)
python3 $S append <docID> '<markdown>' # Append to end
python3 $S overwrite <docID> '<markdown>' # Overwrite entire doc (use with caution)
python3 $S replace <docID> '<selection>' '<md>' # Replace matched range
python3 $S insert-after <docID> '<sel>' '<md>' # Insert after match
python3 $S insert-before <docID> '<sel>' '<md>' # Insert before match
python3 $S delete-range <docID> '<selection>' # Delete matched content
# Comments
python3 $S get-comments <docID> # Get all comments
python3 $S get-comments <docID> whole # Whole-doc comments only
python3 $S get-comments <docID> segment # Inline comments only
python3 $S add-comments <docID> <text> # Add a text comment
# Files
python3 $S fetch-file <token> # Get file/image content
python3 $S fetch-file <token> whiteboard # Get whiteboard content
# Messaging (via MCP)
python3 $S send-msg <chat_id|open_id> <text> [--user] # Send markdown message
python3 $S send-card <chat_id|open_id> '<json>' [--user] # Send interactive card
python3 $S reply <message_id> <text> [--thread] # Reply to a message
python3 $S get-msgs <chat_id> [time] [count] # Get group chat history
python3 $S get-msgs-user <open_id> [time] [count] # Get DM history
python3 $S search-msgs <keyword> [time] # Search messages across chats
python3 $S get-thread <thread_id> # Get thread replies
# Calendar / Meeting (via Open API)
python3 $S create-event <title> <start> <end> [attendees_json] # Create event with video meeting
python3 $S list-events [date] # List events (default: today)
# Bitable / Multi-dimensional Table (via Open API)
python3 $S list-tables <app_token> # List tables in a bitable
python3 $S list-records <app_token> <table_id> [page_size] # List records
python3 $S create-record <app_token> <table_id> '<fields_json>' # Create a record
python3 $S update-record <app_token> <table_id> <record_id> '<fields_json>' # Update a record
# Group Management (via Open API, uses TAT/bot identity)
python3 $S create-group <name> [members_json] # Create a group chat
python3 $S add-members <chat_id> '<members_json>' # Add members to group
python3 $S list-groups # List groups bot is in
# Advanced (raw JSON call to any tool)
python3 $S call <toolName> '<jsonArgs>'
python3 $S update-doc '{"doc_id":"xxx","mode":"replace_range","selection_by_title":"## Section","markdown":"New content"}'
选择语法(用于替换 / 插入 / 删除)
- 范围匹配:
起始文本...结束文本——匹配两个文本片段之间的所有内容 - 精确匹配:
精确文本——不含...,进行精确匹配 - 按标题选择:在
update-doc的 JSON 模式中使用selection_by_title: "## 标题",以定位整个章节
工作流
读取文档
- 从用户的 URL 中提取 docID
- 运行
fetch-doc <docID> - 解析返回的 JSON——
result.content[0].text中包含 Markdown 内容 - 对于大型文档,使用分页:
fetch-doc <docID> <offset> <limit>
搜索并读取
- 运行
search-doc <keyword>查找文档 - 从结果的
items数组中提取id(docID)和title - 如果有多个结果,列出这些结果并让用户选择
- 运行
fetch-doc <docID>读取选定的文档
创建文档(一步完成)
- 运行
create-doc <title> '<markdown>',创建并填入内容 - 可选指定位置:知识库节点
wiki_node、知识库空间wiki_space(my_library= 个人知识库)或文件夹folder_token - 返回
doc_id和doc_url - 注意:未指定位置时,文档会创建在个人空间根目录中,不会出现在“最近”列表里。建议使用
wiki_space: "my_library",方便用户查找
编辑文档
优先使用局部更新,而不是覆盖:
append— 在末尾添加内容replace— 查找并替换指定内容(使用start...end范围匹配或精确文本)insert-after/insert-before— 在指定位置后/前插入delete-range— 删除匹配的内容overwrite— 最后手段,会清空整个文档(图片、评论等也会丢失)
按标题定位整个章节(适合替换/删除整个章节):
python3 $S call update-doc '{"doc_id":"xxx","mode":"replace_range","selection_by_title":"### Section Title","markdown":"### Section Title\n\nReplaced content"}'
selection_by_title 会从标题匹配到下一个同级标题。
浏览知识库
- 运行
list-docs查看“我的知识库” - 或运行
list-docs <docID>查看子文档(响应中包含has_child字段) - 递归浏览更深层级
@提及工作流
- 运行
search-user <name>获取用户的open_id - 在
add-comments中使用高级模式:call add-comments '{"doc_id":"xxx","elements":[{"type":"mention","open_id":"ou_xxx"}]}'
创建文档并发送到群聊
- 运行
create-doc <title> '<markdown>'创建文档 - 运行
send-msg <chat_id> <text>,将文档链接分享给群组(在文本中包含文档 URL) - 要 @提及用户:在消息文本中使用
<mention-user id="openId"/>语法(先运行search-user获取 open_id)
发送消息
消息通过官方 Feishu/Lark MCP 使用 UAT(用户身份)发送,无需机器人能力。
- 群消息:
send-msg <chat_id> <text>— 以已认证用户的身份发送 - 私聊:
send-msg <open_id> <text> --user— 通过 open_id 向用户发送 - 交互式卡片:
send-card <chat_id|open_id> '<json>' [--user]— 发送卡片消息 - 回复:
reply <message_id> <text>— 回复指定消息 - 在话题中回复:
reply <message_id> <text> --thread— 在话题中回复 - 群聊历史记录:
get-msgs <chat_id> [time] [count]— 按时间筛选获取聊天记录 - 私聊历史记录:
get-msgs-user <open_id> [time] [count]— 读取私聊记录 - 搜索:
search-msgs <keyword> [time]— 搜索所有聊天中的消息 - 话题回复:
get-thread <thread_id>— 获取话题中的所有回复
Markdown 格式:send-msg 支持在消息文本中使用 Markdown 语法。
@提及语法:
- 提及特定用户:
<mention-user id="openId"/> - 提及所有人:
<mention-user id="all"/> - 支持 Emoji:
[SMILE]、[THUMBSUP]等
get-msgs、get-msgs-user、search-msgs 的时间筛选条件:today、yesterday、this_week、last_week、this_month、last_month、last_30_minutes、last_3_days 等。
创建会议
- 运行
create-event <title> <start> <end>— 自动创建 Feishu/Lark 视频会议 - 邀请参会者:
create-event "Sprint Review" "2026-03-28T14:00+08:00" "2026-03-28T15:00+08:00" '["ou_xxx","ou_yyy"]' - 先使用
search-user获取参会者的 open_id
使用 Bitable
- 从 Bitable URL 中提取 app_token:
https://xxx.feishu.cn/base/XXX— app_token = XXX - 运行
list-tables <app_token>查看可用的数据表 - 运行
list-records <app_token> <table_id>读取数据 - 运行
create-record或update-record写入数据
创建群组并添加成员
- 运行
create-group "Project Alpha" '["ou_xxx","ou_yyy"]',创建群组并添加初始成员 - 或运行
create-group "Project Alpha",然后运行add-members <chat_id> '["ou_xxx"]' - 群组管理使用机器人身份(TAT),需要启用机器人能力
错误处理
| 代码 | 含义 | 解决方案 |
|---|---|---|
-32011 | 缺少身份验证凭据 | 检查是否已设置 FEISHU_APP_ID 和 FEISHU_APP_SECRET 环境变量 |
-32003 | 凭据无效或已过期 | TAT:检查 App Secret;UAT:运行 login 重新授权 |
-32601 | 未找到工具或方法 | 运行 tools 查看可用工具 |
-32602 | 参数无效 | 检查参数名称和格式 |
-32700 | JSON 解析错误 | 检查 JSON 参数格式 |
429 | 请求频率受限 | 等待几秒后重试 |
99991679 | 用户尚未授权此权限范围 | 重新运行 login,或在应用的权限管理中启用该权限 |
常见问题
search-doc 返回 "required ... search:docs:read"
→ 此权限需要用户身份(UAT)。运行 login 获取 UAT。
fetch-doc 返回 "permission denied"
→ 在 TAT 模式下,必须将应用添加为文档协作者。使用 UAT(运行 login 后)即可访问用户有权限访问的所有文档。
登录后浏览器没有响应
→ 检查是否已在应用的安全设置中添加重定向 URL http://localhost:9876/callback。
UAT 已过期
→ 脚本会自动尝试通过 refresh_token 刷新。如果 refresh_token 也已过期(30 天),请重新运行 login。