# openclaw-bms Python rewrite of the OpenClaw Kaseya BMS skill for ticket and note workflows. ## Goals - reliable ticket CRUD - reliable ticket note CRUD - correct account/location relationship handling - cache stable CRM lookups - support template-based ticket creation cleanly - keep a small shell compatibility layer for existing `scripts/*.sh` entrypoints ## Installation ```bash python3 -m pip install -e . ``` Or run directly from the repo: ```bash bash scripts/bms.sh --help ``` ## Configuration ```bash export BMS_TENANT="your-tenant" export BMS_USERNAME="your-user" export BMS_PASSWORD="your-password" export BMS_MFA_CODE="123456" # when needed export BMS_API_BASE="https://api.bms.kaseya.com" export BMS_TOKEN_FILE="$HOME/.bms_token.json" export BMS_CACHE_FILE="$HOME/.cache/openclaw-bms/cache.json" ``` ## Key behavior ### Accounts and Locations Locations are account-scoped. Use: ```bash bms accounts bms locations --account 12345 ``` Do not assume a location name like `Main` is globally unique. A location name can exist under multiple accounts with different IDs. Cached for 24 hours: - accounts list - locations per account Refresh explicitly: ```bash bms accounts --refresh bms locations --account 12345 --refresh ``` ### Tickets List/search: ```bash bms tickets list --status Open --assignee "Jane Doe" ``` Create: ```bash bms tickets create \ --title "Server down" \ --details "Main server offline" \ --account-id 123 \ --location-id 456 \ --status-id 1 \ --priority-id 2 \ --type-id 3 \ --source-id 1 \ --queue-id 9 \ --open-date 2026-04-07T14:00:00+00:00 ``` Template-based create: ```bash bms tickets create \ --template-id 7 \ --title "Override title" \ --account-id 123 \ --location-id 456 \ --queue-id 9 ``` Template logic: - fetches the template - merges template defaults with CLI overrides - CLI values win - validates required fields before the create call - requires routing via either `queue-id` or `assignee-id` - makes exactly one create API call per invocation - treats create as success only when the response includes success=true and a valid ticket ID ### Notes List notes: ```bash bms notes list 33919447 ``` Add a note with a custom date: ```bash bms notes add 33919447 --message "Backfilled note" --note-date 2026-04-01T15:00:00+00:00 ``` Update a note with a custom date: ```bash bms notes update 33919447 1001 --message "Corrected note" --note-date 2026-04-01T16:00:00+00:00 ``` Delete a note: ```bash bms notes delete 33919447 1001 ``` ## Architectural decisions - Python standard library only - avoids packaging friction for a personal skill - service layer separated from CLI - easier to audit and extend - caching stored in a JSON file - simple, transparent, sufficient for account/location lookups - shell scripts kept as compatibility wrappers - existing command habits keep working ## Audit notes Primary audit focus was on: - ticket create safety - note CRUD support - account/location correctness - template create correctness Changes from bash version: - removed fragile mixed endpoint usage - fixed account/location handling through CRM endpoints - added explicit cache for accounts and per-account locations - added `open-date` support for ticket creation - added `note-date` support for note create and update - added full note CRUD in the Python CLI - reduced duplicate-create risk by validating before create and checking response semantics after create