aeat.entrypoints.mcp._annotations module

Project operator mutability onto MCP tool annotations.

The capability manifest annotates each command family READ_ONLY or LOCAL_STATE_MUTATING. MCP clients use ToolAnnotations hints (readOnlyHint / destructiveHint / idempotentHint) to decide when to ask a human before a tool runs. This module is the single mapping from the backend mutability contract to those hints, plus the small, explicit set of verb families that are destructive or naturally idempotent.

It also owns the annotation-coverage contract: annotations_are_covered() defines when a descriptor’s read-only / destructive hints are present and mutually consistent, annotation_coverage_gaps() sweeps a descriptor set for violations, and annotations_for_command() enforces the same guard at construction, so the server build and the tests inherit full coverage from one place.

class McpAnnotations(**data)[source]

Bases: BaseModel

SDK-independent MCP tool annotations for one command.

Maps to the MCP ToolAnnotations hint fields, derived from the single classify_command() authority (ADR mcp-protocol-hardening H3). read_only_hint mirrors the family mutability; destructive_hint is true only for irreversible state-destroying verbs; idempotent_hint for pure repeatable reads; open_world_hint for a verb that reaches the outside AEAT sede.

Parameters:
  • title (str)

  • read_only_hint (bool)

  • destructive_hint (bool)

  • idempotent_hint (bool)

  • open_world_hint (bool)

title: str
read_only_hint: bool
destructive_hint: bool
idempotent_hint: bool
open_world_hint: bool
annotations_for_command(*, command_key, mutability, title)[source]

Build the MCP annotations for one command key.

Derived from classify_command() - the one authority the HITL confirmation tier also reads - so the client hint and the server gate cannot drift.

Parameters:
  • command_key (str) – The registry command key (e.g. "ledger.remove").

  • mutability (OperatorMutability) – The owning family’s mutability from the manifest.

  • title (str) – A human-readable tool title.

Return type:

McpAnnotations

Returns:

McpAnnotations for the command’s MCP descriptor.

annotations_are_covered(annotations)[source]

Return whether one annotation’s read-only / destructive hints are coherent.

Coverage means the two decision hints a client acts on are present (they are non-optional booleans) and mutually consistent: a tool is never both read-only and destructive, a read-only tool is idempotent, and a destructive tool mutates state. A descriptor that fails this is an annotation gap.

Return type:

bool

Parameters:

annotations (McpAnnotations)

annotation_coverage_gaps(annotated)[source]

Return the command keys whose annotations fail annotations_are_covered().

The shared coverage function the server build and the tests both run over the full descriptor set; an empty result is full annotation coverage.

Return type:

tuple[str, ...]

Returns:

The command keys with an annotation coverage gap, in input order.

Parameters:

annotated (Iterable[tuple[str, McpAnnotations]])