🎁 Get the FREE AI Skills Starter Guide β€” Subscribe β†’
BytesAgainBytesAgain
πŸ¦€ ClawHub

Lark Toolkit

by @pengxiao-wang

Comprehensive Lark/Feishu API skill for OpenClaw agents. Covers all Lark operations via three access paths: claw-lark plugin (message tool), MCP tools (mcpor...

Versionv1.0.0
Downloads1,940
TERMINAL
clawhub install lark-toolkit

πŸ“– About This Skill


name: lark-toolkit description: "Comprehensive Lark/Feishu API skill for OpenClaw agents. Covers all Lark operations via three access paths: claw-lark plugin (message tool), MCP tools (mcporter), and direct Open API (curl). Use when: (1) sending/receiving Lark messages, (2) managing groups or members, (3) listing department users or contacts, (4) creating calendar events, (5) working with docs/bitable/wiki/OKR/tasks, (6) setting up a new Lark bot, (7) debugging webhook/connection issues, (8) any Lark Open API operation the message tool or MCP doesn't support. Covers both Lark International (open.larksuite.com) and Feishu China (open.feishu.cn)."

Lark Toolkit

Prerequisites & Security

This skill is a documentation-only reference guide. It contains no executable code that accesses credentials automatically.

Required credentials (user-provided, never bundled):

  • Lark App ID (app_id) β€” from Lark Developer Console
  • Lark App Secret (app_secret) β€” from the same console
  • How credentials are used:

  • All API examples in SKILL.md use placeholders (, , CHAT_ID, etc.) β€” no real secrets
  • The scripts/get_token.sh helper obtains a temporary tenant_access_token from Lark's auth API. It reads credentials from (in order):
  • 1. Command-line arguments 2. LARK_APP_ID / LARK_APP_SECRET environment variables 3. ~/.openclaw/openclaw.json (standard OpenClaw config, path channels.lark.accounts.default.appId/appSecret)
  • The script prints the config source to stderr when falling back to the config file
  • No credentials are hardcoded, cached to disk, logged, or transmitted beyond the single Lark auth API call
  • The token is exported as LARK_TOKEN env var for subsequent commands in the same shell session
  • Three Access Paths

    | Need | Path | When | |------|------|------| | Send/receive messages | claw-lark plugin (message tool) | Basic text, media, reactions β€” simplest | | Structured CRUD ops | MCP tools via mcporter | Bitable, calendar, docs, tasks, OKR β€” 38 tools | | Everything else | Direct API (curl) | Contacts, member mgmt, anything MCP doesn't cover |

    Rule: claw-lark first β†’ MCP second β†’ direct API as fallback.

    Authentication (Direct API)

    TOKEN=$(curl -s -X POST 'https://open.larksuite.com/open-apis/auth/v3/tenant_access_token/internal' \
      -H 'Content-Type: application/json' \
      -d '{"app_id":"","app_secret":""}' \
      | python3 -c "import sys,json; print(json.load(sys.stdin)['tenant_access_token'])")
    

    Or use the helper: bash scripts/get_token.sh

    Token validity: ~2 hours. Cache it.

    API Base URLs

    | Platform | API Base | Dev Console | |----------|----------|-------------| | Lark International | https://open.larksuite.com/open-apis/ | https://open.larksuite.com/app | | Feishu (China) | https://open.feishu.cn/open-apis/ | https://open.feishu.cn/app |

    ⚠️ Lark β‰  Feishu. Always confirm which platform the tenant uses.

    Common API Patterns

    Send a Message

    curl -X POST "https://open.larksuite.com/open-apis/im/v1/messages?receive_id_type=chat_id" \
      -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
      -d '{"receive_id":"CHAT_ID","msg_type":"text","content":"{\"text\":\"hello\"}"}'
    

    Reply in Thread

    curl -X POST "https://open.larksuite.com/open-apis/im/v1/messages/MSG_ID/reply" \
      -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
      -d '{"msg_type":"text","content":"{\"text\":\"reply\"}","reply_in_thread":true}'
    

    Add Reaction

    curl -X POST "https://open.larksuite.com/open-apis/im/v1/messages/MSG_ID/reactions" \
      -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
      -d '{"reaction_type":{"emoji_type":"THUMBSUP"}}'
    

    Emoji types: THUMBSUP HEART LAUGH OK COOL FINGERHEART SMILE JIAYOU

    List Department Users (MCP gap β€” direct API only)

    # List root departments
    curl -s -H "Authorization: Bearer $TOKEN" \
      'https://open.larksuite.com/open-apis/contact/v3/departments?parent_department_id=0&page_size=50&fetch_child=true'

    List users in a department

    curl -s -H "Authorization: Bearer $TOKEN" \ 'https://open.larksuite.com/open-apis/contact/v3/users?department_id=&page_size=50'

    Key fields: name, open_id, employee_type (1=regular, 2=intern), department_ids

    Read Chat History

    curl -s -H "Authorization: Bearer $TOKEN" \
      'https://open.larksuite.com/open-apis/im/v1/messages?container_id_type=chat&container_id=&page_size=20&sort_type=ByCreateTimeDesc'
    

    Add Bot to Group

    curl -X POST "https://open.larksuite.com/open-apis/im/v1/chats//members?member_id_type=app_id" \
      -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
      -d '{"id_list":[""]}'
    

    MCP Tools (38 available)

    mcporter call lark-mcp. key=value
    

    Full catalog with parameters: references/mcp-tools.md

    MCP Coverage

    | Module | Key Tools | |--------|-----------| | Bitable | create apps/tables, CRUD records, list fields | | Calendar | create/get/patch events, free/busy, primary calendar | | Docs | read content, search, import, set permissions | | IM | create/list groups, get members, send messages, list history | | OKR | batch get, list periods, CRUD progress, query reviews | | Report | query rules/tasks, manage views | | Task | create/patch tasks, add members/reminders | | Wiki | search nodes, get node details | | Contacts | batch get user IDs by email/phone |

    MCP Gaps (use direct API)

  • List users by department β€” GET /contact/v3/users?department_id=
  • List departments β€” GET /contact/v3/departments
  • Add/remove group members β€” POST /im/v1/chats/{chat_id}/members
  • Send reactions β€” POST /im/v1/messages/{msg_id}/reactions
  • Upload images/files β€” POST /im/v1/images / POST /im/v1/files
  • Pagination

    Most list APIs use cursor-based pagination:

    ?page_size=50&page_token=
    

    Check has_more in response.

    Error Handling

    | Code | Meaning | |------|---------| | 0 | Success | | 99991663 | Token expired β€” refresh | | 99991664 | Token invalid | | 99991400 | Bad request | | 99991403 | No permission β€” check app permissions |

    Critical Pitfalls

    1. Lark β‰  Feishu β€” International uses open.larksuite.com, China uses open.feishu.cn 2. open_id is per-app β€” Same user has different open_id across different Lark apps 3. Webhook 5s timeout β€” Return 200 immediately, process async 4. Event dedup β€” Use event_id (Lark retries up to 3x) 5. Bot-to-bot blind spot β€” Lark does NOT push Bot A's messages to Bot B's webhook 6. Publishing required β€” Permission/event changes only take effect after publishing a new app version 7. ngrok IPv6 trap β€” Use 127.0.0.1:PORT not localhost:PORT in ngrok config 8. ngrok free domain β€” Returns interstitial HTML that Lark rejects. Use paid domain.

    Detailed References

  • Bot setup playbook: references/bot-setup.md
  • API reference: references/api-reference.md
  • MCP tools catalog: references/mcp-tools.md
  • Webhook & tunnel: references/webhook-setup.md
  • Troubleshooting: references/troubleshooting.md
  • Permissions: references/permissions.md