小爱音箱语音播报

WarnAudited by ClawScan on May 10, 2026.

Overview

The skill matches its stated purpose, but it asks for Xiaomi account credentials, encourages storing the password persistently, and loads an unpinned helper from /tmp before using those credentials.

Only install this if you are comfortable giving the skill Xiaomi account access and allowing it to make speakers speak remotely. Avoid putting your Xiaomi password in ~/.zshrc or cron commands, do not disable two-factor protection unless you fully understand the risk, explicitly choose the target device, and verify or pin the MiService dependency instead of loading code from /tmp.

Findings (5)

Artifact-based informational review of SKILL.md, metadata, install specs, static scan signals, and capability signals. ClawScan does not execute the skill or run runtime probes.

What this means

A local user, backup, shell history/config reader, or compromised process could recover the Xiaomi password, and the agent can use that account to list and control linked speaker devices.

Why it was flagged

The skill requires the user's Xiaomi account password and recommends saving it in a shell startup file. This is sensitive account authority, especially because the registry metadata declares no primary credential or required environment variables.

Skill content
export MI_USER="你的小米账号"
export MI_PASS="你的小米密码"
...
echo 'export MI_PASS="你的小米密码"' >> ~/.zshrc
Recommendation

Declare the Xiaomi credential requirement clearly, avoid storing the account password in shell profiles, prefer a dedicated limited account or safer token/OAuth mechanism if available, and use a secret manager for scheduled jobs.

What this means

Users may underestimate the credential risk or weaken their Xiaomi account security to make the skill work.

Why it was flagged

The safety statement says credentials are not stored in files, but the setup instructions store the password in ~/.zshrc. The FAQ also suggests temporarily disabling two-factor verification.

Skill content
账号信息通过**环境变量**传入,不存储在文件中 ... echo 'export MI_PASS="你的小米密码"' >> ~/.zshrc ... 如开启二次验证,可能需要临时关闭
Recommendation

Remove or correct the misleading safety claim, do not recommend disabling two-factor protection except with strong warnings, and document the risks of storing passwords in shell files.

What this means

If /tmp/MiService is missing, replaced, or tampered with, unexpected Python code could run inside the skill and receive the Xiaomi credentials.

Why it was flagged

The code imports a credential-handling dependency from /tmp/MiService and then passes the Xiaomi username/password into it. /tmp is a mutable location, and the artifacts do not pin or verify the dependency.

Skill content
sys.path.insert(0, '/tmp/MiService')
...
from miservice import MiAccount, MiNAService
...
account = MiAccount(session, MI_USER, MI_PASS)
Recommendation

Install the dependency into a trusted virtual environment or vendored package path, pin a reviewed version or commit, verify integrity, and avoid adding /tmp to sys.path for credentialed code.

What this means

Scheduled broadcasts can continue until the user removes the cron job, and credentials may remain in cron/OpenClaw configuration.

Why it was flagged

The documentation intentionally supports persistent scheduled execution. This is purpose-aligned for reminders, but it can keep running and may embed credentials in scheduler configuration.

Skill content
openclaw cron add \
  --name "喝水提醒" \
  --schedule "0 * * * *" \
  --command "export MI_USER='xxx' MI_PASS='xxx' && python3 /path/to/xiaoai_cli.py say '该喝水了'"
Recommendation

Review scheduled jobs after setup, remove them when no longer needed, and avoid placing plaintext passwords directly in cron commands.

What this means

A message could play on an unintended device or room if device matching is wrong.

Why it was flagged

If no speaker-like device is matched, the script falls back to the first available device instead of failing closed.

Skill content
if not target_device:
    target_device = devices[0]
    print(f"⚠️ 未找到小爱音箱,使用第一个可用设备: {target_device.get('name')}")
...
result = await service.text_to_speech(device_id, message)
Recommendation

Set MI_DEVICE_ID or MI_DEVICE_NAME explicitly and consider changing the script to stop rather than using the first device when no match is found.