Ad tooling is almost entirely dashboards, which makes it almost entirely unautomatable. You cannot cron a dashboard, you cannot pipe a dashboard into jq, and you cannot ask a terminal agent to click one. The Hermoso CLI exists so the ad loop stops being a place you visit and starts being a thing you can script.
Install and sign in:
npm install -g hermoso
hermoso auth login
auth login spins up a loopback listener and opens the browser, the same pattern gh and firebase use — nothing to paste. The minted key is written to ~/.hermoso/config.json with owner-only permissions (directory 0700, file 0600), because it carries real spend authority. For CI, hermoso auth login --token <key> stores one non-interactively, and HERMOSO_TOKEN / HERMOSO_API_BASE override the config from the environment.
The commands
Every command takes --json, which is the whole point: the human-readable line is a convenience, the JSON is the contract.
| Command | What it does |
|---|---|
hermoso capabilities | Valid model ids and their exact credit costs. Run this first — it is free and read-only, and it is how you stop guessing model names. |
hermoso credits | Balance, session usage and recent priced calls. |
hermoso brand --domain example.com | Reads a website into a brand profile — products, palette, logo, voice — that later renders are grounded in. |
hermoso competitors --domain example.com | Discovers direct rivals and similar brands worth learning from. |
hermoso ads --company "Brand" | Pulls that advertiser’s real running ads from the Meta, Google and LinkedIn ad libraries, deduped and sorted. |
hermoso research "longest-running protein bar ads" | Natural-language ad research across the libraries plus organic TikTok, returning the ads it found. |
hermoso create --brand … --product … --format video | Turns a brief into a finished ad concept: copy variants plus an image concept or a video storyboard, with the model ids to render it. |
hermoso generate image --prompt "…" --ref ./bottle.png | Renders and returns a served URL. --ref composites your real product so the label on screen is your actual SKU. |
hermoso jobs / hermoso fetch <url> | Inspect renders in flight; resolve any asset to a clickable and a direct-download URL. |
hermoso mcp | Serves the full 301-tool MCP surface over stdio — the same tools the hosted server exposes. |
Two surfaces, one package, and why that matters
Terminal agents pay for tools twice: once in the manifest they carry in context, and once in the tokens each call costs. A 301-tool manifest is not free. So the same package ships both surfaces and lets the agent choose:
- MCP (
hermoso mcp, or the hostedhttps://app.hermoso.ai/mcp) when you want the full surface and rich typed arguments. - Subprocess commands when you want the token-cheap path: the agent shells out, reads JSON, and never loads a manifest at all. This is the pattern the bundled Claude skills use.
Both hit the same API, bill the same credits and write to the same library, so nothing is stranded on one side.
Things worth scripting
- A weekly competitor sweep.
hermoso competitorsintohermoso ads, diff against last week, and you have a standing report on what your market started and stopped running. - Batch creative for a catalogue. Loop over SKUs, render one grounded ad per product, and collect the returned URLs — the sort of job that is genuinely tedious in a UI.
- A credit guard in CI.
hermoso credits --json | jq .balanceand fail the pipeline before a long batch starts against an empty balance. - Cost-aware model selection.
hermoso capabilities --jsonexposes exact per-model costs, so a script can pick the cheapest model that meets the brief instead of hardcoding one.
Publishing and campaigns
The CLI subcommands cover research and creation. Publishing, scheduling and campaign management on Meta, Google Ads, Microsoft Advertising, Reddit Ads, LinkedIn, Pinterest and ChatGPT Ads live in the MCP surface — reachable from the same package with hermoso mcp, from the hosted endpoint, or from the web studio. Publishing targets are Facebook, Instagram, Threads, TikTok, YouTube, X, LinkedIn and Pinterest.
What it will not do without asking
An agent with a budget is only useful if the blast radius is bounded, so spend authority is fenced in the server rather than in a prompt. Meta campaigns, ad sets and ads are created PAUSED with no caller override. The seven tools that can arm real ad spend — set_meta_campaign_status, set_google_ads_status, set_microsoft_ads_status, set_reddit_ads_status, set_linkedin_ads_status, set_pinterest_ads_status and set_openai_ads_status — each refuse to run without an explicit confirmation flag, and that same gate covers creating an enabled Google Ads ad group, ad or keyword under an already-enabled parent, because that serves on the very next auction. Deletes are confirm-gated too. On the generation side, hermoso_capabilities publishes each model’s exact credit cost before anything runs, and every render reserves an estimate then settles the true cost, so a failed dispatch refunds instead of quietly billing you.
Working inside an agent rather than a shell? See Claude Code marketing automation and the full MCP & CLI reference.
Frequently asked
Is there a command-line tool for running ads?
Yes. npm install -g hermoso installs the Hermoso CLI, which researches competitor ads across the Meta, Google and LinkedIn ad libraries, drafts a brand profile from a website, plans and renders finished image and video ads, and reports credits and jobs — with --json output on every command for scripting. The same package also serves the full 301-tool MCP server over stdio.
How do I authenticate the Hermoso CLI?
Run hermoso auth login. It opens a loopback browser sign-in — the same pattern gh and firebase use — and stores the minted key at ~/.hermoso/config.json with owner-only permissions (directory 0700, file 0600). For CI, hermoso auth login --token <key> stores one non-interactively, and HERMOSO_TOKEN and HERMOSO_API_BASE override the config from the environment.
Can I pipe the output into jq?
Yes — every command accepts --json and prints a structured object. That is the intended contract; the human-readable line is just a convenience. hermoso credits --json | jq .balance is a useful CI guard before a long render batch.
Why use the CLI instead of the MCP server?
Token cost. An MCP client loads the tool manifest into context, and 301 tools are not free. A terminal agent that shells out to subprocess commands and reads JSON carries no manifest at all. Both surfaces hit the same API, bill the same credits and write to the same library, so you can mix them.
Can the CLI publish to Facebook or manage Meta ads?
Publishing, scheduling and campaign management on Meta, Google Ads, Microsoft Advertising, Reddit Ads, LinkedIn, Pinterest and ChatGPT Ads live in the MCP surface rather than the CLI subcommands — reachable from the same package by running hermoso mcp, from the hosted endpoint at https://app.hermoso.ai/mcp, or from the web studio. Publishing targets are Facebook, Instagram, Threads, TikTok, YouTube, X, LinkedIn and Pinterest.
Does it work against a local server?
Yes. Set HERMOSO_API_BASE to your own origin (for example http://localhost:3000) and the CLI and MCP server both target it. A localhost base needs no auth token.
Install the CLI, sign in from your browser, and your first competitor sweep is one command away. Free account, 250+ earnable free credits, no card.
Start free → Read the MCP docs →