Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 49 additions & 24 deletions rh-sre/skills/fleet-inventory/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ description: |
model: inherit
color: blue
license: Apache-2.0
allowed-tools: inventory__get_host_details vulnerability__get_cve_systems
allowed-tools: inventory__list_hosts inventory__find_host_by_name inventory__get_host_details inventory__get_host_system_profile vulnerability__get_cve_systems
---

# Fleet Inventory Skill
Expand All @@ -31,8 +31,11 @@ This skill queries Red Hat Lightspeed to retrieve and display information about
**Required MCP Servers**: `lightspeed-mcp` ([setup guide](https://console.redhat.com/))

**Required MCP Tools**:
- `get_host_details` (from lightspeed-mcp) - Retrieve system inventory
- `get_cve_systems` (from lightspeed-mcp) - Find CVE-affected systems
- `inventory__list_hosts` (from lightspeed-mcp) - List and discover registered hosts
- `inventory__find_host_by_name` (from lightspeed-mcp) - Resolve hostname to host UUID
- `inventory__get_host_details` (from lightspeed-mcp) - Retrieve inventory metadata for known host UUIDs
- `inventory__get_host_system_profile` (from lightspeed-mcp) - Retrieve OS version and system profile when needed
- `vulnerability__get_cve_systems` (from lightspeed-mcp) - Find CVE-affected systems

**Required Environment Variables**:
- `LIGHTSPEED_CLIENT_ID` - Red Hat Lightspeed service account client ID
Expand Down Expand Up @@ -100,28 +103,38 @@ Proceeding with fleet inventory query...
### Step 1: Retrieve System Inventory

**Document Consultation** (REQUIRED - Execute FIRST):
1. **Action**: Read [insights-api.md](docs/insights/insights-api.md) using the Read tool to understand the `get_host_details` response format and pagination handling
2. **Output to user**: "I consulted [insights-api.md](docs/insights/insights-api.md) to understand the `get_host_details` response format and pagination handling."
1. **Action**: Read [insights-api.md](docs/insights/insights-api.md) using the Read tool to understand `inventory__list_hosts` response format and pagination handling
2. **Output to user**: "I consulted [insights-api.md](docs/insights/insights-api.md) to understand the `inventory__list_hosts` response format and pagination handling."

**MCP Tool**: `get_host_details` (from lightspeed-mcp)
**MCP Tool**: `inventory__list_hosts` (from lightspeed-mcp)

**Purpose**: Query Lightspeed for comprehensive system information
**Purpose**: Query Lightspeed for registered hosts. Use for fleet discovery, tag filters, and environment scoping.

**Parameters**: See [references/01-parameter-reference.md](references/01-parameter-reference.md) for get_host_details/get_cve_systems parameters and response fields.
**Parameters**: `per_page=10` on first call, then `page` for pagination. Optional filters: `display_name`, `tags`, `staleness`, `hostname_or_id`. See [references/01-parameter-reference.md](references/01-parameter-reference.md).

**Optional enrichment**: After host UUIDs are known:
- `inventory__get_host_details(host_ids="uuid-1,uuid-2")` — inventory metadata (similar fields to `list_hosts`)
- `inventory__get_host_system_profile(host_ids="uuid-1")` — OS version and system profile when RHEL version is required (one or two UUIDs at a time; large response)
- `inventory__find_host_by_name(hostname="...")` — resolve a hostname to a UUID

**Verification Checklist**:
- ✓ Systems list returned with metadata
- ✓ Total count matches expectation
- ✓ System details include RHEL version, tags, status
- ✓ Response includes `total`, `count`, `page`, `per_page`, and `results`
- ✓ Hosts list returned with metadata
- ✓ Total count matches expectation (paginate with `page` while `count` equals `per_page`)
- ✓ No authentication errors (401/403)

**Key Fields to Extract**:
**Key Fields to Extract** (from `results[]` on `list_hosts` / `get_host_details`):
- `id`: Unique system identifier (use for remediation workflows)
- `display_name` / `fqdn`: Human-readable hostname
- `rhel_version`: OS version (critical for remediation compatibility)
- `tags`: Environment labels (production, staging, dev)
- `stale`: Whether system recently checked in (< 7 days)
- `last_seen`: Last Lightspeed client run timestamp
- `updated`: Last inventory record update
- `last_check_in`: Last reporter check-in (prefer for active/stale display)
- `stale_timestamp`, `stale_warning_timestamp`, `culled_timestamp`: Staleness thresholds
- `per_reporter_staleness`: Per-reporter check-in detail
- `groups`: Inventory groups (when present)

**When RHEL version or environment tags are required** (not on every `list_hosts` record):
- `system_profile.operating_system.version` or equivalent — from `inventory__get_host_system_profile`; equivalents include `operating_system.major`/`minor`, `os_release`, `operating_system.name`
- `tags`: Environment labels (when present on the host)

### Step 2: Filter and Organize Systems

Expand All @@ -133,11 +146,11 @@ Apply user-requested filters and grouping. See [references/01-parameter-referenc

### Step 3: Query CVE-Affected Systems

**MCP Tool**: `get_cve_systems` (from lightspeed-mcp)
**MCP Tool**: `vulnerability__get_cve_systems` (from lightspeed-mcp)

**Purpose**: Find systems affected by specific CVEs

**Parameters**: `cve_id` (CVE-YYYY-NNNNN, uppercase). See [references/01-parameter-reference.md](references/01-parameter-reference.md).
**Parameters**: `cve` (CVE-YYYY-NNNNN, uppercase). Paginate with `limit` and `offset`. See [references/01-parameter-reference.md](references/01-parameter-reference.md).

**Verification Checklist**:
- ✓ CVE ID matches request exactly
Expand Down Expand Up @@ -191,13 +204,25 @@ Examples:
- `lightspeed-mcp` - Red Hat Lightspeed platform access for system inventory and CVE data

### Required MCP Tools
- `get_host_details` (from lightspeed-mcp) - Retrieve all registered systems with metadata
- Parameters: Optional filters (system_id, hostname_pattern, tags, operating_system)
- Returns: List of systems with id, display_name, fqdn, rhel_version, tags, stale status
- `inventory__list_hosts` (from lightspeed-mcp) - List and discover registered hosts
- Parameters: `per_page`, `page`, `display_name`, `tags`, `staleness`, etc.
- Returns: `{ total, count, page, per_page, results[] }` with id, display_name, fqdn, updated, last_check_in, staleness timestamps

- `inventory__find_host_by_name` (from lightspeed-mcp) - Resolve hostname to host record
- Parameters: `hostname` (required)
- Returns: Host record with UUID

- `inventory__get_host_details` (from lightspeed-mcp) - Retrieve inventory metadata for known host UUIDs
- Parameters: `host_ids` (required, comma-separated UUID string)
- Returns: Same pagination wrapper; host records similar to `list_hosts` (not guaranteed to include `system_profile`)

- `inventory__get_host_system_profile` (from lightspeed-mcp) - Retrieve OS version and system profile
- Parameters: `host_ids` (comma-separated; one or two UUIDs at a time)
- Returns: `system_profile` with `operating_system` (name, major, minor), `os_release`, packages, services

- `get_cve_systems` (from lightspeed-mcp) - Find systems affected by specific CVEs
- Parameters: cve_id (string, format: CVE-YYYY-NNNNN)
- Returns: List of affected systems with vulnerability and remediation status
- `vulnerability__get_cve_systems` (from lightspeed-mcp) - Find systems affected by specific CVEs
- Parameters: `cve` (string, format: CVE-YYYY-NNNNN), `limit`, `offset`
- Returns: Paginated list of affected systems with vulnerability and remediation status

### Related Skills
- `mcp-lightspeed-validator` - **PREREQUISITE** - Validates Lightspeed MCP server configuration and connectivity
Expand Down
95 changes: 89 additions & 6 deletions rh-sre/skills/fleet-inventory/docs/insights/insights-api.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,94 @@
---
title: TODO
status: draft
title: Lightspeed Inventory API Patterns for Fleet Discovery
category: insights
tags: [lightspeed, inventory, list_hosts, pagination]
last_updated: 2026-06-22
---

# TODO
# Lightspeed Inventory API Patterns

Placeholder stub created during skill-local docs migration.
Fleet discovery and listing use **`inventory__list_hosts`**, not `inventory__get_host_details`. The latter requires known host UUIDs.

- Keep link targets valid for migration PR review.
- Content will be authored in a follow-up PR.
## Tool routing by intent

| User intent | Tool | Key parameters |
|-------------|------|----------------|
| List or discover the fleet; filter by tag, name, staleness | `inventory__list_hosts` | `per_page=10` (first call), `page`, `display_name`, `tags`, `staleness` |
| Resolve hostname → UUID | `inventory__find_host_by_name` | `hostname` |
| Inventory metadata for known host(s) | `inventory__get_host_details` | `host_ids` (comma-separated UUIDs) |
| OS version / system profile for known host(s) | `inventory__get_host_system_profile` | `host_ids` (one or two UUIDs at a time) |
| Systems affected by a CVE | `vulnerability__get_cve_systems` | `cve`, `limit`, `offset`; optional `system_uuid` |

## Response envelope (list_hosts, get_host_details, get_host_system_profile)

All three inventory tools return the same top-level shape:

| Field | Meaning |
|-------|---------|
| `total` | Total hosts matching the query |
| `count` | Hosts in this page |
| `page` | Current page number |
| `per_page` | Page size |
| `results` | Array of host records |

## inventory__list_hosts pagination

- **First call**: always use `per_page=10` (integer). The MCP tool description requires this default to avoid performance and context issues.
- **Subsequent pages**: increment `page` (`1`, `2`, `3`, …) while keeping the same filters.
- **Stop condition**: when `count` is less than `per_page`, or `results` is empty.

```
inventory__list_hosts(per_page=10, page=1, display_name="")
inventory__list_hosts(per_page=10, page=2, display_name="")
```

Use `per_page`, not `page_size`. Lightspeed inventory uses different pagination parameter names than AAP MCP.

## Response fields (list_hosts / get_host_details)

Extract from each `results[]` host record:

- `id` — host UUID (use for enrichment and remediation workflows)
- `display_name` / `fqdn` — human-readable hostname
- `updated` — last inventory record update
- `last_check_in` — last reporter check-in (prefer for active/stale display)
- `stale_timestamp`, `stale_warning_timestamp`, `culled_timestamp` — staleness thresholds
- `per_reporter_staleness` — per-reporter check-in detail
- `groups` — inventory groups (when present)
- `facts` — limited rhsm facts when profile data is sparse

**When present** (not guaranteed on every host): `tags`

`list_hosts` and `get_host_details` do **not** reliably return `system_profile`. Do not expect RHEL version from fleet listing alone.

## OS version (get_host_system_profile)

When the user asks for RHEL version distribution or version-based filtering, call:

```
inventory__get_host_system_profile(host_ids="68ce32aa-57da-49b7-8ded-dc4ad54e520a")
```

Use **one or two UUIDs at a time** — responses are large.

Extract RHEL version from `results[].system_profile`:

- `system_profile.operating_system.version` or equivalent
- Equivalents: `operating_system.major` / `operating_system.minor`, `os_release`, `operating_system.name`

Example live shape: `"operating_system": {"name": "RHEL", "major": 10, "minor": 1}`, `"os_release": "10.1"`

## CVE-affected systems pagination

Use `vulnerability__get_cve_systems` with parameter **`cve`** (not `cve_id`):

```
vulnerability__get_cve_systems(cve="CVE-2024-1234", limit=100, offset=0)
```

Paginate with `offset += limit` until the page returns fewer records than `limit`.

## Related references

- [01-parameter-reference.md](../../references/01-parameter-reference.md) — parameter tables for all fleet-inventory tools
- [lightspeed-mcp-parameters.md](../../../cve-impact/docs/references/lightspeed-mcp-parameters.md) — shared Lightspeed MCP parameter reference (inventory and vulnerability tools)
139 changes: 111 additions & 28 deletions rh-sre/skills/fleet-inventory/references/01-parameter-reference.md
Original file line number Diff line number Diff line change
@@ -1,49 +1,132 @@
# Fleet Inventory Parameter Reference

Read when calling `get_host_details` or `get_cve_systems` to ensure correct parameters.
Read when calling inventory or vulnerability tools to ensure correct parameters.

## get_host_details
## inventory__list_hosts

**Parameters** (based on user query):
**Purpose**: List and discover hosts. Use for fleet queries, tag filters, and environment scoping.

```python
# No filters
get_host_details()
| Parameter | Type | Required | Example | Notes |
|-----------|------|----------|---------|-------|
| `per_page` | integer | No | `10` | **Use 10 on first call.** Not `page_size`. |
| `page` | integer | No | `1` | Increment for pagination. |
| `display_name` | string | No | `""` | Filter by display name. Empty string = no filter. |
| `hostname_or_id` | string | No | `""` | Filter by display_name, fqdn, or id. |
| `fqdn` | string | No | `""` | Filter by FQDN. |
| `tags` | string | No | `"ns1/key1=val1"` | Tag filter string (not an array). |
| `staleness` | string | No | `"fresh"` | One of `fresh`, `stale`, `stale_warning`, `unknown`. |
| `order_by` | string | No | `"display_name"` | Sort field: `display_name`, `updated`, `created`. |
| `order_how` | string | No | `"ASC"` | `ASC` or `DESC`. |

# Specific system
get_host_details(system_id="abc-123")
**Correct**:
```
inventory__list_hosts(per_page=10, page=1, display_name="")
inventory__list_hosts(per_page=10, page=1, tags="insights-client/owner=staging")
```

**Wrong**:
```
inventory__list_hosts() # Missing per_page guidance; always pass per_page=10 first
inventory__list_hosts(page_size=100) # Use per_page, not page_size
inventory__list_hosts(tags=["production"]) # tags is a string, not an array
```

# Hostname pattern
get_host_details(hostname_pattern="web-*")
**Response envelope**: `{ total, count, page, per_page, results[] }`

# Tag filter
get_host_details(tags=["production"])
**Response fields** (per host in `results[]`): `id`, `display_name`, `fqdn`, `updated`, `last_check_in`, `stale_timestamp`, `per_reporter_staleness`, `groups`, `facts`. Tags when present. No `system_profile` — use `get_host_system_profile` for OS version.

# RHEL version filter
get_host_details(operating_system__version__startswith="8")
## inventory__find_host_by_name

**Purpose**: Resolve a hostname or display name to a host record.

| Parameter | Type | Required | Example |
|-----------|------|----------|---------|
| `hostname` | string | Yes | `"web-server-01"` |

# Combined
get_host_details(tags=["production", "web-tier"], operating_system__version__startswith="8")
```
inventory__find_host_by_name(hostname="web-server-01")
```

**Response fields**: id, display_name, fqdn, rhel_version, last_seen, tags, stale, satellite_managed
## inventory__get_host_details

## get_cve_systems
**Purpose**: Retrieve full details for **known** host UUIDs. Not for fleet enumeration.

**Parameters**: `cve_id` (string, format CVE-YYYY-NNNNN, uppercase)
| Parameter | Type | Required | Example |
|-----------|------|----------|---------|
| `host_ids` | string | Yes | `"uuid-1,uuid-2"` |

```python
get_cve_systems(cve_id="CVE-2024-1234")
```
inventory__get_host_details(host_ids="68ce32aa-57da-49b7-8ded-dc4ad54e520a")
```

**Response fields**: cve_id, affected_systems (system_id, display_name, status, remediation_available), total_affected, total_remediated, total_vulnerable
**Response**: Same envelope as `list_hosts`; host shape is similar (inventory metadata, not guaranteed to include `system_profile`).

**Wrong**:
```
inventory__get_host_details() # host_ids is required
inventory__get_host_details(system_id="abc-123") # Use host_ids
inventory__get_host_details(hostname_pattern="web-*") # Not supported; use list_hosts
inventory__get_host_details(tags=["production"]) # Not supported; use list_hosts
```

## inventory__get_host_system_profile

**Purpose**: Retrieve OS version and full system profile for **known** host UUIDs. Use when RHEL version distribution or version-based filtering is required.

| Parameter | Type | Required | Example | Notes |
|-----------|------|----------|---------|-------|
| `host_ids` | string | No | `"uuid-1"` or `"uuid-1,uuid-2"` | Comma-separated UUIDs. **One or two at a time** — MCP warns of very large responses. Default `""`. |

```
inventory__get_host_system_profile(host_ids="68ce32aa-57da-49b7-8ded-dc4ad54e520a")
```

**Response envelope**: `{ total, count, page, per_page, results[] }` (same as `list_hosts`).

**Each `results[]` item** (live shape): `id` + `system_profile` only — not the full inventory record from `list_hosts`.

**`system_profile` fields** (live; OS version equivalents):
- `operating_system.name` — e.g. `"RHEL"`
- `operating_system.major` / `operating_system.minor` — e.g. `10` / `1` (no `operating_system.version` string in live responses)
- `os_release` — e.g. `"10.1"`
- `installed_packages`, `enabled_services`, `installed_services`
- Hardware/infrastructure: `cpu_model`, `number_of_cpus`, `system_memory_bytes`, `network_interfaces`, etc.

Use `system_profile.operating_system.version` in docs as the canonical name; at runtime read `major`/`minor`, `os_release`, or `operating_system.name` when `version` is absent.

## vulnerability__get_cve_systems

**Purpose**: List systems affected by a CVE.

| Parameter | Type | Required | Example | Notes |
|-----------|------|----------|---------|-------|
| `cve` | string | Yes | `"CVE-2024-1234"` | Required. Not `cve_id`. |
| `limit` | integer | No | `100` | Records per page (default 10). |
| `offset` | integer | No | `0` | Pagination offset. |
| `sort` | string | No | `"-updated"` | Prefix `-` for descending. |
| `filter_` | string | No | `""` | Full-text filter on system display name. |
| `system_uuid` | string | No | `"68ce32aa-..."` | Check if a specific system is affected. |

**Correct**:
```
vulnerability__get_cve_systems(cve="CVE-2024-1234", limit=100, offset=0)
```

**Wrong**:
```
vulnerability__get_cve_systems(cve_id="CVE-2024-1234") # Use cve, not cve_id
```

**Response fields**: affected systems with id, display_name, status, remediation_available; paginate with limit/offset for large result sets.

**Status values**: Vulnerable (patch needed), Patched (no action), Not Affected (exclude)

## Filtering and Sorting
## Client-side filtering and sorting

When API filters are insufficient, filter after listing or after fetching profiles:

**By RHEL**: `[s for s in systems if s['rhel_version'].startswith("8")]`
**By tag**: `[s for s in systems if "production" in s.get('tags', [])]`
**By stale**: `[s for s in systems if not s.get('stale', False)]`
**Sort by last_seen**: `sorted(systems, key=lambda s: s['last_seen'], reverse=True)`
**Sort by display_name**: `sorted(systems, key=lambda s: s['display_name'])`
**By RHEL major** (requires `get_host_system_profile` data): `[h for h in profiles if h.get('system_profile', {}).get('operating_system', {}).get('major') == 8]`
**By tag** (when present on host): `[h for h in hosts if any("production" in t for t in h.get('tags', []))]`
**By stale** (from list_hosts): compare `last_check_in` to `stale_timestamp`, or use `staleness` filter on `list_hosts`
**Sort by last check-in**: `sorted(hosts, key=lambda h: h.get('last_check_in', ''), reverse=True)`
**Sort by updated**: `sorted(hosts, key=lambda h: h.get('updated', ''), reverse=True)`
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ Retrieved from Red Hat Lightspeed on YYYY-MM-DDTHH:MM:SSZ
| Environment | Count | Systems |

## Top 20 Systems (by last check-in)
[Table: display_name, rhel_version, tags, last_seen]
[Table: display_name, last_check_in, updated, groups or tags when present]

For RHEL version breakdown, call `inventory__get_host_system_profile` and use `system_profile.operating_system.version` or equivalent (`os_release`, `major`/`minor`).

**Would you like to**: Filter by environment/RHEL, view CVEs, create remediation plans
```
Expand Down
Loading
Loading