aeat.entrypoints.mcp._input_schema module¶
Derive a per-verb JSON input schema from the CLI’s own click parameters.
Each operator-callable registry command key resolves to exactly one leaf in the
aeat Typer/click command tree. This module walks that tree once, reads each
command’s declared parameters (positional Argument`s and
`–option`` Option`s), and projects them into a strict, typed
:class:`VerbInputSchema: the ordered parameter list, each parameter’s JSON type,
requiredness, enum choices, multiplicity, and flag shape, plus the resolved CLI
path tokens.
The resolved path is load-bearing. A registry command key carries segment tokens
with underscores (app.live.iva_wallet.pull) while the live CLI command is
hyphenated (aeat app live iva-wallet pull); walking the real tree records the
command names as click knows them, so cli_argv_for() builds an argv that
actually dispatches. The prior {args: [string]} bag forced the operator to
run --help per verb and split the argv itself; a per-verb schema replaces it
so a client renders a typed form and the console maps named arguments back to CLI
tokens deterministically.
This module owns no MCP protocol detail. It reads the CLI command tree and emits SDK-independent pydantic records, so it is unit-tested directly.
- class VerbParamKind(*values)[source]¶
Bases:
StrEnumWhether a parameter is a positional argument or a
--option.- ARGUMENT¶
- OPTION¶
- class JsonType(*values)[source]¶
Bases:
StrEnumThe JSON Schema scalar type a CLI parameter projects onto.
- STRING¶
- INTEGER¶
- NUMBER¶
- BOOLEAN¶
- class VerbParameter(**data)[source]¶
Bases:
BaseModelOne CLI parameter projected into a JSON-schema property.
nameis the click parameter name (the JSON property key). For anOPTIONthecli_flagis the long option token (--file); for anARGUMENTit is empty and the value is a bare positional.multiplerenders the property as a JSON array and repeats the token per element;is_flagis a bare boolean switch that emits itscli_flagwhen truthy and, for a--flag/--no-flagpair, itsoff_flag(the secondary--no-token) when explicitly false.defaultcarries the parameter’s click default rendered JSON-safely, so a client can see the real default (including a default-on flag it may disable).- Parameters:
- name: str¶
- kind: VerbParamKind¶
- cli_flag: str¶
- off_flag: str¶
- json_type: JsonType¶
- required: bool¶
- is_flag: bool¶
- multiple: bool¶
- choices: tuple[str, ...]¶
- default: bool | int | float | str | list[Any] | None¶
- help: str¶
- class VerbInputSchema(**data)[source]¶
Bases:
BaseModelThe strict per-verb input contract for one exposed MCP tool.
cli_pathis the resolved command path as click names it (hyphenated leaf tokens), so dispatch never re-derives it from the underscored command key.parameterspreserves the CLI declaration order, whichcli_argv_for()relies on to place positional arguments before options.- Parameters:
- command_key: str¶
- cli_path: tuple[str, ...]¶
- parameters: tuple[VerbParameter, ...]¶
- help: str¶
The command’s own one-line help (its click
short_help/ first help line), so the MCP tool description can be verb-specific rather than the shared family intent (ADR mcp-progressive-discovery P2/S05).
- exception SchemaResolutionError[source]¶
Bases:
RuntimeErrorA command key’s CLI subtree failed to materialise during schema build.
Raised by
assert_schema_coverage()when the tree walk RAISED while materialising a lazily-loaded subcommand. Such a failure would otherwise degrade silently to an argument-free schema (research finding F2), shipping a verb whose parameters vanished because of a Typer declaration bug; this error turns that silent degradation into a loud, verb-named build-time failure.
- assert_schema_coverage(resolution_errors)[source]¶
Fail the build when any command key’s subtree failed to materialise.
resolution_errorsmaps a command key to the reason its lazily-loaded subtree raised during the tree walk. An empty mapping is the healthy state (a genuine no-arg command or a stale not-found key never appears here — only a resolution FAILURE does). Any entry names a verb that would silently ship an argument-free schema and raisesSchemaResolutionError.
- build_verb_input_schema(root, command_key)[source]¶
Build the
VerbInputSchemafor one command key.Resolves the leaf command in the tree rooted at
rootand reads its click parameters. A key that does not resolve to a live command - a stale registry key, or one whose subtree cannot be introspected because a command in it declares a Typer-unconvertible parameter type - falls back to an empty parameter set over the naive path, yielding a valid (argument-free) descriptor rather than crashing this single-key build. The batch entry pointbuild_verb_input_schemas()runs the coverage gate that turns a resolution FAILURE into a loud build error.- Return type:
- Returns:
The strict
VerbInputSchemafor the command.- Parameters:
root (Command)
command_key (str)
- build_verb_input_schemas(command_keys)[source]¶
Build the per-verb input schemas for every command key.
Materialises the
aeatclick command once and walks it per key. The walk imports each lazily-loaded command subtree exactly as real dispatch does, so the schemas reflect the live CLI surface. Any subtree whose materialisation RAISES fails the coverage gate (assert_schema_coverage()) with the offending verb named, rather than silently degrading to an argument-free schema.- Return type:
- Returns:
A mapping of command key to its
VerbInputSchema.- Parameters:
- cli_argv_for(schema, arguments)[source]¶
Build the
aeatargv tail for a tool call from namedarguments.Positional arguments are emitted in their CLI declaration order and precede every option; a multiple argument or option repeats per element; a boolean flag emits its on-token when truthy and, for a
--flag/--no-flagpair, itsoff_flag(--no-flag) when explicitly false — so a default-on flag can be turned off through the surface. A bare switch (no off-token) emits nothing when false.--format jsonleads the tail so the machine envelope is always requested, followed by the resolved command path.