5.0 KiB
name, description
| name | description |
|---|---|
| yealink-ymcs | Manage ACG's Yealink phone fleets via the YMCS v2 API: sites/devices/accounts/firmware/alarms/RPS; gated writes (add MAC, reboot, push SIP account). Pairs with packetdial. Triggers: yealink, ymcs, provision phone, register MAC, RPS, reboot phone. |
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)
packetdial onboard-domain→ create the PBX domain + users + DIDs (NetSapiens SIP accounts).yealink-ymcs→ the phones:add-devices-by-macinto the client's site,add-sipaccountto push each NetSapiens SIP cred onto its phone, and/orrps-addso the phone zero-touch- provisions on first boot (RPS serverWL - ACG=ftp://p.packetdials.net).- 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 toC:/Program Files/Git/v2/.... Therawcommand auto-recovers (cuts back to/v2/); don't useMSYS_NO_PATHCONV=1(it breaks the vault subprocess). Named wrappers are unaffected. /v2/dm/sipAccountsis the create endpoint (not a list) — wrapped as the gatedadd-sipaccount. There's no list-sip-accounts in the v2 API.- Verification: token + sites/devices/accounts/rps-servers are [V]; writes + official-firmwares +
the
--sitefilter 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-yealinkymcscommunity node + Yealink "Open API for YMCS V4X" doc. Full/v2/dm/*+/v2/rps/*surface reachable viaraw.