Read and write Lark documents - get content as markdown or blocks, create new documents, append content (text, headings, lists, code), list folders. Use when user asks about a Lark doc, wants to read/create/edit a document, or mentions a document URL/ID.
Query and retrieve Lark document content via the lark CLI.
Ensure lark is in your PATH, or use the full path to the binary. Set the config directory if not using the default:
lark doc <command>
# Or with explicit config:
LARK_CONFIG_DIR=/Users/yingcong/Code/lark-cli/.lark lark doc <command>
lark doc search <query> [--owner <user-id>] [--chat <chat-id>] [--type <doc-type>]
Searches for documents by keyword. Returns documents from Drive that match the query.
Options:
--owner: Filter by owner user ID (can be repeated)--chat: Filter by chat ID where document is located (can be repeated)--type: Filter by document type (can be repeated). Valid types: doc, sheet, slide, bitable, mindnote, fileOutput:
{
"query": "project plan",
"results": [
{
"token": "doxcntan34DX4QoKJu7jJyabcef",
"type": "docx",
"title": "Q4 Project Plan",
"owner_id": "ou_xxxx"
}
],
"total": 15,
"count": 15
}
Note: Maximum 200 results can be returned per search.
lark doc list [folder-token]
Lists items in a Lark Drive folder. If no folder token is provided, lists items in the root cloud space.
Output:
{
"folder_token": "fldbcRho46N6MQ3mJkOAuPabcef",
"items": [
{
"token": "doxcntan34DX4QoKJu7jJyabcef",
"name": "My Document",
"type": "docx",
"parent_token": "fldbcRho46N6MQ3mJkOAuPabcef",
"url": "https://larksuite.com/docx/doxcntan34DX4QoKJu7jJyabcef"
}
],
"count": 1
}
Item types: doc, docx, sheet, bitable, mindnote, file, folder, shortcut
For shortcuts, includes shortcut_info with target_type and target_token.
lark doc download <file_token> -o <output_path>
Downloads a file from Lark Drive. The file token is obtained from doc list or doc search output. Only files with type "file" can be downloaded (not docs, sheets, etc - those are Lark native formats).
Options:
-o, --output: Output file path (required)Output:
{
"file_token": "FG3obxWuaoftXIx0CvxlQAabcef",
"filename": "report.pdf",
"content_type": "application/pdf",
"size": 1048576
}
Note: You must have read access to the file. If you get a 403 error, the file may not be shared with you.
lark doc wiki <node-token>
Resolves a wiki node token to get the underlying document ID. Required for wiki URLs before fetching content.
Output:
{
"node_token": "X8Tawq431ifOYSklP2tlamKsgNh",
"obj_token": "QdqJdegH8oAKmuxqGBBlKjGMgAc",
"obj_type": "docx",
"title": "Document Title",
"space_id": "7384661266473713695",
"node_type": "origin",
"has_child": false
}
Use the obj_token value with doc get or doc blocks.
lark doc wiki-children <node-token>
Lists the immediate child nodes of a wiki node. Useful for browsing wiki hierarchies (e.g., listing all PRDs under a PRDs folder).
Output:
{
"parent_node_token": "RBCmwZEqhili9ZkKS5fl1Ov2gKc",
"space_id": "7344964278161604639",
"children": [
{
"node_token": "ABC123",
"obj_token": "XYZ789",
"obj_type": "docx",
"title": "PRD: Feature X",
"space_id": "7344964278161604639",
"node_type": "origin",
"has_child": false
}
],
"count": 5
}
The command automatically resolves the space_id from the node token. Use obj_token with doc get to read child documents.
lark doc wiki-search <query> [--space-id <space-id>] [--node-id <node-id>]
Searches for wiki nodes by keyword. Returns wiki nodes the user has permission to view.
Note: Results are limited to 50 items to avoid API rate limits.
Options:
--space-id: Filter to a specific wiki space ID--node-id: Search within a node and its children (requires --space-id)Output:
{
"query": "meeting notes",
"results": [
{
"node_id": "BAgPwq6lIi5Nykk0E5fcJeabcef",
"obj_token": "AcnMdexrlokOShxe40Fc0Oabcef",
"obj_type": "docx",
"title": "Weekly Meeting Notes",
"url": "https://sample.larksuite.com/wiki/BAgPwq6lIi5Nykk0E5fcJeabcef",
"space_id": "7307457194084925443"
}
],
"count": 1
}
Use the obj_token value with doc get to retrieve the document content.
lark doc get <document-id>
Returns document content as markdown - compact and readable.
Output:
{
"document_id": "ABC123xyz",
"title": "My Document",
"content": "# Heading\n\nDocument content as markdown..."
}
lark doc blocks <document-id>
Returns full block structure as JSON - useful for programmatic analysis.
Output:
{
"document_id": "ABC123xyz",
"title": "My Document",
"block_count": 42,
"blocks": [...]
}
lark doc comments <document-id>
Retrieves all comments from a document, including replies.
Output:
{
"file_token": "ABC123xyz",
"comments": [
{
"comment_id": "6916106822734512356",
"user_id": "ou_cc19b2bfb93f8a44db4b4d6eab",
"create_time": "2026-01-02T09:00:00+08:00",
"is_solved": false,
"is_whole": true,
"quote": "The quoted text",
"replies": [
{
"reply_id": "6916106822734512357",
"user_id": "ou_cc19b2bfb93f8a44db4b4d6eab",
"create_time": "2026-01-02T09:05:00+08:00",
"text": "This is the reply text"
}
]
}
],
"count": 1
}
Fields:
is_whole: true for document-level comments, false for inline/local commentsis_solved: whether the comment thread has been resolvedquote: the highlighted text from the document (for inline comments)lark doc create --title "My Document" [--folder <folder-token>]
Creates a new empty Lark document. Optionally specify a folder to create it in.
Options:
--title: Document title (required)--folder: Folder token to create the document in (default: root cloud space)Output:
{
"success": true,
"document_id": "BKlmdClegoCan5x5Rzbl73QQgEC",
"revision_id": 1,
"title": "My Document"
}
lark doc append <document-id> [flags]
Appends content blocks to an existing document. Supports multiple block types.
Content flags (at least one required):
--text "content": Append a text paragraph--heading "content" --level <1-9>: Append a heading (default level 1)--code "content" --language <id>: Append a code block--bullet "item": Append bullet list items (repeatable)--ordered "item": Append ordered list items (repeatable)--todo "item": Append a todo/checkbox item--divider: Append a horizontal divider--table "ROWSxCOLS": Append a table (e.g., --table 3x4 for 3 rows, 4 columns; header row enabled by default)--json: Read raw block JSON from stdinOther flags:
--block-id: Parent block ID to append under (default: document root)--index: Insertion position (-1=end, 0=beginning)Examples:
# Add a heading and text
lark doc append ABC123xyz --heading "Section Title" --level 2
lark doc append ABC123xyz --text "Hello from CLI"
# Add a bullet list
lark doc append ABC123xyz --bullet "First item" --bullet "Second item"
# Add a code block (Python)
lark doc append ABC123xyz --code "print('hello')" --language 49
# Add a 3x4 table
lark doc append ABC123xyz --table 3x4
# Add raw blocks via JSON stdin
echo '[{"block_type":2,"text":{"elements":[{"text_run":{"content":"raw"}}]}}]' | lark doc append ABC123xyz --json
Common code language IDs: 1=PlainText, 7=Bash, 22=Go, 29=Java, 30=JavaScript, 49=Python, 53=Rust, 56=SQL, 63=TypeScript, 67=YAML
Output:
{
"success": true,
"document_revision_id": 5,
"blocks": [...]
}
lark doc update-block <document-id> <block-id> [flags]
Updates the text content of an existing block. Useful for populating table cells after creating a table, or modifying any text block.
Important: You must target a text block (block_type 2), not a container block. For table cells, each table_cell (block_type 32) contains a child text block — use that child's block ID.
Content flags (one required):
--text "content": Set plain text content--json: Read rich text elements JSON from stdinExamples:
# Set plain text content
lark doc update-block DOC_ID TEXT_BLOCK_ID --text "Cell content"
# Set rich text (bold, etc.) via JSON stdin
echo '{"elements":[{"text_run":{"content":"Bold text","text_element_style":{"bold":true}}}]}' | \
lark doc update-block DOC_ID TEXT_BLOCK_ID --json
Table workflow:
lark doc append DOC_ID --table 3x4lark doc blocks DOC_IDtable_cell (block_type 32) — use the child block ID, not the cell block IDlark doc update-block DOC_ID TEXT_BLOCK_ID --text "content"Output:
{
"success": true,
"document_revision_id": 6,
"block": {...}
}
lark sheet list <spreadsheet_token>
Lists all sheets (tabs) within a Lark spreadsheet.
Output:
{
"spreadsheet_token": "T4mHsrFyzhXrj0tVzRslUGx8gkA",
"sheets": [
{
"sheet_id": "abc123",
"title": "Sheet1",
"index": 0,
"row_count": 100,
"column_count": 10
}
],
"count": 1
}
lark sheet read <spreadsheet_token> [--sheet <sheet_id>] [--range A1:Z100]
Reads cell values from a Lark spreadsheet.
Options:
--sheet: Sheet ID to read from (default: first sheet by index)--range: Cell range to read (e.g., A1:Z100). Default: all data up to 1000 rowsOutput:
{
"spreadsheet_token": "T4mHsrFyzhXrj0tVzRslUGx8gkA",
"sheet_id": "abc123",
"range": "abc123!A1:D10",
"row_count": 10,
"column_count": 4,
"values": [
["Header1", "Header2", "Header3", "Header4"],
["Value1", "Value2", 123, true]
]
}
Note: Cell values preserve their types (string, number, boolean). Empty cells may be omitted from rows.
| URL Type | Example | How to Get Content |
|----------|---------|----------------------------|
| Direct doc | https://xxx.larksuite.com/docx/ABC123xyz | Use ABC123xyz directly with doc get |
| Wiki | https://xxx.larksuite.com/wiki/X8Tawq43... | First run doc wiki X8Tawq43... to get obj_token, then use that with doc get |
| Spreadsheet | https://xxx.larksuite.com/sheets/T4mHsr... | Use T4mHsr... with sheet list or sheet read |
Important: Wiki URLs require a two-step process - resolve the node first, then fetch the document.
| Use Case | Command | Why |
|----------|---------|-----|
| Search for documents | doc search | Find docs by keyword across Drive |
| Search wiki by keyword | doc wiki-search | Find wiki nodes by keyword |
| List folder contents | doc list [folder-token] | Browse Drive files and folders |
| Download a file | doc download | Save Drive files locally |
| Wiki URL | doc wiki then doc get | Must resolve wiki node first |
| List wiki sub-pages | doc wiki-children | Browse wiki hierarchy |
| Create a new document | doc create | Creates empty doc with title |
| Append content to doc | doc append | Add text, headings, lists, code, tables, etc. |
| Update block content | doc update-block | Modify existing block text (e.g., table cells) |
| Read/summarize content | doc get | Markdown is compact (~90KB) |
| Analyze structure | doc blocks | Full block hierarchy |
| Search for text | doc get | Grep-able markdown |
| Count elements | doc blocks | Block types enumerated |
| Read comments/feedback | doc comments | Get all comments and replies |
| List sheets in spreadsheet | sheet list | See all tabs and their sizes |
| Read spreadsheet data | sheet read | Get cell values as JSON |
Default to doc get - it's 2-3x smaller and sufficient for most tasks.
When using doc blocks, key block types:
| Type | Description | |------|-------------| | 1 | Page (root block) | | 2 | Text paragraph | | 3-11 | Headings H1-H9 | | 12 | Bullet list | | 13 | Ordered list | | 14 | Code block | | 15 | Quote | | 17 | Todo/checkbox | | 22 | Divider | | 27 | Image | | 31 | Table |
All commands output JSON. Format appropriately when presenting to user.
Errors return JSON:
{
"error": true,
"code": "ERROR_CODE",
"message": "Description"
}
Common error codes:
AUTH_ERROR - Need to run lark auth loginSCOPE_ERROR - Missing documents permissions. Run lark auth login --add --scopes documentsAPI_ERROR - Lark API issue (often permissions)This skill requires the documents scope group. If you see a SCOPE_ERROR, the user needs to add documents permissions:
lark auth login --add --scopes documents
To check current permissions:
lark auth status
If you get an API_ERROR after confirming scopes are granted, the user may need to ensure they have access to the specific document in Lark.
For large documents, use jq and grep to extract specific information without loading everything into context.
# Extract all headings from markdown
lark doc get <id> | jq -r '.content' | grep -E '^#{1,6} '
lark doc get <id> | jq -r '.title'
# Count how many of each block type
lark doc blocks <id> | jq '.blocks | group_by(.block_type) | map({type: .[0].block_type, count: length})'
# Get all todo/checkbox blocks (type 17)
lark doc blocks <id> | jq '[.blocks[] | select(.block_type == 17)]'
# Find lines mentioning a keyword
lark doc get <id> | jq -r '.content' | grep -i "keyword"
# With context
lark doc get <id> | jq -r '.content' | grep -i -C 3 "keyword"
# Get all code blocks (type 14)
lark doc blocks <id> | jq '[.blocks[] | select(.block_type == 14)]'
# Quick stats: title, block count
lark doc blocks <id> | jq '{title, block_count}'
/docx/ URL: Extract document ID directly/wiki/ URL: Run doc wiki <node-token> first to get obj_tokendoc get <id> | jq -r '.content' | grep -E '^#{1,6} 'Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer