aeat.entrypoints.mcp._meta_tools module

The search + execute meta-tool pair for the long-tail verb surface.

The curated domain toolsets (_toolsets) cover the common path; the rest of the operator-callable verb tree is reached through two meta-tools, the Cloudflare precedent for a large API surface (ADR decision R2): search maps a natural query onto matching command keys with their intent and mutability, and execute runs one command key with typed arguments.

The load-bearing guarantee is that execute is NOT a side door. It routes through the exact same gates a direct tool call runs - gate_refusal() applies the persona-scope boundary and the permanent live-write block before any dispatch, producing byte-identical refusals - so a verb an active persona may not call directly cannot be reached by naming it to execute either. The dispatch itself is injected (meta_execute() takes the server’s subprocess runner) so this module stays SDK-independent and unit-tested.

ToolRunner

it takes a descriptor and the named arguments and returns the CLI envelope plus an error flag, exactly as the direct call path runs it.

Type:

The subprocess runner the server injects into meta_execute()

alias of Callable[[McpToolDescriptor, dict[str, object]], tuple[dict[str, object], bool]]

class MetaSearchResult(**data)[source]

Bases: BaseModel

One command matched by search_commands(), with its decision hints.

The result is self-sufficient (ADR mcp-progressive-discovery P2): besides the mutability hints it carries the per-verb input_schema, so a model that finds a verb through search can call it through execute in ONE more round-trip without a separate schema lookup.

Parameters:
command_key: str
tool_name: str
description: str
read_only: bool
destructive: bool
score: float
input_schema: dict[str, Any]
class MetaExecuteResult(**data)[source]

Bases: BaseModel

The outcome of a meta_execute() call.

Exactly one of refused or envelope is populated: a gated or unknown command carries the refusal message and no envelope; an allowed command carries the CLI envelope and its error flag.

Parameters:
command_key: str
refused: str | None
envelope: dict[str, object] | None
is_error: bool
build_command_search_index(descriptors)[source]

Build the hybrid command-search index over the descriptor set.

Built once per server from the full descriptor set so search reaches the whole verb universe, not just the advertised surface.

Return type:

CommandIndex

Parameters:

descriptors (tuple[McpToolDescriptor, ...])

search_commands(query, *, descriptors, index=None, limit=20)[source]

Rank the command surface against query for the search meta-tool.

Backed by the hybrid command index (FTS5 lexical + Spanish stemming + diacritics folding, degrading to token overlap on a minimal install), so a concept query bridges the operator’s vocabulary to the command’s own tokens where a bare substring match would miss it (ADR mcp-progressive-discovery P2). Each result carries the mutability hints AND the per-verb input schema so it is actionable in one further execute round-trip. index may be a prebuilt index (the server builds it once); when omitted it is built from descriptors.

Return type:

tuple[MetaSearchResult, ...]

Returns:

The matched commands, highest score first, capped at limit.

Parameters:
class MetaSearchResponse(**data)[source]

Bases: BaseModel

The search meta-tool result with its overflow signal.

Wraps the capped MetaSearchResult page with how much the corpus actually matched (ADR mcp-progressive-discovery P2/S11): total_matches is the full count over the whole verb surface, truncated is true when the page dropped some of them, and hint names the next moves - describe for one command’s full schema, toolsets to widen the advertised surface - so a model that overflowed the page knows it did and how to recover.

Parameters:
results: tuple[MetaSearchResult, ...]
total_matches: int
truncated: bool
hint: str
search_commands_response(query, *, descriptors, index=None, limit=20)[source]

Rank the command surface and report how much of it overflowed the page.

Returns the same capped page as search_commands() alongside the full match count over the whole verb corpus, so the client sees whether the page truncated the result set. total_matches counts every command key the index matches (capped internally at the corpus size, never a semantic backend - that is a later step); truncated and the recovery hint follow from it. A blank query returns the empty response.

Return type:

MetaSearchResponse

Returns:

The MetaSearchResponse for query.

Parameters:
class MetaDescribeResult(**data)[source]

Bases: BaseModel

One command’s full descriptor for the describe meta-tool.

The self-sufficient counterpart to a MetaSearchResult hit (ADR mcp-progressive-discovery P2/S10): where search returns a ranked page of decision hints, describe returns ONE command’s whole shape by key - its per-verb input_schema, its mutability annotations, its confirmation tier, its declared risk posture, its owning curated toolset, and exactly which personas may call it - so a model can inspect a verb fully before spending an execute round-trip on it.

Parameters:
  • command_key (str)

  • tool_name (str)

  • description (str)

  • input_schema (dict[str, Any])

  • read_only (bool)

  • destructive (bool)

  • idempotent (bool)

  • open_world (bool)

  • confirmation_tier (str)

  • risk_destructive (bool)

  • risk_handoff (bool)

  • risk_live_write (bool)

  • owning_toolset (str | None)

  • reachable_personas (tuple[str, ...])

command_key: str
tool_name: str
description: str
input_schema: dict[str, Any]
read_only: bool
destructive: bool
idempotent: bool
open_world: bool
confirmation_tier: str
risk_destructive: bool
risk_handoff: bool
risk_live_write: bool
owning_toolset: str | None
reachable_personas: tuple[str, ...]
describe_command(command_key, *, descriptors)[source]

Return one command’s full descriptor by key, or None when unexposed.

Resolves everything from the live descriptor set and the real classifiers - the annotation hints from the descriptor, the confirmation tier from confirmation_for_tool(), the declared risk from declared_risk() (all-false for a read-only command with no row), the owning toolset from toolset_for_command(), and the reachable personas from the same scope + handoff-deny gates the call path enforces. A key that names no exposed descriptor returns None.

Return type:

MetaDescribeResult | None

Returns:

The MetaDescribeResult for command_key, or None.

Parameters:
gate_refusal(*, persona, descriptor)[source]

Return the refusal a tool call incurs, or None when it may proceed.

The single gate sequence run by BOTH the direct call path and execute: an out-of-scope call is refused, then a persona’s handoff-denied verb, then the permanent live-write block. The messages are byte-identical to the direct path’s refusals, so the two entry points cannot diverge — the per-verb handoff deny (verifier-only export/record-marker, ADR R6(iii)) is enforced here STRUCTURALLY, not left to the sync path’s incidental no-elicitation fallback.

Return type:

str | None

Returns:

The refusal message, or None when the call is allowed.

Parameters:
class ToolsetAction(*values)[source]

Bases: StrEnum

The three verbs the toolsets management meta-tool accepts.

LIST
ACTIVATE
DEACTIVATE
class ToolsetManageResult(**data)[source]

Bases: BaseModel

The outcome of a manage_toolsets() call.

changed is true only when the active set actually moved (so the caller knows whether to emit tools/list_changed). groups lists every toolset with its member count and current active state; refused carries an instructive message when an action could not be applied (unknown name, cap reached).

Parameters:
action: str
changed: bool
active: tuple[str, ...]
groups: tuple[dict[str, object], ...]
refused: str | None
manage_toolsets(action, name, *, active)[source]

Apply a toolsets action, mutating active in place.

list reports the groups and current state without change. activate adds a toolset (refused past MAX_ACTIVE_TOOLSETS or on an unknown name); deactivate removes one. Activation widens the advertised surface within the active persona’s scope (the server applies the scope filter when it rebuilds the tool list), so this function owns only the set membership and the cap.

Return type:

ToolsetManageResult

Returns:

A ToolsetManageResult; changed drives the list-changed notification.

Parameters:
meta_execute(command_key, arguments, *, descriptors, persona, run)[source]

Execute one command key through the same gates as a direct tool call.

Resolves the descriptor, applies gate_refusal(), and only on a clear gate invokes the injected run dispatcher. An unknown command key is refused; a gated one carries its refusal and never reaches run.

Return type:

MetaExecuteResult

Returns:

The MetaExecuteResult for the call.

Parameters: