Design note

JSON payloads and runtime schema discovery.

Why CLIs for agents should accept structured data instead of flags, and why the API contract should come from the tool itself.

Why JSON payloads, not flags

Most CLIs accept input as flags: --title "My Document" --author "Jane". This works for humans because flag namespaces are small and mnemonic. You remember -v for verbose and reach for --help when you forget.

For agents driving complex operations, flags fall apart. A tool with 49 operation types, each with its own parameter set, would need hundreds of flags: --add-text-slide-index, --add-text-left, --add-text-top, --add-chart-categories... The namespace becomes ambiguous, the --help output becomes a wall, and the agent burns context tokens parsing it to find the three flags it actually needs.

JSON payloads fix this. The agent generates {"op": "add_text", "slide_index": 0, "left": 1, ...} from a schema. The schema is the documentation. The payload is self-describing, so there's no gap between what the agent intended and what the CLI received. And the CLI can validate the entire payload as a unit before touching any state, instead of trying to make sense of individual flags in isolation.

Why the schema should come from the tool itself

A common approach is to embed tool documentation in the system prompt or in a skill file. This works until the documentation and the implementation drift. A developer adds a parameter, forgets to update the docs, and agents start generating payloads that fail for reasons nobody can diagnose.

The alternative is runtime schema discovery. The tool exposes its own API contract (methods, parameters, types, response shapes) as queryable JSON. The schemas come from the same Pydantic models that validate input. They can't be stale because they are the implementation.

In agent-slides, slides docs schema:slides-document returns the exact JSON Schema that the validation layer enforces. When the agent needs to know what parameters add_text accepts, the answer comes from the model definition, not from documentation someone wrote months ago.

I didn't build this out of principle. I built it because a lot of early agent failures traced back to schema drift: skill files documenting parameter names that had been renamed, or formats that had been tightened. Once the agent could query the tool for its own schema, that entire category of failure went away.

Previous Why agents need a different CLI Next Context-window discipline