Development

My Template for Build Me a CLI for This Messy API

Kevin PlumleeSeptember 28, 20265 min read
My Template for Build Me a CLI for This Messy API

Every few months you inherit an API that looks like it was designed by three teams who never shared a Slack channel. Different auth schemes on different endpoints. Pagination that changes personality mid-response. Docs that say “see Swagger” and the Swagger is three years out of date.

I used to spend a weekend hand-rolling a CLI, then another weekend fixing the edge cases. Now brief an agent with a template and get a tool I can actually keep.

This is not “AI wrote my whole product.” This is “AI wrote the boring glue so I can ship the useful part.”

Why a CLI beats another dashboard

If you are the only person hitting an API for ops work, Avoid a Next.js app with a login screen and a design system. Aim for:

  • something I can run from a terminal
  • flags I can remember after coffee
  • JSON or a clean table when you need to pipe it
  • exit codes that play nice with scripts

A CLI is also easier to review. Diffs are small. Secrets stay in env. Nobody deploys a half-baked UI to prod because they felt productive on a Sunday.

The brief you paste almost every time

Keep a skeleton prompt. Fill in the blanks. Attach the OpenAPI file or a handful of real request/response samples. Then say:

Goal: Build a Python CLI (Typer or Click) that wraps this API for day-to-day ops.

Auth: Tell me exactly how tokens work. Refresh? Header name? Where env vars live.

Commands you need first: List, get, create, update. Only the verbs you will use this week. Not the whole catalog.

Output: Default to human-readable tables. --json for machines. Fail loud on HTTP errors with status and body snippet.

Do not: Invent endpoints. Do not silently swallow 4xx. Do not hardcode secrets. Do not build a web UI.

Done means: I can pip install -e., run --help, hit one happy path and one failure path, and the README is not a novel.

That last line matters. Agents love writing READMEs that assume you already know the system.

Attach receipts, not vibes

If you only say “wrap this messy API,” you will get a beautiful CLI for an imaginary API.

Attach:

  • the OpenAPI or Postman collection if it exists
  • 2 to 5 real curl examples that worked today
  • one example of a weird error body
  • the base URL for staging vs prod

Then say: “Prefer the samples over the docs when they disagree.”

They often disagree. That sentence has saved me hours of polite nonsense.

Structure you ask for every time

Be boring on purpose:

  1. `client.py` with the HTTP session, retries, and auth
  2. `commands/` split by resource
  3. `models.py` or typed dicts for the responses Focus on
  4. thin `__main__` entrypoint
  5. tests that mock HTTP, not the live world

Also ask for a --dry-run on anything that writes. Operators make typos. Dry-run is cheaper than apology emails.

How to keep the agent from rewriting Earth

Halfway through, agents get ambitious. Suddenly there is a plugin system, a TUI, and a config DSL.

Cut that off early:

“Small diffs. One command group at a time. Show me the patch for list and get first. No rewrite.”

If the first two commands are solid, the rest is copy-paste with taste. If the first two are wrong, a giant scaffold just makes the wrongness harder to delete.

Testing without lying to yourself

Do not need 100% coverage on a glue CLI. You need:

  • auth failure returns a clear message
  • pagination stops when the API says stop
  • create path rejects missing required fields before the network call when possible
  • `–json` is valid JSON, always

Then run the real staging list once with my own eyes. Automated tests catch regressions. Humans catch “this API returns 200 with an error string in the body because reasons.”

A maintenance rule that keeps me sane

Every CLI you ship this way gets a CHANGELOG.md line and a pinned dependency set. When the upstream API changes, I do not “vibe refactor.” I update the client methods, re-run the two happy paths, and move on.

If the CLI grows past roughly ten commands and three people depend on it, then maybe it graduates into a small internal package with CI. Until then, resist the urge to build a platform around your wrench.

Steal this starter prompt

“` Build a Typer CLI for this API. Use env vars for base URL and token. Commands: Default output: table. Flag: –json. Never invent endpoints. Prefer attached samples over docs. Include –dry-run on write commands. Add a short README with install and one example per command. Show me the file tree first, then implement list + get only. “`

Paste samples under that. Hit send. Review like a senior, not like a tourist.

Bottom line

Messy APIs are not going away. Your weekend does not have to disappear with them. A good brief turns “figure it out” into “ship a tool by Friday,” which is the whole game when you are the operator holding the pager and the laptop.

Kevin Plumlee

Founder, RVNOPS

Kevin Plumlee

15+ years running healthcare SEO, paid media, and operations. Now I advise the teams who do that work, across marketing, intake, technology, and AI.

More about me

Tell me what’s not working.

Stalled growth, spend you can’t trace, systems that fight your team. That’s a good place to start.

Start a conversation