microcli-toolkit
Lean CLI framework for AI-friendly micro-apps
Microcli is a decorator-based CLI framework designed for building tools that agents can use. Unlike traditional CLIs that return data, microcli tools return instructions that guide the next step.
Installation
pip install microcli-toolkit
# or
uv add microcli-toolkit
Quick Start
#!/usr/bin/env python3
from typing import Annotated
import microcli as m
@m.command
def hello(name: Annotated[str, "Your name"]):
"""Greet a user."""
m.ok(f"Hello, {name}!")
if __name__ == "__main__":
m.main()
python hello.py hello Alice
# ✓ Hello, Alice!
Composing apps with App + mount
The module-level m.command / m.main() shorthand is fine for one-file
scripts. When you want to compose multiple sub-CLIs under one entry point,
construct explicit App instances and mount them under prefix keys:
import microcli as m
from mosaico import app as mosaico_app
from mira import app as mira_app
root = m.App(name="claude-toolkit", description="Alex's agent toolbox.")
root.mount("image", mosaico_app) # claude-toolkit image gen ...
root.mount("mira", mira_app) # claude-toolkit mira search ...
@root.command
def hello(name: str):
m.ok(f"Hello, {name}!")
if __name__ == "__main__":
root.main()
Each App owns its own command registry — there are no name clashes between
sub-apps. Mount-prefix collisions raise at mount time. --tour propagates
naturally: claude-toolkit --tour shows the root tour and lists mounts;
claude-toolkit image --tour shows mosaico's tour as if invoked standalone.
The Three Principles
- Validate before acting — Check inputs before executing
- Return descriptive messages — Tell the agent what to do next
- Use two-phase patterns — Draft → Save for safety
Parameters
| Style | Becomes |
|---|---|
| No default | Positional argument (required) |
| Has default | --flag optional argument |
bool type |
Boolean flag (--flag or nothing) |
def cmd(name): # python cmd.py cmd John
def cmd(name="World"): # python cmd.py cmd --name John
def cmd(verbose: bool = False): # python cmd.py cmd --verbose
Use Annotated[type, "help text"] to add help documentation.
Utilities
Status Helpers
m.ok(msg)— ✓ Success messagem.fail(msg)— ✗ Error message + exit(1)m.info(msg)— → Informational messagem.warn(msg)— ⚠ Warning messagem.step(msg)— → Step indicator
File Operations
m.read(path)— Read file contentsm.write(path, content)— Write to filem.ls()/m.glob(pattern)— List filesm.touch(path)— Create empty filem.rm(path, recursive)— Remove file/directorym.cp(src, dst)— Copy file/directorym.mv(src, dst)— Move/rename
Shell
m.sh(cmd, timeout)— Run shell command, returnsResultm.which(cmd)— Find command in PATH
Navigation
with m.cd(path):— Context manager for directory changesm.env(name)— Get environment variable
Design Patterns
Two-Phase (Safety)
if not save:
m.info("Draft mode. Rerun with --save to persist")
return
# ... save operation
Validation First
content = sys.stdin.read().strip()
if not content:
m.fail("No content provided via stdin")
Descriptive Outputs
# Bad: return # silent
# Good: m.ok("Saved to: " + str(filepath))
Follow-up Commands (.explain)
if not save:
m.info("Draft mode. Rerun with --save:")
m.info(" " + create.explain(title=title, save=True))
return
--learn Mode
Auto-discovers command tours by analyzing source code:
python tool.py --learn # Show all commands
python tool.py --learn create # Show focused view for 'create'
Output includes:
- Next steps — Commands discovered via
.explain()calls - Failure modes — Errors discovered via
m.fail()calls - Happy paths — Success messages via
m.ok()calls
Complex Types from stdin
For complex data structures, use stdin[T] to read JSON from stdin. Requires pydantic extra:
uv add microcli-toolkit --extra pydantic
Basic Usage
from microcli import command, stdin
@command
def create(
title: str,
metadata: stdin[dict],
):
"""Create a resource with metadata."""
m.ok(f"Creating {title} with {len(metadata)} properties")
echo '{"tags": ["a", "b"], "priority": 1}' | python cmd.py create "My Title"
With Pydantic Models
from microcli import command, stdin
from pydantic import BaseModel
class NoteMetadata(BaseModel):
title: str
tags: list[str] = []
priority: int = 1
@command
def create(
content: str,
metadata: stdin[NoteMetadata],
):
"""Create a note with metadata."""
m.ok(f"Creating note: {metadata.title} (priority: {metadata.priority})")
echo '{"title": "My Note", "tags": ["work", "urgent"]}' | python note.py create "Note body"
Error Handling
Invalid JSON:
✗ Invalid JSON: Expecting value
Pydantic validation errors:
✗ Validation error: 2 validation errors
License
MIT
Metadata
Release files for microcli-toolkit 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| microcli_toolkit-0.4.0.tar.gz | 58.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| microcli_toolkit-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 81.5 kB
Release files / microcli_toolkit-0.4.0.tar.gz
| Download URL | microcli_toolkit-0.4.0.tar.gz |
|---|---|
| Size | 58.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
092528b8aa722246a9b2774bd7b20317d230bb2e1de30c82a688deb8504a65b2
|
|
BLAKE2b-256 checksum How to use checksums |
66b8577a4bd15278244d871666332b0bb1e6899cf3d33b8f961910d9d5f4a164
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / microcli_toolkit-0.4.0-py3-none-any.whl
| Download URL | microcli_toolkit-0.4.0-py3-none-any.whl |
|---|---|
| Size | 23.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8b4b83184f3e309fad30e2f08defe7a6f361252ad81336cbdf2a7205830b54b8
|
|
BLAKE2b-256 checksum How to use checksums |
862d07c50b8639b7675fa5e9b5d6b7269de4f52ff484a0cb78bad95d21c348f0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|