Skip to main content
Glama

Feishu MCP Server

by sdd330
README.md13.3 kB
# 飞书MCP服务器 [![TypeScript](https://img.shields.io/badge/TypeScript-5.8-blue.svg)](https://www.typescriptlang.org/) [![Node.js](https://img.shields.io/badge/Node.js->=23-green.svg)](https://nodejs.org/) [![License](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) 飞书MCP服务器是一个基于[Model Context Protocol](https://modelcontextprotocol.ai/)的服务,提供飞书API集成,使AI模型能够轻松与飞书服务交互。 ## 目录 - [功能特点](#功能特点) - [项目架构](#项目架构) - [代码结构](#代码结构) - [设计原则](#设计原则) - [工作流程](#工作流程) - [快速开始](#快速开始) - [前提条件](#前提条件) - [安装步骤](#安装步骤) - [运行服务](#运行服务) - [配置说明](#配置说明) - [API文档](#api文档) - [文档操作](#文档操作) - [机器人操作](#机器人操作) - [聊天操作](#聊天操作) - [多维表格操作](#多维表格操作) - [开发指南](#开发指南) - [代码规范](#代码规范) - [错误处理](#错误处理) - [提交规范](#提交规范) - [扩展指南](#扩展指南) - [常见问题](#常见问题) - [许可证](#许可证) - [贡献指南](#贡献指南) ## 功能特点 - **文档服务**:读取飞书文档内容和元数据 - **机器人服务**:发送文本消息和交互卡片到飞书聊天 - **聊天服务**:管理群组和聊天会话 - **多模式支持**: - **STDIO模式**:通过标准输入/输出通信,适用于CLI环境和集成到其他应用 - **HTTP模式**:提供REST API和SSE连接,适用于Web服务和分布式部署 - **完善的错误处理**:统一的错误处理机制,提供详细的错误信息 - **类型安全**:基于TypeScript,提供完整的类型定义 - **模块化架构**:易于扩展新功能和集成其他飞书API ## 项目架构 ### 代码结构 ``` /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错误 - 客户端层返回原始错误 - 服务层捕获并转换为业务相关错误 - 工具层处理所有异常并返回用户友好消息 ### 工作流程 1. MCP服务器接收请求(STDIO或HTTP) 2. 工具层验证参数并调用相应服务 3. 服务层实现业务逻辑并调用客户端 4. 客户端执行实际API请求并返回结果 5. 结果经由服务层处理后返回给工具层 6. 工具层格式化结果并返回给MCP服务器 ## 快速开始 ### 前提条件 - Node.js 23.0或更高版本 - pnpm包管理器 - 有效的飞书开发者账号和已创建的自建应用 ### 安装步骤 1. 克隆仓库 ```bash git clone https://github.com/yourusername/feishu-mcp-server.git cd feishu-mcp-server ``` 2. 安装依赖 ```bash pnpm install ``` 3. 创建`.env`文件 ``` # 飞书应用凭证(必填) FEISHU_APP_ID=your_app_id FEISHU_APP_SECRET=your_app_secret # 服务器配置(可选) PORT=3344 LOG_LEVEL=info ``` ### 运行服务 #### 开发模式 ```bash # 开发模式(自动重启) pnpm dev # 或使用普通启动 pnpm start ``` #### 生产模式 ```bash # 构建项目 pnpm build # 运行编译后的代码 node dist/index.js ``` #### STDIO模式 ```bash # 方法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_doc_raw` 获取飞书文档的原始内容。 参数: - `docId` - 文档ID,通常在URL中找到 (例如:feishu.cn/docx/<documentId>) 返回: - 文档的文本内容 #### `get_feishu_doc_info` 获取飞书文档的元数据信息。 参数: - `docId` - 文档ID 返回: - 文档的元数据(JSON格式) ### 机器人操作 #### `send_feishu_text_message` 发送文本消息到飞书聊天。 参数: - `chatId` - 聊天ID - `text` - 要发送的文本内容 返回: - 发送状态和消息ID #### `send_feishu_card` 发送交互卡片到飞书聊天。 参数: - `chatId` - 聊天ID - `cardContent` - 卡片内容(JSON字符串) 返回: - 发送状态和消息ID ### 聊天操作 #### `get_feishu_chat_info` 获取飞书聊天的基本信息。 参数: - `chatId` - 聊天ID 返回: - 聊天的基本信息(JSON格式) ### 多维表格操作 #### `get_feishu_sheet_meta` 获取飞书多维表格的元数据信息。 参数: - `appToken` - 多维表格ID,通常在URL中找到 (例如:feishu.cn/base/<appToken> 或 feishu.cn/app/<appToken>) 返回: - 多维表格的元数据(JSON格式),包含表格ID、名称、修订版本、创建者、创建时间、权限等信息 #### `get_feishu_sheet_tables` 获取飞书多维表格中的数据表列表。 参数: - `appToken` - 多维表格ID,通常在URL中找到 (例如:feishu.cn/base/<appToken> 或 feishu.cn/app/<appToken>) - `pageSize` - 每页返回的数据表数量,可选,默认为20,最大为100 - `pageToken` - 分页标记,可选,用于获取下一页数据 返回: - 数据表列表(JSON格式),包含表ID、名称、字段信息等 #### `get_feishu_sheet_views` 获取飞书多维表格中数据表的视图列表。 参数: - `appToken` - 多维表格ID,通常在URL中找到 (例如:feishu.cn/base/<appToken> 或 feishu.cn/app/<appToken>) - `tableId` - 数据表ID - `pageSize` - 每页返回的视图数量,可选,默认为20,最大为100 - `pageToken` - 分页标记,可选,用于获取下一页数据 返回: - 视图列表(JSON格式),包含视图ID、名称、类型和属性等信息 #### `get_feishu_sheet_view` 获取飞书多维表格中数据表特定视图的详细信息。 参数: - `appToken` - 多维表格ID,通常在URL中找到 (例如:feishu.cn/base/<appToken> 或 feishu.cn/app/<appToken>) - `tableId` - 数据表ID - `viewId` - 视图ID,要获取详细信息的视图 返回: - 视图详情(JSON格式),包含视图ID、名称、类型和属性等信息 #### `get_feishu_sheet_records` 获取飞书多维表格中的数据表记录。 参数: - `appToken` - 多维表格ID,通常在URL中找到 (例如:feishu.cn/base/<appToken> 或 feishu.cn/app/<appToken>) - `tableId` - 数据表ID - `viewId` - 视图ID,可选,不指定时使用默认视图 - `fieldIds` - 字段ID列表,可选,指定返回哪些字段 - `filter` - 过滤条件,可选,使用FQL格式 - `sort` - 排序条件,可选,使用JSON格式 - `pageSize` - 每页返回的记录数量,可选,默认为20,最大为100 - `pageToken` - 分页标记,可选,用于获取下一页数据 返回: - 记录列表(JSON格式),包含记录ID和字段值 #### `get_feishu_sheet_record` 获取飞书多维表格中的单条记录。 参数: - `appToken` - 多维表格ID,通常在URL中找到 (例如:feishu.cn/base/<appToken> 或 feishu.cn/app/<appToken>) - `tableId` - 数据表ID - `recordId` - 记录ID - `fieldIds` - 字段ID列表,可选,指定返回哪些字段 返回: - 单条记录(JSON格式),包含记录ID和字段值 ## 开发指南 ### 代码规范 项目使用严格的TypeScript规范和ESLint配置: - 使用TypeScript接口和类型定义 - 避免使用 `any` 类型 - 使用 `Record<string, unknown>` 替代 `object` 类型 - 所有代码文件、注释和错误消息使用英文 运行代码检查: ```bash # 运行代码检查 pnpm lint # 运行代码检查并修复 pnpm lint:fix # 运行代码格式化 pnpm format ``` ### 错误处理 所有与飞书API相关的错误应使用 `FeiShuApiError` 类处理: ```typescript 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`: 修复Bug - `docs`: 文档变更 - `style`: 代码格式调整 - `refactor`: 代码重构 - `perf`: 性能优化 - `test`: 测试相关 - `chore`: 构建过程或辅助工具的变动 ### 扩展指南 添加新功能的步骤: 1. **创建客户端类** - 在 `src/client/<feature>/` 目录下创建 - 继承 `ApiClient` 基类 - 实现API请求方法 ```typescript // src/client/feature/feature-client.ts export class FeatureClient extends ApiClient { async getFeatureData(id: string): Promise<FeatureData> { return this.request<FeatureResponse>('/feature/get', { id }); } } ``` 2. **创建服务类** - 在 `src/services/<feature>/` 目录下创建 - 使用相应的客户端类 - 实现业务逻辑和错误处理 ```typescript // 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); } } } ``` 3. **注册服务** - 在 `src/services/index.ts` 中导出新服务 - 将服务添加到 `FeiShuServices` 类 4. **创建MCP工具** - 在 `src/server/tools/feature-tools.ts` 中创建 - 使用Zod进行参数验证 - 调用服务层方法 ```typescript // 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); } } ); } ``` 5. **注册工具** - 在 `src/server/tools/index.ts` 中引入并注册新工具 ## 常见问题 ### 认证失败 **问题**:API请求返回认证错误 **解决方案**: - 检查应用ID和密钥是否正确 - 确认应用具有所需的权限范围 - 检查服务器时间是否正确同步 ### 令牌刷新问题 **问题**:令牌刷新失败 **解决方案**: - 设置更短的令牌缓存时间 - 检查网络连接稳定性 - 查看飞书开发者平台的应用状态 ## 许可证 MIT ## 贡献指南 欢迎贡献!请遵循以下步骤: 1. Fork仓库 2. 创建功能分支(`git checkout -b feature/amazing-feature`) 3. 提交更改(`git commit -m 'feat: add some amazing feature'`) 4. 推送到分支(`git push origin feature/amazing-feature`) 5. 开启Pull Request 提交PR前请确保: - 代码通过所有测试 - 更新了相关文档 - 遵循项目的代码风格和命名约定 - 添加必要的单元测试

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sdd330/feishu-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server