15. Mark a tool read-only / destructive (annotation hints)
You want to advertise behavioral hints โ this tool only reads, that one might delete โ so clients can warn users or auto-approve safe calls.
Problem. You want to advertise behavioral hints โ this tool only reads, that one might delete โ so clients can warn users or auto-approve safe calls.
Solution. Declarative bangs on the tool wrapper. These map to standard MCP tool annotations.
class FetchLatestApplicantTool < McpAuthorization::Tool
tool_name "fetch_latest_applicant"
read_only! # only reads data
dynamic_contract Workflows::FetchLatestApplicant
end
class AdvanceStepTool < McpAuthorization::Tool
tool_name "advance_step"
not_destructive! # mutates, but doesn't destroy
idempotent! # repeat calls = same effect
dynamic_contract Workflows::AdvanceStep
endResult. The hints ride along in the tool definition. Full set: read_only!, destructive!, not_destructive!, idempotent!, open_world! (touches external services), closed_world! (stays in-system). They're advisory metadata โ not a security boundary. For security, reach for authorization, gate, and @requires.
Collected from COOKBOOK.md in the repository. Edit it there, not here.