MCP Tool Annotations
Safety metadata for MCP tools — read/write/destructive hints for proper client confirmation UX.
Every MCP tool exposed by AACWorkflow is annotated with safety metadata so MCP clients (Claude, ChatGPT, custom tools) can render correct confirmation UI and enforce appropriate guardrails before invoking sensitive operations.
Annotation types
| Annotation | Meaning | Examples |
|---|---|---|
ReadOnlyHint | Does not modify state | list_issues, get_issue, dashboard_usage_daily |
DestructiveHint | May delete or overwrite data | delete_issue, delete_comment |
IdempotentHint | Repeat calls have no extra effect | update_issue, assign_issue_to_agent |
OpenWorldHint | Touches external systems | Any tool that calls GitHub, Telegram, or third-party APIs |
Tool classification
| Tool | ReadOnly | Destructive | Idempotent | Scopes |
|---|---|---|---|---|
list_issues | ✓ | ✓ | issues:read | |
get_issue | ✓ | ✓ | issues:read | |
list_comments | ✓ | ✓ | comments:read | |
dashboard_usage_daily | ✓ | ✓ | dashboard:read | |
create_issue | issues:write | |||
update_issue | ✓ | issues:write | ||
comment_issue | comments:write | |||
assign_issue_to_agent | ✓ | agents:write | ||
trigger_autopilot | autopilot:run | |||
delete_issue (if added) | ✓ | ✓ | issues:write |
Client behavior
Read-only tools
MCP hosts do not require confirmation for read-only operations. The tool is safe to invoke without user interaction.
Destructive tools
Before invoking a destructive tool, MCP hosts must:
- Request user confirmation — "Are you sure you want to delete this issue?"
- Pass
confirm: truein the tool arguments
The server validates that confirm: true is present. If absent, the call is rejected with a 400 Bad Request:
{
"error": "confirm: true required for destructive operations"
}Idempotent tools
Idempotent tools can be safely retried without side effects. MCP hosts can invoke them multiple times (e.g., for resilience against transient failures) and get the same result.
Read-write tools (non-idempotent)
Tools like create_issue and comment_issue that create new entities are not idempotent. MCP hosts should NOT retry them on failure — doing so creates duplicate records.
Server enforcement
Annotations are advisory to the client but authoritative on the server:
- Scopes are enforced — a destructive call still fails closed if the token lacks
issues:write, regardless of client-side hints - Destructive flag is checked — missing
confirm: trueon a destructive tool is rejected server-side - Read-only queries are audited — even read-only calls are logged for compliance, but do not require confirmation
Example: Destructive tool invocation
A client wants to delete an issue. The flow:
- Client checks tool annotations and sees
DestructiveHint: true - Client prompts the user: "Delete issue AAC-42?"
- User confirms
- Client calls the tool with
confirm: true
{
"name": "delete_issue",
"arguments": {
"issue_id": "550e8400-e29b-41d4-a716-446655440000",
"confirm": true
}
}The server verifies:
- Token has
issues:writescope confirm: trueis present- Issue exists and belongs to the token's workspace
- User has permissions
If all checks pass, the issue is deleted. Otherwise, a 400 or 403 error is returned.
Implementation notes
Read-only tool handlers must never call Queries.Update* or Delete* methods. CI tests enforce this invariant across all tools tagged ReadOnlyHint: true.
- Each tool handler is marked with its annotations
- Annotations are embedded in the MCP
Tooldefinition when registering with MCP servers - The same annotations are returned by the
/toolsintrospection endpoint so clients can discover capabilities - Scope checking happens at the token layer; annotations supplement but do not replace scope enforcement
Audit trail
Every tool invocation (read or write, successful or denied) is recorded in the connector audit log:
{
"tool": "delete_issue",
"outcome": "denied",
"reason": "destructive_flag_missing",
"scopes_provided": ["issues:write"],
"timestamp": "2025-06-22T15:30:00Z"
}This allows admins to monitor which tools are being invoked and detect unusual patterns.