lark-bridge
Unofficial Feishu/Lark Web SDK using cookie-based authentication. Provides real-time message listening via WebSocket, message search/fetch, sending, and Drive operations.
⚠️ This library is reverse-engineered from Feishu's web client. It is not an official API and may break without notice.
Installation
pip install lark-bridge
Quick Start
import asyncio
from lark_bridge import LarkBridge
bridge = LarkBridge("your_cookie_string_here")
# For enterprise tenants with custom domain:
bridge = LarkBridge("your_cookie_string_here", domain="yourcompany.feishu.cn")
# If WebSocket connection fails, you may need to provide app_key explicitly:
bridge = LarkBridge("your_cookie_string_here", domain="yourcompany.feishu.cn", app_key="your_app_key")
How to Get app_key
The app_key is used for WebSocket authentication. A default value is built-in, but if Feishu updates it you'll need to extract a new one:
- Open your Feishu domain in Chrome (e.g.
https://yourcompany.feishu.cn/messenger/) - Open DevTools → Sources → find
lark.xxxxxxxx.js(underfeishucdn.com) - Search for
sass:"in that JS file — the 32-char hex string is yourapp_key
Alternatively, from the browser console Network tab, look for WebSocket connections to msg-frontier.feishu.cn and find the access_key parameter derivation.
Listen to Messages
async def main():
async for msg in bridge.listen(watch_chats=["chat_id"]):
print(f"[{msg['chat_id']}] {msg['from_id']}: {msg['text']}")
asyncio.run(main())
Search History
# Simple: auto-paginate up to limit
result = await bridge.search_messages(
chat_id="7052636707732193282",
start_time=1716192000,
end_time=1716278400,
limit=50,
)
print(result["msg_ids"])
# Manual pagination:
page = await bridge.search_messages_page(chat_id="7052636707732193282")
while page["has_more"]:
page = await bridge.search_messages_page(
chat_id="7052636707732193282",
page_token=page["page_token"],
)
print(page["msg_ids"])
Fetch Messages
messages = await bridge.fetch_messages(["msg_id_1", "msg_id_2"])
for msg in messages:
print(msg["text"])
# Each message dict contains:
# msg_id, type, from_id, chat_id, chat_type, parent_id, root_id, create_time, text
# chat_type: 0=unknown, 1=P2P(private), 2=GROUP, 3=TOPIC_GROUP
Send Message
await bridge.send_message(
chat_id="7052636707732193282",
text="Hello!",
reply_id="optional_msg_id",
at_user_ids=["user_id"],
)
Drive Operations
# Create folder
folder = await bridge.create_folder("My Folder", parent_token="root_token")
# folder = {"token": "...", "url": "https://domain/drive/folder/..."}
# Upload file
result = await bridge.upload_file(folder["token"], "report.txt", b"file content")
# result = {"file_token": "...", "node_token": "...", "url": "https://domain/file/..."}
# List my space root folders
items = await bridge.list_my_space()
# List shared folders
items = await bridge.list_shared_folders()
# List children of a folder
items = await bridge.list_children("fldcnfByPeMzPxrgtS5Xl06YRid")
# Each item: {"token", "obj_token", "name", "type", "type_code", "url", "edit_time"}
# Download a file (use obj_token, not node token)
content = await bridge.download_file("boxcnAbcDef123")
if content:
Path("report.pdf").write_bytes(content)
# Delete files/folders (use node token)
await bridge.delete_nodes(["nodcnXxx123"])
Export Document
# Export a docx/wiki page as markdown
content = await bridge.export_document(
token="GSeJdHQbQo3b2jxg8CYc1Zqqnah",
type="docx", # "docx" | "sheet" | "doc"
file_extension="markdown", # "markdown" | "docx" | "pdf" | "xlsx" | "csv"
)
if content:
Path("output.md").write_bytes(content)
Supported combinations:
type="docx"(wiki/docx pages) → markdown, docx, pdftype="sheet"→ xlsx only
Import Document
# Import a markdown file as an online docx
result = await bridge.import_document(
folder_token="fldcnfByPeMzPxrgtS5Xl06YRid",
file_name="report.md",
file_content=Path("report.md").read_bytes(),
file_extension="md", # source format
target_type="docx", # target online doc type
)
# result = {"token": "...", "url": "https://domain/docx/..."}
MCP Server
Expose lark-bridge as an MCP server so AI clients (Claude Desktop, Cursor, Kiro, etc.) can call Feishu tools directly.
Install
pip install lark-bridge[mcp]
Run
FEISHU_COOKIE="your_cookie_string" lark-bridge-mcp
For enterprise tenants with a custom domain:
FEISHU_COOKIE="your_cookie_string" FEISHU_DOMAIN="yourcompany.feishu.cn" lark-bridge-mcp
If your cookie changes frequently, use a file instead of an environment variable. The server reads the file on every tool call, so updates take effect immediately without restarting:
FEISHU_COOKIE_FILE="/path/to/cookie.txt" lark-bridge-mcp
MCP Client Config
{
"mcpServers": {
"lark-bridge": {
"command": "lark-bridge-mcp",
"env": {
"FEISHU_COOKIE": "your_cookie_string"
}
}
}
}
Available tools: send_message, search_messages, fetch_messages, create_folder, upload_file.
Cookie Setup
- Open Feishu Web in your browser and log in
- Open DevTools (F12) → Application → Cookies
- Copy the full cookie string (all key=value pairs joined by
;) - Pass it to
LarkBridge("your_cookie_string")
Example cookie format:
cookie = "passport_web_did=YOUR_DID; session=YOUR_SESSION; _csrf_token=YOUR_CSRF_TOKEN"
bridge = LarkBridge(cookie)
Cookie typically stays valid as long as the WebSocket connection is maintained.
License
Metadata
Release files for lark-bridge 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| lark_bridge-0.6.0.tar.gz | 29.2 kB | With provenance | Details for lark_bridge-0.6.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| lark_bridge-0.6.0-py3-none-any.whl | Python 3 | none | any | Details for lark_bridge-0.6.0-py3-none-any.whl |
Total release size: 63.6 kB
Release files / lark_bridge-0.6.0.tar.gz
| Download URL | lark_bridge-0.6.0.tar.gz |
|---|---|
| Size | 29.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2de34ce721863af170d776fd4949f3eda1973a98a1c1bac0040643cce05d25e9
|
|
BLAKE2b-256 checksum How to use checksums |
ebe6fe6e88530701cb9d553f5ab5ed2e032458779e3bda0b32247e95b4ae550a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.
Transparency logRelease files / lark_bridge-0.6.0-py3-none-any.whl
| Download URL | lark_bridge-0.6.0-py3-none-any.whl |
|---|---|
| Size | 34.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
84520c6a7791746ccf80c06c7af668a6222d18a422cf4908789d30dabfd4b695
|
|
BLAKE2b-256 checksum How to use checksums |
ecaf2f2dfe146233cc8fe6f73b04ad7a82b4b3351a0daab020f463326a85754b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.
Transparency logSecurity for lark-bridge 0.6.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for lark_bridge-0.6.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.