Skip to content

Commit 523e305

Browse files
authored
Merge pull request #126 from dmartinol/fix/124-fleet-inventory-mcp-tool-params
fix(rh-sre): align fleet-inventory with Lightspeed MCP tool schemas
2 parents 4c46ab0 + a9daffb commit 523e305

6 files changed

Lines changed: 278 additions & 71 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../fleet-inventory/references/01-parameter-reference.md

rh-sre/skills/fleet-inventory/SKILL.md

Lines changed: 49 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ description: |
1919
model: inherit
2020
color: blue
2121
license: Apache-2.0
22-
allowed-tools: inventory__get_host_details vulnerability__get_cve_systems
22+
allowed-tools: inventory__list_hosts inventory__find_host_by_name inventory__get_host_details inventory__get_host_system_profile vulnerability__get_cve_systems
2323
---
2424

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

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

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

102105
**Document Consultation** (REQUIRED - Execute FIRST):
103-
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
104-
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."
106+
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
107+
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."
105108

106-
**MCP Tool**: `get_host_details` (from lightspeed-mcp)
109+
**MCP Tool**: `inventory__list_hosts` (from lightspeed-mcp)
107110

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

110-
**Parameters**: See [references/01-parameter-reference.md](references/01-parameter-reference.md) for get_host_details/get_cve_systems parameters and response fields.
113+
**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).
114+
115+
**Optional enrichment**: After host UUIDs are known:
116+
- `inventory__get_host_details(host_ids="uuid-1,uuid-2")` — inventory metadata (similar fields to `list_hosts`)
117+
- `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)
118+
- `inventory__find_host_by_name(hostname="...")` — resolve a hostname to a UUID
111119

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

118-
**Key Fields to Extract**:
126+
**Key Fields to Extract** (from `results[]` on `list_hosts` / `get_host_details`):
119127
- `id`: Unique system identifier (use for remediation workflows)
120128
- `display_name` / `fqdn`: Human-readable hostname
121-
- `rhel_version`: OS version (critical for remediation compatibility)
122-
- `tags`: Environment labels (production, staging, dev)
123-
- `stale`: Whether system recently checked in (< 7 days)
124-
- `last_seen`: Last Lightspeed client run timestamp
129+
- `updated`: Last inventory record update
130+
- `last_check_in`: Last reporter check-in (prefer for active/stale display)
131+
- `stale_timestamp`, `stale_warning_timestamp`, `culled_timestamp`: Staleness thresholds
132+
- `per_reporter_staleness`: Per-reporter check-in detail
133+
- `groups`: Inventory groups (when present)
134+
135+
**When RHEL version or environment tags are required** (not on every `list_hosts` record):
136+
- `system_profile.operating_system.version` or equivalent — from `inventory__get_host_system_profile`; equivalents include `operating_system.major`/`minor`, `os_release`, `operating_system.name`
137+
- `tags`: Environment labels (when present on the host)
125138

126139
### Step 2: Filter and Organize Systems
127140

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

134147
### Step 3: Query CVE-Affected Systems
135148

136-
**MCP Tool**: `get_cve_systems` (from lightspeed-mcp)
149+
**MCP Tool**: `vulnerability__get_cve_systems` (from lightspeed-mcp)
137150

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

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

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

193206
### Required MCP Tools
194-
- `get_host_details` (from lightspeed-mcp) - Retrieve all registered systems with metadata
195-
- Parameters: Optional filters (system_id, hostname_pattern, tags, operating_system)
196-
- Returns: List of systems with id, display_name, fqdn, rhel_version, tags, stale status
207+
- `inventory__list_hosts` (from lightspeed-mcp) - List and discover registered hosts
208+
- Parameters: `per_page`, `page`, `display_name`, `tags`, `staleness`, etc.
209+
- Returns: `{ total, count, page, per_page, results[] }` with id, display_name, fqdn, updated, last_check_in, staleness timestamps
210+
211+
- `inventory__find_host_by_name` (from lightspeed-mcp) - Resolve hostname to host record
212+
- Parameters: `hostname` (required)
213+
- Returns: Host record with UUID
214+
215+
- `inventory__get_host_details` (from lightspeed-mcp) - Retrieve inventory metadata for known host UUIDs
216+
- Parameters: `host_ids` (required, comma-separated UUID string)
217+
- Returns: Same pagination wrapper; host records similar to `list_hosts` (not guaranteed to include `system_profile`)
218+
219+
- `inventory__get_host_system_profile` (from lightspeed-mcp) - Retrieve OS version and system profile
220+
- Parameters: `host_ids` (comma-separated; one or two UUIDs at a time)
221+
- Returns: `system_profile` with `operating_system` (name, major, minor), `os_release`, packages, services
197222

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

202227
### Related Skills
203228
- `mcp-lightspeed-validator` - **PREREQUISITE** - Validates Lightspeed MCP server configuration and connectivity
Lines changed: 89 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,94 @@
11
---
2-
title: TODO
3-
status: draft
2+
title: Lightspeed Inventory API Patterns for Fleet Discovery
3+
category: insights
4+
tags: [lightspeed, inventory, list_hosts, pagination]
5+
last_updated: 2026-06-22
46
---
57

6-
# TODO
8+
# Lightspeed Inventory API Patterns
79

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

10-
- Keep link targets valid for migration PR review.
11-
- Content will be authored in a follow-up PR.
12+
## Tool routing by intent
13+
14+
| User intent | Tool | Key parameters |
15+
|-------------|------|----------------|
16+
| List or discover the fleet; filter by tag, name, staleness | `inventory__list_hosts` | `per_page=10` (first call), `page`, `display_name`, `tags`, `staleness` |
17+
| Resolve hostname → UUID | `inventory__find_host_by_name` | `hostname` |
18+
| Inventory metadata for known host(s) | `inventory__get_host_details` | `host_ids` (comma-separated UUIDs) |
19+
| OS version / system profile for known host(s) | `inventory__get_host_system_profile` | `host_ids` (one or two UUIDs at a time) |
20+
| Systems affected by a CVE | `vulnerability__get_cve_systems` | `cve`, `limit`, `offset`; optional `system_uuid` |
21+
22+
## Response envelope (list_hosts, get_host_details, get_host_system_profile)
23+
24+
All three inventory tools return the same top-level shape:
25+
26+
| Field | Meaning |
27+
|-------|---------|
28+
| `total` | Total hosts matching the query |
29+
| `count` | Hosts in this page |
30+
| `page` | Current page number |
31+
| `per_page` | Page size |
32+
| `results` | Array of host records |
33+
34+
## inventory__list_hosts pagination
35+
36+
- **First call**: always use `per_page=10` (integer). The MCP tool description requires this default to avoid performance and context issues.
37+
- **Subsequent pages**: increment `page` (`1`, `2`, `3`, …) while keeping the same filters.
38+
- **Stop condition**: when `count` is less than `per_page`, or `results` is empty.
39+
40+
```
41+
inventory__list_hosts(per_page=10, page=1, display_name="")
42+
inventory__list_hosts(per_page=10, page=2, display_name="")
43+
```
44+
45+
Use `per_page`, not `page_size`. Lightspeed inventory uses different pagination parameter names than AAP MCP.
46+
47+
## Response fields (list_hosts / get_host_details)
48+
49+
Extract from each `results[]` host record:
50+
51+
- `id` — host UUID (use for enrichment and remediation workflows)
52+
- `display_name` / `fqdn` — human-readable hostname
53+
- `updated` — last inventory record update
54+
- `last_check_in` — last reporter check-in (prefer for active/stale display)
55+
- `stale_timestamp`, `stale_warning_timestamp`, `culled_timestamp` — staleness thresholds
56+
- `per_reporter_staleness` — per-reporter check-in detail
57+
- `groups` — inventory groups (when present)
58+
- `facts` — limited rhsm facts when profile data is sparse
59+
60+
**When present** (not guaranteed on every host): `tags`
61+
62+
`list_hosts` and `get_host_details` do **not** reliably return `system_profile`. Do not expect RHEL version from fleet listing alone.
63+
64+
## OS version (get_host_system_profile)
65+
66+
When the user asks for RHEL version distribution or version-based filtering, call:
67+
68+
```
69+
inventory__get_host_system_profile(host_ids="68ce32aa-57da-49b7-8ded-dc4ad54e520a")
70+
```
71+
72+
Use **one or two UUIDs at a time** — responses are large.
73+
74+
Extract RHEL version from `results[].system_profile`:
75+
76+
- `system_profile.operating_system.version` or equivalent
77+
- Equivalents: `operating_system.major` / `operating_system.minor`, `os_release`, `operating_system.name`
78+
79+
Example live shape: `"operating_system": {"name": "RHEL", "major": 10, "minor": 1}`, `"os_release": "10.1"`
80+
81+
## CVE-affected systems pagination
82+
83+
Use `vulnerability__get_cve_systems` with parameter **`cve`** (not `cve_id`):
84+
85+
```
86+
vulnerability__get_cve_systems(cve="CVE-2024-1234", limit=100, offset=0)
87+
```
88+
89+
Paginate with `offset += limit` until the page returns fewer records than `limit`.
90+
91+
## Related references
92+
93+
- [01-parameter-reference.md](../../references/01-parameter-reference.md) — parameter tables for all fleet-inventory tools
94+
- [lightspeed-mcp-parameters.md](../../../cve-impact/docs/references/lightspeed-mcp-parameters.md) — shared Lightspeed MCP parameter reference (inventory and vulnerability tools)
Lines changed: 111 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,132 @@
11
# Fleet Inventory Parameter Reference
22

3-
Read when calling `get_host_details` or `get_cve_systems` to ensure correct parameters.
3+
Read when calling inventory or vulnerability tools to ensure correct parameters.
44

5-
## get_host_details
5+
## inventory__list_hosts
66

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

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

13-
# Specific system
14-
get_host_details(system_id="abc-123")
21+
**Correct**:
22+
```
23+
inventory__list_hosts(per_page=10, page=1, display_name="")
24+
inventory__list_hosts(per_page=10, page=1, tags="insights-client/owner=staging")
25+
```
26+
27+
**Wrong**:
28+
```
29+
inventory__list_hosts() # Missing per_page guidance; always pass per_page=10 first
30+
inventory__list_hosts(page_size=100) # Use per_page, not page_size
31+
inventory__list_hosts(tags=["production"]) # tags is a string, not an array
32+
```
1533

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

19-
# Tag filter
20-
get_host_details(tags=["production"])
36+
**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.
2137

22-
# RHEL version filter
23-
get_host_details(operating_system__version__startswith="8")
38+
## inventory__find_host_by_name
39+
40+
**Purpose**: Resolve a hostname or display name to a host record.
41+
42+
| Parameter | Type | Required | Example |
43+
|-----------|------|----------|---------|
44+
| `hostname` | string | Yes | `"web-server-01"` |
2445

25-
# Combined
26-
get_host_details(tags=["production", "web-tier"], operating_system__version__startswith="8")
46+
```
47+
inventory__find_host_by_name(hostname="web-server-01")
2748
```
2849

29-
**Response fields**: id, display_name, fqdn, rhel_version, last_seen, tags, stale, satellite_managed
50+
## inventory__get_host_details
3051

31-
## get_cve_systems
52+
**Purpose**: Retrieve full details for **known** host UUIDs. Not for fleet enumeration.
3253

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

35-
```python
36-
get_cve_systems(cve_id="CVE-2024-1234")
58+
```
59+
inventory__get_host_details(host_ids="68ce32aa-57da-49b7-8ded-dc4ad54e520a")
3760
```
3861

39-
**Response fields**: cve_id, affected_systems (system_id, display_name, status, remediation_available), total_affected, total_remediated, total_vulnerable
62+
**Response**: Same envelope as `list_hosts`; host shape is similar (inventory metadata, not guaranteed to include `system_profile`).
63+
64+
**Wrong**:
65+
```
66+
inventory__get_host_details() # host_ids is required
67+
inventory__get_host_details(system_id="abc-123") # Use host_ids
68+
inventory__get_host_details(hostname_pattern="web-*") # Not supported; use list_hosts
69+
inventory__get_host_details(tags=["production"]) # Not supported; use list_hosts
70+
```
71+
72+
## inventory__get_host_system_profile
73+
74+
**Purpose**: Retrieve OS version and full system profile for **known** host UUIDs. Use when RHEL version distribution or version-based filtering is required.
75+
76+
| Parameter | Type | Required | Example | Notes |
77+
|-----------|------|----------|---------|-------|
78+
| `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 `""`. |
79+
80+
```
81+
inventory__get_host_system_profile(host_ids="68ce32aa-57da-49b7-8ded-dc4ad54e520a")
82+
```
83+
84+
**Response envelope**: `{ total, count, page, per_page, results[] }` (same as `list_hosts`).
85+
86+
**Each `results[]` item** (live shape): `id` + `system_profile` only — not the full inventory record from `list_hosts`.
87+
88+
**`system_profile` fields** (live; OS version equivalents):
89+
- `operating_system.name` — e.g. `"RHEL"`
90+
- `operating_system.major` / `operating_system.minor` — e.g. `10` / `1` (no `operating_system.version` string in live responses)
91+
- `os_release` — e.g. `"10.1"`
92+
- `installed_packages`, `enabled_services`, `installed_services`
93+
- Hardware/infrastructure: `cpu_model`, `number_of_cpus`, `system_memory_bytes`, `network_interfaces`, etc.
94+
95+
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.
96+
97+
## vulnerability__get_cve_systems
98+
99+
**Purpose**: List systems affected by a CVE.
100+
101+
| Parameter | Type | Required | Example | Notes |
102+
|-----------|------|----------|---------|-------|
103+
| `cve` | string | Yes | `"CVE-2024-1234"` | Required. Not `cve_id`. |
104+
| `limit` | integer | No | `100` | Records per page (default 10). |
105+
| `offset` | integer | No | `0` | Pagination offset. |
106+
| `sort` | string | No | `"-updated"` | Prefix `-` for descending. |
107+
| `filter_` | string | No | `""` | Full-text filter on system display name. |
108+
| `system_uuid` | string | No | `"68ce32aa-..."` | Check if a specific system is affected. |
109+
110+
**Correct**:
111+
```
112+
vulnerability__get_cve_systems(cve="CVE-2024-1234", limit=100, offset=0)
113+
```
114+
115+
**Wrong**:
116+
```
117+
vulnerability__get_cve_systems(cve_id="CVE-2024-1234") # Use cve, not cve_id
118+
```
119+
120+
**Response fields**: affected systems with id, display_name, status, remediation_available; paginate with limit/offset for large result sets.
40121

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

43-
## Filtering and Sorting
124+
## Client-side filtering and sorting
125+
126+
When API filters are insufficient, filter after listing or after fetching profiles:
44127

45-
**By RHEL**: `[s for s in systems if s['rhel_version'].startswith("8")]`
46-
**By tag**: `[s for s in systems if "production" in s.get('tags', [])]`
47-
**By stale**: `[s for s in systems if not s.get('stale', False)]`
48-
**Sort by last_seen**: `sorted(systems, key=lambda s: s['last_seen'], reverse=True)`
49-
**Sort by display_name**: `sorted(systems, key=lambda s: s['display_name'])`
128+
**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]`
129+
**By tag** (when present on host): `[h for h in hosts if any("production" in t for t in h.get('tags', []))]`
130+
**By stale** (from list_hosts): compare `last_check_in` to `stale_timestamp`, or use `staleness` filter on `list_hosts`
131+
**Sort by last check-in**: `sorted(hosts, key=lambda h: h.get('last_check_in', ''), reverse=True)`
132+
**Sort by updated**: `sorted(hosts, key=lambda h: h.get('updated', ''), reverse=True)`

rh-sre/skills/fleet-inventory/references/03-output-templates.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ Retrieved from Red Hat Lightspeed on YYYY-MM-DDTHH:MM:SSZ
2525
| Environment | Count | Systems |
2626

2727
## Top 20 Systems (by last check-in)
28-
[Table: display_name, rhel_version, tags, last_seen]
28+
[Table: display_name, last_check_in, updated, groups or tags when present]
29+
30+
For RHEL version breakdown, call `inventory__get_host_system_profile` and use `system_profile.operating_system.version` or equivalent (`os_release`, `major`/`minor`).
2931

3032
**Would you like to**: Filter by environment/RHEL, view CVEs, create remediation plans
3133
```

0 commit comments

Comments
 (0)