飞书 MCP 服务器 - 基于 Model Context Protocol 的飞书 API 集成服务,提供 20+ 工具支持文档、机器人、聊天和多维表格操作
飞书 MCP 服务器
飞书 MCP 服务器是一个基于 Model Context Protocol 的服务,提供飞书 API 集成,使 AI 模型能够轻松与飞书服务交互。
目录
功能特点
- 文档服务:读取、创建飞书文档,支持内容块操作和权限管理
- 机器人服务:发送文本消息和交互卡片到飞书聊天
- 聊天服务:搜索和管理群组会话
- 多维表格服务:完整的 Bitable CRUD 操作,支持批量创建记录
- 多模式支持:
- STDIO 模式:通过标准输入/输出通信,适用于 CLI 环境和集成到其他应用
- HTTP 模式:提供 REST API 和 SSE 连接,适用于 Web 服务和分布式部署
- 完善的错误处理:统一的错误处理机制,提供详细的错误信息
- 类型安全:基于 TypeScript,提供完整的类型定义
- 模块化架构:易于扩展新功能和集成其他飞书 API
支持的工具
文档操作 (6 个工具)
| 工具名称 | 描述 |
|---------|------|
| get_feishu_document_raw | 获取文档原始内容 |
| get_feishu_document | 获取文档元数据 |
| create_feishu_document | 创建新文档 |
| create_feishu_document_block | 在文档中创建内容块 |
| set_feishu_document_permission | 设置文档分享权限 |
| create_feishu_document_password | 创建文档分享密码 |
机器人操作 (2 个工具)
| 工具名称 | 描述 |
|---------|------|
| send_feishu_text_message | 发送文本消息 |
| send_feishu_card | 发送交互卡片 |
聊天操作 (2 个工具)
| 工具名称 | 描述 |
|---------|------|
| search_feishu_chats | 搜索群组 |
| get_feishu_chats | 获取群组列表 |
多维表格操作 (10 个工具)
| 工具名称 | 描述 |
|---------|------|
| get_feishu_sheet_meta | 获取多维表格元数据 |
| get_feishu_sheet_tables | 获取数据表列表 |
| get_feishu_sheet_views | 获取视图列表 |
| get_feishu_sheet_view | 获取视图详情 |
| get_feishu_sheet_records | 获取记录列表 |
| get_feishu_sheet_record | 获取单条记录 |
| create_feishu_sheet_record | 创建记录 |
| update_feishu_sheet_record | 更新记录 |
| delete_feishu_sheet_record | 删除记录 |
| batch_create_feishu_sheet_records | 批量创建记录 |
项目架构
代码结构
/src
/client # API客户端实现(底层API请求封装)
/documents # 文档相关API客户端
/bots # 机器人API客户端
/chats # 聊天相关API客户端
/services # 服务层实现(业务逻辑和错误处理)
/documents # 文档相关服务
/bots # 机器人相关服务
/chats # 聊天相关服务
/server # MCP服务器实现
/tools # MCP工具注册和实现
/typings # 类型定义
/utils # 通用工具函数
/http # HTTP服务器实现
/logger # 日志服务
/consts # 常量定义
config.ts # 配置管理
index.ts # 入口点
设计原则
项目采用分层架构设计,确保关注点分离和职责明确:
1. 分层职责
-
客户端层(Client)
- 封装HTTP请求的细节
- 处理底层API参数和响应格式
- 管理认证和令牌刷新
- 不包含业务逻辑
-
服务层(Service)
- 使用客户端执行API操作
- 实现业务逻辑
- 处理和转换错误
- 提供友好的接口给上层使用
-
工具层(Tools)
- 实现MCP协议定义的工具
- 处理参数验证和格式转换
- 调用服务层完成实际操作
- 格式化返回结果
2. 依赖方向
- 服务层依赖客户端层
- 工具层依赖服务层
- 严格避免循环依赖
3. 错误处理策略
- 使用
FeiShuApiError统一处理API错误 - 客户端层返回原始错误
- 服务层捕获并转换为业务相关错误
- 工具层处理所有异常并返回用户友好消息
工作流程
- MCP服务器接收请求(STDIO或HTTP)
- 工具层验证参数并调用相应服务
- 服务层实现业务逻辑并调用客户端
- 客户端执行实际API请求并返回结果
- 结果经由服务层处理后返回给工具层
- 工具层格式化结果并返回给MCP服务器
快速开始
前提条件
- Node.js 23.0或更高版本
- pnpm包管理器
- 有效的飞书开发者账号和已创建的自建应用
安装步骤
- 克隆仓库
git clone https://github.com/opsworld30/feishu-mcp-server.git
cd feishu-mcp-server
- 安装依赖
pnpm install
- 创建
.env文件
# 飞书应用凭证(必填)
FEISHU_APP_ID=your_app_id
FEISHU_APP_SECRET=your_app_secret
# 服务器配置(可选)
PORT=3344
LOG_LEVEL=info
运行服务
开发模式
# 开发模式(自动重启)
pnpm dev
# 或使用普通启动
pnpm start
生产模式
# 构建项目
pnpm build
# 运行编译后的代码
node dist/index.js
STDIO模式
# 方法1:使用环境变量
NODE_ENV=cli node dist/index.js
# 方法2:使用命令行参数
node dist/index.js --stdio
配置说明
| 选项 | 环境变量 | 命令行参数 | 默认值 | 描述 |
|------|----------|------------|--------|------|
| 飞书应用ID | FEISHU_APP_ID | --feishu-app-id | - | 飞书自建应用的App ID |
| 飞书应用密钥 | FEISHU_APP_SECRET | --feishu-app-secret | - | 飞书自建应用的App Secret |
| 服务器端口 | PORT | --port | 3344 | HTTP服务器端口号 |
| 日志级别 | LOG_LEVEL | --log-level | info | 日志级别(debug/info/warn/error) |
| 令牌缓存时间 | TOKEN_CACHE_DURATION | - | 7100 | 访问令牌缓存时间(秒) |
API文档
文档操作
get_feishu_document_raw
获取飞书文档的原始内容。
- 参数:
docId- 文档ID (例如:feishu.cn/docx/<documentId>) - 返回:文档的文本内容
get_feishu_document
获取飞书文档的元数据信息。
- 参数:
docId- 文档ID - 返回:文档的元数据(JSON格式)
create_feishu_document
创建新的飞书文档。
- 参数:
title- 文档标题(可选)folderToken- 目标文件夹Token(可选,不指定则创建在根目录)
- 返回:新文档的ID和URL
create_feishu_document_block
在文档中创建内容块。
- 参数:
documentId- 文档IDblockId- 父块ID(可选,默认为文档根节点)blocks- 块数组,支持类型:text, heading1-6, bullet, ordered, code, quote, todo, dividerindex- 插入位置(可选,-1表示末尾)
- 返回:创建的块信息
set_feishu_document_permission
设置文档的公开分享权限。
- 参数:
documentId- 文档IDlinkShareEntity- 权限类型:tenant_readable, tenant_editable, anyone_readable, anyone_editable, closed
- 返回:设置结果
create_feishu_document_password
为文档创建分享密码。
- 参数:
documentId- 文档ID - 返回:分享密码
机器人操作
send_feishu_text_message
发送文本消息到飞书聊天。
- 参数:
chatId- 聊天IDtext- 要发送的文本内容
- 返回:消息ID
send_feishu_card
发送交互卡片到飞书聊天。
- 参数:
chatId- 聊天IDcardContent- 卡片内容(JSON字符串)
- 返回:消息ID
聊天操作
search_feishu_chats
搜索用户或机器人可见的群组。
- 参数:
query- 搜索关键词(可选)page_token- 分页标记(可选)page_size- 每页数量,默认10,最大100(可选)user_id_type- 用户ID类型:open_id, union_id, user_id(可选)
- 返回:群组列表
get_feishu_chats
获取用户或机器人所在的群组列表。
- 参数:
page_token- 分页标记(可选)page_size- 每页数量,默认10,最大100(可选)user_id_type- 用户ID类型(可选)
- 返回:群组列表
多维表格操作
get_feishu_sheet_meta
获取多维表格的元数据信息。
- 参数:
appToken- 多维表格ID (例如:feishu.cn/base/<appToken>) - 返回:表格元数据(JSON格式)
get_feishu_sheet_tables
获取多维表格中的数据表列表。
- 参数:
appToken- 多维表格IDpageSize- 每页数量,默认20,最大100(可选)pageToken- 分页标记(可选)
- 返回:数据表列表
get_feishu_sheet_views
获取数据表的视图列表。
- 参数:
appToken- 多维表格IDtableId- 数据表IDpageSize- 每页数量(可选)pageToken- 分页标记(可选)
- 返回:视图列表
get_feishu_sheet_view
获取特定视图的详细信息。
- 参数:
appToken- 多维表格IDtableId- 数据表IDviewId- 视图ID
- 返回:视图详情
get_feishu_sheet_records
获取数据表记录列表。
- 参数:
appToken- 多维表格IDtableId- 数据表IDviewId- 视图ID(可选)fieldIds- 字段ID列表(可选)filter- FQL格式过滤条件(可选)sort- JSON格式排序条件(可选)pageSize- 每页数量(可选)pageToken- 分页标记(可选)
- 返回:记录列表
get_feishu_sheet_record
获取单条记录。
- 参数:
appToken- 多维表格IDtableId- 数据表IDrecordId- 记录IDfieldIds- 字段ID列表(可选)
- 返回:单条记录
create_feishu_sheet_record
创建新记录。
- 参数:
appToken- 多维表格IDtableId- 数据表IDfields- 字段键值对
- 返回:新记录信息
update_feishu_sheet_record
更新现有记录。
- 参数:
appToken- 多维表格IDtableId- 数据表IDrecordId- 记录IDfields- 要更新的字段键值对
- 返回:更新后的记录
delete_feishu_sheet_record
删除记录。
- 参数:
appToken- 多维表格IDtableId- 数据表IDrecordId- 记录ID
- 返回:删除结果
batch_create_feishu_sheet_records
批量创建记录。
- 参数:
appToken- 多维表格IDtableId- 数据表IDrecords- 记录数组,每条记录包含fields对象
- 返回:创建的记录列表
开发指南
代码规范
项目使用严格的TypeScript规范和ESLint配置:
- 使用TypeScript接口和类型定义
- 避免使用
any类型 - 使用
Record<string, unknown>替代object类型 - 所有代码文件、注释和错误消息使用英文
运行代码检查:
# 运行代码检查
pnpm lint
# 运行代码检查并修复
pnpm lint:fix
# 运行代码格式化
pnpm format
错误处理
所有与飞书API相关的错误应使用 FeiShuApiError 类处理:
try {
// API操作
} catch (error) {
if (error instanceof FeiShuApiError) {
// 处理特定的API错误
logger.error(`FeiShu API Error (${error.code}): ${error.message}`);
} else {
// 处理通用错误
logger.error('Unexpected error:', error);
}
// 转换为用户友好消息
throw new FeiShuApiError('操作失败', { cause: error });
}
提交规范
提交消息必须遵循以下格式:
<type>(<scope>): <subject>
例如:
feat(bot): 添加发送卡片功能fix(documents): 修复文档内容获取错误
支持的类型:
feat: 新功能fix: 修复Bugdocs: 文档变更style: 代码格式调整refactor: 代码重构perf: 性能优化test: 测试相关chore: 构建过程或辅助工具的变动
扩展指南
添加新功能的步骤:
-
创建客户端类
- 在
src/client/<feature>/目录下创建 - 继承
ApiClient基类 - 实现API请求方法
// src/client/feature/feature-client.ts export class FeatureClient extends ApiClient { async getFeatureData(id: string): Promise<FeatureData> { return this.request<FeatureResponse>('/feature/get', { id }); } } - 在
-
创建服务类
- 在
src/services/<feature>/目录下创建 - 使用相应的客户端类
- 实现业务逻辑和错误处理
// src/services/feature/feature-service.ts export class FeatureService { private client: FeatureClient; constructor(config: ApiClientConfig) { this.client = new FeatureClient(config); } async getFeature(id: string): Promise<Feature> { try { const data = await this.client.getFeatureData(id); return this.transformData(data); } catch (error) { handleError(error); } } } - 在
-
注册服务
- 在
src/services/index.ts中导出新服务 - 将服务添加到
FeiShuServices类
- 在
-
创建MCP工具
- 在
src/server/tools/feature-tools.ts中创建 - 使用Zod进行参数验证
- 调用服务层方法
// src/server/tools/feature-tools.ts export function registerFeatureTools(params: ToolRegistryParams): void { const { server, services, logger } = params; server.tool( 'get_feishu_feature', 'Get feature from FeiShu', { id: z.string().describe('Feature ID'), }, async ({ id }) => { try { const feature = await services.feature.getFeature(id); return { content: [{ type: 'text', text: JSON.stringify(feature) }] }; } catch (error) { return handleToolError(error, logger); } } ); } - 在
-
注册工具
- 在
src/server/tools/index.ts中引入并注册新工具
- 在
常见问题
认证失败
问题:API请求返回认证错误
解决方案:
- 检查应用ID和密钥是否正确
- 确认应用具有所需的权限范围
- 检查服务器时间是否正确同步
令牌刷新问题
问题:令牌刷新失败
解决方案:
- 设置更短的令牌缓存时间
- 检查网络连接稳定性
- 查看飞书开发者平台的应用状态
许可证
MIT
贡献指南
欢迎贡献!请遵循以下步骤:
- Fork仓库
- 创建功能分支(
git checkout -b feature/amazing-feature) - 提交更改(
git commit -m 'feat: add some amazing feature') - 推送到分支(
git push origin feature/amazing-feature) - 开启Pull Request
提交PR前请确保:
- 代码通过所有测试
- 更新了相关文档
- 遵循项目的代码风格和命名约定
- 添加必要的单元测试