Module

commands

CLI application with command decorator and dispatch.

Classes

CLI 50
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 9 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 = '', annotations: dict[str, Any] | None = None, display_result: bool = True) -> 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:''
annotations

MCP tool annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint).

Default:None
display_result

If False, suppress plain-format output while still returning data for--format json or --output-file.

Default:True
Returns
Callable
lazy_command 11 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 = '', annotations: dict[str, Any] | None = None, display_result: bool = True) -> 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.

When providing a pre-computed schema, include"default"fields in properties for optional parameters so argparse receives the correct defaults without importing the handler module.

Parameters
Name Type Description
name
import_path
description Default:''
schema Default:None
aliases Default:()
tags Default:()
hidden Default:False
examples Default:()
confirm Default:''
annotations Default:None
display_result Default:True
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
call_raw 2 Any
Call a command without consuming generators. Like `call`(), but returns the ra…
def call_raw(self, command_name: str, **kwargs: Any) -> Any

Call a command without consuming generators.

Likecall(), but returns the raw result — if the handler returns a generator, it is not consumed. The MCP server uses this to streamProgressyields as notifications.

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 26
__init__ 3
def __init__(self, *, name: str = '', description: str = '', version: str = '') -> None
Parameters
Name Type Description
name Default:''
description Default:''
version Default:''
_bump_command_version 0
Mark command discovery caches stale.
def _bump_command_version(self) -> None
_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
_resolve_builtin_mode 1 BuiltinMode | None
Return the selected built-in top-level mode, if any.
def _resolve_builtin_mode(self, args: argparse.Namespace) -> BuiltinMode | None
Parameters
Name Type Description
args
Returns
BuiltinMode | None
_run_builtin_mode 2
Execute a built-in top-level mode.
def _run_builtin_mode(self, args: argparse.Namespace, mode: BuiltinMode) -> None
Parameters
Name Type Description
args
mode
_resolve_command_execution 1 CommandExecution | None
Resolve parsed args to an executable command or handle help cases.
def _resolve_command_execution(self, args: argparse.Namespace) -> CommandExecution | None
Parameters
Name Type Description
args
Returns
CommandExecution | None
_build_run_kwargs 3 dict[str, Any]
Build handler kwargs from parsed args, injecting the active context.
def _build_run_kwargs(self, args: argparse.Namespace, ctx: Context, command: CommandDef) -> dict[str, Any]
Parameters
Name Type Description
args
ctx
command
Returns
dict[str, Any]
_build_handler_kwargs_from_namespace 3 dict[str, Any]
Build handler kwargs from an argparse namespace.
def _build_handler_kwargs_from_namespace(self, args: argparse.Namespace, ctx: Context, command: CommandDef) -> dict[str, Any]
Parameters
Name Type Description
args
ctx
command
Returns
dict[str, Any]
_get_resolved_command 1 tuple[CommandDef | LazyC…
Resolve a command name to the registered definition and eager command. Raises …
def _get_resolved_command(self, command_name: str) -> tuple[CommandDef | LazyCommandDef, CommandDef]

Resolve a command name to the registered definition and eager command.

RaisesLazyImportErrorif a lazy command fails to import.

Parameters
Name Type Description
command_name
Returns
tuple[CommandDef | LazyCommandDef, CommandDef]
_filter_call_kwargs 2 dict[str, Any]
Filter programmatic kwargs to handler parameters, excluding context injection.
def _filter_call_kwargs(self, command: CommandDef, kwargs: dict[str, Any]) -> dict[str, Any]

Filter programmatic kwargs to handler parameters, excluding context injection.

Parameters
Name Type Description
command
kwargs
Returns
dict[str, Any]
_build_call_kwargs 3 dict[str, Any]
Build handler kwargs for programmatic/MCP calls, injecting context.
def _build_call_kwargs(self, command: CommandDef, kwargs: dict[str, Any], ctx: Context) -> dict[str, Any]
Parameters
Name Type Description
command
kwargs
ctx
Returns
dict[str, Any]
_new_call_context 0 Context
Create a default context for programmatic command calls.
def _new_call_context(self) -> Context
Returns
Context
_execute_command 6 Any
Execute a command with context setup, hooks, middleware, and error handling.
def _execute_command(self, command: CommandDef, ctx: Context, kwargs: dict[str, Any], *, method: str = 'command', call_name: str | None = None, raise_on_error: bool = False) -> Any
Parameters
Name Type Description
command
ctx
kwargs
method Default:'command'
call_name Default:None
raise_on_error Default:False
Returns
Any
_run_before_command_hooks 3
Execute before-command hooks.
def _run_before_command_hooks(self, ctx: Context, command_name: str, kwargs: dict[str, Any]) -> None
Parameters
Name Type Description
ctx
command_name
kwargs
_run_after_command_hooks 3
Execute after-command hooks.
def _run_after_command_hooks(self, ctx: Context, command_name: str, result: Any) -> None
Parameters
Name Type Description
ctx
command_name
result
_consume_result 2 Any
Consume generator-based command results.
def _consume_result(self, result: Any, *, emit_progress: bool = True) -> Any
Parameters
Name Type Description
result
emit_progress Default:True
Returns
Any
_write_command_output 4
Write command output to stdout or a file. When *output_file* already exists an…
def _write_command_output(self, result: Any, fmt: str, output_file: str, *, force: bool = False) -> None

Write command output to stdout or a file.

When output_file already exists and force is False, prints an error and exits instead of silently overwriting.

Parameters
Name Type Description
result
fmt
output_file
force Default:False
_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
_format_root_help 0
Render root help from command/group registries and the actual parser.
def _format_root_help(self) -> None
_resolve_command_from_args 1 ResolveResult
Walk the parsed args to find the leaf command, group, or nothing.
def _resolve_command_from_args(self, args: argparse.Namespace) -> ResolveResult
Parameters
Name Type Description
args
Returns
ResolveResult
_resolve_group_command 4 ResolveResult
Recursively resolve a command within a group from parsed args.
def _resolve_group_command(self, group: Group, args: argparse.Namespace, fmt: str, prog: str = '') -> ResolveResult
Parameters
Name Type Description
group
args
fmt
prog Default:''
Returns
ResolveResult
_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