agents · architecture · tutorial

CLI First: If Your Agent Can't Run It, You Didn't Ship It

Build the API route and the terminal command before the page, and your AI agent can operate the app, not just write it. Scoped keys inside.

Engraving of the great telegraph exchange in Paris, rows of operators at long desks under tall windows, 1893
Engraving of the great telegraph exchange in Paris, rows of operators at long desks under tall windows, 1893 · Photo: Unknown artist, public domain, via Wikimedia Commons

Your agent wrote the app and still can't use it

You asked an agent to build a refunds screen. It did. Now a customer writes in, and you open a laptop, sign in, click through three pages, and press the button yourself.

The agent that wrote the feature is standing right there. It can't press the button, because the feature only exists as a page.

That gap is the whole argument for building CLI first.

What CLI first means

Every feature is reachable three ways, built in this order:

  1. An API route that accepts a browser login or a key.
  2. A terminal command that calls that route.
  3. A page, for people who like clicking.

Most apps build these backwards. The page comes first, the API exists only to feed it, and a command never appears.

What it looks like

Log a machine in once. The terminal prints a short code, you approve it in your browser, and nothing gets pasted anywhere:

bp login --remote https://yourdomain.com

After that, the app is a set of commands:

bp orders list
bp users grant --email [email protected] --yes
bp analytics revenue --days 7

The second command changes data, so it needs --yes. Leave it off and the command refuses, then tells you what to type.

The part that makes it safe to hand to an agent

A key is either read-only or read-and-write. An agent that only needs to answer "how many orders came in today?" gets a read key:

bp login --scopes read

That key can list and show. It cannot create, delete, or grant access, however confidently the agent tries.

Read key Read + write key
List orders, products, users Yes Yes
Create or delete anything No Yes, with --yes
Grant or revoke access No Admins only
Lifetime 90 days 90 days

When the job is done, revoke the key:

bp tokens revoke --id <id> --yes

Why not just give the agent your login?

Because a login can do everything you can, forever, and you can't take back one part of it.

A key has a scope, an expiry and a kill switch. The server stores only a fingerprint of it, so a leaked database doesn't leak working keys.

The paywall is the same either way. A free user's key is exactly as limited as their login.

The fix in 3 steps

  1. Route first. Guard it with one check that accepts a session or a key.
  2. Command second. One small file per feature, calling that route.
  3. Page last. By now it is a thin layer over something that already works.

In BoringPush, step 2 is a copy of an existing command, such as the boards one. The CLI finds new commands by name, so yours works as soon as it exists.

Three jobs this changes

Support from your phone. A customer paid with one email and signed up with another. Over SSH, bp users grant --email fixes it in one line, and you never open a laptop.

A morning report you didn't write. Give an agent a read key and ask for yesterday's orders and revenue. It runs two commands and summarises them. It cannot do anything else with that key.

Scripts that survive a redesign. A script that calls bp orders list --json keeps working when the dashboard changes, because it never touched the dashboard.

None of these need a new screen. They need the feature to exist somewhere other than a screen.

Already have an app built page first?

You don't have to rewrite it. Pick the three things you do by hand most often — usually looking up an order, fixing a customer's access, and checking revenue.

For each one, move the logic out of the page and into a route that accepts a key. Then add the command. The page keeps working, because it now calls the same route.

Do the read-only ones first. They carry no risk, and they are the ones an agent uses most.

What this doesn't do

It doesn't make an agent careful. A read-write key in the wrong hands still writes.

It limits what a mistake can reach, and it gives you a key you can switch off. Start every job with a read key and widen only when the job needs it.

FAQ

Is CLI first only for developers?

No. You don't have to type the commands yourself. Your agent does, and you read the answer.

Does it work against a live site?

Yes. Add --remote https://yourdomain.com to any command, or save it as the default at login.

What stops someone guessing a key?

Keys are long and random, only their fingerprint is stored, and the login and API routes are rate limited per address.

Can I see what a key has been used for?

Each key records when it was last used, and bp tokens list shows every key on your account with its scope. Revoke any you don't recognise.

Do I have to build a command for every feature?

For anything you want an agent or a script to operate, yes. It is one small file, and the page can come later.

Related reading:

+ all the boring stuff (analytics, auth, SQLite ↔ Supabase, full marketplace, webhooks)

The Agent-First Shipping Kit

Command from your phone.

Built so autonomous AI agents build what you want without breaking what's already paying you.

$199

Get BoringPush

One-time payment · Lifetime updates · Unlimited projects.

Keep reading