Feat/apt tools#9
Merged
Merged
Conversation
gjolly
commented
May 13, 2026
Collaborator
Adds three MCP tools so an agent can answer "is this host up to date?": - apt_update_status — one-call summary: pending updates, security updates, reboot-required + triggering packages, last apt-update age. - list_upgradable_packages — per-package upgrade detail with origin, suite, and security flag, plus security_only / name_pattern filters. - list_installed_packages — dpkg inventory parsed from /var/lib/dpkg/ status, with name_pattern / limit filters. Excludes residual config-files entries (deinstall status). Implementation lives in a new internal/aptdb package that mirrors the procfs/sysfs pattern: pure-Go parsers, no os/exec. It reads dpkg status, walks /var/lib/apt/lists for *_Packages indexes (uncompressed and gzip), joins them with sibling Release / InRelease files for Origin/Suite, and computes upgrades via a from-scratch dpkg version comparator (deb-version(7): epoch / upstream / revision with tilde-ordering and mixed alpha-numeric segments). Two correctness notes baked in: - InRelease files wrap the Release stanza in a PGP signed-message envelope; the parser skips the envelope header so Origin/Suite are picked up instead of "Hash: SHA512". - Suites ending in -backports are filtered out of upgrade candidates, matching apt's default pin priority 100 (Ubuntu backports never upgrade automatically). This brings the count in line with `apt list --upgradable`; the only remaining divergence on a typical Ubuntu host is ESM-pinned packages, which would need apt-preferences parsing to handle exactly. Snap confinement: /var/lib/dpkg and /var/lib/apt are not visible inside strict confinement under the existing *-observe plugs, so the snap declares the system-backup plug (read-only host filesystem view at /var/lib/snapd/hostfs). Manual-connect like log-observe today. The mcpserver picks the hostfs root when snapconf.InSnap() is true and "/" otherwise. CLAUDE.md's plug rule is updated to admit read-only host-fs plugs alongside *-observe. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
toolResultText only extracted text blocks from result.content[], so any
tool whose payload lives in structuredContent (every FleetMind list tool)
was invisible to both the chat agent and the operator card — the LLM
only ever saw the "N items" one-line summary.
Return the pretty-printed structuredContent when present, fall back to
text blocks otherwise. When both are present the summary text just
duplicates fields already in the structured payload (e.g. "3 installed
package(s)" vs {"count": 3, ...}), so skipping it keeps the LLM's
tool_result tight.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.