Module

commands

CLI application with command decorator and dispatch.

Classes

CLI 33
Command-line application with typed commands and nested groups. Each @command becomes a CLI subcom…

Command-line application with typed commands and nested groups.

Each @command becomes a CLI subcommand, an MCP tool, and a help entry. Groups create nested command namespaces.

Usage::

cli = CLI(name="myapp", description="My tool", version="1.0.0")

@cli.command("greet", description="Say hello")
def greet(name: str, loud: bool = False) -> str:
    msg = f"Hello, {name}!"
    return msg.upper() if loud else msg

site = cli.group("site", description="Site operations")

@site.command("build", description="Build the site")
def build(output: str = "_site") -> str:
    return f"Building to {output}"

cli.run()

CLI::

myapp greet --name Alice
myapp site build --output _site
myapp --llms-txt
myapp --mcp

Methods

commands 0 dict[str, CommandDef | L…
All registered top-level commands (eager and lazy).
property
def commands(self) -> dict[str, CommandDef | LazyCommandDef]
Returns
dict[str, CommandDef | LazyCommandDef]
groups 0 dict[str, Group]
All registered top-level groups.
property
def groups(self) -> dict[str, Group]
Returns
dict[str, Group]
global_option 6
Register a global option available to all commands via Context. Usage:: c…
def global_option(self, name: str, *, short: str = '', option_type: type = str, default: Any = None, description: str = '', is_flag: bool = False) -> None

Register a global option available to all commands via Context.

Usage::

cli.global_option("environment", short="-e", default="local",
                  description="Config environment")
Parameters
Name Type Description
name
short Default:''
option_type Default:str
default Default:None
description Default:''
is_flag Default:False
before_command 1 Callable
Register a hook that runs before every command. The hook receives (ctx, comman…
def before_command(self, fn: Callable) -> Callable

Register a hook that runs before every command.

The hook receives (ctx, command_name, kwargs) and can modify kwargs.

Usage::

@cli.before_command
def check_auth(ctx, command_name, kwargs):
    if not os.environ.get("API_KEY"):
        raise SystemExit("API_KEY not set")
Parameters
Name Type Description
fn
Returns
Callable
after_command 1 Callable
Register a hook that runs after every command. The hook receives (ctx, command…
def after_command(self, fn: Callable) -> Callable

Register a hook that runs after every command.

The hook receives (ctx, command_name, result).

Usage::

@cli.after_command
def log_result(ctx, command_name, result):
    ctx.log(f"{command_name} completed", level=1)
Parameters
Name Type Description
fn
Returns
Callable
command 7 Callable
Register a function as a CLI command. The function's type annotations drive: -…
def command(self, name: str, *, description: str = '', aliases: tuple[str, ...] | list[str] = (), tags: tuple[str, ...] | list[str] = (), hidden: bool = False, examples: tuple[dict[str, Any], ...] | list[dict[str, Any]] = (), confirm: str = '') -> Callable

Register a function as a CLI command.

The function's type annotations drive:

  • argparse argument generation
  • MCP tool schema
  • help text
Parameters
Name Type Description
name
description Default:''
aliases Default:()
tags Default:()
hidden Default:False
examples Default:()
confirm

If set, prompt user with this message before executing.

Default:''
Returns
Callable
lazy_command 9 LazyCommandDef
Register a lazy-loaded command. The handler module is not imported until the c…
def lazy_command(self, name: str, import_path: str, *, description: str = '', schema: dict[str, Any] | None = None, aliases: tuple[str, ...] | list[str] = (), tags: tuple[str, ...] | list[str] = (), hidden: bool = False, examples: tuple[dict[str, Any], ...] | list[dict[str, Any]] = (), confirm: str = '') -> LazyCommandDef

Register a lazy-loaded command.

The handler module is not imported until the command is invoked. This keeps CLI startup fast for large command sets.

Parameters
Name Type Description
name
import_path
description Default:''
schema Default:None
aliases Default:()
tags Default:()
hidden Default:False
examples Default:()
confirm Default:''
Returns
LazyCommandDef
resource 4 Callable
Register a function as an MCP resource. Usage:: @cli.resource("config://a…
def resource(self, uri: str, *, name: str = '', description: str = '', mime_type: str = 'text/plain') -> Callable

Register a function as an MCP resource.

Usage::

@cli.resource("config://app", description="App config")
def get_config() -> dict: ...
Parameters
Name Type Description
uri
name Default:''
description Default:''
mime_type Default:'text/plain'
Returns
Callable
prompt 3 Callable
Register a function as an MCP prompt. Usage:: @cli.prompt("deploy-checkli…
def prompt(self, name: str, *, description: str = '', arguments: tuple[dict[str, Any], ...] | list[dict[str, Any]] = ()) -> Callable

Register a function as an MCP prompt.

Usage::

@cli.prompt("deploy-checklist", description="Pre-deploy steps")
def checklist(environment: str) -> list[dict]: ...
Parameters
Name Type Description
name
description Default:''
arguments Default:()
Returns
Callable
middleware 1 Callable
Register a middleware function. Usage:: @cli.middleware def log_calls…
def middleware(self, fn: Callable) -> Callable

Register a middleware function.

Usage::

@cli.middleware
def log_calls(ctx, call, next_fn):
    result = next_fn(call)
    return result
Parameters
Name Type Description
fn
Returns
Callable
group 4 Group
Create and register a command group. Returns the Group for registering command…
def group(self, name: str, *, description: str = '', aliases: tuple[str, ...] | list[str] = (), hidden: bool = False) -> Group

Create and register a command group.

Returns the Group for registering commands within it::

site = cli.group("site", description="Site operations")

@site.command("build", description="Build the site")
def build(output: str = "_site") -> str: ...
Parameters
Name Type Description
name
description Default:''
aliases Default:()
hidden Default:False
Returns
Group
add_group 1
Register an externally-created Group.
def add_group(self, group: Group) -> None
Parameters
Name Type Description
group
mount 2
Mount another CLI as a command group. In-process, no subprocess. Usage:: …
def mount(self, prefix: str, other: CLI) -> None

Mount another CLI as a command group. In-process, no subprocess.

Usage::

main = CLI(name="main")
sub = CLI(name="sub")
main.mount("sub", sub)
# sub's commands are now at main.sub.*
Parameters
Name Type Description
prefix
other
get_command 1 CommandDef | LazyCommand…
Look up a command by name, alias, or dotted path. Dotted paths traverse groups…
def get_command(self, name: str) -> CommandDef | LazyCommandDef | None

Look up a command by name, alias, or dotted path.

Dotted paths traverse groups:get_command("site.build") resolves to thebuild command inside the sitegroup.

Parameters
Name Type Description
name
Returns
CommandDef | LazyCommandDef | None
walk_commands 0
Yield all commands in the tree as (dotted_path, CommandDef) tuples. Top-level …
def walk_commands(self)

Yield all commands in the tree as (dotted_path, CommandDef) tuples.

Top-level commands have simple names. Group commands use dots::

[("greet", greet_cmd), ("site.build", build_cmd), ...]
walk_resources 0 list[tuple[str, Resource…
Walk all registered resources.
def walk_resources(self) -> list[tuple[str, ResourceDef]]
Returns
list[tuple[str, ResourceDef]]
walk_prompts 0 list[tuple[str, PromptDe…
Walk all registered prompts.
def walk_prompts(self) -> list[tuple[str, PromptDef]]
Returns
list[tuple[str, PromptDef]]
build_parser 0 argparse.ArgumentParser
Build argparse parser from registered commands and groups.
def build_parser(self) -> argparse.ArgumentParser
Returns
argparse.ArgumentParser
run 1 Any
Parse args and dispatch to the appropriate command.
def run(self, argv: list[str] | None = None) -> Any
Parameters
Name Type Description
argv Default:None
Returns
Any
invoke 1 InvokeResult
Run a command and capture output for testing. Stdout and stderr are captured s…
def invoke(self, argv: list[str]) -> InvokeResult

Run a command and capture output for testing.

Stdout and stderr are captured separately.outputcontains stdout (command results),stderrcontains log/error messages.

Usage::

result = cli.invoke(["greet", "--name", "Alice"])
assert result.exit_code == 0
assert "Alice" in result.output
assert result.stderr == ""  # no warnings
Parameters
Name Type Description
argv
Returns
InvokeResult
call 2 Any
Programmatically call a command by name or dotted path. Used by MCP server and…
def call(self, command_name: str, **kwargs: Any) -> Any

Programmatically call a command by name or dotted path.

Used by MCP server and for programmatic invocation::

cli.call("greet", name="Alice")
cli.call("site.build", output="_site")
Parameters
Name Type Description
command_name
**kwargs
Returns
Any
suggest_command 1 str | None
Suggest the closest command name for typo correction.
def suggest_command(self, name: str) -> str | None
Parameters
Name Type Description
name
Returns
str | None
generate_help_all 0 str
Generate a full command tree reference in markdown.
def generate_help_all(self) -> str
Returns
str
Internal Methods 10
__init__ 3
def __init__(self, *, name: str = '', description: str = '', version: str = '') -> None
Parameters
Name Type Description
name Default:''
description Default:''
version Default:''
_resolve_dotted 1 CommandDef | LazyCommand…
Resolve a dotted command path like 'site.config.show'.
def _resolve_dotted(self, path: str) -> CommandDef | LazyCommandDef | None
Parameters
Name Type Description
path
Returns
CommandDef | LazyCommandDef | None
_add_commands_to_subparsers 2
Add command parsers to a subparsers action.
def _add_commands_to_subparsers(self, subparsers: argparse._SubParsersAction, commands: dict[str, CommandDef | LazyCommandDef]) -> None
Parameters
Name Type Description
subparsers
commands
_add_groups_to_subparsers 2
Recursively add group parsers to a subparsers action.
def _add_groups_to_subparsers(self, subparsers: argparse._SubParsersAction, groups: dict[str, Group]) -> None
Parameters
Name Type Description
subparsers
groups
_add_arguments_from_schema 3
Add argparse arguments from a command's JSON schema. Uses the handler's signat…
def _add_arguments_from_schema(self, parser: argparse.ArgumentParser, schema: dict[str, Any], cmd: CommandDef | LazyCommandDef) -> None

Add argparse arguments from a command's JSON schema.

Uses the handler's signature for defaults when available (eager commands), or falls back to schema-only mode (lazy commands).

Parameters
Name Type Description
parser
schema
cmd
_build_context 1 Context
Build a Context from parsed global options.
def _build_context(self, args: argparse.Namespace) -> Context
Parameters
Name Type Description
args
Returns
Context
_resolve_command_from_args 1 tuple[CommandDef | LazyC…
Walk the parsed args to find the leaf command.
def _resolve_command_from_args(self, args: argparse.Namespace) -> tuple[CommandDef | LazyCommandDef | None, str]
Parameters
Name Type Description
args
Returns
tuple[CommandDef | LazyCommandDef | None, str]
_resolve_group_command 3 tuple[CommandDef | None,…
Recursively resolve a command within a group from parsed args.
def _resolve_group_command(self, group: Group, args: argparse.Namespace, fmt: str) -> tuple[CommandDef | None, str]
Parameters
Name Type Description
group
args
fmt
Returns
tuple[CommandDef | None, str]
_mcp_install 0
Register this CLI in the milo gateway.
def _mcp_install(self) -> None
_mcp_uninstall 0
Remove this CLI from the milo gateway.
def _mcp_uninstall(self) -> None