Tempio

Run

The same surface, from a terminal

The command line is an MCP client. It calls the same org-scoped server your agent does, with the same keys and the same scopes; only the interface differs, with named flags and exit codes where a model would be.

That is what a scheduler needs. A build server can hold a key that reads and drafts and is structurally unable to clear anything, so nothing rests on trusting it not to.

A script holding your credentials, or one holding your scopes

Automating against each platform yourself
  • Every platform brings its own authentication dance, its own pagination and its own name for the same three levels.
  • The token sitting in a build server’s environment can do everything the person who minted it could do.
  • A nightly job that changes a budget changes it in the account, and the first review of that decision is the invoice.
  • The response shapes differ per platform, so every script ends in a hundred lines of normalising nobody wants to own.
  • When a job misfires the log names an HTTP call. It does not name a decision, an author or a workspace.

A scheduled job with your whole account in its pocket.

Automating through the same tool layer
  • One command surface over every connected account, with campaigns, ad groups and ads named the same way whatever sits underneath.
  • The key a job holds carries exactly the scopes you gave it, and one that cannot approve cannot be argued into approving.
  • A job that wants a change writes a change request, which waits at the gate like every other change in the workspace.
  • Output is structured by default, so you can pipe it into whatever you already run.
  • Every call lands on the record with the key that made it, so a misfiring job traces back to that key and its workspace.

A scheduled job with exactly the reach you gave it.

How a terminal gets the same reach

  1. 01

    Mint a key for the machine

    A key belongs to one workspace and to the membership that created it, and its scopes are chosen at that moment: read on its own, read and draft, or all three. A build server is the clearest case there is for one of the first two. Approve is opt-in and never the default, so a key that cannot clear anything is what you get unless you ask for more.

  2. 02

    Point the command at it

    The command reads the key from the environment, or from the file that signing in wrote for that endpoint, and talks to the same server an agent would. There is no second permission model to learn and no per-platform credential to distribute. The connections already in the workspace are what the command can see, and nothing outside them exists as far as it is concerned.

  3. 03

    Run it, and read what comes back

    Reads answer in a shape you can pipe, so you compose commands without scraping their output. A write answers with the change request it created and the link to review it; a script checks that the draft was written and, afterwards, what the gate did with it.

What the command line is for

Built for schedulers

A model is a poor fit for a task that runs at four in the morning and has to do exactly one thing. The command line is the same tool layer with the ambiguity taken out: named flags, structured output, and an exit code that means something to whatever called it.

The same three scopes

Read, draft and approve, chosen when the key is minted. A command whose scope the key does not hold is refused by name, with the scope it would need, instead of the command quietly missing.

Structured output by default

Every read answers in a shape another program can consume: JSON the moment the output is a pipe, a readable table when it is a terminal, and a flag that decides it outright either way.

Exit codes that mean something

A guardrail refusing a change, a connection that is missing and a network that is down are three different outcomes and exit as three different things, so a scheduler can tell a mistake from an outage.

One workspace per key

Every command is scoped by organisation before it reaches the database, exactly as every other caller is. The workspace comes off the verified key, so there is no flag to pass, and an identifier sent anyway is dropped rather than trusted.

Same server, different caller

The tool layer does not care whether a model or a shell is asking. The scopes, the organisation boundary and the record are identical either way, which is why there is nothing here to keep in sync.

Point your own agent at it

Writes are still drafts

A command that would change an ad entity writes a change request instead. Filling the queue from a script is ordinary; clearing it is a separate scope, and the row names whatever authority cleared it.

What clears a change

Illustrative exchange

tempio campaign_metrics list --from 2026-09-01 --to 2026-09-13 | jq '.data.rows[] | select(.spend > 100000)'
get_campaign_metrics
The same tool the chat calls, from a terminal: one route, one scoped key, the answer as JSON on the pipe.
range 2026-09-01 to 2026-09-13 · 4 rows, each with name, spend in minor units AUD and roas computed at read time · warnings []
tempio campaign update --connection-id 5e7c… --target-entity-id 1f0a… --payload "$(cat budget.json)"
draft_changes
A write from the terminal is a draft like any other. It lands at the gate with a review link and nothing spends until it is approved by you, or by a rule you wrote.
1 operation · update_budget · pending_approval · reviewUrl /drafts/1f0a… · exit 0
I’ve drafted the budget change and applied nothing. Review it at https://app.tempio.ai/drafts/1f0a…

Questions

Put frontier AI to work on every ad account you run.

Connect your accounts, point your own AI at them over MCP, and read the numbers and draft the work in one place. Every change is a draft until you approve it, or until a rule you wrote does.

Request early access
  • Read and draft by default. Approve is a separate permission you grant.