A Complete Practical Guide to Operating WeCom and Feishu via Terminal: A Deep Dive into wecom-cli and lark-cli

How can you complete daily office software operations by typing in a terminal window instead of clicking a mouse, and even hand these processes over to AI for automation? This article provides a detailed breakdown of two command-line tools—wecom-cli for WeCom and lark-cli for Feishu (Lark)—analyzing their installation, configuration, parameter logic, and underlying architectures to help you transform daily workflows into automated code instructions.

Terminal command line interface
Image source: Unsplash

How Do You Take Over Daily WeCom Business via Command Line?

By encapsulating seven major business domains—such as contacts, todos, and meetings—into independent terminal commands, wecom-cli turns the command-line window into the central control console for operating WeCom.

Built with Rust, the core design goal of this tool is to serve both humans and AI Agents simultaneously. It encapsulates the most critical parts of WeCom—Contacts, Todos, Meetings, Messages, Schedules, Documents, and Smart Sheets—into 7 categories and 12 dedicated AI Skills. For engineering teams, this means you can break free from the constraints of graphical user interfaces (GUIs) and translate daily operations directly into executable scripts or hand them over to AI.

Environment Preparation and Credential Configuration

Before executing any business commands, you must set up the foundational environment. wecom-cli relies on a Node.js environment, and you need to prepare your WeCom bot’s Bot ID and Secret in advance.

The installation process consists of two mandatory steps. The first is installing the CLI main body globally via npm:

npm install -g @wecom/cli

The second step is installing the corresponding CLI Skill, which is a prerequisite for the tool to be recognized and invoked by AI:

npx skills add WeComTeam/wecom-cli -y -g

Once installed, a one-time credential initialization is required. Running wecom-cli init will start an interactive guide. You can also pass the Bot ID directly via an appended parameter. After configuration, the credentials are not left in plain text; they are encrypted and stored locally at the path ~/.config/wecom/bot.enc.

Scenario 1: Quickly Finding Personnel and Assigning Tasks

In cross-departmental collaboration, quickly locating people and assigning tasks is the most frequent scenario. Through the Contacts category, you can directly pull the list of members within your permissions:

wecom-cli contact get_userlist '{}'

The {} here means passing an empty JSON parameter. Since fetching a full list requires no filtering conditions, passing an empty parameter works perfectly. If you forget which methods are available under a category, simply entering the category name (like wecom-cli contact) will list all tools under that domain.

When assigning tasks to a team, the Todo category provides full lifecycle management. When creating a todo, you must strictly pass parameters in the required format:

wecom-cli todo create_todo '{"content": "Complete Q2 planning document", "remind_time": "2026-06-01 09:00:00"}'

In this JSON structure, content carries the task details, while the time format for remind_time must be accurate to the second. As the task progresses, you can modify its status using the update command; in the example logic, setting todo_status to 0 represents marking it as complete. You must be extremely cautious with the delete_todo command, as the documentation explicitly states this operation is irreversible—once executed, the data is permanently lost.

Scenario 2: Meeting Scheduling and Historical Message Tracing

Organizing meetings often involves coordinating and confirming times across multiple parties. Through the Meetings category, you can complete meeting creation and personnel invitations directly in the terminal:

wecom-cli meeting create_meeting '{"title": "Technical Solution Review", "meeting_start_datetime": "2026-03-30 15:00", "meeting_duration": 3600, "invitees": {"userid": ["zhangsan", "lisi"]}}'

Look closely at this parameter structure: the unit for meeting_duration is seconds, not minutes, so 3600 represents 1 hour. Additionally, the invitees field receives an object containing an array of userids. If you need to modify participants later, using the update invited members tool will execute a “full overwrite” logic—you must pass the people you want to keep along with the new people; otherwise, the original list will be wiped out.

In the message tracing scenario, the tool supports pulling chat histories containing multiple types of media—text, images, files—based on time dimensions:

wecom-cli msg get_message '{"chat_type": 1, "chatid": "zhangsan", "begin_time": "2026-03-29 09:00:00", "end_time": "2026-03-29 18:00:00"}'

If you spot an important multimedia file in the records, you can download it directly to your local machine using the obtained media_id. Conversely, sending a text message only requires constructing the corresponding JSON structure to complete the action.

Scan to join the WeCom communication group:

Scan to join the group

Scenario 3: Complex Scheduling and Asynchronous Document Processing

Schedule management reveals a highly structured advantage under the command line. In addition to basic CRUD operations, it supports directly querying time conflicts for multiple members (1 to 10 people) and dynamically adding or removing schedule attendees without rebuilding the entire schedule. When creating a schedule, the parameter nesting is quite deep:

wecom-cli schedule create_schedule '{"schedule": {"start_time": "2026-03-30 14:00:00", "end_time": "2026-03-30 15:00:00", "summary": "Requirement Review", "attendees": [{"userid": "zhangsan"}], "reminders": {"is_remind": 1, "remind_before_event_secs": 900, "timezone": 8}}}'

In this structure, the reminders object controls the reminder logic: is_remind set to 1 means enabled, remind_before_event_secs set to 900 means triggering 15 minutes in advance, and timezone set to 8 represents UTC+8.

When handling cloud documents, you will encounter a very typical asynchronous programming scenario. When reading a document based on Markdown format, the first call to the read interface usually does not return the body directly, but rather a task_id, because the server needs time for format conversion. You must take this task_id to make a second polling call to actually retrieve the document content. Editing a document, on the other hand, involves completely overwriting the body directly using Markdown syntax.

Scenario 4: Structured Data Operations in Smart Sheets

The operational logic for Smart Sheets is strictly mapped to a three-tier structure: “Sub-table – Field – Record.” When creating a sheet, doc_type must be specified as 10. When operating on fields (columns), you need to explicitly specify the field type, such as adding a single-select column:

wecom-cli doc smartsheet_add_fields '{"docid": "DOC_ID", "sheet_id": "SHEET_ID", "fields": [{"field_title": "Status", "field_type": "FIELD_TYPE_SINGLE_SELECT"}]}'

When operating on records (rows), the JSON nesting becomes very rigorous. When adding a record, the key in values is the column name, and the value must be an object array containing type and text properties. When updating a record, to tell the system how to match the column, you must explicitly declare key_type as CELL_VALUE_KEY_TYPE_FIELD_TITLE in the parameters. Similar to todos, the deletion of sub-tables, fields, and records is irreversible.

Author’s Reflection: When dissecting the parameter structure of wecom-cli, I realized that while pure JSON interaction poses a high cognitive load for beginners due to strict formatting requirements, it is precisely the most friendly format for AI Agents. It eliminates the complexity of state machines found in GUIs (like buttons graying out or modal pop-ups), transforming all business logic into absolutely deterministic data structures.

How Do You Use the 3-Tier Architecture of the Feishu (Lark) Open Platform?

By constructing a “Shortcut Command – API Command – Generic Call” three-tier architecture, lark-cli maintains an extremely simple operational experience while providing infinite possibilities covering over 2,500 underlying interfaces of the Feishu Open Platform.

Compared to the WeCom tool, Feishu’s lark-cli has a larger scope, covering 11 business domains including Calendar, Instant Messaging, Cloud Documents, Bitable (Multidimensional Tables), Sheets, Tasks, Wiki, Contacts, Mail, and Video Meetings. It features over 200 curated commands and 19 AI Agent Skills, and has been specifically “AI-tuned” to improve AI invocation success rates by providing more reasonable default values and structured outputs.

Human-AI Diversion Mechanism for Installation and Configuration

The installation and configuration process of lark-cli reflects extreme engineering practicality, clearly distinguishing between two operational paths: human users and AI Agents.

Human users can perform a one-click installation via npm and use the interactive config init and auth login --recommend to complete the setup. The --recommend parameter automatically checks common permissions, saving the hassle of tedious manual selection.

However, if an AI Agent is executing the configuration, the logic is completely different. The Agent must run the configuration command in the background (with the --new parameter appended). At this point, the terminal outputs an authorization link. The Agent’s task is to intercept this link and send it to the human user; only after the human completes the authorization in the browser will the background command automatically terminate. The login process follows the same logic. This design perfectly solves the pain point of AI being unable to perform graphical interface interactions.

Fine-Grained Permission Control and Identity Switching

At the authentication level, lark-cli provides extremely fine-grained control. In addition to standard login, logout, and status checks, you can isolate permissions by business domain using the --domain parameter (e.g., only authorizing the calendar and task domains), or even pinpoint a specific permission string directly via the --scope parameter.

To accommodate the non-blocking needs of automated workflows, the login command offers a --no-wait parameter. Using this parameter causes the command to immediately return an authentication URL and a Device Code without hanging the terminal. The Agent can resume polling status at any later time using the device code.

Even more practical is the identity switching mechanism. By appending --as user or --as bot to the end of any business command, you can forcefully specify whether that particular invocation is executed under your logged-in user identity or the bot’s identity. This is crucial when handling tasks of different privilege levels under a single configuration.

Network architecture and data flow
Image source: Unsplash

Deep Dive into the 3-Tier Architecture and Application Scenarios

Why is a three-tier architecture necessary? Because the demand for operational granularity varies hugely among users with different technical backgrounds. lark-cli divides commands into three levels: Shortcut Commands, API Commands, and Generic API Calls.

Shortcut Command Tier: These commands are prefixed with a + sign, such as lark-cli calendar +agenda or lark-cli im +messages-send --chat-id "oc_xxx" --text "Hello". The core value of this tier is “hiding complexity.” It builds in smart default values and outputs results in table format by default, making it highly suitable for humans doing quick checks or AI performing simple daily operations.

API Command Tier: When shortcut commands fail to meet customization needs, you can use this tier. It consists of over 100 commands automatically generated and filtered from Feishu’s official OAPI metadata, corresponding one-to-one with platform endpoints. When calling, you must manually pass JSON-formatted params, for example:

lark-cli calendar events instance_view --params '{"calendar_id":"primary","start_time":"1700000000","end_time":"1700086400"}'

Generic API Call Tier: This is the “God mode” with the highest privileges. It directly exposes HTTP methods and interface paths, covering over 2,500 underlying endpoints. You pass query parameters via --params and request bodies via --body. When you need to call extremely obscure interfaces or those not yet wrapped as shortcuts, this is the only way out.

Advanced Practical Tips: Formatting, Pagination, and Safety Rehearsals

When faced with massive amounts of returned data, lark-cli provides powerful output control capabilities. Using the --format parameter, you can convert the default JSON response into a highly readable pretty format, a table format for quick scanning, an ndjson format suitable for pipeline processing, or a csv format that can be opened directly with spreadsheet software.

When processing full datasets, pagination parameters become critical. --page-all will automatically turn pages to fetch all data; --page-limit can restrict the maximum number of pages; and --page-delay allows you to set millisecond-level delays between each page request. This is a core mechanism to prevent triggering bans when calling interfaces with strict rate limits.

Before executing side-effect operations like sending messages or creating documents, it is strongly recommended to use the --dry-run parameter. With this parameter attached, the tool will only display the constructed request structure in the terminal without actually sending it to the server, acting as an absolutely safe sandbox environment.

If you are unsure about the parameter structure of a command, there is no need to flip through web documentation. Simply use the Schema introspection feature. For example, executing lark-cli schema calendar.events.instance_view will directly list the required parameters, request body structure, response structure, and required permissions right in the terminal, essentially embedding the documentation directly into the CLI.

Author’s Reflection: Transitioning from the direct invocation of wecom-cli to the three-tier abstraction of lark-cli, I see a compromise and wisdom in tackling the dilemma of “shared human-AI use.” Shortcut commands lower the cognitive barrier for humans, while the underlying HTTP calls preserve absolute freedom for AI. This layered design is highly worthy of reference in complex systems engineering.

Where Is the Security Boundary When Handing Office Software Over to the Terminal and AI?

Granting AI terminal operation permissions means directly exposing user identities to uncontrollable model outputs, so security red lines must be drawn through strict underlying tool restrictions and usage specifications.

While these two tools greatly enhance efficiency, they also introduce inherent risks such as model hallucinations, uncontrollable execution, and prompt injection. Once an AI misunderstands an intent, or is misled by malicious text while reading a document, it could execute unauthorized operations on your behalf or cause sensitive data leaks.

To counter these threats, lark-cli enables multiple default security protections at the underlying level, including input anti-injection mechanisms, terminal output sanitization (preventing sensitive info from lingering on screens), and invoking the OS’s native keychain to store credentials—which offers much higher system-level security than simple local file encryption.

However, technical measures cannot cover all business risks. Based on the explicit specifications in the documentation, bots connected to such tools must be strictly restricted to “private dialogue assistants.” They must absolutely never be pulled into any group chats, nor should other users be allowed to interact with them. Because once placed in a group environment, any group member could potentially trigger the AI to execute high-risk operations through conversation or indirectly access your private data. At the same time, the documentation strongly advises against modifying any default security configurations; once these restrictions are relaxed, all consequences arising thereof will be borne entirely by the user.

Practical Summary / Action Checklist

  • Environment Dependencies: Ensure Node.js and npm/npx environments are installed locally.
  • wecom-cli Core Flow: Globally install the main body and Skill pack -> Execute wecom-cli init to encrypt and store credentials -> Invoke business via the wecom-cli <category> <method> '{json}' format.
  • lark-cli Core Flow: Globally install the main body and Skill pack -> Differentiate between human interactive configuration and Agent background URL extraction configuration -> Use + shortcut commands or underlying API calls as needed.
  • Security Red Lines: Never modify default security configurations; strictly prohibit pulling associated bots into group chats or exposing them to other users.
  • Error Prevention Mechanisms: Before operations involving data changes, always use --dry-run in lark-cli for preview; in wecom-cli, be highly vigilant of delete commands tagged as “irreversible.”

One-page Summary

wecom-cli and lark-cli are two office software control tools designed specifically for the terminal and AI Agents. wecom-cli focuses on seven core categories of WeCom, achieving business operations through strict JSON parameter interaction, featuring asynchronous polling for document reading and three-tier structural management for Smart Sheets. lark-cli covers eleven business domains of Feishu, innovatively proposing a three-tier architecture of “Shortcut Commands – API Commands – Generic Calls,” balancing human ease of use with AI’s full interface coverage, and equipping users with powerful formatted output, anti-ban pagination, and Schema introspection. Both implement input anti-injection and credential encryption at the underlying level, but users must strictly adhere to the security baseline of “private assistant only, strictly no group chats” to guard against unauthorized risks brought about by model hallucinations.

Frequently Asked Questions (FAQ)

Is it safe to store wecom-cli credentials locally?
The tool encrypts the credentials and stores them at the local system path ~/.config/wecom/bot.enc, so they are not exposed in plain text.

Why doesn’t the first call return content when reading a document using lark-cli?
Reading Markdown-based documents is an asynchronous process. The first call usually only returns a task_id; you need to make a second polling call carrying this task_id to retrieve the actual body text.

Which tier of the 3-tier architecture in lark-cli should I choose?
Use the + prefixed shortcut commands for daily checks or simple operations; use API commands when fine-grained parameter control is needed; use the Generic API Call tier when you need to call obscure interfaces that haven’t been wrapped yet.

What should I pay attention to when updating invited members in a wecom-cli meeting?
Updating invited members executes a “full overwrite” logic. You must include all original members you wish to keep along with the new members in the new parameter, otherwise the original list will be wiped clean.

How can I prevent AI Agents from executing dangerous send or delete operations in Feishu?
In lark-cli, you can append the --dry-run parameter to dangerous commands. This causes the tool to only display the request structure without actually sending it, serving as a safe sandbox preview.

Can I pull a configured Feishu bot into a project group for the team to share?
Absolutely not. The documentation explicitly warns that such bots must be used as private dialogue assistants only. Pulling them into group chats can lead to permissions being maliciously or accidentally triggered by other group members, causing severe data leaks or unauthorized operations.