Classes
CLI
50
▼
Command-line application with typed commands and nested groups.
Each @command becomes a CLI subcom…
CLI
50
▼
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
commands
0
dict[str, CommandDef | L…
▼
def commands(self) -> dict[str, CommandDef | LazyCommandDef]
Returns
dict[str, CommandDef | LazyCommandDef]
groups
0
dict[str, Group]
▼
All registered top-level groups.
property
groups
0
dict[str, Group]
▼
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…
global_option
6
▼
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…
before_command
1
Callable
▼
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…
after_command
1
Callable
▼
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:
-…
command
9
Callable
▼
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 True
|
Returns
Callable
lazy_command
11
LazyCommandDef
▼
Register a lazy-loaded command.
The handler module is not imported until the c…
lazy_command
11
LazyCommandDef
▼
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…
resource
4
Callable
▼
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…
prompt
3
Callable
▼
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…
middleware
1
Callable
▼
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…
group
4
Group
▼
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.
add_group
1
▼
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::
…
mount
2
▼
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…
get_command
1
CommandDef | LazyCommand…
▼
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 …
walk_commands
0
▼
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.
walk_resources
0
list[tuple[str, Resource…
▼
def walk_resources(self) -> list[tuple[str, ResourceDef]]
Returns
list[tuple[str, ResourceDef]]
walk_prompts
0
list[tuple[str, PromptDe…
▼
Walk all registered prompts.
walk_prompts
0
list[tuple[str, PromptDe…
▼
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.
build_parser
0
argparse.ArgumentParser
▼
def build_parser(self) -> argparse.ArgumentParser
Returns
argparse.ArgumentParser
run
1
Any
▼
Parse args and dispatch to the appropriate command.
run
1
Any
▼
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…
invoke
1
InvokeResult
▼
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…
call
2
Any
▼
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…
call_raw
2
Any
▼
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.
suggest_command
1
str | None
▼
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.
generate_help_all
0
str
▼
def generate_help_all(self) -> str
Returns
str
Internal Methods 26 ▼
__init__
3
▼
__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.
_bump_command_version
0
▼
def _bump_command_version(self) -> None
_resolve_dotted
1
CommandDef | LazyCommand…
▼
Resolve a dotted command path like 'site.config.show'.
_resolve_dotted
1
CommandDef | LazyCommand…
▼
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.
_add_commands_to_subparsers
2
▼
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.
_add_groups_to_subparsers
2
▼
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…
_add_arguments_from_schema
3
▼
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.
_resolve_builtin_mode
1
BuiltinMode | None
▼
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.
_run_builtin_mode
2
▼
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.
_resolve_command_execution
1
CommandExecution | None
▼
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.
_build_run_kwargs
3
dict[str, Any]
▼
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.
_build_handler_kwargs_from_namespace
3
dict[str, Any]
▼
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 …
_get_resolved_command
1
tuple[CommandDef | LazyC…
▼
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.
_filter_call_kwargs
2
dict[str, Any]
▼
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.
_build_call_kwargs
3
dict[str, Any]
▼
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.
_new_call_context
0
Context
▼
def _new_call_context(self) -> Context
Returns
Context
_execute_command
6
Any
▼
Execute a command with context setup, hooks, middleware, and error handling.
_execute_command
6
Any
▼
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.
_run_before_command_hooks
3
▼
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.
_run_after_command_hooks
3
▼
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.
_consume_result
2
Any
▼
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…
_write_command_output
4
▼
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.
_build_context
1
Context
▼
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.
_format_root_help
0
▼
def _format_root_help(self) -> None
_resolve_command_from_args
1
ResolveResult
▼
Walk the parsed args to find the leaf command, group, or nothing.
_resolve_command_from_args
1
ResolveResult
▼
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.
_resolve_group_command
4
ResolveResult
▼
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.
_mcp_install
0
▼
def _mcp_install(self) -> None
_mcp_uninstall
0
▼
Remove this CLI from the milo gateway.
_mcp_uninstall
0
▼
def _mcp_uninstall(self) -> None