click

Composable command line interface creation toolkit for Python — creates CLI tools with decorators, handles argument parsing, generates help text, and supports complex CLI hierarchies. click features: @click.command(), @click.group() for multi-command CLIs, @click.option() and @click.argument() decorators, types (INT, FLOAT, STRING, BOOL, UUID, Path, File, DateTime), multiple=True for multi-value options, required=True, default=, envvar= for env var fallback, prompt=True for interactive input, password=True for hidden input, confirmation prompts, custom callbacks, lazy loading, click.echo() for output, click.style()/click.secho() for colored output, testing via CliRunner, and progressbar.

Evaluated Mar 06, 2026 (0d ago) v8.x
Homepage ↗ Repo ↗ Developer Tools python click cli command-line arguments options decorators
⚙ Agent Friendliness
70
/ 100
Can an agent use this?
🔒 Security
89
/ 100
Is it safe for agents?
⚡ Reliability
90
/ 100
Does it work consistently?

Score Breakdown

⚙ Agent Friendliness

MCP Quality
--
Documentation
92
Error Messages
88
Auth Simplicity
99
Rate Limits
99

🔒 Security

TLS Enforcement
90
Auth Strength
90
Scope Granularity
88
Dep. Hygiene
92
Secret Handling
85

CLI framework. password=True hides input from terminal echo. envvar= for secrets reads from environment (better than CLI args visible in ps). hide_input=True equivalent. Do not log CLI argument values that may contain secrets.

⚡ Reliability

Uptime/SLA
92
Version Stability
90
Breaking Changes
88
Error Recovery
90
AF Security Reliability

Best When

Production CLI tools needing robust argument handling, nested subcommands, and extensive testing — click is the standard for Python CLI tools with excellent documentation and testing support.

Avoid When

Quick scripts (use fire), type-hint-first CLIs (use typer), or when argparse's stdlib advantage matters.

Use Cases

  • Agent CLI tool — import click; @click.command(); @click.option('--count', default=10, help='Number of items'); @click.option('--output', type=click.Path(), required=True, help='Output file'); @click.argument('input_file'); def process(count, output, input_file): data = load(input_file); results = compute(data, count); save(output, results); if __name__ == '__main__': process() — CLI; agent creates CLI with typed options
  • Agent multi-command — @click.group(); def cli(): pass; @cli.command(); @click.option('--verbose', is_flag=True); def fetch(verbose): do_fetch(verbose); @cli.command(); def process(): do_process(); if __name__ == '__main__': cli() — group; agent creates multi-subcommand CLI (like git); cli fetch --verbose; cli process
  • Agent interactive input — @click.command(); @click.option('--name', prompt='Your name', help='The person to greet'); @click.option('--count', prompt=True, type=int, default=1); def greet(name, count): for _ in range(count): click.echo(f'Hello, {name}!') — prompt; agent interactively collects missing options from user
  • Agent env var options — @click.command(); @click.option('--api-key', envvar='API_KEY', required=True, hide_input=True); @click.option('--endpoint', envvar='API_ENDPOINT', default='https://api.example.com'); def run(api_key, endpoint): call_api(api_key, endpoint) — env vars; agent reads config from environment variables with CLI override
  • Agent file processing — @click.command(); @click.argument('input', type=click.File('r')); @click.argument('output', type=click.File('w')); def transform(input, output): for line in input: output.write(process(line)) — file streams; agent reads/writes files with automatic stream handling; use '-' for stdin/stdout

Not For

  • Zero-config CLI — fire is simpler for wrapping existing functions with minimal code
  • Type-hint-first CLI — typer generates CLI from type annotations; click uses decorators
  • Complex validation pipelines — click handles basic types; for complex validation combine with pydantic

Interface

REST API
No
GraphQL
No
gRPC
No
MCP Server
No
SDK
Yes
Webhooks
No

Authentication

Methods: none
OAuth: No Scopes: No

No auth — CLI framework.

Pricing

Model: open_source
Free tier: Yes
Requires CC: No

click is BSD 3-Clause licensed. Free for all use.

Agent Metadata

Pagination
none
Idempotent
Full
Retry Guidance
Not documented

Known Gotchas

  • pass_context=True for accessing Context object — @click.command(); @click.pass_context; def cmd(ctx, ...): ctx.obj; stores shared data between commands; @click.group(); @click.pass_context; def cli(ctx): ctx.ensure_object(dict) — group pattern; agent multi-command CLIs pass shared state via context object; ctx.obj is the shared data dict
  • invoke_without_command=True for group with default action — @click.group(invoke_without_command=True) allows group to run code when no subcommand given; @click.pass_context; def group(ctx): if ctx.invoked_subcommand is None: do_default(); agent code: add default behavior when user runs just the group name without subcommand
  • standalone_mode=False to prevent sys.exit() — click calls sys.exit(0) on success by default (standalone_mode=True); standalone_mode=False returns return value instead; for embedding in tests or other code: runner.invoke(cli, catch_exceptions=False) or cli(standalone_mode=False); agent testing: use CliRunner.invoke()
  • option names with dashes become underscores — @click.option('--my-option') passes as my_option parameter (dashes to underscores); @click.option('--my-option', 'my_option_name') overrides parameter name; agent code: use dashes in CLI option names for POSIX style (--my-option); Python parameter receives underscore version automatically
  • is_flag=True creates boolean toggle — @click.option('--verbose/--no-verbose', default=False) — pair; @click.option('--verbose', is_flag=True) — single flag; agent code: --verbose sets True, not present = False; count=True for --verbose -v -vvv to count occurrences; is_eager=True for options that should be processed before others (--version)
  • CliRunner for testing does not write to terminal — from click.testing import CliRunner; runner = CliRunner(); result = runner.invoke(cli, ['--option', 'value']); result.exit_code; result.output; result.exception; agent code testing CLIs: use CliRunner — catches sys.exit, captures output, handles input; result.exit_code == 0 for success; check result.output for output

Alternatives

Full Evaluation Report

Detailed scoring breakdown, competitive positioning, security analysis, and improvement recommendations for click.

$99

Scores are editorial opinions as of 2026-03-06.

5208
Packages Evaluated
26151
Need Evaluation
173
Need Re-evaluation
Community Powered