Read devices and agent versions
Enable Read → Devices (READ_DEVICES) on an API service key.
Existing keys need the permission added explicitly. Oneleet Agent must be enabled
for the workspace. This permission grants device reads, including device details
and compliance status; it does not grant device updates or commands.
Use these existing REST endpoints:
GET /api/v1/tenants/{tenant}/tenant-devicesGET /api/v1/tenant-devices/{tenant-device}The corresponding MCP tools are TenantDeviceList and TenantDeviceGet.
Use agentInfo.agentVersion for the reported agent version and
agentInfo.lastPing for the recorded contact time. Unreported values may be absent.
Neither field establishes whether auto-update is working.
Service-key and OAuth lists default to 25 devices. Pass limit (1–100) and follow
nextCursor as cursor with the same workspace until nextCursor is absent.
Pages include archived devices and are ordered by workspace device ID. This is a
live listing; changes during pagination may affect later pages.
curl --fail-with-body \ -H "Authorization: Bearer $ONELEET_API_TOKEN" \ "https://api.oneleet.com/api/v1/tenants/$ONELEET_TENANT_ID/tenant-devices?limit=25"For MCP, the workspace is inferred from the connection; an explicit tenant must
match it. TenantDeviceGet takes tenant-device, the id from a list row.
MCP tool results are limited to 1 MiB; request smaller pages if needed.
These read tools return JSON to the client.
OAuth connections require the corresponding READ_DEVICES permission configured
and granted by the authorization server, plus fresh consent. The signed-in user’s
normal workspace permissions still apply. Under the standard roles, members can
list and export devices; device detail reads require an administrator or auditor role.
See which monitors a device fails
Section titled “See which monitors a device fails”A device’s status and issueCount say whether it’s compliant and how many device
monitors it fails. To see which monitors those are, call TenantDeviceGetMonitors in
MCP, or GET /api/v1/tenant-devices/{tenant-device}/monitors, with the same
READ_DEVICES permission, passing the device’s id from a list row as
tenant-device. The response has one row for every device monitor in your workspace,
with that monitor’s result on the device, and isn’t paginated. For OAuth connections,
the signed-in user’s role must allow reading device monitors. Under the standard roles,
only administrators and auditors can, as for device details. An
organization role with View monitors under
Devices grants it to other members.
set -o pipefailcurl --fail-with-body \ -H "Authorization: Bearer $ONELEET_API_TOKEN" \ "https://api.oneleet.com/api/v1/tenant-devices/$ONELEET_DEVICE_ID/monitors" \ | jq -r '.rows[] | select(.status == "ALERTING" or .status == "BREACHING_SLA") | .monitor.monitorType.name'Each row’s status is that monitor’s result on the device:
PASSING: the device passes the check.ALERTING: the device fails the check.BREACHING_SLA: the device fails the check and is past your workspace’s deadline for fixing it.IGNORED: someone ignored this monitor’s result for the device.SNOOZED: someone snoozed the monitor, or its result for this device.NOT_YET_RUN: the monitor hasn’t checked this device yet.DISABLED: the monitor is turned off, or the device is archived, unassigned, or out of scope.
The device’s issueCount counts its ALERTING and BREACHING_SLA rows, and its
autoFixableIssueCount counts the ones among them whose autoFixAvailable is true,
which the device’s agent can fix automatically. In each row,
monitor.monitorType.name is the monitor’s name and assetResult is the monitor’s
result on this device. On ALERTING and BREACHING_SLA rows, assetResult.reasons
says why the device fails the monitor. Rows for a turned-off or snoozed monitor can still carry its last result,
including old reasons. assetResult is absent on NOT_YET_RUN rows and on archived,
unassigned, or out-of-scope devices.
To find every device that fails one monitor without calling once per device, take that
row’s id, which is the monitor’s ID, and call MonitorAssetResultList in MCP, or
GET /api/v1/monitors/{monitor}/asset-results. Pass ALERTING and BREACHING_SLA as
status, or it also returns passing, ignored, and snoozed devices. In REST, repeat the
parameter: ?status=ALERTING&status=BREACHING_SLA. Results come 50 to a page by default,
and limit raises that to 200, so request each page up to pagination.totalPages. That
call needs Read → Monitors (READ_MONITORS) instead.
Download a bulk export
Section titled “Download a bulk export”Call TenantDeviceListExport in MCP, or
GET /api/v1/tenants/{tenant}/tenant-devices/export, with the same READ_DEVICES
permission as the device list. The file is prepared in the background, so AI
assistants such as ChatGPT and Claude may ask you to confirm the MCP call. The call
waits up to 15 seconds for it (wait sets a different number of seconds, up to 25) and then answers with the export’s status. While the status is PENDING or
RUNNING, call again until it is COMPLETED; the response then carries
downloadUrl, fileName, and recordCount. Download the file from
downloadUrl within one hour. Anyone with that link can access it until it
expires. A completed export is reused for an hour, so repeated calls return the
same file rather than building it again. A FAILED export without a
failureReason is retried by the next call; one with a failureReason cannot
succeed as requested.
The gzip-compressed JSON Lines file contains one TenantDevice per line, with the
same device details, agent info, and compliance status as the device list,
including archived devices. Raw agent reports and logs aren’t included. The
export reads live pages, not a point-in-time snapshot. Stored exports follow a
90-day cleanup policy.
Save the file directly for local analysis, keeping its contents out of the
assistant’s context. For example, after saving it as oneleet-devices.jsonl.gz:
import gzipimport json
with gzip.open("oneleet-devices.jsonl.gz", "rt") as devices: for line in devices: device = json.loads(line) print(device["name"], device.get("agentInfo", {}).get("agentVersion"))