mcp: annotate every tool so a host can tell an observation from an input action - #512
Merged
Conversation
… an input action (fixes #509) destructiveHint and openWorldHint both default to true in the MCP spec, so glass's 30 unannotated tools read to a host as destructive and open-world — glass_a11y_snapshot paid the same confirmation prompt as glass_click. Each tool now declares readOnlyHint and openWorldHint, and each input tool declares destructiveHint. The judgement calls: glass_doctor is not read-only because deep=true spawns a display and a hint is per-tool, not per-argument; glass_start is the only open-world tool because it builds, and a build fetches over the network; idempotentHint is claimed only for glass_stop and glass_select_window, since the rest fire app-visible events whose handlers run again on a repeat. annotations_classify_every_tool holds an exhaustive name -> read_only table, so a tool added later fails until classified and a reclassification cannot be silent. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
xxx
marked this pull request as ready for review
August 22, 2026 00:48
Merged
xxx
added a commit
that referenced
this pull request
Aug 22, 2026
Rename [Unreleased] to [1.5.0] with today's UTC date and open a fresh [Unreleased], updating the two compare links. Also backfills three entries whose PRs merged without one: the MCP tool annotations (#512), the X11 clipboard owner that kept reporting itself alive (#449), and the launched app's log readers that waited for an EOF that never came (#478). 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.
Fixes #509.
destructiveHintandopenWorldHintboth default totruein the MCP spec, so glass's 30 unannotated tools read to a host as destructive and open-world —glass_a11y_snapshotpaid the same confirmation prompt asglass_click. Every tool now declaresreadOnlyHintandopenWorldHint; every input tool also declaresdestructiveHint.The four judgement calls the issue left open:
glass_doctoris not read-only.deep = truespawns and tears down a headless display, and a hint is per-tool, not per-argument, so the worst case wins.glass_startis the only open-world tool. It builds, and a build fetches dependencies over the network. Everything else is bounded by the one local app.glass_stopisdestructive, andidempotent— a second stop adds no further effect.idempotentHintis otherwise claimed only forglass_select_window.glass_move,glass_window,glass_set_valueandglass_clipboard_setall look idempotent but fire app-visible events whose handlers run again on a repeat; claiming otherwise invites a host to auto-retry them.glass_baseline_saveandglass_select_windowareread_only = false, destructive = false: they change glass's state, not the app's.annotations_classify_every_toolholds an exhaustivename -> read_onlytable and checks that every tool carries annotations, that its classification matches the table, thatopenWorldHintis always set, that input tools setdestructiveHint, and that read-only tools set neitherdestructiveHintnoridempotentHint(the spec says both are meaningless there). A tool added later fails until it is classified; a reclassification cannot be silent.Verification
tools/listover stdio against the built binary returns 30 tools, none withoutannotations, in camelCase.cargo test --workspace(0 failures),cargo clippy --workspace --all-targets -- -D warnings,cargo fmt --all --check.Draft until CI is green.