feishu-mcp

repository·main·Indexed 20 days ago

https://github.com/cso1z/feishu-mcp

A Model Context Protocol (MCP) server version 0.3.3 that enables AI coding agents to interact with the Feishu (Lark) ecosystem. It provides tools for document processing (creation, editing, and structural analysis), task management, and user information queries. The package includes a standalone `feishu-tool` CLI for terminal usage and supports various document styles including Markdown, LaTeX math formulas, and Mermaid diagrams.

Tokens
33.8K
Snippets
99
Records
142
Agent score
69%

What's inside feishu-mcp

  1. Overview of feishu-mcp

    main

    The feishu-mcp project is a Model Context Protocol (MCP) server that provides AI-driven coding tools (like Cursor, Windsurf, and Cline) with the ability to access, edit, and structurally process Feishu (Lark) documents. It also supports Feishu task management and user information queries.

    Key capabilities include:

    • Document Processing: Get, understand, create, and edit Feishu documents.
    • Task Management: List, create, update, and delete Feishu tasks (including sub-tasks and member management).
    • User Information: Search for users by name or retrieve users by ID for task assignment and collaboration.
    • CLI Access: Includes a standalone feishu-tool CLI for terminal or script usage without needing to start the MCP server.
  2. Choose between HTTP/SSE and Stdio transport modes

    main

    The Feishu MCP server supports two communication modes depending on your deployment environment:

    1. HTTP/SSE (Server-Sent Events) Mode:

      • Best for: Running as a standalone service.
      • Mechanism: Uses an HTTP server and SSE for real-time, long-lived communication.
      • Endpoint: Typically listens on a configured port (e.g., /mcp for MCP communication).
    2. Stdio (Standard Input/Output) Mode:

      • Best for: CLI environments and direct integration into AI tools like Cursor.
      • Mechanism: Uses the process's standard input/output streams for inter-process communication.
      • Advantages: No network ports required, low overhead, and easy to embed in command-line tools.
  3. How the Feishu MCP Server architecture works

    main

    The Feishu MCP Server acts as a middleware layer between AI coding tools (like Cursor, Windsurf, or Cline) and the Feishu API. It implements the Model Context Protocol (MCP) to allow AI models to access and manipulate Feishu documents directly.

    Core Components

    • McpServer: The core MCP server implementation based on @modelcontextprotocol/sdk.
    • FeishuService: The service layer responsible for interacting with the Feishu API (authentication, document operations, and block operations).
    • Transport Layer: Handles communication via either HTTP/SSE (Server-Sent Events) or Standard Input/Output (stdio).

    Data Flow

    1. The AI tool (e.g., Cursor) requests document content via the MCP server.
    2. The MCP server sends an authentication and data request to the Feishu API.
    3. The Feishu API returns the raw data to the MCP server.
    4. The MCP server returns the processed document content to the AI tool.
    +----------------+       +------------------+       +----------------+
    |                |       |                  |       |                |
    |  AI编码工具     | <===> |  飞书 MCP 服务器  | <===> |  飞书API       |
    | (Cursor等)     |       |                  |       |                |
    +----------------+       +------------------+       +----------------+
  4. Understand the UserContext mechanism

    main

    UserContext is a context-passing mechanism implemented using Node.js AsyncLocalStorage. It allows user information to be passed through asynchronous call chains without explicitly passing arguments to every function.

    UserContext Structure

    An object containing:

    • userKey: A unique identifier for the user (e.g., 'stdio').
    • baseUrl: The base URL for the current context.

    How it works

    By using UserContextManager.run(), you can wrap an asynchronous operation. Any code executed within that callback (and its subsequent asynchronous sub-calls) can access the context via UserContextManager.getUserKey().

    If called outside of a run() block, getUserKey() returns an empty string ''.

    // Setting the context
    userContextManager.run(
      { userKey: 'stdio', baseUrl: 'http://localhost:3333' },
      async () => {
        // Within this callback and its async children, getUserKey() returns 'stdio'
        const userKey = userContextManager.getUserKey(); 
      }
    );
    
    // Outside the context
    const userKey = userContextManager.getUserKey(); // Returns ''
  5. Understand the Token Caching System

    main

    To improve performance and avoid Feishu API rate limits, the server implements a multi-layer caching strategy for access tokens:

    • Memory Caching: Stores frequently used data like access tokens in memory.
    • Expiration Control: Automatically manages cache expiration.
    • Early Refresh: Refreshes tokens slightly before they expire (using a 30-second safety buffer) to prevent request failures.
    • Cache Invalidation: Provides mechanisms to clear invalid data.

    This system reduces latency, decreases the load on Feishu API servers, and enhances stability during temporary API unavailability.

  6. Understand the purpose of tool-schemas

    main

    The tool-schemas directory contains JSON Schema definition files for every MCP tool provided by the server. These schemas are automatically generated by MCP clients (such as Cursor) when they connect to the feishu-mcp server.

    These files serve two primary purposes:

    1. LLM Context: The feishu-tool help <tool-name> command reads these files to provide detailed tool descriptions to Large Language Models (LLMs).
    2. Documentation Reference: They act as the external documentation reference for the parameter schemas required by each tool.
  7. Understand the two paths for creating Feishu tables

    main

    When working with Feishu Docx via this MCP, there are two distinct ways to create tables, which use different API endpoints and payload structures. Choosing the wrong path for your use case may result in error code 1770001 (invalid param).

    1. Simple Table Shell (via /children endpoint):

      • Method: Uses batch_create_feishu_blocks (internally calling createDocumentBlocks).
      • Payload: Sends only the table's properties (e.g., block_type: 31 and property settings).
      • Behavior: It creates a 'shell' of a table. It relies on the Feishu server to automatically generate the internal cells. This is only valid if the Feishu children API supports creating tables this way.
    2. Full Table Tree (via /descendant endpoint):

      • Method: Uses createTableBlock (internally calling feishuService.createTableBlock).
      • Payload: Sends a complete tree structure including the table block, all table_cell blocks, and the content blocks inside those cells.
      • Behavior: This is the more robust method for creating tables with specific content immediately upon creation.
  8. Avoid stdout pollution in MCP Stdio mode

    main

    When running an MCP server in stdio mode, you must ensure that no non-JSON-RPC data is written to stdout. Using console.log, console.info, or console.debug directly will interfere with the protocol.

    To handle logging correctly in stdio mode, you should use the MCP protocol's built-in logging mechanism via sendLoggingMessage instead of standard console methods. This ensures logs are transmitted as structured MCP messages rather than raw text on the communication channel.

  9. How user authentication and userKey work

    main

    Feishu MCP supports two authentication modes:

    1. tenant mode: Uses the application's identity. It has limitations regarding file permissions, Wiki search, and document edit history.
    2. user mode: Uses the user's identity via OAuth. This is strongly recommended as it provides full compatibility with Feishu features (including task management and member queries).

    The userKey concept

    To distinguish between different users (especially in multi-user or proxy scenarios), you must provide a userKey. This is a unique identifier for the user.

    Ways to pass userKey:

    • URL Query Parameter (Recommended): Append ?userKey=123456 to the MCP server URL.
    • Request Header: Pass user-key: 123456 in the HTTP headers.

    Dynamic Switching (HTTP Streamable mode only): In HTTP Streamable mode, you can switch the active user context for a session by sending a new request with a different user-key header. This is not supported in stdio or SSE modes.

  10. Understand Stdio Mode Process Model and Token Sharing

    main

    When running in stdio mode (e.g., via an MCP client like Cursor), the server operates under a specific process model:

    • One-to-One Relationship: Each MCP client instance starts its own independent MCP server process.
    • Process Isolation: Each process has its own memory space, context, and independent stdin/stdout pipes for communication.
    • Token Cache Sharing: Although processes are isolated, they share a single token cache file if they run in the same working directory. The cache file is located at: process.cwd()/user_token_cache.json.

    In stdio mode, the userKey is hardcoded to 'stdio', which results in a consistent clientKey across all processes, allowing them to share the same authentication tokens.

  11. Understand Stdio mode communication in MCP

    main

    In stdio mode, the Model Context Protocol (MCP) communicates via standard input and output streams:

    • stdin: The client (e.g., Cursor) sends JSON-RPC requests to the server.
    • stdout: The server sends JSON-RPC responses and logging messages to the client.
    • stderr: Typically used for error output.

    Critical Constraint: The stdout stream must contain only valid JSON-RPC 2.0 messages. Any other text output (like standard console.log messages) will pollute the stream, causing the MCP client to fail when parsing the protocol messages.

  12. How the Feishu MCP Server processes data

    main

    The server optimizes data sent to AI models through several mechanisms:

    • Data Simplification: Removes unnecessary metadata to reduce the payload size sent to the AI.
    • Format Conversion: Transforms complex Feishu API responses into formats that are easier for LLMs to parse.
    • Content Extraction: Extracts key text from document blocks while ignoring non-essential styling information.
    • Markdown Support: Automatically converts Markdown syntax into Feishu document style attributes.