Serve the offline analysis to an assistant, read-only, over stdio - #33
Merged
Merged
Conversation
`bootintel mcp` speaks the Model Context Protocol over stdin and stdout, so an assistant can do the reasoning half of reading a boot log while this binary does the reading half. Given an inventory, a boot-chain verdict and a kernel posture, what to look at first is exactly the question a model is good at; recognising them in a capture is what this already does. It runs locally, and that is the whole point rather than an implementation detail. The model is the operator's own, under whatever agreement they already work under, and no capture leaves the machine. A hosted version would have to receive the log, which is the thing an NDA-bound consultancy cannot do and the reason the offline tooling exists at all. Every tool reads. None opens a serial port, writes to a device, or reaches the network, and a test asserts the tool list by name rather than trusting a policy, so adding a write is a deliberate edit somebody reviews. If that ever changes, the allowlist belongs in this process where the bytes are written and not in a prompt: a model can be argued into anything, a refusal in code cannot. Captures arrive as text rather than as a path, so the caller decides what is disclosed instead of the server reading whatever it likes off the disk. The engine's honesty survives the trip through a summariser, which is the part most at risk of being lost. An empty finding list says the capture was not recognised rather than that the device is clean, absence is reported as unknown rather than hardened, and each verdict carries the value it was read from. Protocol details worth stating because they are the ones that break quietly: notifications get no reply, an unrecognised protocol version falls back instead of failing the handshake, a malformed line does not end the session, and a tool failure is a result carrying isError rather than a transport error, so the model sees why it failed rather than the client seeing a broken connection. Verified against a real handshake, not only unit tests: initialize, initialized, tools/list and a tools/call round trip driven through the built binary. 402 tests with --features tui, 381 without, clippy clean under -D warnings in both, rustfmt clean. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Zenofex
added a commit
that referenced
this pull request
Sep 29, 2026
Version bump, lockfile, changelog. No code changes: everything here is on `main` and was reviewed in #33. ## What ships ```sh claude mcp add bootintel -- bootintel mcp ``` `bootintel mcp` serves the offline analysis over stdio: `scan_log`, `boot_chain_verdict`, `list_detectors`, `sample_log`. The model is the operator's own and no capture leaves the machine. This is the release that makes it usable — the config line above needs the installed binary to carry the subcommand. ## Why MINOR New subcommand. Nothing renamed or removed, no exit-code policy change, no output-format schema broken. ## Verification - `cargo test --workspace --features tui`: 402 passed; without: 381 passed - clippy `-D warnings` and `fmt --check`: clean - Release binary reports `bootintel 0.13.0` and lists its four tools Every tool is read-only and `the_tool_set_is_read_only` asserts the list by name, so a write to a device cannot arrive with an upgrade. Both version bumps landed first try, fifth release running for `docs/releasing.md` step 1. After merge: dispatch `cli-release` for `0.13.0` with `publish_crates`, verify the draft against `SHA256SUMS`, publish and mark latest, then move the tap (step 7) and sync the in-repo reference copy. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5 (1M context) <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.
bootintel mcpspeaks MCP over stdio, so an assistant does the reasoning half of reading a boot log while this binary does the reading half.Why local is the point, not a detail
The model is the operator's own, under whatever agreement they already work under, and no capture leaves the machine. A hosted version would have to receive the log, which is the thing an NDA-bound consultancy cannot do and the reason the offline tooling exists at all. It also means this costs nothing to run: the reasoning is paid for by whoever already pays for the assistant.
Read-only, and tested as such
scan_logboot_chain_verdictlist_detectorssample_logNone opens a serial port, writes to a device, or reaches the network.
the_tool_set_is_read_onlyasserts the list by name rather than trusting a policy, so adding a write is a deliberate edit somebody reviews. If that ever changes, the allowlist belongs in the process where the bytes are written, not in a prompt: a model can be argued into anything; a refusal in code cannot.Captures are passed as text rather than a path, so the caller decides what is disclosed instead of the server reading whatever it likes off the disk.
The honesty has to survive a summariser
That is the part most at risk when a model sits between the tool and the reader:
Protocol details that break quietly
Notifications get no reply (answering one is an error some clients tolerate and others do not). An unrecognised protocol version falls back rather than failing the handshake. A malformed line does not end the session. A tool failure is a result carrying
isError, not a transport error, so the model sees why rather than the client seeing a broken connection.Verification
cargo test --workspace --features tui: 402 passed; without: 381 passed-D warningsandfmt --check: cleaninitialize→notifications/initialized→tools/list→tools/call, returning five verdicts and the KASLR reason from a synthetic capture🤖 Generated with Claude Code