Skip to main content

Tooli

The agent-native CLI framework for Python.

Tooli turns typed Python functions into command-line tools that work for both humans and AI agents: rich output in a terminal, strict structured output in automation, and self-describing schemas for tool calling and orchestration.

The name comes from "tool" + "CLI" = "tooli".

Why Tooli?

AI agents invoke lots of local commands, but typical CLIs are optimized for humans:

  • Huge, unstructured stdout that burns context windows
  • Opaque errors that don't suggest a fix
  • Fragile pipelines that mix logs with machine output
  • Undocumented flags that agents hallucinate

Tooli is built to be machine-consumable by default while still feeling great for humans.

Install

pip install tooli

Optional extras:

pip install "tooli[mcp]"   # MCP server support
pip install "tooli[api]"   # HTTP API + OpenAPI export (experimental)

Quick Start

Create file_tools.py:

from __future__ import annotations

from pathlib import Path
from typing import Annotated

from tooli import Argument, Option, Tooli
from tooli.annotations import Idempotent, ReadOnly

app = Tooli(name="file-tools", description="File utilities", version="4.1.0")


@app.command(annotations=ReadOnly | Idempotent, paginated=True, list_processing=True)
def find_files(
    pattern: Annotated[str, Argument(help="Glob to match")],
    root: Annotated[Path, Option(help="Root directory")] = Path("."),
) -> list[dict[str, str]]:
    return [{"path": str(p)} for p in root.rglob(pattern)]


if __name__ == "__main__":
    app()

Run it:

python file_tools.py find-files "*.py" --root .
python file_tools.py find-files "*.py" --root . --output json
python file_tools.py find-files --schema

Structured Output (JSON / JSONL)

Tooli supports dual-mode output:

  • Human mode: pretty output when attached to a TTY
  • Agent mode: strict envelopes when using --output json or --output jsonl

JSON envelope shape:

{
  "ok": true,
  "result": {"...": "..."},
  "meta": {
    "tool": "file-tools.find-files",
    "version": "2.0.0",
    "duration_ms": 12,
    "annotations": {"readOnlyHint": true, "idempotentHint": true}
  }
}

Structured Errors With Recovery Hints

When a command fails, Tooli emits a structured error with an actionable suggestion:

{
  "ok": false,
  "error": {
    "code": "E1004",
    "category": "input",
    "message": "Exact search string was not found in source.",
    "suggestion": {
      "action": "adjust search text",
      "fix": "Double-check exact spacing/newlines. Did you mean: \"...\"?"
    },
    "is_retryable": true
  }
}

Schemas, Docs, and Agent Bootstrap

Tooli can generate tool schemas and agent-facing docs directly from type hints and metadata:

python file_tools.py find-files --schema
python file_tools.py generate-skill > SKILL.md
python file_tools.py generate-skill --target claude-code > SKILL.md
python file_tools.py find-files --agent-bootstrap > SKILL.md
python file_tools.py docs llms
python file_tools.py docs man

v4 generates task-oriented SKILL.md with "When to use" guidance, recovery playbooks, composition patterns, and target-specific formatting (generic, Claude, Claude Code).

Run as an MCP server (one tool per command):

python file_tools.py mcp serve --transport stdio
python file_tools.py mcp serve --transport http --host 127.0.0.1 --port 8080
python file_tools.py mcp serve --transport sse --host 127.0.0.1 --port 8080

Universal Input (files / URLs / stdin)

Use StdinOr[T] to accept a file path, a URL, or piped stdin with one parameter.

from pathlib import Path
from typing import Annotated

from tooli import Argument, StdinOr, Tooli

app = Tooli(name="log-tools")


@app.command()
def head(
    source: Annotated[StdinOr[str], Argument(help="Path, URL, or '-' for stdin")],
) -> dict[str, int]:
    return {"bytes": len(source)}  # `source` resolves to the content

Built-In Guardrails

Tooli provides primitives for safer automation:

  • ReadOnly, Idempotent, Destructive, OpenWorld annotations on commands
  • --dry-run planning support via @dry_run_support + record_dry_action(...)
  • SecretInput[T] with automatic redaction in outputs and errors
  • Cursor pagination (--limit, --cursor, --fields, --filter) for list-shaped results

Example Apps (agent pain points)

The GitHub repo includes sample apps under examples/ that target common agent failure modes:

  • code-lens: token-efficient symbol outlines from Python ASTs (avoid dumping whole files)
  • safe-patch: self-healing file edits with dry-run plans and recovery hints
  • log-sift: pipeline-friendly log extraction with strict JSON/JSONL output
  • sqlite-probe: read-only SQLite exploration with pagination and guardrails

Metadata

Release files for tooli 6.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tooli 6.6.0
File Size Uploaded
tooli-6.6.0.tar.gz 152.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tooli 6.6.0
File Interpreter ABI Platform
tooli-6.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 269.6 kB

Release files / tooli-6.6.0.tar.gz

Download URL tooli-6.6.0.tar.gz
Size 152.4 kB
Tags Source
SHA-256 checksum
How to use checksums
2a3e87714f2d50df605794fcedbbf29959dc1d34cf65da36cb9623055108c9cf
BLAKE2b-256 checksum
How to use checksums
7a29fa5edfa5d09da3c77828c585f3d0b81edd770473f24cbceaaba28a72c193
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 22, 2026.

Transparency log

Release files / tooli-6.6.0-py3-none-any.whl

Download URL tooli-6.6.0-py3-none-any.whl
Size 117.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1feba7a54ee788a05d5d3b850c06cf4f6130cd3afe91bc944f6a1eac1e2c140c
BLAKE2b-256 checksum
How to use checksums
dd41332bba1b3a1abfbb1cd3bd37bc59f403197963ba7648f757fed2747702ed
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 22, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

6.6.0 This release

2 release files

6.5.0

2 release files

6.2.1

2 release files

6.1.0

2 release files

6.0.0

2 release files

5.0.1

2 release files

5.0.0

2 release files

4.1.0

2 release files

4.0.0

2 release files

3.0.0

2 release files

2.0.0

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.2

2 release files

1.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page