Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
651 changes: 165 additions & 486 deletions README.md

Large diffs are not rendered by default.

144 changes: 144 additions & 0 deletions docs/product-positioning.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# Milo Product Positioning

This brief keeps Milo's README, package metadata, documentation site, launch
copy, and visual system centered on one evidence-backed product story. It is a
messaging guide, not a public API contract.

## Category

Milo is a **CLI and agent-tooling framework for Python**.

"Terminal UI framework" describes an important capability but misses Milo's
strongest distinction. "MCP framework" overstates the protocol surface. Lead
with the problem Milo owns: one capability must stay truthful across human CLI,
Python, MCP, and agent discovery.

## Audience

Lead for Python developers who:

- maintain internal, developer, or operational CLIs that agents should call;
- want CLI parsing and MCP schema to share one source of truth;
- need structured results for agents without sacrificing human presentation;
- build interactive terminal workflows, forms, or multi-screen tools; or
- care about auditable types and free-threaded Python 3.14t.

## Problem

Teams commonly build an MCP server beside an existing CLI. The two surfaces
start aligned, then drift as one adds defaults, constraints, renamed options,
hidden commands, or richer errors. The adapter still runs, but it is no longer
true.

## Promise

> One typed Python function becomes a human CLI command, an MCP tool, and an
> agent-readable discovery entry.

The short supporting line is:

> Define the command once. Milo derives and verifies CLI + MCP + llms.txt.

## Message Pillars

### 1. One definition owns every surface

Types, defaults, `Annotated[...]` constraints, and docstrings feed argparse,
direct Python dispatch, JSON Schema, MCP tools, and llms.txt.

**Proof:** the `one-definition-three-surfaces` entry in
`public-claims.json` names the command and protocol tests behind the claim.

### 2. Verification makes the projection trustworthy

Generating a schema is not enough. `milo verify app.py` checks the assembled
application from import through subprocess JSON-RPC transport.

**Proof:** `src/milo/verify.py` defines the ten checks and
`tests/test_verify.py` exercises success and repair paths.

### 3. Humans and agents receive appropriate presentation

The operation stays shared while its boundary adapts. Humans can receive
terminal rendering, confirmation, forms, or flows; agents receive structured
input, progress, errors, and results.

**Proof:** command, Context, MCP, and terminal-runtime examples exercise both
paths without duplicating the business function.

### 4. Pure Python with an explicit runtime

Milo uses standard Python types, one runtime dependency (`kida-templates`), and
a concurrency model tested with the GIL disabled on Python 3.14t.

**Proof:** package metadata, CI, stress tests, and the claims ledger bound each
statement.

## Boundaries

- Milo does not replace every CLI framework or every MCP platform.
- Typer may be stronger when only the human CLI matters.
- FastMCP may be stronger when hosted MCP transports, clients, auth, deployment,
and protocol breadth are the product.
- Milo's current public MCP promise is local stdio. Streamable HTTP and parallel
HTTP tool-call claims remain pending until their evidence lands.
- Terminal applications are a first-class pillar, not the opening category.
- Milo is pre-1.0; stable commitments should not be described as a frozen API.

## Message Hierarchy

Use this order on landing surfaces:

1. One typed function becomes CLI, MCP, and agent discovery.
2. Shared schema and dispatch prevent cross-surface drift.
3. `milo verify` proves the assembled contract.
4. Dual-mode human and agent presentation.
5. Interactive terminal runtime for richer workflows.
6. One dependency and free-threading as engineering proof.
7. Gateway, MCP Apps, sagas, pipelines, and advanced runtime features.

## Preferred Terms

| Prefer | Avoid as the lead | Reason |
|---|---|---|
| one command contract | AI-native magic | Concrete and testable |
| CLI + MCP + llms.txt | every protocol | Names the proven surfaces |
| generated and enforced JSON Schema | automatic types | States what Milo actually owns |
| verified before registration | production ready | Bounded by the ten-check verifier |
| one runtime dependency | lightweight | Stronger metadata-backed proof |
| free-threading tested | no-GIL speed | Avoids an unproven performance claim |

## Reusable Descriptions

**One sentence**

Milo turns one typed Python function into a human CLI command, an MCP tool, and
an llms.txt discovery entry, then verifies that the surfaces agree.

**Short paragraph**

Milo is a pure-Python CLI and agent-tooling framework. Define a command once
with annotations and a docstring; Milo derives argparse, direct Python dispatch,
MCP JSON Schema, validation, and llms.txt. Use the same runtime for structured
agent tools and reducer-driven terminal applications.

## Hero Direction

The hero depicts Milo as an active Russian blue cat operating a three-way
command switchboard. One paw feeds a single definition tile into the mechanism,
the other throws the routing lever, and his tail closes a signal path. Three
tracks terminate in terminal, MCP-tool, and discovery artifacts.

The visual belongs to the same personal-project family as Kida and Murlocs:
tactile screen-print texture, limited inks, confident shapes, and a character
who causes the system to work. Russian blue, slate, green, copper, and parchment
give Milo a distinct terminal-at-night identity.

## Editorial Standard

Prefer short sentences, concrete nouns, and proof near each claim. Cut feature
inventories that do not help a reader decide, repeated explanations, inflated
category language, and implementation detail before the promise is clear. The
README should orient and persuade; the published docs should teach; internal
agent docs should remain executable; the claims ledger should authorize public
proof.
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ build-backend = "setuptools.build_meta"
[project]
name = "milo-cli"
version = "0.4.3"
description = "Template-driven CLI applications for free-threaded Python"
description = "Typed Python CLIs that project one command to CLI, MCP, and llms.txt"
readme = "README.md"
requires-python = ">=3.14"
license = "MIT"
dependencies = ["kida-templates>=0.11.0,<0.13.0"]
keywords = ["cli", "terminal", "forms", "free-threading", "template", "elm"]
keywords = ["cli", "mcp", "agent-tools", "json-schema", "terminal", "free-threading", "elm"]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion site/config/_default/site.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ site:
title: "Milo"
baseurl: ""
logo_text: "ᗣᗣ"
description: "Build CLIs that humans and AI agents both use natively"
description: "One typed Python function becomes a CLI command, MCP tool, and llms.txt entry"
language: "en"

template_engine: kida
Expand Down
132 changes: 106 additions & 26 deletions site/content/_index.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
title: Milo
description: Build CLIs that humans and AI agents both use natively
description: One typed Python function becomes a CLI command, MCP tool, and llms.txt entry
template: home.html
weight: 100
type: page
draft: false
lang: en
keywords: [cli, terminal, elm-architecture, free-threading, python]
keywords: [milo, python cli, mcp tools, agent tools, json schema, llms.txt, terminal apps]
category: home
cascade:
author: lbliii
Expand All @@ -17,42 +17,122 @@ cta_buttons:
- text: Get Started
url: /docs/get-started/
style: primary
- text: Docs
url: /docs/
- text: Compare Approaches
url: /docs/about/comparisons/
style: secondary

show_recent_posts: false
---

Milo is a Python framework where every CLI is simultaneously a terminal app, a command-line tool, and an MCP server. Write one function with type annotations — Milo generates the argparse subcommand, the MCP tool schema, and the llms.txt entry automatically. Built on the Elm Architecture with [[ext:kida:|Kida]] templates and generator-based sagas, targeting Python 3.14t free-threading.
## One Function. Three Surfaces.

**Build Python capabilities that stay truthful for humans and agents.**

Define a command once with annotations, constraints, defaults, and a docstring.
Milo derives the human CLI, direct Python dispatch, MCP JSON Schema and tool,
and llms.txt discovery from that shared contract—then verifies the assembled
application before you register it with an agent.

![Milo, a Russian blue cat, routing one typed command into terminal, MCP, and agent-discovery surfaces](https://raw.githubusercontent.com/lbliii/milo-cli/main/site/assets/images/milo-command-switchyard-hero.webp)

```python
from milo import App
from milo import CLI

cli = CLI(name="greet", description="Say hello", version="1.0")

def reducer(state, action):
if state is None:
return {"count": 0}
if action.type == "@@KEY" and action.payload.char == " ":
return {**state, "count": state["count"] + 1}
return state

app = App(template="counter.kida", reducer=reducer, initial_state=None)
app.run()
@cli.command("greet", description="Return a greeting")
def greet(name: str, loud: bool = False) -> str:
"""Greet someone by name."""
message = f"Hello, {name}!"
return message.upper() if loud else message


if __name__ == "__main__":
cli.run()
```

## The Bengal Ecosystem
---

## One Command Contract

:::{cards}
:columns: 2
:gap: medium

:::{card} Human CLI
:icon: terminal
Milo derives argparse commands, options, defaults, help, and terminal
presentation from the registered function.
:::{/card}

:::{card} MCP Tool
:icon: cpu
The same signature becomes enforced JSON Schema, tool metadata, structured
dispatch, progress, errors, and results.
:::{/card}

:::{card} Agent Discovery
:icon: search
llms.txt and MCP `tools/list` stay tied to the command definition instead of a
separate hand-maintained catalog.
:::{/card}

:::{card} Verification
:icon: check-circle
`milo verify app.py` checks import, schema, discovery, MCP Apps, gateway
projection, and real subprocess JSON-RPC transport.
:::{/card}

:::{/cards}

## Humans and Agents Need Different Presentation

The operation stays shared; the boundary adapts. A human can receive a
confirmation, form, multi-screen flow, or live terminal view. An agent receives
structured input and output without an interactive prompt blocking the call.

Milo's terminal runtime adds immutable state, pure reducers, Kida templates,
commands, sagas, and deterministic test helpers when a command needs a richer
human interface.

[Build a typed command](./docs/build-clis/commands/) or
[build an interactive app](./docs/build-apps/).

---

## Know the Boundary

Choose Milo when drift between a human CLI and its agent-facing tool is the
problem you want the framework to own. Choose Typer when only the polished human
CLI matters. Choose FastMCP when remote MCP transport, auth, clients, deployment,
and protocol breadth are the product.

[Read the evidence-backed comparison](./docs/about/comparisons/).

---

## Pure Python, Explicit Proof

- Python 3.14+ with required free-threaded CI lanes.
- One runtime dependency: `kida-templates`.
- Standard annotations and docstrings remain the schema source.
- Public claims are classified in the repository's `public-claims.json` ledger.

## Python Components Ecosystem

A structured reactive stack — every layer written in pure Python for 3.14t free-threading.
Milo is the terminal and agent-tooling layer in a personal, pure-Python stack
built for Python 3.14t.

| | | | |
|--:|---|---|---|
| **ᓚᘏᗢ** | [Bengal](https://github.com/lbliii/bengal) | Static site generator | [Docs](https://lbliii.github.io/bengal/) |
| **∿∿** | [Purr](https://github.com/lbliii/purr) | Content runtime | — |
| **⌁⌁** | [Chirp](https://github.com/lbliii/chirp) | Web framework | [Docs](https://lbliii.github.io/chirp/) |
| **=^..^=** | [Pounce](https://github.com/lbliii/pounce) | ASGI server | [Docs](https://lbliii.github.io/pounce/) |
| **)彡** | [Kida](https://github.com/lbliii/kida) | Template engine | [Docs](https://lbliii.github.io/kida/) |
| **ฅᨐฅ** | [Patitas](https://github.com/lbliii/patitas) | Markdown parser | [Docs](https://lbliii.github.io/patitas/) |
| **⌾⌾⌾** | [Rosettes](https://github.com/lbliii/rosettes) | Syntax highlighter | [Docs](https://lbliii.github.io/rosettes/) |
| **ᗣᗣ** | **Milo** (PyPI: `milo-cli`) | CLI framework ← You are here | [Docs](https://lbliii.github.io/milo-cli/) |
| | Project | Role |
|--:|---|---|
| **⌁⌁** | [Chirp](https://github.com/lbliii/chirp) | Web framework |
| **=^..^=** | [Pounce](https://github.com/lbliii/pounce) | ASGI server |
| **)彡** | [Kida](https://github.com/lbliii/kida) | Server-side component system |
| **∿∿** | [Purr](https://github.com/lbliii/purr) | Content runtime |
| **ᓚᘏᗢ** | [Bengal](https://github.com/lbliii/bengal) | Static-site integration |
| **ฅᨐฅ** | [Patitas](https://github.com/lbliii/patitas) | Markdown parser |
| **⌾⌾⌾** | [Rosettes](https://github.com/lbliii/rosettes) | Syntax highlighter |
| **ᗣᗣ** | **Milo** | CLI and agent-tooling framework ← You are here |

Python-native. Free-threading ready. No npm required.
Loading