Files
claudetools/.claude/skills/yealink-ymcs/SKILL.md
Mike Swanson 850e685d8d feat: yealink-ymcs skill — YMCS v2 device-management API, pairs with packetdial
New skill to manage ACG's Yealink phone fleets via Yealink Management Cloud Service v2
(us-api.ymcs.yealink.com). RTFM'd the API (token auth via POST /v2/token Basic+bearer, NOT the
legacy RPS HMAC; legacy-TLS renegotiation required) + endpoint map from the dszp/n8n-nodes-
yealinkymcs community node. Live-verified: token auth, sites (one ACG AccessKey sees ALL client
sites — VWP/GuruHQ/Ace Pick Up Parks as children of the ACG parent), devices, accounts,
rps-servers (RPS = "WL - ACG" ftp://p.packetdials.net). Gated writes (--confirm): add-devices-by-mac,
add-sipaccount (push a NetSapiens SIP cred onto a phone = the PBX glue), reboot, reset, rps add/del;
+ raw passthrough (auto-recovers the MSYS /v2 path-mangling). Creds vaulted at
services/yealink-ymcs.sops.yaml. Pairs with packetdial onboard-domain for new-client phone
provisioning; VWP is the live pilot. Honest [V]/[P] verification status in SKILL.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 09:59:52 -07:00

5.3 KiB

name, description
name description
yealink-ymcs Manage ACG's Yealink phone fleets via the Yealink Management Cloud Service (YMCS) v2 open API (us-api.ymcs.yealink.com). List sites/devices/accounts/firmwares/models/alarms, RPS servers + devices; gated writes (add devices by MAC, reboot/factory-reset, RPS add/remove, push a SIP account onto a device). Read-only by default; writes gated --confirm. Pairs with the `packetdial` skill (NetSapiens PBX) for phone provisioning. One ACG AccessKey sees ALL client sites. Triggers: yealink, ymcs, provision phone, register MAC, RPS, device firmware, reboot phone, push sip account to phone, yealink device manager.

yealink-ymcs — Yealink Management Cloud Service (YMCS) v2 API

Manages the physical Yealink phones for ACG-managed clients. Pairs with packetdial: the PBX (NetSapiens/PacketDial) owns the SIP accounts; YMCS owns the phones (provisioning, config, firmware, RPS zero-touch). See reference_packetdial_oit_netsapiens for the vendor stack.

Auth (v2 — token, not the legacy RPS HMAC)

POST /v2/token with HTTP Basic base64(AccessKeyID:Secret) (+ timestamp ms + nonce headers + body {"grant_type":"client_credentials"}) → bearer token (~24h). Subsequent calls send Authorization: Bearer <token>. Creds from vault services/yealink-ymcs.sops.yaml (credentials.access_key_id / access_key_secret); env overrides YMCS_ACCESS_KEY_ID / YMCS_ACCESS_KEY_SECRET; region YMCS_REGION (us|eu|au, default us → us-api.ymcs.yealink.com). Yealink servers require LEGACY TLS renegotiation — handled in-client via an SSL context with OP_LEGACY_SERVER_CONNECT.

Account scope (verified 2026-06-22)

The ACG AccessKey is the parent account — one key sees all client sites as children: Arizona Computer Guru LLC (parent) → VWP (Valley Wide Plastering), GuruHQ, Ace Pick Up Parks. No per-client keys needed. (Per-client YMCS portal logins still exist, e.g. Valleywide in clients/valleywide/, but the API key covers everything.)

Commands

PY="$CLAUDETOOLS_ROOT/.claude/scripts/py.sh"; Y=".claude/skills/yealink-ymcs/scripts/ymcs.py"
# reads (live-verified [V] unless noted)
bash "$PY" "$Y" sites                 # [V] site tree (id/name/parentId/level)
bash "$PY" "$Y" devices [--site <id>] # [V] devices (keys: mac, modelName, deviceStatus, siteId, sn, programVersion, wanIp...) — --site filter is best-effort [P]
bash "$PY" "$Y" accounts              # [V] device accounts
bash "$PY" "$Y" device-groups | device-configs | firmwares | models | alarms | oplogs
bash "$PY" "$Y" official-firmwares    # [P] returns a non-standard shape; may need a model param
bash "$PY" "$Y" rps-servers           # [V] RPS provisioning servers (ACG: "WL - ACG" ftp://p.packetdials.net)
bash "$PY" "$Y" rps-devices           # [V] devices registered in RPS
# writes (ALL gated --confirm)
bash "$PY" "$Y" add-devices-by-mac --body '{...}' --confirm   # bulk-add phones by MAC to a site
bash "$PY" "$Y" add-sipaccount --body '{...}' --confirm        # push a SIP account onto a device (PBX glue)
bash "$PY" "$Y" reboot --body '{"ids":[...]}' --confirm        # reboot device(s)
bash "$PY" "$Y" reset  --body '{"ids":[...]}' --confirm        # FACTORY RESET — careful
bash "$PY" "$Y" rps-add --body '{...}' --confirm               # add device(s) to RPS (zero-touch)
bash "$PY" "$Y" rps-del --body '{...}' --confirm
bash "$PY" "$Y" raw POST /v2/dm/listDevices --body '{"skip":0,"limit":50,"autoCount":true}' [--confirm]

List endpoints page automatically ({skip,limit,autoCount}{total, data:[]}); the wrappers return {total, count, data} with all pages.

How it pairs with packetdial (the onboarding pipeline)

  1. packetdial onboard-domain → create the PBX domain + users + DIDs (NetSapiens SIP accounts).
  2. yealink-ymcs → the phones: add-devices-by-mac into the client's site, add-sipaccount to push each NetSapiens SIP cred onto its phone, and/or rps-add so the phone zero-touch- provisions on first boot (RPS server WL - ACG = ftp://p.packetdials.net).
  3. Result: new client → domain live → phones registered to pbx.packetdial.com. VWP is the live pilot (just onboarded to the PBX; 21 devices in YMCS, fleet partly pending).

Gotchas

  • Legacy TLS (handled). If a future Python drops OP_LEGACY_SERVER_CONNECT, connections fail.
  • MSYS path conversion: in raw, a leading /v2/... arg gets rewritten by Git-Bash to C:/Program Files/Git/v2/.... The raw command auto-recovers (cuts back to /v2/); don't use MSYS_NO_PATHCONV=1 (it breaks the vault subprocess). Named wrappers are unaffected.
  • /v2/dm/sipAccounts is the create endpoint (not a list) — wrapped as the gated add-sipaccount. There's no list-sip-accounts in the v2 API.
  • Verification: token + sites/devices/accounts/rps-servers are [V]; writes + official-firmwares + the --site filter are [P] (plumbed per the n8n reference + spec, not lifecycle-exercised — no throwaway device to safely test writes on).

Reference

  • Vendor stack: reference_packetdial_oit_netsapiens. Portal login (web UI): infrastructure/voip-phones.sops.yaml. Per-client portal e.g. clients/valleywide/.
  • Endpoint map harvested from the dszp/n8n-nodes-yealinkymcs community node + Yealink "Open API for YMCS V4X" doc. Full /v2/dm/* + /v2/rps/* surface reachable via raw.