Primary Purpose:
DingTalk Workspace CLI (dws) is a command-line tool designed to manage DingTalk workspace operations efficiently. It serves as an interface for developers and AI agents, enabling seamless interaction with DingTalk's ecosystem.
Key Features:
For Humans: The tool offers intuitive commands such as --help for usage guidance, --dry-run to preview actions without execution, and flexible output formats (-f table/json/raw) for data presentation.
For AI Agents: It provides structured JSON responses and built-in Agent Skills, facilitating integration with AI tools like Claude Code and Cursor.
For Enterprise Admins: The tool features a zero-trust architecture with OAuth device-flow authentication, domain allowlisting, and least-privilege scoping, ensuring robust security.
Audience & Benefit:
Ideal for developers seeking efficient workspace management, AI agents requiring direct interaction, and enterprise admins prioritizing secure access. Benefits include enhanced productivity through command-line efficiency, secure access mechanisms, and seamless integration with AI tools, all underpinned by a zero-trust security model.
This tool can be installed via winget, offering a straightforward setup process for users.
README
DingTalk Workspace CLI (dws)
dws — DingTalk Workspace on the command line, built for humans and AI agents.
> [!IMPORTANT]
> Co-creation Phase: This project accesses DingTalk enterprise data and requires enterprise admin authorization. Join the DingTalk DWS co-creation group for support and updates. See Getting Started below.
>
>
For humans — --help for usage, --dry-run to preview requests, -f table/json/raw for output formats.
For AI agents — structured JSON responses + built-in Agent Skills, ready out of the box.
For enterprise admins — zero-trust architecture: OAuth device-flow auth + domain allowlisting + least-privilege scoping. Not a single byte can bypass authentication and audit.
Installation
macOS / Linux:
curl -fsSL https://raw.githubusercontent.com/DingTalk-Real-AI/dingtalk-workspace-cli/main/scripts/install.sh | sh
The installer ships skills in one of two layouts. CLI commands (dws aitable ..., dws calendar ...) are identical in both modes — only the agent-side skill layout differs.
> 🧪 multi is currently EXPERIMENTAL / preview. 18 product-scoped skills all pass the dispatch verifier, but interface, naming and cross-skill references may change in future releases. For production / shared environments, prefer mono. File issues if you hit problems.
> macOS users: If you see "cannot be opened because Apple cannot check it for malicious software", run:
> bash > xattr -d com.apple.quarantine /path/to/dws >
Build from source:
git clone https://github.com/DingTalk-Real-AI/dingtalk-workspace-cli.git
cd dingtalk-workspace-cli
go build -o dws ./cmd # build to current directory
cp dws ~/.local/bin/ # install to PATH
> Requires Go 1.25+. Use make package to cross-compile for all platforms (macOS / Linux / Windows x amd64 / arm64).
China mirror
For users in mainland China, the following channels avoid GitHub network issues. By default (without setting these environment variables) the installer pulls from GitHub.
DWS_GITEE_REPO=DingTalk-Real-AI/dingtalk-workspace-cli curl -fsSL https://gitee.com/DingTalk-Real-AI/dingtalk-workspace-cli/raw/main/scripts/install.sh | sh
> With DWS_GITEE_REPO set, the installer resolves the latest version and every release asset (binary, checksums, skills) from the Gitee API instead of GitHub. If it is unset, installation defaults to GitHub.
> npmmirror automatically syncs public packages from the public npm registry, so this works directly in China.
3. Skills only (Gitee mirror):
DWS_GITEE_REPO=DingTalk-Real-AI/dingtalk-workspace-cli curl -fsSL https://gitee.com/DingTalk-Real-AI/dingtalk-workspace-cli/raw/main/scripts/install-skills.sh | sh
> With DWS_GITEE_REPO set, install-skills.sh resolves the version and skills package from Gitee; it also auto-falls back to the Gitee mirror when GitHub is unreachable.
Upgrade
> Requires v1.0.7 or later. For earlier versions, please re-run the install script to upgrade.
dws has built-in self-upgrade capability. Updates are pulled directly from GitHub Releases with SHA256 integrity verification and automatic backup.
dws upgrade # interactive upgrade to latest version
dws upgrade --check # check for new versions without installing
dws upgrade --list # list all available versions
dws upgrade --version v1.0.7 # upgrade to a specific version
dws upgrade --rollback # rollback to the previous version
dws upgrade -y # skip confirmation prompt
How it works
The upgrade process follows a two-phase atomic flow to ensure consistency:
Prepare — downloads the platform-specific binary and skill packages to a temporary directory, verifies SHA256 checksums, and extracts/validates all files. If any step fails, the upgrade aborts without modifying the existing installation.
Apply — only after all preparations succeed, the binary is replaced and skill packages are installed to all detected agent directories (~/.agents/skills/dws, ~/.claude/skills/dws, ~/.cursor/skills/dws, etc.).
A backup of the current version is automatically created before each upgrade. Use dws upgrade --rollback to restore the previous version if needed.
Flag
Description
--check
Check for updates without installing
--list
List all available versions with changelogs
--version
Upgrade to a specific version (e.g. v1.0.7)
--rollback
Rollback to the previous backed-up version
--force
Force reinstall even if already on the latest version
Credentials are securely persisted after first login (Keychain). Subsequent runs auto-refresh tokens.
Migrate auth between Linux sandboxes
Copying only ~/.dws/app.json does not carry the refresh token; access tokens expire after ~2 hours. Use the official export/import flow:
# Sandbox A (already logged in)
dws auth export -o /tmp/dws-auth.tar.gz
# Or for copy/paste: dws auth export --base64 -o /tmp/dws-auth.b64
# Sandbox B
dws auth import -i /tmp/dws-auth.tar.gz
# Or: dws auth import -i /tmp/dws-auth.b64 --base64
dws auth status # confirm "Refresh Token: valid"
The bundle includes the encrypted keychain under ~/.local/share/dws-cli (with auth-token.enc and dek) plus required ~/.dws config files.
Quick Start
dws contact user search --query "engineering" # search contacts
dws calendar event list # list today's calendar events
dws doc search --query "quarterly" # search DingTalk Docs
dws minutes list mine # list AI meeting notes I created
dws drive list # list DingTalk drive files
dws todo task create --title "Quarterly report" --executors "" # create a todo (replace )
dws todo task list --dry-run # preview without executing
> Full command list: docs/command-index.md — all commands with descriptions and when-to-use guidance.
Using with Agents
dws is designed as an AI-native CLI. Complete Installation and Getting Started first, then configure your agent:
Agent Invocation Patterns
# Use --yes to skip confirmation prompts (required for agents)
dws todo task create --title "Review PR" --executors "" --yes
# Use --dry-run to preview operations (safe execution)
dws contact user search --query "engineering" --dry-run
# Use --jq to extract precisely (save tokens)
dws contact user get-self --jq '.result[0].orgEmployeeModel | {name: .orgUserName, dept: .depts[0].deptName, userId}'
Schema Discovery
Agents don't need pre-built knowledge of every command. Use dws schema to dynamically discover capabilities:
skills/multi/ — per-product skills (dingtalk-aitable/, dingtalk-calendar/, dingtalk-chat/, ... 20 products in total), each with its own SKILL.md. 🧪 EXPERIMENTAL / preview — see banner in each multi SKILL.md for caveats.
After installing, AI tools like Claude Code / Cursor can operate DingTalk directly through natural language:
# Install skills into current project (defaults to mono)
curl -fsSL https://raw.githubusercontent.com/DingTalk-Real-AI/dingtalk-workspace-cli/main/scripts/install-skills.sh | sh
> install.sh installs to $HOME/.agents/skills/dws (global); install-skills.sh installs to ./.agents/skills/dws (current project).
>
> China users: prefix DWS_GITEE_REPO to use the Gitee mirror — see China mirror.
Switching or re-installing with dws skill setup:
# Interactive: prompts for mode + target agents
dws skill setup
# Install mono skill to every detected agent home (claude / cursor / codex / opencode / qoder)
dws skill setup --mode mono --target all --yes
# Install multi skills to a single agent home
dws skill setup --mode multi --target cursor --yes
# Point at a local source tree (e.g. a fork or work-in-progress)
DWS_SKILL_SOURCE=/path/to/skills dws skill setup --mode multi
Flag
Values
Description
--mode
mono | multi
Skill layout; defaults to interactive prompt
--target
all | claude | cursor | codex | opencode | qoder
Where to install; all covers every detected agent home
--source
path
Local source directory (overrides bundled skills)
--yes
—
Skip confirmation prompts
Env vars: DWS_SKILL_MODE=mono|multi (also honored by install.sh / install.ps1), DWS_SKILL_SOURCE=.
Per-product command reference (aitable, chat, calendar, etc.)
Intent guide
skills/mono/references/intent-guide.md
Disambiguation for confusing scenarios (e.g. report vs todo)
Global reference
skills/mono/references/global-reference.md
Auth, output formats, global flags
Error codes
skills/mono/references/error-codes.md
Error codes + debugging workflows
Recovery guide
skills/mono/references/recovery-guide.md
RECOVERY_EVENT_ID handling
Ready-made scripts
skills/mono/scripts/*.py
13 batch operation scripts (see below)
Ready-made scripts — 13 Python scripts for common multi-step workflows
Script
Description
calendar_schedule_meeting.py
Create event + add participants + find & book available meeting room
calendar_free_slot_finder.py
Find common free slots across multiple people, recommend best meeting time
calendar_today_agenda.py
View today/tomorrow/this week's schedule
import_records.py
Batch import records from CSV/JSON into AITable
bulk_add_fields.py
Batch add fields to an AITable data table
upload_attachment.py
Upload attachment to AITable attachment field
todo_batch_create.py
Batch create todos from JSON (with priority, due date, executors)
todo_daily_summary.py
Summarize today/this week's incomplete todos
todo_overdue_check.py
Scan overdue todos and output overdue list
contact_dept_members.py
Search department by name and list all members
attendance_my_record.py
View my attendance records for today/this week/specific date
attendance_team_shift.py
Query team shift schedules and attendance statistics
report_inbox_today.py
View today's received reports with details
ISV Integration: Author your own Agent Skills and orchestrate them with dws skills for cross-product workflows: ISV Skill → dws Skill → DingTalk Open Platform API (enforced auth + full audit).
Features
Raw API Access — call any DingTalk OpenAPI directly
dws api lets you call any DingTalk OpenAPI without an SDK. Tokens are automatically acquired and refreshed.
> Prerequisite: Must login with your own app credentials (see Custom App mode). Encrypted tokens from MCP default-credential login are not supported for raw API calls.
# Login (first time only)
dws auth login --client-id --client-secret
# === api.dingtalk.com ===
# List all enterprise apps
dws api GET /v1.0/microApp/allApps
# Search users (POST + JSON body)
dws api POST /v1.0/contact/users/search \
--data '{"queryWord":"engineering","offset":0,"size":10}'
# === oapi.dingtalk.com ===
# Get user details (use --base-url to specify domain)
dws api POST /topapi/v2/user/get \
--base-url https://oapi.dingtalk.com \
--data '{"userid":""}'
# Or use the full URL directly
dws api POST https://oapi.dingtalk.com/topapi/v2/user/get \
--data '{"userid":""}'
# === General ===
dws api GET /v1.0/microApp/allApps --page-all # auto-paginate
dws api GET /v1.0/microApp/allApps --dry-run # preview request
dws api GET /v1.0/microApp/allApps --jq '.agentId' # jq filtering
Feature
Details
Dual-form auto-detection
Automatically selects api.dingtalk.com (header auth) or oapi.dingtalk.com (query-param auth) based on URL
Automatic token management
App-level accessToken is fetched on first call, cached while valid, auto-refreshed on expiry
Domain allowlist
Only api.dingtalk.com and oapi.dingtalk.com permitted — prevents token leakage
Auto-pagination
--page-all iterates all pages. --page-limit caps the maximum (default 10, set to 0 for unlimited, hard cap at 500 to prevent infinite loops)
Smart Input Correction — auto-corrects common AI model parameter mistakes
Built-in pipeline engine that normalizes flag names, splits sticky arguments, and fuzzy-matches typos:
# Naming convention auto-conversion (camelCase / snake_case / UPPER -> kebab-case)
dws aitable record query --baseId BASE_ID --tableId TABLE_ID # auto-corrected to --base-id --table-id
# Sticky argument splitting
dws contact user search --query "engineering" --timeout30 # auto-split to --timeout 30
# Fuzzy flag name matching
dws aitable record query --base-id BASE_ID --tabel-id TABLE_ID # --tabel-id -> --table-id
# Value normalization (boolean / number / date / enum)
# "yes" -> true, "1,000" -> 1000, "2024/03/29" -> "2024-03-29", "ACTIVE" -> "active"
Agent Output
dws Auto-Corrects To
--userId
--user-id
--limit100
--limit 100
--tabel-id
--table-id
--USER-ID
--user-id
--user_name
--user-name
jq Filtering & Field Selection — fine-grained output control to reduce token consumption
# Built-in jq expressions
dws aitable record query --base-id BASE_ID --table-id TABLE_ID --jq '.invocation.params'
dws schema --jq '.products[] | {id, tools: (.tools | length)}'
# Return only specific fields
dws aitable record query --base-id BASE_ID --table-id TABLE_ID --fields invocation,response
Schema Introspection — query parameter schemas before making calls
> Note: @ is treated as the @ file-injection prefix only when the next character is an ASCII path-shaped character (A-Z / a-z / 0-9 / . / / / ~ / _ / -), or @- for stdin. Chat-bot payloads like --text "@所有人 周报" or --text "@张三 看一下" pass through unchanged, so literal mentions reach the API as-is.
DingTalk bot — connect a robot to your local AI
dws dev connect bridges a DingTalk robot to a local AI CLI (Claude Code / Codex / opencode / Qoder / Gemini, or any tool via --agent-cmd): @-mention the bot in a chat and it answers using your local agent, keeping per-conversation multi-turn memory.
dws dev connect --channel auto --robot-client-id --robot-client-secret
In-chat session commands (send the bare command as the whole message — no agent turn, no tokens):
Command
Effect
/new (aliases /start, /reset)
Start a fresh session; the previous one is left intact (resumable where the agent supports it)
/clear
Wipe the current session — disposed through the agent's real session op (opencode issues DELETE /session/:id); channels whose agent exposes no delete primitive fall back to a reset
See docs/robot-quickstart.md for the full 4-step walkthrough (install → create robot → connect → add to a group).
Key Services
Service
Command
Commands
Subcommands
Description
Contact
contact
15
userdeptlabelrelation
Search users by name / mobile / job-number, batch query, departments, labels & roles, person relations, roster profile & dismissions, current user
Knowledge base management: spaces (create / get / list / search / delete), members (add / list / update / remove), node tree (create / delete / list / search / move / copy / transfer), docs & files
DevDoc
devdoc
2
articleerror
Search the DingTalk Open Platform documentation and diagnose API errors
AI Search
aisearch
3
person
Enterprise people search by name / department / position / duty / supervisor / subordinate / phone / job-number (single command, multi-dimension filter)
Live
live
1
stream
DingTalk live streaming: list my lives
Raw API
api
1
—
Call any DingTalk OpenAPI directly (api / oapi dual-form), with automatic app-level token management
> 466 commands across 18 products (after the dws-wukong alignment in 1.0.43). Full listing with descriptions and usage scenarios: docs/command-index.md. Run dws --help for the top-level tree, or dws --help for subcommands.
> Note on chat bot: bot capabilities (send-by-bot / recall-by-bot / add-bot / send-by-webhook / bot search) are merged into the relevant chat subtrees (e.g. dws chat message send-by-bot, dws chat group members add-bot) so the agent-facing command surface stays flat and discoverable. There is no longer a separate top-level bot product.
Coming soon
conference (video meetings)
Multi-skill mode (experimental) — per-product skills under skills/multi/; opt in via dws skill setup --mode multi
Security by Design
dws treats security as a first-class architectural concern, not an afterthought. Credentials never touch disk, tokens never leave trusted domains, permissions never exceed grants, operations never escape audit — every API call must pass through DingTalk Open Platform's authentication and audit chain, no exceptions.
For Developers
Mechanism
Details
Encrypted token storage
PBKDF2 + AES-256-GCM encryption, keyed by device physical MAC address; cross-platform Keychain/DPAPI integration provides additional protection — tokens cannot be decrypted on another machine
Input security
Path traversal protection (symlink resolution + working directory containment), CRLF injection blocking, Unicode visual spoofing filtering — prevents AI Agents from being tricked by malicious instructions
Domain allowlist
DWS_TRUSTED_DOMAINS defaults to *.dingtalk.com; bearer tokens are never sent to non-allowlisted domains
HTTPS enforced
All requests require TLS; HTTP only permitted for loopback during development
Dry-run preview
--dry-run shows call parameters without executing, preventing accidental mutations
Zero credential persistence
Client ID / Secret used in memory only — never written to config files or logs
For Enterprise Admins
Mechanism
Details
OAuth device-flow auth
Users must authenticate through an admin-authorized DingTalk application
Least-privilege scoping
CLI can only invoke APIs granted to the application — no privilege escalation
Allowlist gating
Admin confirmation required during co-creation phase; self-service approval planned
Full-chain audit
Every data read/write passes through the DingTalk Open Platform API — enterprise admins can trace complete call logs in real time; no anomalous operation can hide
For ISVs
Mechanism
Details
Tenant data isolation
Operates under authorized app identity; cross-tenant access is impossible
Skill sandbox
Agent Skills are Markdown documents (SKILL.md) — prompt descriptions only, no arbitrary code execution
Zero blind spots
Every API call during ISV–dws skill orchestration is forced through DingTalk Open Platform authentication — full call chain is traceable with no bypass path