Atlas / Skills / wecomteam / wecom-cli

wecom-cliBLOCK

skills/wecomteam/wecomcli-create-meeting

企业微信开放平台命令行工具 — 让人类和 AI Agent 都能在终端中操作企业微信

Verdict
BLOCK
Grade
D
Trust score
69 /100
Version
1.0.0
Hosts
1 documented
License
MIT
Stars
3,231
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

[](https://opensource.org/licenses/MIT) [](https://www.rust-lang.org/)

💬 扫码加入企业微信交流群:

企业微信命令行工具,覆盖消息、邮件、文档、待办、日程、会议、微盘、通讯录等业务功能。支持机器人主动通知、新建与读取文档、文档搜索、新建与管理日程、预约与获取会议信息、新建与跟进待办、上传与获取微盘文件、发送与获取邮件、获取通讯录成员信息,以提升企业办公效率

功能范围

覆盖企业微信核心业务品类:

快速开始

前置条件

  • 支持平台:macOS (x64/arm64)、Linux (x64/arm64) 及 Windows (x64)
  • Node.js >= 18
  • 企业微信账号
  • (可选)智能机器人 Bot ID 和 Secret,获取方式参考 说明

安装 & 使用

# 安装 CLI
npm install -g @wecom/cli

# 安装 CLI Skill(必需)
npx skills add WeComTeam/wecom-cli -y -g

# 配置凭证(交互式,仅需一次;默认扫码,--manual 可手动输入)
wecom-cli auth init

# 查看授权状态
wecom-cli auth show

📖 更多使用方法,请参阅 CLI 命令参考。

Agent Skills

🤖 支持的 Skills 使用说明,请参阅 Skills 文档。

数据收集说明

请参阅 数据收集说明。

许可证

本项目基于 [MIT 许可证](.

Read from source at commit 1187471fe8a6OBSERVED · 2026-10-21
Advertisement
02

Install

Commands as the repository documents them. They are shown, not run.

npm install -g @wecom/cli
npx skills add WeComTeam/wecom-cli -y -g
npm install -g @wecom/cli
npm install -g @wecom/cli
npm install -g @wecom/cli
npm install -g @wecom/cli
03

Host compatibility

What the documentation claims. We have not run a compatibility test.

HostStatusNotes
cursormentioned
04

What it tells the agent

The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.

---
name: wecomcli-calendar
description: "企业微信日程管理。当用户需要预约日程、预订会议室、查看/更新/取消日程或查忙闲时触发。本技能负责『日程』——即不含在线会议链接的安排(也涵盖纯线下面对面碰头);若用户要的是『在线会议』(含会议号/入会链接、可远程或视频参会),改用 wecomcli-meeting 技能。用户仅说'开会/约个会/某会'等、未明确要创建的是日程还是在线会议时,必须先读取本技能并按其中的消歧流程向用户追问确认后再处理,不可臆断直接创建。"
metadata:
  requires:
    bins: ["wecom-cli"]
---

# 企业微信日程技能

> 执行任何 `wecom-cli` 命令前,必须先读取并完成 `wecomcli-shared` 技能的公共前置检查。

## 适用范围

### 适用

- 预约 / 创建日程(含纯线下面对面碰头,即不带在线会议链接的安排)
- 查看 / 浏览日程(今天有什么安排、查本周日程)
- 搜索日程(按关键词、按组织人、按参与人找某个日程)
- 更新 / 修改日程(改时间、改地点、加减人、换会议室;不支持更新周期日程)
- 取消日程(不支持取消周期日程)
- 查忙闲 / 约多人共同空闲时段
- 订会议室、查会议室空不空、查办公楼

### 不适用

- 创建、更新、取消周期 / 重复日程(每周 / 每月 / 每天重复)→ 均不支持,引导用户在企业微信客户端手动操作
- 回复 / 拒绝日程邀请(接受 / 拒绝 / 待定,含"拒绝这个日程""不参加")→ 不支持,引导用户在企业微信客户端操作或私信发起人

### 易混淆场景路由

- 用户要**创建含在线会议链接的会议**(需会议号 / 入会链接 / 远程或视频参会)→ 改用 `wecomcli-meeting`(创建会议会同时生成日程,无需在本技能再建)
- 用户仅说"开会 / 约个会 / 安排个会 / xx 会"等、**未明确是日程还是在线会议**(创建场景)→ 必须先用文字追问消歧(固定问题"需要创建日程还是会议?",请用户回复"日程 / 会议"),不得臆断直接创建
- 用户要的会**同时支持线下与远程参会**(如"线下开、外地同事远程接入")→ 含在线会议链接,改用 `wecomcli-meeting`
- **仅给了地点 / 会议室号**(如"在 1605 开会""订个会议室开会")→ 不构成"明确是日程",仍需先用文字询问消歧,不能因带地点就跳过追问
- **查询场景的模糊表述**("最近有什么会 / 有哪些会")→ 严禁追问,日程和会议都查并合并展示;仅当明确提到"在线会议 / 视频会议 / 入会链接 / 会议号 / 腾讯会议 / 远程参会"时才改用 `wecomcli-meeting` 只查会议

## 路由规则

| 用户意图 | 参考文档 |
|---------|---------|
| 预约日程、安排纯线下面对面会议(不含在线会议链接)、创建日程 | [calendar-create](references/calendar-create.md) |
| 看日程、今天有什么安排、查本周日程 | [calendar-agenda](references/calendar-agenda.md) |
| 找某个日程、项目评审是什么时候 | [calendar-search](references/calendar-search.md) |
| 查日程详情、看周期规则、看会议链接 | [calendar-agenda](references/calendar-agenda.md) |
| 取消日程、不开了 | [calendar-cancel](references/calendar-cancel.md) |
| 修改日程、更新日程、改时间、加人/移除人、换会议室 | [calendar-update](references/calendar-update.md) |
| 查忙闲、某人什么时候有空、约多人共同空闲 | [calendar-freebusy](references/calendar-freebusy.md) |
| 订会议室、查会议室空不空、查办公楼、约会议室 | [calendar-meeting-room](references/calendar-meeting-room.md) |

> **浏览 vs 搜索的选择原则**:用户提到**日程主题关键词**时走搜索;**只给了时间/日期而无日程主题关键词时,必须走列表浏览(`list`)**。需要周期规则、会议链接等详情时再读取单条日程详情补充。

## 技能边界:日程 vs 会议 [CRITICAL]

本技能(wecomcli-calendar)只负责**日程**——即非会议的日程安排,以及不含在线会议链接的纯线下面对面会议。**只要涉及在线会议链接(含远程/视频参会)的会议,一律归 wecomcli-meeting 技能**,不在本技能创建。

| 用户意图 | 归属技能 |
|---------|---------|
| 预约日程、安排纯线下面对面会议(不含在线会议链接)、订会议室、查/改/取消日程、查忙闲 | **本技能 wecomcli-calendar** |
| 创建含在线会议链接的会议、需要会议号或入会链接的会、需要远程/视频参会的会 | **wecomcli-meeting 技能** |

**消歧规则(仅创建场景)**:用户仅说"会议/会/开个会/约个会/安排个会/xx会/xx会议"等而未明确是日程还是会议时,**必须先用文字追问**,再路由到对应技能,禁止默认直接创建日程。此文字消歧仅用于「创建」;查询场景严格禁止追问——明确指向在线会议时只查会议,明确是日程/安排时只查日程,模糊表述("会 / xx会 / 最近有什么会"等)则日程和会议都查(见下文「查询消歧」)。

> **问题与选项固定 [CRITICAL]**:消歧确认时,问题与可选项都必须原文照用、严格禁止修改任何内容——问题固定为 `"需要创建日程还是会议?"`,可选项固定为 `日程` / `会议`;不得改写问题措辞、增减或改写选项、翻译,或自行设计其他表述(如"在线会议 / 线上会议 / 视频会议 / 线下会议"等)。

用文字向用户提问:`需要创建日程还是会议?(请回复:日程 / 会议)`

- **"会议""会""开会"等词本身不构成"明确" [CRITICAL]**:这些词只表示要碰头议事,并未说明是日程还是会议。禁止仅因 query 里出现"会议"二字就默认归本技能(日程)创建,也禁止反向默认成会议——只要未明确,一律先用文字追问后再路由。只有出现"碰个面/创建日程"等纯线下信号时才直接留在本技能。
- 用户答「日程」→ 留在本技能,按"预约日程工作流"创建日程。
- 用户答「会议」→ 改用 `读取 wecomcli-meeting 技能` 创建会议(创建会议会同时生成对应日程,无需在本技能再建一条)。
- 用户已明确(如"碰个面""创建日程"=日程;"发个入会链接""要会议号""远程参会"=会议)时,直接路由,无需追问。
- **同时支持线下与远程参会**(如"线下开、外地同事远程接入")时,因含在线会议链接,归 wecomcli-meeting 技能:创建会议即同时生成日程,无需在本技能另建日程。
- **仅有地点/会议室号**(如"在 1605 开会""到 A 座会议室碰一下""订个会议室开会")不构成"明确是日程"——会议室里同样可能要远程接入,是日程还是会议仍未知,必须先用文字询问消歧,不能因为带了地点就跳过追问。

## 改约 / 重建日程前必须先识别会议关联 [CRITICAL]

"改约 / 改时间 / 挪到 / 顺延 / 重新约"等改期意图(即使用户说"取消......再约到......",带"取消"也算改期),禁止机械拆成 `cancel` + `create`:

1. **先定位再判定会议关联**:`search` / `list` 返回均含 `meeting` 字段,定位到目标日程后**直接检查 `meeting.meeting_code`**——非空为「含在线会议链接的会议形态日程」,为空为纯日程;无需为此再补一次读取日程详情(仅当还需 `repeat_rule` 等字段时才补)。
2. **纯日程** → 用本技能路由表中更新日程意图改时间,禁止 cancel + create。
3. **含会议链接** → 改用 `读取 wecomcli-meeting 技能`,把 `meeting.meeting_id` 传入 `meeting update` 改时间(保留会议链接与参会人),无需重新 search 定位。

> **根因**:`create` 只能建纯日程、重建不出会议链接(能拆不能合),cancel + create 会让会议链接永久丢失,故改约一律走 update。


## 核心场景

### 1. 预约日程

读取 [calendar-create](references/calendar-create.md),按其中"预约日程工作流"执行(信息补全 → 参与人解析 → 时间协商/忙闲检查 → 执行创建 → 结果反馈)。

### 2. 查看/搜索日程

| 场景 | 参考文档 |
|------|---------|
| 泛泛查询("今天有什么安排") | [calendar-agenda](references/calendar-agenda.md) |
| 有关键词("项目评审是什么时候") | [calendar-search](references/calendar-search.md) |
| 需要详情(只拿到 `schedule_id` 时补齐字段) | [calendar-agenda](references/calendar-agenda.md) |

> **浏览 vs 搜索**:有**日程主题关键词** → 搜索(不追问时间);**只给时间/日期而无主题关键词 → 列表浏览(`list`)**,禁止把日期当 `keywords` 喂给 `search`。列表浏览已返回 `repeat_rule`,无需额外读取单条详情判断是否周期日程。

> **查询消歧(模糊查询时日程 + 会议都查)[REQUIRED]**:查询场景严格禁止用文字追问"是日程还是会议"——日程/会议消歧追问仅用于创建,查询时一律按以下规则直接处理、不追问。**判定分两个独立维度,不要混为一谈**:
>
> **维度一:查哪一边(日程 / 会议 / 两边都查)**
> - **明确是在线会议** → 用户明确提到"在线会议 / 视频会议 / 入会链接 / 会议号 / 腾讯会议 / 远程参会"等在线会议专属特征时,改用 `读取 wecomcli-meeting 技能` 只查会议。
> - **明确是日程 / 安排** → 用户说的明显是日程类内容(如"日程 / 安排 / 我的安排 / 日历 / 今天有什么安排",且不带在线会议特征)时,只查日程。
> - **模糊表述无法判定**("会 / xx会 / xx会议 / 开会 / 最近有什么会 / 有哪些会 / 找下 xx会议"等,既可能是日程也可能是会议)→ **日程和会议都要查**:既查日程,又 `读取 wecomcli-meeting 技能` 查会议。
>
> **维度二:每一边用 `search` 还是 `list`(与维度一独立,逐边各自判断)**
> - **有主题/名称关键词**(如"找下 xx会议""项目评审是什么时候")→ 该边用 `search`(把关键词传入 `keywords`)。
> - **只有时间/日期或泛浏览无关键词**(如"最近有什么会""今天有什么安排")→ 该边用 `list`,禁止把日期当`keywords` 喂给 `search`。
> - 即使"两边都查",也按本维度对每一边各自选择:带关键词时两边都用 `search`,纯时间/泛浏览时两边都用 `list`。
>
> **合并展示**:两边都查时,合并结果后统一展示——按是否含在线会议链接分成「(会议)」(来自会议侧、或日程中 `meeting.meeting_code` 非空者)和「(日程)」(`meeting_code` 为空的纯日程)两部分,同一场会议在两边都出现时按"主题 + 时间"去重只保留一条,末尾汇总"共 N 场,其中会议 X 场、日程 Y 场"。
>
> - 本消歧仅针对查询;创建场景仍按上文"日程 vs 会议"用文字追问。

### 3. 取消日程

先定位日程(有**日程主题关键词**走搜索;只给时间/日期而无主题关键词走列表浏览 `list`,禁止把日期当 `keywords` 喂给 `search`),再判断是否周期日程(可直接读取列表返回的 `repeat_rule`,无需额外读取单条详情)——**周期日程不支持取消**,告知用户并引导其在企业微信客户端操作(见「已知限制」)。普通日程**不预先按"是否本人创建"拦截取消**,直接执行取消并根据工具返回结果判断能否取消(成功返回 `{}`,无权限则返回错误,此时告知用户并建议联系创建人)。**若用户意图实为"改约 / 挪到 / 顺延"(即使带"取消"字样),按上文「改约 / 重建日程前必须先识别会议关联」走更新流程。** 完整流程见 [calendar-cancel](references/calendar-cancel.md)。

### 4. 更新日程

- 先定位日程(有**日程主题关键词**走搜索;只给时间/日期而无主题关键词走列表浏览 `list`,禁止把日期当 `keywords` 喂给 `search`),判断是否周期日程——**周期日程不支持更新**,告知用户并引导其在企业微信客户端操作(见「已知限制」),禁止逐场 `update` 拼凑或改为取消重建。普通日程收集修改内容后执行更新,**不预先按"是否本人创建"拦截修改**,直接执行更新并根据工具返回结果判断能否修改(成功返回更新后的 `detail`,无权限则返回错误,此时告知用户并建议联系创建人)。
- **改时间
05

Trust audit

BLOCKgrade D · trust 69/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (15 observation(s))
Network
declared (10 observation(s))
Shell
declared (1 observation(s))
Dependencies
not all pinned
Secrets in source
none-found

Findings (25)

HIGHFilesystem / path · fs.credential_store · CWE-22, CWE-59
crates/wecom-cli/test-e2e/cases/sandbox_paths/004-deny-credential-read/test.rs:74
let out = upload_media(&fake_home.path().join(".ssh/id_rsa"))
Why it matters. touches a credential store
HIGHFilesystem / path · fs.credential_store · CWE-22, CWE-59
crates/wecom-cli/test-e2e/cases/sandbox_paths/005-hardlink-alias-threat-model/test.rs:21
fake_home.path().join(".ssh/id_rsa"),
Why it matters. touches a credential store
HIGHFilesystem / path · fs.credential_store · CWE-22, CWE-59
crates/wecom-cli/test-e2e/cases/sandbox_paths/005-hardlink-alias-threat-model/test.rs:75
let out = upload_media(&cwd.path().join("id_rsa"))
Why it matters. touches a credential store
HIGHFilesystem / path · fs.credential_store · CWE-22, CWE-59
crates/wecom-fs/src/sandbox/policy/denylist.rs:45
"**/.git-credentials",
Why it matters. touches a credential store
HIGHFilesystem / path · fs.credential_store · CWE-22, CWE-59
crates/wecom-fs/src/sandbox/policy/denylist.rs:47
"**/.netrc",
Why it matters. touches a credential store
MEDIUMCode injection · code.dynamic_import · CWE-78, CWE-94, CWE-95
skills/wecomcli-pptx/scripts/doc_image_extractor.py:157
__import__(package_name)
MEDIUMFilesystem / path · fs.system_paths · CWE-22, CWE-59
crates/wecom-cli/src/trace/chain.rs:577
assert_eq!(app_bundle_names("/usr/local/bin/node"), None);
MEDIUMFilesystem / path · fs.system_paths · CWE-22, CWE-59
crates/wecom-cli/src/trace/chain.rs:611
node("node", "/usr/local/bin/node"),
MEDIUMFilesystem / path · fs.system_paths · CWE-22, CWE-59
crates/wecom-cli/test-e2e/cases/sandbox_paths/001-external-output-confined-to-roots/test.rs:117
let denied = "/etc/wecom-sandbox-probe.json";
MEDIUMFilesystem / path · fs.system_paths · CWE-22, CWE-59
crates/wecom-cli/test-e2e/cases/sandbox_paths/002-workspace-roots/test.rs:225
&json!({ "media": "/etc/hosts" }).to_string(),
MEDIUMFilesystem / path · fs.system_paths · CWE-22, CWE-59
crates/wecom-fs/src/sandbox/io.rs:672
let real = resolve_real_path(Path::new("/etc/passwd"));
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
crates/wecom-cli/test-e2e/cases/config/004-invalid-config-json/test.rs:12
.env("WECOM_CLI_BASE_URL", "http://127.0.0.1:1")
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
crates/wecom-cli/test-e2e/cases/startup/001-version/test.rs:4
let client = build_test_client("http://127.0.0.1:1");
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
crates/wecom-transport/src/http/endpoint.rs:473
let h = HttpEndpoint::new("/").with_base_url("http://10.0.0.1:8080");
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
crates/wecom-transport/src/http/endpoint.rs:640
let e = http_endpoint("http://10.0.0.1:8080", "/");
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
crates/wecom-transport/src/http/request.rs:1553
.post(ep("http://0.0.0.0:1", "/nop"), json!({}))
LOWInventory / provenance · inv.hidden_file · CWE-1104
crates/wecom-cli/.clippy.toml
.clippy.toml
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
crates/wecom-fs/.clippy.toml
.clippy.toml
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
crates/wecom/.clippy.toml
.clippy.toml
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
crates/wecom-cli/test-e2e/cases/sandbox_paths/007-dotdot-escape/test.rs:64
&["hr", "department", "list", "--output", "../../escape.json"],
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
crates/wecom-cli/test-e2e/cases/sandbox_paths/007-dotdot-escape/test.rs:74
"a/../../../escape2.json",
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
crates/wecom-cli/test-e2e/cases/sandbox_paths/007-dotdot-escape/test.rs:85
"../../escape-dir",
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
crates/wecom-fs/src/sandbox/paths.rs:158
normalize_path(Path::new("/a/b/c/../../d")),
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
crates/wecom-fs/src/sandbox/policy/tests/mod.rs:170
let joined = root.join("../../../etc/passwd");
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
package.json
@changesets/cli, @commitlint/cli, @commitlint/config-conventional, @eslint/js, @tsconfig/node-lts, @types/node, eslint, eslint-config-prettier
Why it matters. 14 dependency range(s) float
Fix. pin exact versions or ship a lockfile

Gates applied: no_behavioural_pass.

Audited 2026-10-21 · audit v0.4.1 · source sha 1187471fe8a6full audit observations/trust-audit/skill/wecomteam__wecomcli-create-meeting.json · Report an issue / request a re-scan
06

Audit history

Every audit this skill has had.

DateSourceVerdictGradeScoreChange
2026-10-211187471fe8a6BLOCKD69first audit
07

Questions

What does the wecomcli-create-meeting — wecomteam/wecom-cli skill do?

企业微信开放平台命令行工具 — 让人类和 AI Agent 都能在终端中操作企业微信

Is wecomcli-create-meeting — wecomteam/wecom-cli safe to install?

No — not without reading the findings first. The audit graded it D (69/100) and found 5 critical or high issues in the source. Each one is listed on this page with the file and line it is on.

What can wecomcli-create-meeting — wecomteam/wecom-cli access on my machine?

The audit observed that it reaches the network, runs shell commands and reads or writes files. Each of those is consistent with what it says it does. Secrets in the source: none found.

Which assistants does wecomcli-create-meeting — wecomteam/wecom-cli work with?

Its documentation mentions cursor. That is what the text claims, not a compatibility test we ran.

How current is this page?

The grade is for one exact copy of the source (1187471fe8a6), read on 2026-10-21. The repository is watched, and a new audit runs when it changes — this is the first audit.

Add this badge to your README

Shows this page's audit result and links back to it. It updates when the audit does.

ModelsAtlas audit badge

Markdown
[![ModelsAtlas audit: wecom-cli](https://modelsatlas.com/skills/wecomteam/wecomcli-create-meeting/badge.svg)](https://modelsatlas.com/skills/wecomteam/wecomcli-create-meeting/)

Not your listing, or something out of date? Claim or update your listing.

Advertisement