feishu-user-plugin 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +9 -0
- package/.env.example +18 -0
- package/.mcp.json.example +13 -0
- package/CHANGELOG.md +62 -0
- package/LICENSE +21 -0
- package/README.md +473 -0
- package/package.json +57 -0
- package/proto/lark.proto +317 -0
- package/skills/feishu-user-plugin/SKILL.md +103 -0
- package/skills/feishu-user-plugin/references/CLAUDE.md +94 -0
- package/skills/feishu-user-plugin/references/digest.md +26 -0
- package/skills/feishu-user-plugin/references/doc.md +27 -0
- package/skills/feishu-user-plugin/references/drive.md +24 -0
- package/skills/feishu-user-plugin/references/reply.md +23 -0
- package/skills/feishu-user-plugin/references/search.md +22 -0
- package/skills/feishu-user-plugin/references/send.md +28 -0
- package/skills/feishu-user-plugin/references/status.md +22 -0
- package/skills/feishu-user-plugin/references/table.md +32 -0
- package/skills/feishu-user-plugin/references/wiki.md +26 -0
- package/src/client.js +364 -0
- package/src/index.js +697 -0
- package/src/oauth-auto.js +196 -0
- package/src/oauth.js +215 -0
- package/src/official.js +365 -0
- package/src/test-all.js +324 -0
- package/src/test-comprehensive.js +301 -0
- package/src/test-send.js +67 -0
- package/src/utils.js +39 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "feishu-user-plugin",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "All-in-one Feishu plugin for Claude Code — send messages as yourself, read chats, manage docs/tables/wiki. 33 tools + 8 skills, 3 auth layers.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "EthanQC"
|
|
7
|
+
},
|
|
8
|
+
"keywords": ["feishu", "lark", "claude-code", "plugin", "messaging", "im", "document", "bitable", "protobuf"]
|
|
9
|
+
}
|
package/.env.example
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# === User Identity (reverse-engineered protocol) ===
|
|
2
|
+
# Required for: send_as_user, send_to_user, send_to_group, search_contacts, etc.
|
|
3
|
+
# How to get: Login to feishu.cn → Playwright context.cookies() or DevTools
|
|
4
|
+
LARK_COOKIE=
|
|
5
|
+
|
|
6
|
+
# === Official API (Feishu Open Platform) ===
|
|
7
|
+
# Required for: read_messages, reply_message, docs, tables, wiki, drive, contacts
|
|
8
|
+
# How to get: Create app at open.feishu.cn → get App ID and App Secret
|
|
9
|
+
LARK_APP_ID=
|
|
10
|
+
LARK_APP_SECRET=
|
|
11
|
+
|
|
12
|
+
# === User OAuth UAT (optional, for P2P chat reading) ===
|
|
13
|
+
# Required for: read_p2p_messages, list_user_chats
|
|
14
|
+
# How to get: Run "node src/oauth.js" after configuring App ID/Secret above
|
|
15
|
+
# These are auto-populated by the OAuth flow and auto-refreshed at runtime
|
|
16
|
+
LARK_USER_ACCESS_TOKEN=
|
|
17
|
+
LARK_USER_REFRESH_TOKEN=
|
|
18
|
+
LARK_UAT_EXPIRES=
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mcpServers": {
|
|
3
|
+
"feishu-user-plugin": {
|
|
4
|
+
"command": "npx",
|
|
5
|
+
"args": ["-y", "feishu-user-plugin"],
|
|
6
|
+
"env": {
|
|
7
|
+
"LARK_COOKIE": "YOUR_FEISHU_COOKIE_HERE",
|
|
8
|
+
"LARK_APP_ID": "YOUR_APP_ID_HERE",
|
|
9
|
+
"LARK_APP_SECRET": "YOUR_APP_SECRET_HERE"
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [1.0.0] - 2026-03-09
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
- Renamed from `feishu-user-mcp` to `feishu-user-plugin`
|
|
11
|
+
- Converted to Claude Code Plugin standard structure (`.claude-plugin/`, `skills/`)
|
|
12
|
+
- Skills moved from `.claude/commands/` to `skills/feishu-user-plugin/references/`
|
|
13
|
+
- MCP server config template added (`.mcp.json`)
|
|
14
|
+
- All client configurations now use `npx -y feishu-user-plugin`
|
|
15
|
+
- Version reset to 1.0.0
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- `.claude-plugin/plugin.json` — Plugin metadata
|
|
19
|
+
- `skills/feishu-user-plugin/SKILL.md` — Main skill definition with allowed-tools
|
|
20
|
+
- `skills/feishu-user-plugin/references/CLAUDE.md` — Troubleshooting guide
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
- Version number consistency across `package.json`, `src/index.js`, and `server.json`
|
|
24
|
+
|
|
25
|
+
## [0.5.1] - 2026-03-08
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
- `search_docs` — SDK method `docx.builtin.search` does not exist; switched to `client.request()` with `/open-apis/suite/docs-api/search/object`
|
|
29
|
+
- `search_wiki` — SDK method `wiki.node.search` does not exist; switched to suite docs search API
|
|
30
|
+
- Message timestamp parsing — Feishu returns millisecond strings; added `_normalizeTimestamp()` to convert to seconds
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
- Updated README to reflect all 33 tools with full documentation
|
|
34
|
+
- Updated `server.json` manifest with complete tool list
|
|
35
|
+
- Updated `.env.example` with UAT fields
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
- `src/test-all.js` — comprehensive test suite for all tools
|
|
39
|
+
|
|
40
|
+
## [0.5.0] - 2026-03-06
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
- P2P (direct message) chat reading via `read_p2p_messages`
|
|
44
|
+
- OAuth v2 authorization flow (`src/oauth.js`, `src/oauth-auto.js`)
|
|
45
|
+
- `list_user_chats` — list all chats the user is in
|
|
46
|
+
- Third auth layer: User OAuth UAT for P2P access
|
|
47
|
+
- Auto-refresh of `user_access_token` with `.env` persistence
|
|
48
|
+
|
|
49
|
+
## [0.4.0] - 2026-03-04
|
|
50
|
+
|
|
51
|
+
### Added
|
|
52
|
+
- Multi-type messaging: image, file, rich text (post), sticker, audio
|
|
53
|
+
- Cookie heartbeat — auto-refresh CSRF every 4h to extend session
|
|
54
|
+
- Chat name auto-resolution — pass group name instead of `oc_xxx` ID
|
|
55
|
+
|
|
56
|
+
## [0.3.0] - 2026-03-01
|
|
57
|
+
|
|
58
|
+
### Added
|
|
59
|
+
- Initial release: 27 tools, 8 slash commands, dual backend
|
|
60
|
+
- User identity messaging via reverse-engineered Protobuf protocol
|
|
61
|
+
- Official API integration for docs, Bitable, wiki, drive, contacts
|
|
62
|
+
- Support for Claude Code, Claude Desktop, Cursor, VS Code, Windsurf
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 EthanQC
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
# feishu-user-plugin
|
|
2
|
+
|
|
3
|
+
[](LICENSE)
|
|
4
|
+
[](https://nodejs.org)
|
|
5
|
+
[](https://modelcontextprotocol.io)
|
|
6
|
+
[](#tools-33-total)
|
|
7
|
+
[](CONTRIBUTING.md)
|
|
8
|
+
|
|
9
|
+
**All-in-one Feishu/Lark MCP Server -- 33 tools, 8 skills, 3 auth layers for messaging, docs, tables, wiki, and drive.**
|
|
10
|
+
|
|
11
|
+
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.
|
|
12
|
+
|
|
13
|
+
## Highlights
|
|
14
|
+
|
|
15
|
+
- **Send as yourself** -- Messages show your real name, not a bot. Supports text, rich text, images, files, stickers, and audio.
|
|
16
|
+
- **Read everything** -- Group chats via bot API, P2P (direct messages) via OAuth UAT.
|
|
17
|
+
- **Full Feishu suite** -- Docs, Bitable (spreadsheets), Wiki, Drive, Contacts -- all in one plugin.
|
|
18
|
+
- **3 auth layers** -- Cookie-based user identity, app credentials (Official API), and OAuth UAT (P2P reading). Each is independent; configure only what you need.
|
|
19
|
+
- **8 slash commands** for Claude Code -- `/send`, `/reply`, `/search`, `/digest`, `/doc`, `/table`, `/wiki`, `/status`
|
|
20
|
+
- **Auto session management** -- Cookie heartbeat every 4h, UAT auto-refresh with token rotation.
|
|
21
|
+
- **Chat name resolution** -- Pass a group name instead of `oc_xxx` ID; it resolves automatically.
|
|
22
|
+
|
|
23
|
+
## Why This Exists
|
|
24
|
+
|
|
25
|
+
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"`.
|
|
26
|
+
|
|
27
|
+
This project combines three auth layers into one plugin:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
User Identity (cookie): You -> Protobuf -> Feishu (messages appear as YOU)
|
|
31
|
+
Official API (app token): You -> REST API -> Feishu (docs, tables, wiki, drive)
|
|
32
|
+
User OAuth (UAT): You -> REST API -> Feishu (read P2P chats, list all chats)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**One plugin. Everything Feishu. No other MCP needed.**
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
### Option 1: npx (recommended)
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npx feishu-user-plugin
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
No installation needed. The package runs directly via npx.
|
|
46
|
+
|
|
47
|
+
### Option 2: Clone and run locally
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
git clone https://github.com/EthanQC/feishu-user-plugin.git
|
|
51
|
+
cd feishu-user-plugin
|
|
52
|
+
npm install
|
|
53
|
+
npm start
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Create Your Feishu App
|
|
57
|
+
|
|
58
|
+
To use the Official API tools (docs, tables, wiki, drive, bot messaging), you need to create a Feishu app:
|
|
59
|
+
|
|
60
|
+
### Step 1: Create the App
|
|
61
|
+
|
|
62
|
+
1. Go to [Feishu Open Platform](https://open.feishu.cn/app) and log in
|
|
63
|
+
2. Click **Create Custom App** (创建自建应用) -- you must choose **Custom App** (自建应用), NOT marketplace/third-party types
|
|
64
|
+
3. Fill in the app name and description, then create it
|
|
65
|
+
|
|
66
|
+
### Step 2: Enable Bot Capability
|
|
67
|
+
|
|
68
|
+
1. In your app settings, go to **Add Capabilities** (添加应用能力)
|
|
69
|
+
2. Enable **Bot** (机器人)
|
|
70
|
+
|
|
71
|
+
### Step 3: Add Permissions (Scopes)
|
|
72
|
+
|
|
73
|
+
Go to **Permissions & Scopes** (权限管理) and add the following scopes:
|
|
74
|
+
|
|
75
|
+
| Scope | Purpose |
|
|
76
|
+
|-------|---------|
|
|
77
|
+
| `im:message` | Send messages as bot |
|
|
78
|
+
| `im:message:readonly` | Read message history |
|
|
79
|
+
| `im:chat:readonly` | List and read chats |
|
|
80
|
+
| `docx:document` | Read and create documents |
|
|
81
|
+
| `docx:document:readonly` | Read documents |
|
|
82
|
+
| `bitable:record` | Read and write Bitable records |
|
|
83
|
+
| `wiki:wiki:readonly` | Read wiki spaces and nodes |
|
|
84
|
+
| `drive:drive:readonly` | List Drive files and folders |
|
|
85
|
+
| `contact:user.id:readonly` | Look up users by email/mobile |
|
|
86
|
+
|
|
87
|
+
> Add more scopes as needed depending on which tools you use.
|
|
88
|
+
|
|
89
|
+
### Step 4: Get App Credentials
|
|
90
|
+
|
|
91
|
+
1. Go to **Credentials & Basic Info** (凭证与基础信息)
|
|
92
|
+
2. Copy the **App ID** (`cli_xxxxxxxxxxxx`) and **App Secret**
|
|
93
|
+
3. Set them as `LARK_APP_ID` and `LARK_APP_SECRET` in your environment
|
|
94
|
+
|
|
95
|
+
### Step 5: Publish and Approve
|
|
96
|
+
|
|
97
|
+
1. **Create a version** and submit it for review (创建版本)
|
|
98
|
+
2. Have your organization admin approve the app (管理员审核)
|
|
99
|
+
3. After approval, the app is live
|
|
100
|
+
|
|
101
|
+
### Step 6: Add Bot to Group Chats
|
|
102
|
+
|
|
103
|
+
Add your bot to the group chats where you want it to read messages. The bot can only access chats it has been added to.
|
|
104
|
+
|
|
105
|
+
## Environment Variables
|
|
106
|
+
|
|
107
|
+
| Variable | Required For | Description |
|
|
108
|
+
|----------|-------------|-------------|
|
|
109
|
+
| `LARK_COOKIE` | User identity tools | Feishu web session cookie string. Needed for `send_to_user`, `send_to_group`, `search_contacts`, etc. |
|
|
110
|
+
| `LARK_APP_ID` | Official API tools | App ID from Feishu Open Platform. Needed for `read_messages`, docs, tables, wiki, drive. |
|
|
111
|
+
| `LARK_APP_SECRET` | Official API tools | App Secret from Feishu Open Platform. Used together with `LARK_APP_ID`. |
|
|
112
|
+
| `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`. |
|
|
113
|
+
|
|
114
|
+
Each auth layer is independent. You can configure:
|
|
115
|
+
- **Cookie only** -- for sending messages as yourself
|
|
116
|
+
- **App credentials only** -- for reading docs, tables, wiki, group chats
|
|
117
|
+
- **All three** -- for the full feature set
|
|
118
|
+
|
|
119
|
+
## How to Get Your Cookie
|
|
120
|
+
|
|
121
|
+
**Option A: Automated via Playwright MCP (recommended, zero manual copying)**
|
|
122
|
+
|
|
123
|
+
First, install Playwright MCP if you don't have it:
|
|
124
|
+
```bash
|
|
125
|
+
npx @anthropic-ai/claude-code mcp add playwright -- npx @anthropic-ai/mcp-server-playwright
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Then just tell Claude Code: **"Help me set up my Feishu cookie"**
|
|
129
|
+
|
|
130
|
+
Claude Code will automatically:
|
|
131
|
+
1. Open feishu.cn in a browser via Playwright
|
|
132
|
+
2. Show you the QR code — scan it with Feishu mobile app
|
|
133
|
+
3. Extract the full cookie (including HttpOnly) via `context.cookies()`
|
|
134
|
+
4. Write it to your `.mcp.json` LARK_COOKIE field
|
|
135
|
+
5. Prompt you to restart Claude Code
|
|
136
|
+
|
|
137
|
+
**Option B: Manual (via Network tab)**
|
|
138
|
+
|
|
139
|
+
1. Open [feishu.cn/messenger](https://www.feishu.cn/messenger/) in your browser and log in
|
|
140
|
+
2. Open DevTools (`F12` or `Cmd+Option+I`)
|
|
141
|
+
3. Go to the **Network** tab → check **Disable cache** → press `Cmd+R` to reload
|
|
142
|
+
4. Click the first request in the list (usually the page itself)
|
|
143
|
+
5. In the right panel, find **Request Headers** → **Cookie:** → right-click → **Copy value**
|
|
144
|
+
6. Set it as `LARK_COOKIE` in your environment
|
|
145
|
+
|
|
146
|
+
> Do NOT use `document.cookie` in the Console or copy from Application → Cookies tab — they miss HttpOnly cookies (`session`, `sl_session`) required for auth.
|
|
147
|
+
|
|
148
|
+
> The server automatically refreshes the session via heartbeat every 4 hours. The `sl_session` cookie has a 12-hour max-age.
|
|
149
|
+
|
|
150
|
+
## How to Set Up P2P Chat Reading (OAuth)
|
|
151
|
+
|
|
152
|
+
To read direct message history with `read_p2p_messages` and `list_user_chats`:
|
|
153
|
+
|
|
154
|
+
1. Your Feishu app must be a **Custom App** (自建应用), NOT marketplace/third-party
|
|
155
|
+
2. Add scopes: `im:message`, `im:message:readonly`, `im:chat:readonly`
|
|
156
|
+
3. In your app's **Security Settings** (安全设置), add the OAuth redirect URI: `http://127.0.0.1:9997/callback`
|
|
157
|
+
4. **Important**: Make sure "对外共享" (external sharing) is **disabled** in your app version settings — enabling it marks the app as b2c/b2b type, which blocks P2P chat access
|
|
158
|
+
5. Run the authorization flow:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
# If you cloned the repo:
|
|
162
|
+
node src/oauth.js
|
|
163
|
+
|
|
164
|
+
# If you installed via npx:
|
|
165
|
+
cd $(npm root -g)/feishu-user-plugin && node src/oauth.js
|
|
166
|
+
# Or clone the repo just for the OAuth step, then use npx for daily use
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
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.
|
|
170
|
+
|
|
171
|
+
## MCP Client Configuration
|
|
172
|
+
|
|
173
|
+
### Claude Code
|
|
174
|
+
|
|
175
|
+
Add to your project's `.mcp.json` (or `~/.claude/.mcp.json` for global):
|
|
176
|
+
|
|
177
|
+
**Using npx:**
|
|
178
|
+
|
|
179
|
+
```json
|
|
180
|
+
{
|
|
181
|
+
"mcpServers": {
|
|
182
|
+
"feishu": {
|
|
183
|
+
"command": "npx",
|
|
184
|
+
"args": ["-y", "feishu-user-plugin"],
|
|
185
|
+
"env": {
|
|
186
|
+
"LARK_COOKIE": "your-cookie-string",
|
|
187
|
+
"LARK_APP_ID": "cli_xxxxxxxxxxxx",
|
|
188
|
+
"LARK_APP_SECRET": "your-app-secret"
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Using a local clone:**
|
|
196
|
+
|
|
197
|
+
```json
|
|
198
|
+
{
|
|
199
|
+
"mcpServers": {
|
|
200
|
+
"feishu": {
|
|
201
|
+
"command": "node",
|
|
202
|
+
"args": ["/absolute/path/to/feishu-user-plugin/src/index.js"],
|
|
203
|
+
"env": {
|
|
204
|
+
"LARK_COOKIE": "your-cookie-string",
|
|
205
|
+
"LARK_APP_ID": "cli_xxxxxxxxxxxx",
|
|
206
|
+
"LARK_APP_SECRET": "your-app-secret"
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Then just say things like:
|
|
214
|
+
- "Send a message to Alice saying the meeting is at 3pm"
|
|
215
|
+
- "What did the engineering group chat about today?"
|
|
216
|
+
- "Search for docs about MCP"
|
|
217
|
+
|
|
218
|
+
### Claude Desktop
|
|
219
|
+
|
|
220
|
+
Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
|
|
221
|
+
|
|
222
|
+
```json
|
|
223
|
+
{
|
|
224
|
+
"mcpServers": {
|
|
225
|
+
"feishu": {
|
|
226
|
+
"command": "npx",
|
|
227
|
+
"args": ["-y", "feishu-user-plugin"],
|
|
228
|
+
"env": {
|
|
229
|
+
"LARK_COOKIE": "your-cookie-string",
|
|
230
|
+
"LARK_APP_ID": "cli_xxxxxxxxxxxx",
|
|
231
|
+
"LARK_APP_SECRET": "your-app-secret"
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Cursor
|
|
239
|
+
|
|
240
|
+
Add to `.cursor/mcp.json` in your project:
|
|
241
|
+
|
|
242
|
+
```json
|
|
243
|
+
{
|
|
244
|
+
"mcpServers": {
|
|
245
|
+
"feishu": {
|
|
246
|
+
"command": "npx",
|
|
247
|
+
"args": ["-y", "feishu-user-plugin"],
|
|
248
|
+
"env": {
|
|
249
|
+
"LARK_COOKIE": "your-cookie-string",
|
|
250
|
+
"LARK_APP_ID": "cli_xxxxxxxxxxxx",
|
|
251
|
+
"LARK_APP_SECRET": "your-app-secret"
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### VS Code (Copilot)
|
|
259
|
+
|
|
260
|
+
Add to `.vscode/mcp.json` in your project:
|
|
261
|
+
|
|
262
|
+
```json
|
|
263
|
+
{
|
|
264
|
+
"servers": {
|
|
265
|
+
"feishu": {
|
|
266
|
+
"type": "stdio",
|
|
267
|
+
"command": "npx",
|
|
268
|
+
"args": ["-y", "feishu-user-plugin"],
|
|
269
|
+
"env": {
|
|
270
|
+
"LARK_COOKIE": "your-cookie-string",
|
|
271
|
+
"LARK_APP_ID": "cli_xxxxxxxxxxxx",
|
|
272
|
+
"LARK_APP_SECRET": "your-app-secret"
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Windsurf
|
|
280
|
+
|
|
281
|
+
Add to `~/.codeium/windsurf/mcp_config.json`:
|
|
282
|
+
|
|
283
|
+
```json
|
|
284
|
+
{
|
|
285
|
+
"mcpServers": {
|
|
286
|
+
"feishu": {
|
|
287
|
+
"command": "npx",
|
|
288
|
+
"args": ["-y", "feishu-user-plugin"],
|
|
289
|
+
"env": {
|
|
290
|
+
"LARK_COOKIE": "your-cookie-string",
|
|
291
|
+
"LARK_APP_ID": "cli_xxxxxxxxxxxx",
|
|
292
|
+
"LARK_APP_SECRET": "your-app-secret"
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## Tools (33 total)
|
|
300
|
+
|
|
301
|
+
### User Identity -- Messaging (cookie auth, Protobuf)
|
|
302
|
+
|
|
303
|
+
Send messages as yourself, not as a bot.
|
|
304
|
+
|
|
305
|
+
| Tool | Description |
|
|
306
|
+
|------|-------------|
|
|
307
|
+
| `send_to_user` | Search user by name + send text -- one step |
|
|
308
|
+
| `send_to_group` | Search group by name + send text -- one step |
|
|
309
|
+
| `send_as_user` | Send text to any chat by ID, supports reply threading (`root_id` / `parent_id`) |
|
|
310
|
+
| `send_image_as_user` | Send image (requires `image_key` from upload) |
|
|
311
|
+
| `send_file_as_user` | Send file (requires `file_key` from upload) |
|
|
312
|
+
| `send_post_as_user` | Send rich text with title + formatted paragraphs (links, @mentions) |
|
|
313
|
+
| `send_sticker_as_user` | Send sticker/emoji |
|
|
314
|
+
| `send_audio_as_user` | Send audio message |
|
|
315
|
+
|
|
316
|
+
### User Identity -- Contacts & Info (cookie auth)
|
|
317
|
+
|
|
318
|
+
| Tool | Description |
|
|
319
|
+
|------|-------------|
|
|
320
|
+
| `search_contacts` | Search users, bots, or group chats by name |
|
|
321
|
+
| `create_p2p_chat` | Create/get P2P (direct message) chat, returns numeric `chat_id` |
|
|
322
|
+
| `get_chat_info` | Group details: name, description, member count, owner |
|
|
323
|
+
| `get_user_info` | User display name lookup by user ID |
|
|
324
|
+
| `get_login_status` | Check cookie, app credentials, and UAT status |
|
|
325
|
+
|
|
326
|
+
### User OAuth UAT -- P2P Chat Reading
|
|
327
|
+
|
|
328
|
+
| Tool | Description |
|
|
329
|
+
|------|-------------|
|
|
330
|
+
| `read_p2p_messages` | Read P2P (direct message) history. Works for chats the bot cannot access. |
|
|
331
|
+
| `list_user_chats` | List all chats the user is in, including P2P. |
|
|
332
|
+
|
|
333
|
+
### Official API -- IM (Bot Identity)
|
|
334
|
+
|
|
335
|
+
| Tool | Description |
|
|
336
|
+
|------|-------------|
|
|
337
|
+
| `list_chats` | List all chats the bot has joined |
|
|
338
|
+
| `read_messages` | Read message history (accepts chat name or `oc_xxx` ID) |
|
|
339
|
+
| `reply_message` | Reply to a specific message by `message_id` (as bot) |
|
|
340
|
+
| `forward_message` | Forward a message to another chat |
|
|
341
|
+
|
|
342
|
+
### Official API -- Documents
|
|
343
|
+
|
|
344
|
+
| Tool | Description |
|
|
345
|
+
|------|-------------|
|
|
346
|
+
| `search_docs` | Search documents by keyword |
|
|
347
|
+
| `read_doc` | Read raw text content of a document |
|
|
348
|
+
| `create_doc` | Create a new document |
|
|
349
|
+
|
|
350
|
+
### Official API -- Bitable (Spreadsheets)
|
|
351
|
+
|
|
352
|
+
| Tool | Description |
|
|
353
|
+
|------|-------------|
|
|
354
|
+
| `list_bitable_tables` | List all tables in a Bitable app |
|
|
355
|
+
| `list_bitable_fields` | List all fields (columns) in a table |
|
|
356
|
+
| `search_bitable_records` | Query records with filter and sort |
|
|
357
|
+
| `create_bitable_record` | Create a new record (row) |
|
|
358
|
+
| `update_bitable_record` | Update an existing record |
|
|
359
|
+
|
|
360
|
+
### Official API -- Wiki
|
|
361
|
+
|
|
362
|
+
| Tool | Description |
|
|
363
|
+
|------|-------------|
|
|
364
|
+
| `list_wiki_spaces` | List all accessible wiki spaces |
|
|
365
|
+
| `search_wiki` | Search wiki/docs by keyword |
|
|
366
|
+
| `list_wiki_nodes` | Browse wiki node tree |
|
|
367
|
+
|
|
368
|
+
### Official API -- Drive
|
|
369
|
+
|
|
370
|
+
| Tool | Description |
|
|
371
|
+
|------|-------------|
|
|
372
|
+
| `list_files` | List files in a folder |
|
|
373
|
+
| `create_folder` | Create a new folder |
|
|
374
|
+
|
|
375
|
+
### Official API -- Contacts
|
|
376
|
+
|
|
377
|
+
| Tool | Description |
|
|
378
|
+
|------|-------------|
|
|
379
|
+
| `find_user` | Find user by email or mobile number |
|
|
380
|
+
|
|
381
|
+
## Claude Code Slash Commands (8 skills)
|
|
382
|
+
|
|
383
|
+
This plugin includes 8 built-in skills in `skills/feishu-user-plugin/`:
|
|
384
|
+
|
|
385
|
+
| Skill | Usage | Description |
|
|
386
|
+
|-------|-------|-------------|
|
|
387
|
+
| `/send` | `/send Alice: meeting at 3pm` | Send message as yourself |
|
|
388
|
+
| `/reply` | `/reply engineering-chat` | Read recent messages and reply |
|
|
389
|
+
| `/digest` | `/digest engineering-chat 7` | Summarize recent chat messages |
|
|
390
|
+
| `/search` | `/search engineering` | Search contacts and groups |
|
|
391
|
+
| `/doc` | `/doc search MCP` | Search, read, or create documents |
|
|
392
|
+
| `/table` | `/table query appXxx` | Query or create Bitable records |
|
|
393
|
+
| `/wiki` | `/wiki search protocol` | Search and browse wiki |
|
|
394
|
+
| `/status` | `/status` | Check login and auth status |
|
|
395
|
+
|
|
396
|
+
Skills are automatically available when the plugin is installed.
|
|
397
|
+
|
|
398
|
+
## Architecture
|
|
399
|
+
|
|
400
|
+
```
|
|
401
|
+
Cookie + Proto ┌──────────────────────────────────────┐
|
|
402
|
+
────────────────── >│ internal-api-lark-api.feishu.cn │
|
|
403
|
+
┌──────────────┐ │ /im/gateway/ (Protobuf over HTTP) │
|
|
404
|
+
│ MCP Client │ └──────────────────────────────────────┘
|
|
405
|
+
│ (Claude, │ App Token (REST) ┌──────────────────────────────────────┐
|
|
406
|
+
│ Cursor, │ ────────────────->│ open.feishu.cn/open-apis/ │
|
|
407
|
+
│ VS Code) │ │ (Official REST API) │
|
|
408
|
+
│ │ └──────────────────────────────────────┘
|
|
409
|
+
│ │ User OAuth (REST)┌──────────────────────────────────────┐
|
|
410
|
+
│ │ ────────────────->│ open.feishu.cn/open-apis/ │
|
|
411
|
+
└──────────────┘ │ (UAT -- P2P chat reading) │
|
|
412
|
+
└──────────────────────────────────────┘
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
## Session & Token Lifecycle
|
|
416
|
+
|
|
417
|
+
| Auth Layer | Token | Lifetime | Refresh |
|
|
418
|
+
|------------|-------|----------|---------|
|
|
419
|
+
| Cookie | `sl_session` | 12h max-age | Auto-refreshed every 4h via heartbeat |
|
|
420
|
+
| App Token | `tenant_access_token` | 2h | Auto-managed by SDK |
|
|
421
|
+
| User OAuth | `user_access_token` | ~2h | Auto-refreshed via `refresh_token`, saved to `.env` |
|
|
422
|
+
|
|
423
|
+
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.
|
|
424
|
+
|
|
425
|
+
## Project Structure
|
|
426
|
+
|
|
427
|
+
```
|
|
428
|
+
feishu-user-plugin/
|
|
429
|
+
├── .claude-plugin/
|
|
430
|
+
│ └── plugin.json # Plugin metadata
|
|
431
|
+
├── skills/
|
|
432
|
+
│ └── feishu-user-plugin/
|
|
433
|
+
│ ├── SKILL.md # Main skill definition (trigger, tools, auth)
|
|
434
|
+
│ └── references/ # 8 skill reference docs + CLAUDE.md
|
|
435
|
+
├── src/
|
|
436
|
+
│ ├── index.js # MCP server entry point (33 tools)
|
|
437
|
+
│ ├── client.js # User identity client (Protobuf gateway)
|
|
438
|
+
│ ├── official.js # Official API client (REST, UAT)
|
|
439
|
+
│ ├── utils.js # ID generators, cookie parser
|
|
440
|
+
│ ├── oauth.js # OAuth flow for user_access_token
|
|
441
|
+
│ ├── test-send.js # Quick CLI test
|
|
442
|
+
│ └── test-all.js # Full test suite
|
|
443
|
+
├── proto/
|
|
444
|
+
│ └── lark.proto # Protobuf message definitions
|
|
445
|
+
├── .mcp.json.example # MCP server config template
|
|
446
|
+
├── server.json # MCP Registry manifest
|
|
447
|
+
├── .env.example # Configuration template
|
|
448
|
+
└── package.json
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
## Limitations
|
|
452
|
+
|
|
453
|
+
- Cookie-based auth requires periodic refresh (auto-heartbeat extends to ~12h; manual re-login needed after that)
|
|
454
|
+
- Depends on Feishu's internal Protobuf protocol -- may break if Feishu updates their web client
|
|
455
|
+
- Image/file/audio sending requires pre-uploaded keys (upload via Official API or external bridge)
|
|
456
|
+
- No real-time message receiving (WebSocket push not yet implemented)
|
|
457
|
+
- May violate Feishu's Terms of Service -- use at your own risk
|
|
458
|
+
|
|
459
|
+
## Contributing
|
|
460
|
+
|
|
461
|
+
Issues and PRs welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, code style, and submission guidelines.
|
|
462
|
+
|
|
463
|
+
If Feishu updates their protocol and something breaks, please [open an issue](https://github.com/EthanQC/feishu-user-plugin/issues/new?template=bug_report.md) with the error details.
|
|
464
|
+
|
|
465
|
+
## License
|
|
466
|
+
|
|
467
|
+
[MIT](LICENSE)
|
|
468
|
+
|
|
469
|
+
## Acknowledgments
|
|
470
|
+
|
|
471
|
+
- [cv-cat/LarkAgentX](https://github.com/cv-cat/LarkAgentX) -- Original Feishu protocol reverse-engineering (Python)
|
|
472
|
+
- [cv-cat/OpenFeiShuApis](https://github.com/cv-cat/OpenFeiShuApis) -- Underlying API research
|
|
473
|
+
- [Model Context Protocol](https://modelcontextprotocol.io) -- The MCP standard
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "feishu-user-plugin",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "All-in-one Feishu plugin for Claude Code — send messages as yourself, read chats, manage docs/tables/wiki. 33 tools + 8 skills, 3 auth layers.",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"feishu-user-plugin": "src/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "node src/index.js",
|
|
11
|
+
"test": "node src/test-all.js",
|
|
12
|
+
"test:quick": "node src/test-send.js",
|
|
13
|
+
"oauth": "node src/oauth.js"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"feishu",
|
|
17
|
+
"lark",
|
|
18
|
+
"claude-code",
|
|
19
|
+
"plugin",
|
|
20
|
+
"mcp",
|
|
21
|
+
"model-context-protocol",
|
|
22
|
+
"im",
|
|
23
|
+
"messaging",
|
|
24
|
+
"protobuf",
|
|
25
|
+
"agent"
|
|
26
|
+
],
|
|
27
|
+
"author": "EthanQC",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "https://github.com/EthanQC/feishu-user-plugin.git"
|
|
32
|
+
},
|
|
33
|
+
"homepage": "https://github.com/EthanQC/feishu-user-plugin#readme",
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/EthanQC/feishu-user-plugin/issues"
|
|
36
|
+
},
|
|
37
|
+
"files": [
|
|
38
|
+
"src/",
|
|
39
|
+
"proto/",
|
|
40
|
+
".claude-plugin/",
|
|
41
|
+
"skills/",
|
|
42
|
+
".mcp.json.example",
|
|
43
|
+
".env.example",
|
|
44
|
+
"CHANGELOG.md",
|
|
45
|
+
"README.md",
|
|
46
|
+
"LICENSE"
|
|
47
|
+
],
|
|
48
|
+
"engines": {
|
|
49
|
+
"node": ">=18.0.0"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"@larksuiteoapi/node-sdk": "^1.59.0",
|
|
53
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
54
|
+
"dotenv": "^16.4.7",
|
|
55
|
+
"protobufjs": "^7.4.0"
|
|
56
|
+
}
|
|
57
|
+
}
|