Claude
Skills
Sign in
Back

dingtalk-workspace-cli

Included with Lifetime
$97 forever

Use DingTalk Workspace CLI (dws) to manage DingTalk contacts, calendar, todos, attendance, approvals, and more from the command line or AI agent workflows.

AI Agents

What this skill does


# DingTalk Workspace CLI (dws)

> Skill by [ara.so](https://ara.so) — Daily 2026 Skills collection.

`dws` is an officially open-sourced cross-platform CLI tool from DingTalk that unifies DingTalk's full product suite into a single binary. It is designed for both human users and AI agent workflows. Every response is structured JSON, and built-in Agent Skills let LLMs use DingTalk out of the box.

---

## Installation

### One-liner (recommended)

**macOS / Linux:**
```bash
curl -fsSL https://raw.githubusercontent.com/DingTalk-Real-AI/dingtalk-workspace-cli/main/scripts/install.sh | sh
```

**Windows (PowerShell):**
```powershell
irm https://raw.githubusercontent.com/DingTalk-Real-AI/dingtalk-workspace-cli/main/scripts/install.ps1 | iex
```

The installer:
- Auto-detects OS and architecture
- Downloads a pre-compiled binary to `~/.local/bin`
- Installs Agent Skills to `~/.agents/skills/dws`

Add to PATH if needed:
```bash
export PATH="$HOME/.local/bin:$PATH"
# Add to ~/.bashrc or ~/.zshrc to persist
```

### Build from source

```bash
git clone https://github.com/DingTalk-Real-AI/dingtalk-workspace-cli.git
cd dingtalk-workspace-cli
make build
./dws version
```

---

## Prerequisites & Setup

### 1. Create a DingTalk app

Go to [DingTalk Open Platform](https://open-dev.dingtalk.com/fe/app?hash=%23%2Fcorp%2Fapp#/corp/app), create an enterprise internal app, and note the **Client ID (AppKey)** and **Client Secret (AppSecret)**.

### 2. Configure redirect URL

In the app's **Security Settings**, add `http://127.0.0.1` as a redirect URL.

### 3. Publish the app

Go to **App Release → Version Management** and publish the app so it is active.

### 4. Whitelist (beta)

During the co-creation phase, join the DingTalk DWS group and provide your Client ID and enterprise admin confirmation to be whitelisted.

### 5. Authenticate

```bash
# Via CLI flags
dws auth login --client-id $DWS_CLIENT_ID --client-secret $DWS_CLIENT_SECRET

# Or set env vars first, then login
export DWS_CLIENT_ID=your-app-key
export DWS_CLIENT_SECRET=your-app-secret
dws auth login
```

Tokens are stored encrypted with **PBKDF2 (600,000 iterations) + AES-256-GCM**, keyed to your device MAC address.

---

## Environment Variables

| Variable | Purpose |
|---|---|
| `DWS_CLIENT_ID` | OAuth Client ID (DingTalk AppKey) |
| `DWS_CLIENT_SECRET` | OAuth Client Secret (DingTalk AppSecret) |
| `DWS_CONFIG_DIR` | Override default config directory |
| `DWS_SERVERS_URL` | Custom server registry endpoint |
| `DWS_TRUSTED_DOMAINS` | Comma-separated domains for bearer token (default: `*.dingtalk.com`) |
| `DWS_ALLOW_HTTP_ENDPOINTS` | Set to `1` to allow HTTP on loopback (dev only) |

---

## Key Commands

### Authentication

```bash
dws auth login                        # Authenticate via OAuth device flow
dws auth logout                       # Remove stored credentials
dws auth status                       # Show current auth status
```

### Contacts

```bash
# Search users
dws contact user search --keyword "Alice"

# List departments
dws contact department list

# Get user details
dws contact user get --user-id <userId>
```

### Calendar

```bash
# List events
dws calendar event list

# Create an event
dws calendar event create \
  --title "Q2 Planning" \
  --start "2026-04-01T10:00:00+08:00" \
  --end "2026-04-01T11:00:00+08:00" \
  --attendees "<userId1>,<userId2>"

# Check room availability
dws calendar room list
```

### Todo

```bash
# List tasks
dws todo task list

# Create a task
dws todo task create \
  --title "Prepare quarterly report" \
  --executors "<userId>"

# Complete a task
dws todo task complete --task-id <taskId>
```

### Chat

```bash
# List groups
dws chat group list

# Send a message via webhook
dws chat webhook send \
  --url $DINGTALK_WEBHOOK_URL \
  --content "Deployment succeeded ✅"

# Send robot message
dws chat robot send \
  --group-id <groupId> \
  --content "Hello from dws"
```

### Attendance

```bash
# Get attendance records
dws attendance record list --user-id <userId> --date "2026-03-01"

# List shift schedules
dws attendance shift list
```

### Approval

```bash
# List approval templates
dws approval template list

# Submit an approval instance
dws approval instance create \
  --process-code <processCode> \
  --form-values '{"key":"value"}'

# Query approval instances
dws approval instance list --status RUNNING
```

### DING Messages

```bash
# Send a DING message
dws ding send --receiver-ids "<userId>" --content "Urgent: please review PR"

# Recall a DING message
dws ding recall --ding-id <dingId>
```

### AI Table (aitable)

```bash
# List tables
dws aitable table list --space-id <spaceId>

# Query records
dws aitable record list --table-id <tableId>
```

### Developer Docs

```bash
# Search DingTalk open platform docs
dws devdoc search --keyword "webhook"
```

### Workbench

```bash
# List workbench apps
dws workbench app list
```

---

## Output Formats

All commands support `-f` / `--format`:

```bash
# Human-readable table (default)
dws contact user search --keyword "Alice" -f table

# Structured JSON (for agents and piping)
dws contact user search --keyword "Alice" -f json

# Raw API response
dws contact user search --keyword "Alice" -f raw
```

Save output to a file:
```bash
dws contact user search --keyword "Alice" -f json -o results.json
```

---

## Dry Run

Preview the MCP tool call without executing it:

```bash
dws todo task list --dry-run
dws calendar event create --title "Test" --dry-run
```

---

## Shell Completion

```bash
# Bash
dws completion bash > /etc/bash_completion.d/dws

# Zsh
dws completion zsh > "${fpath[1]}/_dws"

# Fish
dws completion fish > ~/.config/fish/completions/dws.fish
```

---

## Exit Codes

| Code | Category | Meaning |
|---|---|---|
| 0 | Success | Command completed successfully |
| 1 | API | MCP tool call or upstream API failure |
| 2 | Auth | Authentication or authorization failure |
| 3 | Validation | Bad input flags or schema mismatch |
| 4 | Discovery | Service discovery or cache failure |
| 5 | Internal | Unexpected internal error |

When using `-f json`, errors include structured fields: `category`, `reason`, `hint`, `actions`.

---

## Common Patterns

### Scripting: find a user then create a todo assigned to them

```bash
#!/bin/bash
set -euo pipefail

# Search for user and extract userId
USER_ID=$(dws contact user search --keyword "Alice" -f json | \
  jq -r '.data[0].userId')

echo "Found user: $USER_ID"

# Create a todo assigned to that user
dws todo task create \
  --title "Review design doc" \
  --executors "$USER_ID" \
  -f json
```

### Scripting: send a daily standup reminder

```bash
#!/bin/bash
dws ding send \
  --receiver-ids "$TEAM_USER_IDS" \
  --content "🕘 Daily standup in 5 minutes — please join!" \
  -f json
```

### CI/CD: post build status to a DingTalk group

```bash
#!/bin/bash
STATUS=${1:-"unknown"}
EMOJI=$([[ "$STATUS" == "success" ]] && echo "✅" || echo "❌")

dws chat webhook send \
  --url "$DINGTALK_WEBHOOK_URL" \
  --content "$EMOJI Build #$BUILD_NUMBER $STATUS — $BUILD_URL"
```

### Using dws in a Go project

```go
package main

import (
    "os/exec"
    "encoding/json"
    "fmt"
)

type SearchResult struct {
    Data []struct {
        UserID string `json:"userId"`
        Name   string `json:"name"`
    } `json:"data"`
}

func searchDingTalkUser(keyword string) (*SearchResult, error) {
    cmd := exec.Command("dws", "contact", "user", "search",
        "--keyword", keyword,
        "-f", "json",
    )
    out, err := cmd.Output()
    if err != nil {
        return nil, fmt.Errorf("dws error: %w", err)
    }
    var result SearchResult
    if err := json.Unmarshal(out, &result); err != nil {
        return nil, err
    }
    return &result, nil
}

func main() {
    result, err := searchDingTalkUser("Alice")
    if err != nil {
        panic(err)
    }
    for _, u := range result.Data {
        fmt.Printf("User: %s (%s)\n", u.Name, u.UserID)
    }
}
```

---

## AI Agent Integration

Related in AI Agents