Skip to content

feat(mcp): annotate tools with behavior hints (readOnly/destructive/idempotent)#134

Open
adityamparikh wants to merge 1 commit into
apache:mainfrom
adityamparikh:mcp-tool-hints
Open

feat(mcp): annotate tools with behavior hints (readOnly/destructive/idempotent)#134
adityamparikh wants to merge 1 commit into
apache:mainfrom
adityamparikh:mcp-tool-hints

Conversation

@adityamparikh
Copy link
Copy Markdown
Contributor

Summary

Adds @McpTool.McpAnnotations to every MCP tool so clients can make sensible approval decisions instead of treating every call as worst-case destructive.

Tool readOnlyHint destructiveHint idempotentHint
search, list-collections, get-collection-stats, check-health, get-schema true n/a n/a
create-collection false (default) false (additive provisioning) false (default — re-creating errors)
index-json-documents, index-csv-documents, index-xml-documents false (default) true (default — Solr overwrites by uniqueKey) true (re-posting same payload → same end state)

Why

NSA's Model Context Protocol: Security Design Considerations CSI (U/OO/6030316-26, May 2026) flags "poor approval workflows" as one of the top risks for MCP deployments. The CSI calls out that clients today often can't distinguish a read from a destructive write without parsing prose tool descriptions, which produces consent fatigue and pushes operators toward blanket approvals.

Exposing the spec's standard behavior hints is the server-side enabler clients need to build approval UX that doesn't desensitize users.

Test plan

  • Extended McpClientIntegrationTestBase.toolsExposeBehaviorHints to assert hint values flow through listTools for every tool — runs under both HTTP and stdio transports, so the wire-level annotations are verified end-to-end.
  • ./gradlew build passes locally (38s, all tests green).
  • Spotless check passes.

🤖 Generated with Claude Code

…dempotent)

MCP clients use these annotations to decide whether to prompt for user
approval before invoking a tool. Without them, every call has to be
treated as worst-case destructive, which produces consent fatigue and
discourages clients from auto-allowing safe reads.

Hints applied:
- search, list-collections, get-collection-stats, check-health,
  get-schema → readOnlyHint=true
- create-collection → destructiveHint=false (additive provisioning)
- index-{json,csv,xml}-documents → idempotentHint=true (Solr overwrites
  by uniqueKey, so re-posting the same payload leaves the index in the
  same end state)

NSA's "Model Context Protocol: Security Design Considerations"
(U/OO/6030316-26, May 2026) flags poor approval workflows as a top
risk; exposing these hints is the server-side enabler clients need to
build sensible approval UX.

Test: extends McpClientIntegrationTestBase to assert each hint flows
through to listTools output, so both HTTP and stdio transports verify
the wire-level annotations.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Signed-off-by: adityamparikh <[email protected]>
adityamparikh added a commit to adityamparikh/solr-mcp that referenced this pull request May 22, 2026
…safety

README:
- Add `add-fields` and `add-field-types` to the Tools table (PR apache#131).
- Add a sentence on MCP behavior hints (`readOnlyHint`,
  `destructiveHint`, `idempotentHint`) so client integrators know to
  read them (PR apache#134).
- Add an "MCP Prompts" section listing the six workflow prompts
  introduced in the prompts PR.
- Clarify that `solr://{collection}/schema` autocompletion is
  prefix-filtered, case-insensitive, capped at 100 — describing the
  behavior shipped with the completion PR.

CONTRIBUTING:
- Add a "Null safety" subsection covering the project-wide
  `@NullMarked` contract and NullAway enforcement (PR apache#133).

These docs land alongside the corresponding feature PRs at apache/main.

Signed-off-by: adityamparikh <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant