
Company News
Socket Joins New OpenJS Program to Fund Node.js Security Work
Socket is joining the OpenJS Security Stewardship Program to fund Node.js vulnerability research, maintainer remediation, and security releases.
feishu-user-mcp
Advanced tools
All-in-one Feishu/Lark MCP Server — 33 tools, 3 auth layers: user identity messaging (Protobuf), official API (REST), P2P chat reading (OAuth UAT).
All-in-one Feishu/Lark MCP Server -- 33 tools, 8 skills, 3 auth layers for messaging, docs, tables, wiki, and drive.
The only MCP server that lets you send messages as your personal identity (not a bot), while also integrating the full official Feishu API for documents, spreadsheets, wikis, and more.
/send, /reply, /search, /digest, /doc, /table, /wiki, /statusoc_xxx ID; it resolves automatically.Feishu's official API has a hard limitation: there is no send_as_user scope. Even with user_access_token (OAuth), messages still show sender_type: "app".
This project combines three auth layers into one plugin:
User Identity (cookie): You -> Protobuf -> Feishu (messages appear as YOU)
Official API (app token): You -> REST API -> Feishu (docs, tables, wiki, drive)
User OAuth (UAT): You -> REST API -> Feishu (read P2P chats, list all chats)
One plugin. Everything Feishu. No other MCP needed.
npx feishu-user-mcp
No installation needed. The package runs directly via npx.
git clone https://github.com/EthanQC/feishu-user-mcp.git
cd feishu-user-mcp
npm install
npm start
To use the Official API tools (docs, tables, wiki, drive, bot messaging), you need to create a Feishu app:
Go to Permissions & Scopes (权限管理) and add the following scopes:
| Scope | Purpose |
|---|---|
im:message | Send messages as bot |
im:message:readonly | Read message history |
im:chat:readonly | List and read chats |
docx:document | Read and create documents |
docx:document:readonly | Read documents |
bitable:record | Read and write Bitable records |
wiki:wiki:readonly | Read wiki spaces and nodes |
drive:drive:readonly | List Drive files and folders |
contact:user.id:readonly | Look up users by email/mobile |
Add more scopes as needed depending on which tools you use.
cli_xxxxxxxxxxxx) and App SecretLARK_APP_ID and LARK_APP_SECRET in your environmentAdd your bot to the group chats where you want it to read messages. The bot can only access chats it has been added to.
| Variable | Required For | Description |
|---|---|---|
LARK_COOKIE | User identity tools | Feishu web session cookie string. Needed for send_to_user, send_to_group, search_contacts, etc. |
LARK_APP_ID | Official API tools | App ID from Feishu Open Platform. Needed for read_messages, docs, tables, wiki, drive. |
LARK_APP_SECRET | Official API tools | App Secret from Feishu Open Platform. Used together with LARK_APP_ID. |
LARK_USER_ACCESS_TOKEN | P2P chat reading | OAuth user token. Needed for read_p2p_messages and list_user_chats. Obtained via node src/oauth.js. |
Each auth layer is independent. You can configure:
Option A: With Playwright MCP (recommended)
If you have Playwright MCP configured, let Claude Code handle it automatically — you just scan the QR code to log in:
// Playwright can access HttpOnly cookies that document.cookie cannot
const cookies = await context.cookies('https://www.feishu.cn');
const cookieStr = cookies.map(c => c.name + '=' + c.value).join('; ');
Option B: Manual (via Network tab)
F12 or Cmd+Option+I)Cmd+R to reloadLARK_COOKIE in your environment⚠️ Do NOT use
document.cookiein the Console or copy from Application → Cookies tab individually — neither method captures HttpOnly cookies (session,sl_session), which are required for authentication.
The server automatically refreshes the session via heartbeat every 4 hours. The
sl_sessioncookie has a 12-hour max-age.
To read direct message history with read_p2p_messages and list_user_chats:
im:message, im:message:readonly, im:chat:readonlyhttp://127.0.0.1:9997/callback# If you cloned the repo:
node src/oauth.js
# If you installed via npx:
cd $(npm root -g)/feishu-user-mcp && node src/oauth.js
# Or clone the repo just for the OAuth step, then use npx for daily use
A browser window will open for OAuth consent. The token is saved to .env automatically and auto-refreshes at runtime. Add the resulting LARK_USER_ACCESS_TOKEN to your .mcp.json env.
Add to your project's .mcp.json (or ~/.claude/.mcp.json for global):
Using npx:
{
"mcpServers": {
"feishu": {
"command": "npx",
"args": ["-y", "feishu-user-mcp"],
"env": {
"LARK_COOKIE": "your-cookie-string",
"LARK_APP_ID": "cli_xxxxxxxxxxxx",
"LARK_APP_SECRET": "your-app-secret"
}
}
}
}
Using a local clone:
{
"mcpServers": {
"feishu": {
"command": "node",
"args": ["/absolute/path/to/feishu-user-mcp/src/index.js"],
"env": {
"LARK_COOKIE": "your-cookie-string",
"LARK_APP_ID": "cli_xxxxxxxxxxxx",
"LARK_APP_SECRET": "your-app-secret"
}
}
}
}
Then just say things like:
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"feishu": {
"command": "npx",
"args": ["-y", "feishu-user-mcp"],
"env": {
"LARK_COOKIE": "your-cookie-string",
"LARK_APP_ID": "cli_xxxxxxxxxxxx",
"LARK_APP_SECRET": "your-app-secret"
}
}
}
}
Add to .cursor/mcp.json in your project:
{
"mcpServers": {
"feishu": {
"command": "npx",
"args": ["-y", "feishu-user-mcp"],
"env": {
"LARK_COOKIE": "your-cookie-string",
"LARK_APP_ID": "cli_xxxxxxxxxxxx",
"LARK_APP_SECRET": "your-app-secret"
}
}
}
}
Add to .vscode/mcp.json in your project:
{
"servers": {
"feishu": {
"type": "stdio",
"command": "npx",
"args": ["-y", "feishu-user-mcp"],
"env": {
"LARK_COOKIE": "your-cookie-string",
"LARK_APP_ID": "cli_xxxxxxxxxxxx",
"LARK_APP_SECRET": "your-app-secret"
}
}
}
}
Add to ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"feishu": {
"command": "npx",
"args": ["-y", "feishu-user-mcp"],
"env": {
"LARK_COOKIE": "your-cookie-string",
"LARK_APP_ID": "cli_xxxxxxxxxxxx",
"LARK_APP_SECRET": "your-app-secret"
}
}
}
}
Send messages as yourself, not as a bot.
| Tool | Description |
|---|---|
send_to_user | Search user by name + send text -- one step |
send_to_group | Search group by name + send text -- one step |
send_as_user | Send text to any chat by ID, supports reply threading (root_id / parent_id) |
send_image_as_user | Send image (requires image_key from upload) |
send_file_as_user | Send file (requires file_key from upload) |
send_post_as_user | Send rich text with title + formatted paragraphs (links, @mentions) |
send_sticker_as_user | Send sticker/emoji |
send_audio_as_user | Send audio message |
| Tool | Description |
|---|---|
search_contacts | Search users, bots, or group chats by name |
create_p2p_chat | Create/get P2P (direct message) chat, returns numeric chat_id |
get_chat_info | Group details: name, description, member count, owner |
get_user_info | User display name lookup by user ID |
get_login_status | Check cookie, app credentials, and UAT status |
| Tool | Description |
|---|---|
read_p2p_messages | Read P2P (direct message) history. Works for chats the bot cannot access. |
list_user_chats | List all chats the user is in, including P2P. |
| Tool | Description |
|---|---|
list_chats | List all chats the bot has joined |
read_messages | Read message history (accepts chat name or oc_xxx ID) |
reply_message | Reply to a specific message by message_id (as bot) |
forward_message | Forward a message to another chat |
| Tool | Description |
|---|---|
search_docs | Search documents by keyword |
read_doc | Read raw text content of a document |
create_doc | Create a new document |
| Tool | Description |
|---|---|
list_bitable_tables | List all tables in a Bitable app |
list_bitable_fields | List all fields (columns) in a table |
search_bitable_records | Query records with filter and sort |
create_bitable_record | Create a new record (row) |
update_bitable_record | Update an existing record |
| Tool | Description |
|---|---|
list_wiki_spaces | List all accessible wiki spaces |
search_wiki | Search wiki/docs by keyword |
list_wiki_nodes | Browse wiki node tree |
| Tool | Description |
|---|---|
list_files | List files in a folder |
create_folder | Create a new folder |
| Tool | Description |
|---|---|
find_user | Find user by email or mobile number |
This repo includes 8 ready-to-use slash commands in .claude/commands/:
| Skill | Usage | Description |
|---|---|---|
/send | /send Alice: meeting at 3pm | Send message as yourself |
/reply | /reply engineering-chat | Read recent messages and reply |
/digest | /digest engineering-chat 7 | Summarize recent chat messages |
/search | /search engineering | Search contacts and groups |
/doc | /doc search MCP | Search, read, or create documents |
/table | /table query appXxx | Query or create Bitable records |
/wiki | /wiki search protocol | Search and browse wiki |
/status | /status | Check login and auth status |
To use these skills, copy .claude/commands/ into your project.
Cookie + Proto ┌──────────────────────────────────────┐
────────────────── >│ internal-api-lark-api.feishu.cn │
┌──────────────┐ │ /im/gateway/ (Protobuf over HTTP) │
│ MCP Client │ └──────────────────────────────────────┘
│ (Claude, │ App Token (REST) ┌──────────────────────────────────────┐
│ Cursor, │ ────────────────->│ open.feishu.cn/open-apis/ │
│ VS Code) │ │ (Official REST API) │
│ │ └──────────────────────────────────────┘
│ │ User OAuth (REST)┌──────────────────────────────────────┐
│ │ ────────────────->│ open.feishu.cn/open-apis/ │
└──────────────┘ │ (UAT -- P2P chat reading) │
└──────────────────────────────────────┘
| Auth Layer | Token | Lifetime | Refresh |
|---|---|---|---|
| Cookie | sl_session | 12h max-age | Auto-refreshed every 4h via heartbeat |
| App Token | tenant_access_token | 2h | Auto-managed by SDK |
| User OAuth | user_access_token | ~2h | Auto-refreshed via refresh_token, saved to .env |
When the cookie expires (after ~12-24h without heartbeat), re-login at feishu.cn and update LARK_COOKIE. Use get_login_status to check health proactively.
feishu-user-mcp/
├── src/
│ ├── index.js # MCP server entry point (33 tools)
│ ├── client.js # User identity client (Protobuf gateway)
│ ├── official.js # Official API client (REST, UAT)
│ ├── utils.js # ID generators, cookie parser
│ ├── oauth.js # OAuth flow for user_access_token
│ ├── oauth-auto.js # Automated OAuth with Playwright
│ ├── test-send.js # Quick CLI test
│ └── test-all.js # Full test suite
├── proto/
│ └── lark.proto # Protobuf message definitions
├── .claude/
│ └── commands/ # 8 Claude Code slash commands
├── server.json # MCP Registry manifest
├── .env.example # Configuration template
└── package.json
Issues and PRs welcome! See CONTRIBUTING.md for development setup, code style, and submission guidelines.
If Feishu updates their protocol and something breaks, please open an issue with the error details.
FAQs
All-in-one Feishu/Lark MCP Server — 33 tools, 3 auth layers: user identity messaging (Protobuf), official API (REST), P2P chat reading (OAuth UAT).
The npm package feishu-user-mcp receives a total of 2 weekly downloads. As such, feishu-user-mcp popularity was classified as not popular.
We found that feishu-user-mcp demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Company News
Socket is joining the OpenJS Security Stewardship Program to fund Node.js vulnerability research, maintainer remediation, and security releases.

Security News
Two compromised GitHub Actions were re-enabled with malicious tags intact, exposing thousands of downstream repositories to Mini Shai-Hulud.

Research
/Security News
A malicious Firefox extension fetches its payload after installation to evade detection, steal Google session cookies, and automate account takeover.