Skip to content

larksuite/meegle-cli

Repository files navigation

Meegle CLI

License: MIT Node.js npm version

English | 简体中文

Command-line tool for Meegle (Lark Project). Manage work items, schedules, and data from your terminal — no browser needed.

Install · Quick Start · Agent Skill · Commands · Auth · Config · Security · Contributing

Why Meegle CLI?

  • Agent-Native — Ships a bundled AI Agent Skill that teaches Trae, Claude Code, Cursor, Windsurf, Gemini CLI and other agents how to drive Meegle with one command. Every CLI command is designed for both humans and agents, with structured JSON output, --dry-run previews, and --device-code flows for non-TTY environments
  • Broad Coverage — 12 business domains (work items, workflow, subtasks, comments, work hours, relations, my-work, views, charts, team, user, project) and 40+ commands mapping to Meegle's core capabilities
  • Two-Layer Parameters — Ergonomic --flag-name for everyday use, fallback --params <json> for complex payloads like fields[] — pick the right granularity per call
  • Flexible Outputjson / table / ndjson / raw, with --select dot-path projection for piping to other tools
  • Secure by Default — OS keychain credential storage, ${VAR} env-var templating so secrets never land in config files, multi-profile switching for staging / prod

Features

Category Capabilities
📋 Work Items Create, read, update, batch-read, query (MQL), list operation records, inspect metadata
🔀 Workflow Transition nodes & states, update node fields, list available transitions and required fields
Subtasks Create, update, complete, rollback subtasks
💬 Comments Add and list comments on work items
⏱️ Work Hours List work hour records, view team-member schedules
🔗 Relations List related work items, inspect relation-type definitions
📌 My Work View this week / overdue / completed to-dos
👁️ Views Create and update fixed views, search views by name
📊 Charts List charts under a view, fetch chart details
👥 Team & User List teams, team members, search users, view current login
🗂️ Projects Search projects by keyword
🔐 Auth & Config OAuth login, device-code flow, multi-profile config, env-var injection
🤖 Agent Skill Pre-built skill for Trae / Claude Code / Cursor / Windsurf / Gemini CLI / Copilot

Installation

Requirements

  • Node.js >= 16 (ships with npm / npx)

Install

npm install -g @lark-project/meegle

Quick Start (Human Users)

Note for AI assistants: if you are an AI Agent helping the user set this up, jump directly to Quick Start (AI Agent) — it contains the non-interactive steps you need.

# (Optional) Persist the host so future logins skip the arrow-key picker
meegle config set host <host>

# 1. Log in (arrow-key host picker + browser OAuth)
meegle auth login

# 2. View this week's to-dos
meegle mywork todo --action this_week --page-num 1

# 3. View help
meegle --help
meegle workitem --help

# 4. Inspect command parameters
meegle inspect workitem.create

Quick Start (AI Agent / CI / Headless)

The default meegle auth login uses an arrow-key host picker plus a browser OAuth callback — both require a real TTY, so they will hang or fail in CI runners, pipes, and agent shells like Claude Code. Use the Device Code flow instead: it prints an authorization URL that the user opens in any browser.

Step 1 — Install the CLI

npm install -g @lark-project/meegle

Step 2 — Persist the host

meegle config set host <host>

Examples of <host>: project.feishu.cn, meegle.com, or your self-hosted tenant domain such as your-tenant.example.com.

Step 3 — Log in with Device Code

Run this command in the background. It prints an authorization URL — extract it and send it to the user. The command exits automatically once the user completes authorization in the browser.

meegle auth login --device-code

Alternatively, pass the host inline each time without persisting it:

meegle auth login --device-code --host <host>

Step 4 — Verify

meegle auth status

For fully unattended CI (no human-in-the-loop), inject a token via environment variables instead — see Sandbox / CI.

AI Agent Skill

skills/meegle/ is a drop-in skill that teaches AI Agents — Trae, Claude Code, Cursor, Windsurf, Gemini CLI, GitHub Copilot CLI — how to operate Meegle through this CLI. It bundles the command catalog, MQL syntax, field-value conventions, rich-text Markdown rules, and standard operating procedures for common write flows.

Install

# Install the CLI first (the skill calls `meegle` under the hood)
npm install -g @lark-project/meegle

# Then add the skill — auto-detects installed agents and registers in each
npx skills add larksuite/meegle-cli -y -g

npx skills add reads skills/meegle/SKILL.md from the repo and drops it into the skill directory of every agent CLI it finds on the machine. Re-run any time to pick up updates.

What it covers

  • Command reference — every meegle resource / method with required parameters and examples
  • MQL search — syntax for workitem query, operators, scope keywords
  • Field values — how to shape complex field payloads (arrays, nested JSON, date ranges)
  • Rich text — Markdown subset supported by Meegle's rich-text editor
  • SOPs — step-by-step playbooks for creating work items, transitioning nodes, transitioning states, and updating fields
  • Auth guard — the skill refuses to run business commands until meegle auth status succeeds

See skills/meegle/SKILL.md and skills/meegle/references/ for the full contents.

Usage

Once installed, just ask the agent in natural language. For example, in Trae:

Show me this week's P0 stories in the PROJ space.

The agent consults the skill, picks the right meegle commands, and runs them for you. Pair with --dry-run (see Security) to preview side-effectful operations before the agent commits them.

Heads up: the skill name meegle is the same string as the CLI binary. When documentation refers to "the meegle skill" it means the files in skills/meegle/; when it refers to "the meegle CLI" it means the meegle command on your PATH.

Commands

workitem — Work Items

Command Description
workitem create Create a work item
workitem get View work item details
workitem +batch-get Batch-read work items by IDs (client-side fan-out over workitem get; + marks scenario/sugar commands)
workitem update Update work item fields
workitem query Search work items using MQL
workitem list-op-records View operation records
workitem meta-types List work item types
workitem meta-create-fields List fields available at creation
workitem meta-fields List field configurations
workitem meta-roles List role configurations

workflow — Workflow

Command Description
workflow transition Transition or rollback a node
workflow transition-state Transition a state-flow state
workflow get-node View node details
workflow update-node Update a node
workflow meta-node-fields List node field configurations
workflow list-state-transitions List available state transitions
workflow list-state-required List required fields for transitions

subtask — Subtasks

Command Description
subtask update Create / update / complete / rollback subtasks

comment — Comments

Command Description
comment add Add a comment
comment list List comments

workhour — Work Hours

Command Description
workhour list-records List work hour records
workhour list-schedule View team member schedules

relation — Relations

Command Description
relation list List related work items
relation meta-definitions List relation type definitions

mywork — My Work

Command Description
mywork todo View my to-dos / completed items

view — Views

Command Description
view create-fixed Create a fixed view
view get View details of a view
view update-fixed Update a fixed view
view search Search views by name

chart — Charts

Command Description
chart get View chart details
chart list List charts under a view

team / user — People

Command Description
team list List teams in a project
team list-members List team members
user me View current logged-in user information
user search Search user information

project — Projects

Command Description
project search Search projects

auth — Authentication

Command Description
auth login Log in (browser or --device-code)
auth logout Log out
auth status View login status

config — Configuration

Command Description
config init Initialize configuration
config show Show current configuration
config set Set a configuration value
config get Get a configuration value
config profile create|list|use|current|delete Manage configuration profiles

Other Commands

Command Description
inspect [command] Inspect command parameters
completion bash|zsh|fish Generate shell completion script
completion install Auto-install shell completion

Common Examples

To-dos

# This week's to-dos
meegle mywork todo --action this_week --page-num 1

# Completed items
meegle mywork todo --action done --page-num 1

# Overdue items
meegle mywork todo --action overdue --page-num 1

Querying Work Items

# View work item details
meegle workitem get --work-item-id 12345

# View workflow node details
meegle workflow get-node --work-item-id 12345 --need-sub-task

Batch Reading Work Items

workitem +batch-get fans out to workitem get for each ID and aggregates the results into one response. Shared flags (e.g. --project-key) apply to every per-item call. The + prefix marks it as a scenario/sugar command with no 1:1 MCP tool behind it — the CLI composes multiple get calls client-side.

# Comma-separated IDs in one invocation
meegle workitem +batch-get --project-key PROJ --work-item-ids "12345,12346,12347"

# Read IDs from a file (one per line; lines starting with '#' are comments)
meegle workitem +batch-get --project-key PROJ --ids-file ./ids.txt

# Stream one JSON row per item; summary row is emitted last
meegle workitem +batch-get --project-key PROJ --work-item-ids "12345,12346" -o ndjson

Response envelope (JSON):

{
  "summary": { "total": 3, "succeeded": 2, "failed": 1 },
  "results": [
    { "work_item_id": 12345, "data": { /* ... */ } },
    { "work_item_id": 12346, "data": { /* ... */ } },
    { "work_item_id": 12347, "error": { "code": "...", "message": "..." } }
  ]
}

Constraints: up to 200 IDs per invocation, 3 concurrent workers (fixed). Partial failures do not abort the batch — check summary.failed or the per-item error field. A 401 from the server aborts the whole run.

Creating Work Items

# Pass fields[] via --params (JSON)
meegle workitem create --project-key PROJ --work-item-type story \
  --params '{"fields":[
    {"field_key":"name","field_value":"Optimize login flow"},
    {"field_key":"priority","field_value":"P1"}
  ]}'

# Complex field values (arrays, nested JSON) also go through --params
meegle workitem create --project-key PROJ --work-item-type story \
  --params '{"fields":[
    {"field_key":"name","field_value":"Scheduled task"},
    {"field_key":"schedule","field_value":[1722182400000,1722355199999]}
  ]}'

Updating Fields

# Update work item name
meegle workitem update --work-item-id 12345 \
  --params '{"fields":[{"field_key":"name","field_value":"New title"}]}'

# Update multiple fields at once
meegle workitem update --work-item-id 12345 \
  --params '{"fields":[
    {"field_key":"name","field_value":"New title"},
    {"field_key":"priority","field_value":"P0"}
  ]}'

MQL Search

# Query P0 stories in a project
meegle workitem query --project-key PROJ \
  --mql "SELECT \`name\`, \`priority\` FROM \`ProjectName\`.\`Story\` WHERE \`priority\` = 'P0'"

Viewing Schedules

# View team member schedules
meegle workhour list-schedule --project-key PROJ \
  --start-time 2026-03-01 --end-time 2026-03-31 \
  --user-keys "Alice,Bob,Charlie"

Searching Users

meegle user search --user-keys "Alice,Bob" --project-key PROJ

Parameter Passing

Basic Flags

Each command takes parameters via --flag-name:

meegle workitem get --work-item-id 12345 --project-key PROJ

Writing fields[] (Write Commands)

workitem create, workitem update, workflow update-node, and subtask update expect the fields[] payload. Pass it through --params:

--params '{"fields":[
  {"field_key":"name","field_value":"Title"},
  {"field_key":"priority","field_value":"P1"}
]}'

--set key=value (Generic)

--set is an alternate syntax for writing top-level parameters — --set key=value is equivalent to typing --key value. Useful when scripting with a uniform key=value form, or for writing nested top-level params via dot-path. Values are auto-typed (int / float / bool / string).

# These two are equivalent:
meegle mywork todo --action this_week --page-num 1
meegle mywork todo --set action=this_week --set page_num=1

# Dot-path builds nested maps (rarely used in Meegle, but supported):
--set extra.flag=true          # becomes {"extra":{"flag":true}}

--set only writes top-level parameters. To write a work item's fields[], use --params '{"fields":[...]}' (see below).

--params JSON (Fallback)

All commands support --params to pass a full JSON parameter body:

meegle workitem create --project-key PROJ --work-item-type story \
  --params '{"fields":[{"field_key":"name","field_value":"Title"}]}'

Priority

When --set, --params, and regular flags are used together:

  1. Regular CLI flags beat --params / --set for the same top-level key
  2. --set overrides the same top-level key from --params

Array Parameters

Separate multiple values with commas:

--user-keys "Alice,Bob,Charlie"
--field-keys "name,status,priority"

Boolean Parameters

Add the flag to set true; omit it for false:

meegle workflow get-node --work-item-id 12345 --need-sub-task

Global Flags

Flag Short Description
--format -o Output format: json (default), table, ndjson, raw
--select Field projection with dot paths
--set Set nested parameters (repeatable)
--params -P Full JSON parameter body
--dry-run Render request without executing
--verbose -v Verbose output
--profile Use a specific configuration profile

Advanced Usage

Output Formats

# JSON (default)
meegle workitem get --work-item-id 12345

# NDJSON (suitable for piping)
meegle mywork todo --action this_week --page-num 1 -o ndjson

# Table
meegle mywork todo --action this_week --page-num 1 -o table

Field Projection with --select

--select projects fields using . notation. A segment after an array broadcasts the remaining path over every record of the array and collects the results while preserving the enclosing structure.

Expression Response Projection
list {"list":[{"a":1}], "total":1} {"list":[{"a":1}]}
list.a {"list":[{"a":1,"b":2},{"a":3,"b":4}]} {"list":[{"a":1},{"a":3}]}
list.a,list.b same as above {"list":[{"a":1,"b":2},{"a":3,"b":4}]} (merged per index)
list.work_item_info.work_item_name {"list":[{"work_item_info":{"work_item_name":"x"}}]} {"list":[{"work_item_info":{"work_item_name":"x"}}]}
nodes.0 {"nodes":[{"id":"a"},{"id":"b"}]} {"nodes":{"0":{"id":"a"}}} (numeric = index)
# Top-level selection
meegle workitem get --work-item-id 12345 --select "id,name,status"

# Broadcast across arrays — extract fields from nested records
meegle mywork todo --action done --page-num 1 \
  --select "list.work_item_info.work_item_name,list.state_info.end_state_key_name"

# Mix top-level metadata with broadcast — total is retained alongside projected list items
meegle mywork todo --action done --page-num 1 \
  --select "total,list.work_item_info.work_item_name"

Metadata preservation

The default render preserves the full response shape across every --format: list endpoints return {"list":[...], "total":N, "pagination":{...}} verbatim — you see total / pagination even when you do not project them. Drill into records explicitly via --select (and the broadcast syntax above). Under --format table and --format ndjson, a single-key wrapper like {"list":[...]} (no sibling metadata) is still peeled into rows — the peel is loss-less.

Dry Run

For commands with side effects, preview the rendered request with --dry-run before executing:

meegle workitem create --project-key PROJ --work-item-type story \
  --params '{"fields":[{"field_key":"name","field_value":"Test"}]}' --dry-run

Command Introspection

Use inspect to view full parameter information for any command:

# List all commands
meegle inspect

# View parameters for a specific command
meegle inspect workitem.create

Authentication

Browser Login (Default)

meegle auth login

Automatically opens the browser for OAuth authorization. If the browser doesn't open, the terminal displays the authorization URL for manual copying.

Device Code Login (No Browser)

meegle auth login --device-code

The terminal displays a QR code and authorization code. Scan with your phone to authorize. Ideal for SSH remote servers and other headless environments.

Other Auth Commands

# Check login status
meegle auth status

# Log out
meegle auth logout

Configuration

Config File

Configuration is stored in ~/.meegle/config.json:

# Initialize config
meegle config init

# View current config
meegle config show

# Set a config value
meegle config set host project.feishu.cn

# Get a config value
meegle config get host

Main config options:

Field Description Examples
host Site domain project.feishu.cn, meegle.com
user_access_token User access token; use ${VAR} to read from an environment variable ${CI_MEEGLE_TOKEN}
access_token_header Custom HTTP header name that carries the token; empty falls back to default Authorization: Bearer <token> x-meegle-auth
user_agent Caller suffix appended to the default User-Agent (form: meegle-cli/<ver> <user_agent>); supports ${VAR} template; overridden by the MEEGLE_USER_AGENT env var my-service/1.0

Sandbox / CI: Direct Environment-Variable Injection

Two well-known environment variables are read directly at CLI startup and override the matching profile fields without requiring any config set:

export MEEGLE_HOST=project.feishu.cn
export MEEGLE_USER_ACCESS_TOKEN=<your-user-token>
export MEEGLE_USER_AGENT=ci-runner  # optional; appended to User-Agent, highest priority over config.user_agent
meegle workitem get-brief --work_item_id 123

Either variable may be set independently. When this path is taken, the CLI bypasses the keychain and does not attempt to refresh on 401 — the caller is responsible for rotating the env value.

Custom Auth Header

By default the token is sent via the standard Authorization: Bearer <token> header. If the backend requires a different header (and rejects requests that carry Authorization), opt in with access_token_header:

meegle config set access_token_header x-meegle-auth

Or override at runtime via env var:

export MEEGLE_ACCESS_TOKEN_HEADER=x-meegle-auth

When enabled the CLI sends <header>: <token> with the raw token (no Bearer prefix) and omits Authorization entirely — suitable for backends that reject requests carrying both headers.

Environment Variable Templates

If your runtime exposes a variable with a name other than MEEGLE_*, bind it through config.json using a ${VAR} placeholder. The placeholder is resolved against the process environment at runtime. This keeps secrets out of config.json while adapting to whatever variable name your runtime (Docker, Kubernetes, CI system) already injects.

{
  "current": "prod",
  "profiles": {
    "prod":    { "host": "project.feishu.cn", "user_access_token": "${PROD_CI_TOKEN}" },
    "staging": { "host": "staging.feishu.cn", "user_access_token": "${STAGING_CI_TOKEN}" }
  }
}

Rules:

  • Only whole-string placeholders are recognized. "${X}" is expanded; "Bearer ${X}" is treated as a literal.
  • When a referenced variable is unset or empty, the CLI fails fast and reports the field path and variable name.
  • When user_access_token is configured, it takes precedence over any token stored locally by meegle auth login. Because this mode has no refresh path, rotate the environment value yourself when the server returns 401.

Multi-Environment Profiles

Manage multiple environment configurations (different sites, different accounts). Each profile stores its own host and auth credentials independently.

# Create a new profile (interactive host selection + login)
meegle config profile create staging

# List all profiles
meegle config profile list

# Switch default profile
meegle config profile use staging

# View current profile
meegle config profile current

# Temporarily use another profile (without changing default)
meegle mywork todo --action this_week --page-num 1 --profile staging

# Delete a profile
meegle config profile delete staging

FAQ

Empty Command List

The CLI fetches available commands from the server at startup. If the network is unreachable or you're not logged in, dynamic commands won't be registered. Make sure you're logged in first:

meegle auth login

The command list is cached automatically and refreshed silently in the background when expired.

Security & Risk Warnings

This tool is designed to be called by AI Agents to automate Meegle operations, which carries inherent risks — model hallucinations, unpredictable execution, and prompt injection. Once you authorize Meegle permissions, the Agent will act under your user identity within the granted scope, and may perform high-impact actions (field updates, status transitions, work item creation) on your behalf. Use with care.

Recommended safeguards:

  • Preview side-effectful commands with --dry-run before running them
  • Use a dedicated profile (meegle config profile create) for Agent-driven sessions so you can audit and revoke independently
  • For CI / shared environments, prefer short-lived env-var token injection (MEEGLE_USER_ACCESS_TOKEN) and rotate on 401 — do not relax default security settings

By using this tool you are deemed to voluntarily assume all related responsibilities.

Star History

Star History Chart

Contributing

Community contributions are welcome. For bugs and feature requests, open an Issue or Pull Request. For major changes, please start a discussion via an Issue first.

License

This project is licensed under the MIT License.

When running, it calls Lark/Feishu Open Platform APIs. To use these APIs, you must comply with the following agreements and privacy policies:

About

Command-line tool for Meegle (Lark Project). Manage work items, schedules, and data from your terminal — no browser needed.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages