openclaw-bms
Python-first OpenClaw skill for Kaseya BMS ticket and note workflows.
Installation
python3 -m pip install -e .
Primary usage:
bms --help
Alternative direct module invocation:
python3 -m openclaw_bms --help
Configuration
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"
Core behavior
Accounts and Locations
Locations are tied to accounts.
That means a location named Main under one account is a different object from Main under another account.
Always resolve locations in the context of an account.
Commands:
bms accounts
bms accounts --refresh
bms locations --account 12345
bms locations --account 12345 --refresh
Caching:
- accounts cached for 24 hours
- locations cached per account for 24 hours
Ticket CRUD
List/search:
bms tickets list --status Open --assignee "Jane Doe"
Get:
bms tickets get 12345
Create:
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
Create from template:
bms tickets create \
--template-id 7 \
--title "Override title" \
--account-id 123 \
--location-id 456 \
--queue-id 9
Template create flow:
- fetch template
- merge template defaults with explicit CLI overrides
- validate required fields before the API call
- require either
queue-idorassignee-id - make exactly one create API call per invocation
- require a valid ticket ID in the response before reporting success
Patch:
bms tickets patch 12345 /StatusId 6
Assign:
bms tickets assign 12345 --details "Routing to tier 2" --type-id 1 --status-id 6 --queue-id 7
Delete:
bms tickets delete 12345
Ticket Note CRUD
List notes:
bms notes list 12345
Add note with custom date:
bms notes add 12345 --message "Backfilled note" --note-date 2026-04-01T15:00:00+00:00
Update note with custom date:
bms notes update 12345 1001 --message "Corrected note" --note-date 2026-04-01T16:00:00+00:00
Delete note:
bms notes delete 12345 1001
Lookups
bms lookup statuses
bms lookup priorities
bms lookup types
bms lookup sources
Notes:
typesmaps to issue-type lookup in the public BMS v2 Swagger.sourcesis not exposed in the public BMS v2 Swagger; the command fails explicitly and expects tenant-specific source IDs.
Templates
bms templates tickets list
bms templates tickets get 7
bms templates notes list
bms templates timelogs list
Templates are read-only.
Audit logging
Write operations only are logged. Reads are not logged.
Logged operations:
- auth login
- auth refresh
- ticket create
- ticket patch
- ticket delete
- ticket assign
- note add
- note update
- note delete
Log path:
~/.bms-actions/YYYY-MM-DD.jsonl
Entry shape:
timestampcommandargs_sanitizedresultorerrorstatusrevert_infowhen available
Secrets are redacted:
BMS_PASSWORDBMS_MFA_CODE- tokens
- authorization headers
Architecture
- Python standard library only
- console entry point via
pyproject.toml - no shell wrappers required
- service layer separated from CLI
- file-based cache for stable CRM data
- file-based audit log for write history and rollback context
Description
Languages
Python
100%