# Hermoso: MCP, CLI & Skills **The AI marketing agent with an AI ad generator built in**, run from **any AI agent**: Claude Code, Claude.ai, Cursor, Codex, or your own scripts. Research the ads already winning in a market, generate image & video ads (your real product composited in, copy + CTA included), publish them to your own social channels, and build & manage the ad campaigns behind them, all over [MCP](https://modelcontextprotocol.io) tools, a CLI, or installable Claude skills. **1182 tools.** `tools/list` is always the authoritative set; `hermoso_capabilities` (free) returns the live model catalog with exact per-render credit costs plus the full capability map. **No markup on models** on Starter, Pro and Studio. Stop overpaying markups on AI models. Plans: [hermoso.ai/pricing](https://hermoso.ai/pricing). **A Chrome extension too.** [Hermoso: save and clone ads](https://chromewebstore.google.com/detail/hermoso-save-and-clone-ad/kmknkbldeilchhblbfddfnfbadmgcklc) saves any ad to your swipefile in one click, clones it for your brand, and pulls any company's ads from its website. **Most of it costs nothing.** Publishing and scheduling posts, building and managing paid campaigns, analytics and insights, comments and DMs, connectors, profiles and team seats cost **no credits on any plan**, with no per-post fee and no seat pricing. The Free plan includes 10 posts a month on up to 3 platforms; every paid plan posts without a limit and runs autopilot. Basic ($9.99 a month) is unlimited posting and Autopilot with no monthly credits: it includes the same 250+ free credits as the Free plan, monthly credits start on Starter, and Autopilot spends credits. Credits are spent only on running an AI model (image, video, voice, text, planning, post-production) and on Ad Spy research, and posting an ad you already rendered is never a second charge. The one exception is X (Twitter), where posting and reads bill credits per call because X charges per API request (`hermoso_credits` prints the exact credits per X post). **What it connects to.** Ad platforms: Meta, Google Ads, TikTok Ads, LinkedIn Ads, Reddit Ads, X Ads, Pinterest Ads, Snapchat Ads, Microsoft Advertising, Apple Search Ads, ChatGPT Ads and AppLovin Ads, plus product feeds in Google Merchant Center. Publishing and scheduling — **fifteen** channels: Facebook, Instagram, Threads, TikTok, YouTube, X, LinkedIn, Pinterest, Bluesky, Telegram, WordPress, Discord, Slack, Whop and Google Business Profile. Messaging: WhatsApp (you message a person, so it is not a sixteenth publishing channel) and DM automations on Instagram, Facebook Pages and Messenger, and X (a keyword comment, a DM, a story reply or an ig.me / m.me link gets an automatic reply). Ad research: the Meta, Google and LinkedIn ad libraries plus organic TikTok, Instagram, YouTube, Threads and Reddit. Analytics: Google Analytics 4, Google Search Console and every connected platform's own post and campaign insights. Files: Google Drive, Sheets, Docs and OneDrive. **It is not all-or-nothing.** Research, creation, publishing/scheduling and ads management are four *independent* areas — no tool requires that you used another one first. Publish or schedule creative you already have and generate nothing here (`upload_file` turns any local or external file into a URL every publish, schedule and ad-build tool accepts); build and read campaigns on your own ad accounts with your own creative; research competitors with no brand drafted and no channel connected; or generate a file with nothing connected at all and just download it. Use the one piece you need, or all of it together. ## Install in one command This repo is a plugin marketplace, a Gemini CLI extension and a skills package at once, so a coding agent takes Hermoso in one line. Every install brings the same five skills (`hermoso-research`, `hermoso-generate`, `hermoso-ad-from-brand`, `hermoso-product-photoshoot`, `hermoso-marketing`), and the skills drive the `hermoso` CLI through `npx`. No tool list is loaded into your session: a CLI command costs nothing until it runs, and it reaches every tool. The first time, your agent runs `npx -y hermoso auth login`, which opens a browser to sign in. **Claude Code:** ```bash claude plugin marketplace add hermoso-ai/hermoso && claude plugin install hermoso@hermoso ``` Inside a session the same thing is `/plugin marketplace add hermoso-ai/hermoso` then `/plugin install hermoso@hermoso`. **Codex CLI** (it reads the same marketplace file): ```bash codex plugin marketplace add hermoso-ai/hermoso && codex plugin add hermoso@hermoso ``` **Gemini CLI:** ```bash gemini extensions install https://github.com/hermoso-ai/hermoso ``` **Grok** (xAI) comes in three shapes, and each one connects differently: - **grok.com and the Grok apps** take the hosted connector: open **Plugins → Connectors → New Connector → Custom** (or go straight to grok.com/connectors), paste `https://app.hermoso.ai/mcp` and sign in with your Hermoso account. - **Grok Bot**: add the [Hermoso Marketing Bot template](https://x.ai/bot/THQqogUKuhn1whWU0hrmb). It arrives wired to Hermoso and asks for a key, which you create in the app under **MCP & CLI → Terminal & API keys**. - **Grok Build**, xAI's terminal agent, runs a local MCP server. Sign in once, then add it: ```bash npx -y hermoso auth login grok mcp add hermoso -- npx -y hermoso mcp ``` **Cursor, OpenCode, GitHub Copilot, Windsurf and about 75 more agents**, through the open skills installer: ```bash npx skills add hermoso-ai/hermoso ``` It asks which agents to install into; `-a opencode` (or `cursor`, `github-copilot`, `windsurf`) picks one, and `--skill hermoso-research` installs a single skill. VS Code agent plugins can also take this repo whole: run **Chat: Install Plugin From Source** and paste `https://github.com/hermoso-ai/hermoso`. **ChatGPT and Claude.ai** run in a browser and cannot run a CLI, so they use the hosted connector instead (see below). The ChatGPT desktop app and ChatGPT workspace admins can also read this repo's `.claude-plugin/marketplace.json`, which installs the skills. No browser on the machine? Create a key in the app under **MCP & CLI** and run `npx -y hermoso auth login --token `. On a server, a CI job or an agent gateway that calls Hermoso many times a day, install it once (`npm i -g hermoso`) and call `hermoso` directly. `npx` asks the npm registry about the package on every run, and a busy machine can be rate-limited by npm. If the CLI ever says an HTTP error "did not come from Hermoso", something on your side (a proxy, a firewall or the gateway) refused the request before it reached us. ## Which surface should your agent use? Two shapes, and the right one is decided by **what your client can do**, not by which we prefer. | Your client | Use | Why | | --- | --- | --- | | **Runs in a browser**: Claude.ai, ChatGPT, Claude Desktop | the hosted connector `https://app.hermoso.ai/mcp` | It cannot spawn a local process, so a URL is the only shape it has. Nothing to install, no key to paste, and the full toolset arrives with your saved brand context. This is the right answer for these clients, not a lesser one. | | **Can run a shell**: Claude Code, Codex, Gemini CLI, Cursor, Cline, OpenClaw, Hermes, your own scripts | the one-command install above, or the CLI itself (`npm install -g hermoso`) | A tool manifest is loaded into every session whether or not a tool is called. A shell command costs nothing until it runs, and it reaches **every** tool rather than the default roster. | The CLI answers the questions a tool manifest would, on demand and only when asked: ```bash npx -y hermoso tools --search reddit # every matching tool, name + one line npx -y hermoso tools plan_ad # one tool's full argument schema npx -y hermoso call plan_ad --json '{"product":"…"}' # run it ``` `tools` and `tools ` read a registry bundled in the package (no key, no network, no sign-in), so an agent can browse the entire product before anyone signs in. Only `call` spends, and only that needs `hermoso auth login` once. **Want the tools in your coding agent's own list as well?** That is the MCP server, and it is optional. One `hermoso auth login` covers the CLI *and* lets `claude mcp add hermoso -- npx -y hermoso mcp` pick the key up with no `env` block, so the agent can reach for a native tool when it wants structured results and shell out when it wants breadth. It costs context in every session, so add it when a session settles into one area and makes many calls there; `enable_tools({groups:['ads']})` then turns campaign management on in a single free call. ## Your agent can sign itself up An agent with no Hermoso account can provision one, get its own key, and be rendering ads in the same session. No human at a browser, no ticket, no waiting. ```bash # 1. Start a signup. This call takes no credential, because the credential is what it creates. curl -sX POST https://app.hermoso.ai/v1/signup \ -H 'content-type: application/json' \ -d '{"plan":"pro","period":"mo","email":"you@yourcompany.com"}' # -> { "id": "cs_...", "checkout_url": "https://checkout.stripe.com/...", "claim_token": "hsc_...", "email": { "address": "you@yourcompany.com", "verified": false } } # email = the human behind the account. A verification link goes there; the account works before it is clicked. # It is a contact mailbox only, never a sign-in. GET /v1/account/email reports the state; POST /v1/account/email/resend re-sends or changes it. # 2. Pay at checkout_url. Store claim_token first: it is returned only in that response. # 3. Claim it. Poll until status is "ready". curl -sX POST https://app.hermoso.ai/v1/signup/cs_.../claim \ -H 'content-type: application/json' \ -d '{"claim_token":"hsc_..."}' # -> { "status": "ready", "api_key": "hmk_...", "credits": 3000 } ``` That `hmk_` key is the same credential everything else on this page takes: `/v1`, the MCP server, the CLI. Point your client at it and the full surface is open. **Paying is something a browser-capable agent can already do itself.** Checkout is Stripe's own hosted page, so Claude in Chrome and clients like it complete it unattended today. Everything else is a one-click handoff: send `checkout_url` to whoever holds the card. The same shape covers you later, once you are running: `buy_credits` and `upgrade_plan` mint a ready-to-pay link for more credits or a bigger plan, and `billing_status` reads the balance any time. **An agent with its own payment credential can pay with no human at all.** `POST /api/billing/machine-payment` with `{"packId": "pack-1k"}` answers HTTP 402 carrying a `WWW-Authenticate: Payment` challenge (Stripe, through the Machine Payments Protocol); pay the challenge and retry, and the same credit pack lands on the same balance. `GET /api/billing/config` lists the packs under `machinePayments`. Same packs, same prices, no per-call billing. **The agentic path takes a paid plan.** Any of them. The free plan is there for a person signing up at [app.hermoso.ai](https://app.hermoso.ai), and asking for it here returns a refusal that says so. Nothing is created until the payment completes, so an unpaid signup leaves no account behind and charges nothing. **One thing still wants a person, and it is worth knowing up front.** Connecting a social or ad account means an OAuth consent screen, and a consent screen cannot be completed headlessly on any platform. `list_connectors` shows what is already connected and what is not. Everything else runs with no browser at all: research, generation, publishing to a channel that is already connected, campaign builds, reporting. Full request and response shapes, plus every other endpoint, are in the OpenAPI document at [app.hermoso.ai/openapi.json](https://app.hermoso.ai/openapi.json), served live from the same table that mounts the routes. ## Instant: the hosted Claude.ai connector Paste **`https://app.hermoso.ai/mcp?src=readme`** into Claude → Customize → Connectors → Add → *Add custom connector*, press Continue, choose **Sign in now** under Authentication (Claude's detector pre-selects "No sign-in" because our discovery handshake is open, and with that your first request comes back "Authentication required"), press Add and Connect, approve with your Hermoso account, and you are done: the full toolset with your saved brand context, billed to your plan. ## Quickstart for Claude Code (one command) 1. **Get an account** at [app.hermoso.ai](https://app.hermoso.ai). The free tier is included; plans and credits are the same ones the web Studio uses. Or skip the browser entirely and let your agent sign itself up on a paid plan with `POST /v1/signup` (above). 2. **Install the plugin.** It adds the five Hermoso skills, which drive the `hermoso` CLI through `npx`: ```bash claude plugin marketplace add hermoso-ai/hermoso && claude plugin install hermoso@hermoso ``` Already inside a session? `/plugin marketplace add hermoso-ai/hermoso`, then `/plugin install hermoso@hermoso`. Codex, Gemini CLI and the rest are in [Install in one command](#install-in-one-command). 3. **Sign in once.** `npx -y hermoso auth login` opens your browser; your agent also runs it by itself the first time it needs Hermoso. On a machine with no browser, use `npx -y hermoso auth login --token hmk_…` with a key from the **MCP & CLI** tab, under **Terminal & API keys** (Settings → API keys, or https://app.hermoso.ai/?tab=api-keys, go straight there). 4. **Ask for what you want**, in your normal prompts. Claude Code picks the Hermoso skill for the job and runs the commands. You type none of them. Rather install the CLI by hand? `npm install -g hermoso` puts the same `hermoso` command on your PATH, and the skills use it when it is there. The hosted URL works in Claude Code too, but the plugin is the lighter path there because it loads no tool list into your sessions. If you want the connector: `claude mcp add --transport http hermoso "https://app.hermoso.ai/mcp?src=readme"`, and `claude mcp list` reports `! Needs authentication` until you run `claude mcp login hermoso` once and approve in your browser (`--no-browser` prints the link on a headless machine). Measured against Claude Code 2.1.282 on 2026-09-25. Your agent now has the full studio **with your profile's context**: the brand details, products, logos and learned memory you set up in the web app apply automatically (`get_brand` shows what's saved; omit `brand` in `plan_ad`/`plan_variations` to use it). Renders bill your Hermoso credits, at the same prices as the Studio. Only AI model runs and Ad Spy research spend credits; publishing, scheduling, ads management and analytics cost no credits on any plan (posting to X and reading X data are the one per-call exception, managing X ads is free). The Free plan includes 10 posts a month on up to 3 platforms; every paid plan posts without a limit and runs autopilot. Basic ($9.99 a month) is unlimited posting and Autopilot with no monthly credits: it includes the same 250+ free credits as the Free plan, monthly credits start on Starter, and Autopilot spends credits. ## 1. MCP server (stdio), optional in a coding agent `hermoso mcp` runs a stdio MCP server exposing the full toolset, for a client that wants Hermoso's tools in its own list. The published `hermoso` package means no clone: `npx -y hermoso mcp` fetches and runs it. Sign in once with the CLI and no key goes into any client config, because `hermoso mcp` reads the bearer `hermoso auth login` stored: ```bash npm install -g hermoso && hermoso auth login && claude mcp add hermoso -- npx -y hermoso mcp ``` On a machine with no browser, skip the sign-in and pass the key to the client instead: ```bash claude mcp add hermoso -e HERMOSO_TOKEN=hmk_… -- npx -y hermoso mcp ``` Cursor / Codex: sign in the same way, then add to `mcp.json` (Codex uses the TOML equivalent). Drop the `env` block entirely if you signed in above; it is there for CI, where the process cannot read your home directory: ```json { "mcpServers": { "hermoso": { "command": "npx", "args": ["-y", "hermoso", "mcp"], "env": { "HERMOSO_API_BASE": "https://app.hermoso.ai", "HERMOSO_TOKEN": "" } } } } ``` Then ask your agent: *“Generate an image ad with Hermoso.”* ### What the 1182 tools cover **Ad spy / research** — `find_competitors`, `competitor_teardown`, `pull_competitor_ads`, `research_ads`; the Meta / Google / LinkedIn ad libraries (`search_meta_ads`, `search_google_ads`, `search_linkedin_ads`); organic social (`search_tiktok`, `search_instagram`, `search_youtube`, `search_reddit`, `search_threads`); `fetch_social_data`, `mine_angles`, `analyze_video`, `check_ad_policy`, `list_skills` / `get_skill`. **Create** — `draft_brand` → `plan_ad` → `render_ad` (the Studio quality pipeline: composited text, clean speech, music, brand end card), or `generate_image` / `generate_video` / `generate_avatar` (UGC creators + lip-sync). The workspace's **saved cast** is reusable: `list_creators` returns every saved creator with their portrait url, `save_creator` adds one, `delete_creator` drops one — re-pass a portrait to `generate_avatar` / `generate_video` / `recast_motion` and the SAME person stars in every ad, instead of a new face each render. Also `make_template_ad` (native HTML ad formats), `make_explainer`, `product_sizzle`, `make_thumbnail`, `clone_static`, `recast_motion`, `reframe_video`, `upscale_video`, `dub_video`, `change_voice`, `finish_video`, `fix_beat`, `stitch_video`, `clip_video`, `post_edit`, plus `plan_variations` + `score_ad` to fan out and rank. **Length is yours to set:** pass `durationSeconds` to `plan_ad` and the storyboard is *authored* to it — a length that fits one clip of the render model renders as a single continuous take, longer is stitched from acts (on a 15s-clip model, 40s = 15+15+10), never time-compressed. What fits one clip is the model's own maximum, not a fixed number: most video models cap a clip at 15 seconds and the longest-clip one takes **30 seconds in one unbroken take** with native synchronized audio. `hermoso_capabilities` is the live list — durations, resolutions and the exact credit cost of every tier — and naming that model in `model` is how you get it, since an unnamed render is routed by a narrower auto-pool. **Ads Studio** (`make_static_ads`): pick products and a count and get a batch of finished static ads in one call, each a different selling angle and a different layout, with your real product photo and logo laid on. The product catalog it draws from (`list_products`, `add_product`, `refresh_products`, `update_product`, `remove_product`) is a cache of each product's live page, so names, photos and prices come from the page itself. **Swap a person into any video** (`recast_hook`, `recast_motion`): keep the scene, the cuts and the sound and change who is on screen, using your own photo, a saved creator or an AI person (in the web Studio you can describe a presenter in words). Real faces from your own photos need a paid plan; AI people work on every plan. **Raw model playground** — the full catalog (30+ image / video / voice / writing models, each with its exact per-render credit cost) with no ad framing: `generate_image` / `generate_video` with `useBrand:false`, `generate_voice`, `generate_text`. The image default is Nano Banana 2.1. **Publish to your own channels** — **fifteen** of them: Facebook, Instagram and Threads (`post_to_meta`), TikTok (`post_to_tiktok`), YouTube (`post_to_youtube` + `update_youtube_video`, `youtube_video_insights`, comments read/reply), X (`post_to_x`, `x_post_metrics`, `x_post_insights`, `x_mentions`, `list_x_dms`, `send_x_dm`), LinkedIn profile **and** company Pages (`post_to_linkedin`, `post_to_linkedin_page`), Pinterest (`post_to_pinterest` + boards), Bluesky (`post_to_bluesky`, `delete_bluesky_post`, `bluesky_post_metrics`, plus `list_bluesky_convos` / `read_bluesky_dm` / `send_bluesky_dm`) and Telegram (`post_to_telegram`, `delete_telegram_message`, `list_telegram_chats`), WordPress (`post_to_wordpress`, `update_wordpress_post`, `delete_wordpress_post`, `list_wordpress_posts`), Discord and Slack announcements (`post_to_discord`, `edit_discord_message`, `delete_discord_message`, `post_to_slack`), Whop (`post_to_whop`, `edit_whop_post`, `delete_whop_post`, `get_whop_post`, `list_whop_destinations`) and Google Business Profile (below). `schedule_post` / `list_scheduled` / `cancel_scheduled` give you one content calendar over exactly that set. `upload_file` brings in any external or local media, not just Hermoso renders. *X posting bills credits per API call (X charges per request); a post containing a link costs 13× one without.* **Google Business Profile** is the panel a business shows on Google Search and Maps. `post_to_google_business` publishes a Post with text, optionally one photo, and a call-to-action button (Google takes no video in Posts, so a schedule with only a video is refused for that channel); `list_google_business_posts` and `delete_google_business_post` manage what is showing. `list_google_business_reviews` finds the reviews with no answer yet and `reply_to_google_business_review` answers one as the business. `google_business_insights` reports search and Maps impressions, calls, website clicks and direction requests, and `google_business_search_keywords` the words people searched to find the listing. `list_business_locations`, `get_business_location` and `update_business_location` read and edit the listing itself: hours, phone, website, description, categories. Business Profile Q&A is not offered: Google retired it on 2025-11-03. **Message customers on WhatsApp** — messaging, not a twelfth publishing channel: you message a person, and nothing here posts to a feed. `list_whatsapp_accounts` finds the Business Account and its numbers, `list_whatsapp_templates` / `create_whatsapp_template` / `delete_whatsapp_template` manage the templates Meta reviews, and `send_whatsapp_message` sends one — confirm-gated, because it reaches a real phone and Meta bills the business for the conversation. Two limits that are permanent facts about Meta's API rather than anything pending: **Hermoso does not receive WhatsApp webhooks, so there is no message history to read** — it is not an inbox surface and `list_inbox` does not cover it — and **outside the 24-hour window that opens when the customer messages first, WhatsApp accepts an APPROVED template and nothing else.** **Automate Instagram DMs** — `save_instagram_dm_automation` sets up a rule that answers people for the brand: a comment with a keyword on one post, the next post or any post gets a private reply, and a DM, a story reply or an ig.me link gets an answer, with optional link buttons, a public comment reply, a follow gate and a dry run. `test_instagram_dm_automation` shows exactly what a sample comment or DM would send without sending it, and `list_instagram_dm_automations` / `delete_instagram_dm_automation` read each rule's stats and send log or remove it. Each person gets one reply per post, Meta allows a private reply within 7 days of the comment, and no AI runs on the send path, so it costs no credits. **Automate DMs on Facebook and X too** — `save_dm_automation` (with `test_dm_automation`, `list_dm_automations` and `delete_dm_automation`) takes a `channel`: `instagram`, `facebook` (a keyword comment on a Page post or an ad gets a private reply in Messenger; a Messenger keyword or an m.me link gets an answer) or `x` (a keyword @mention or a reply under your post gets a public reply; a DM keyword gets a DM back). X only allows an automated DM after the person has DMed you, and a DM saying STOP opts that person out. Facebook is free like Instagram. X bills us per call, so an X automation is charged in credits for every mention, reply or DM X delivers plus each reply or DM sent, and running out of credits stops its X rules. **Autopilot posting** (`set_post_refill`, `get_post_refill`, `run_post_refill`): say how often, where and what about ("2 posts a day on Instagram and Bluesky about our slow-morning routine, let me review first") and Hermoso makes new posts from your brand and fills your calendar. Pick review first (each batch waits for your approval, edit or redo) or post automatically (straight onto the schedule, still pullable). It follows the notes you leave and writes from what has worked on each channel. Credits are used only when a post is made. **Run the ads** — full campaign trees, built paused and read back before anything is reported, with every spend change confirm-gated, on **twelve** platforms: **Meta**, **Google Ads**, **LinkedIn Ads**, **Reddit Ads**, **Pinterest Ads**, **Microsoft Advertising**, **ChatGPT Ads** (OpenAI's Advertiser API), **X Ads**, **TikTok Ads**, **Snapchat Ads**, **Apple Ads** (Apple Search Ads on the App Store) and **AppLovin Ads** (reporting and the website pixel on the keys every account has; campaign building once AppLovin enables Campaign Management API access on the account, and server-side conversion events with the Conversion API key AppLovin issues on request). Each has list + report + create + budget/status tools (e.g. `list_google_ads_campaigns`, `google_ads_report`, `create_google_ads_campaign`, `set_google_ads_budget`, `set_google_ads_status`). *Snapchat needs one extra step the others do not: an ad points at a CREATIVE, and every Snapchat creative must carry a Public Profile id — build it with `upload_snapchat_ads_creative`.* **Feed the shopping surfaces** — **Google Merchant Center** is the catalog a retail Performance Max or Shopping campaign advertises (`create_google_ads_performance_max_campaign` takes a `merchantCenterId`), and you manage it from here: accounts and account status, data sources, product upsert / update / delete, per-region inventory, quota, `merchant_report` for product-level performance, notifications and conversion sources, plus the disapproval loop — `list_merchant_issues` says what is wrong and `merchant_issue_help` returns Google's own documented fix. *Promotions need the merchant's own enrolment in Google's promotions program; without it Google refuses that sub-API outright.* **Microsoft Merchant Center** is covered on the same shape (stores, catalogs, products, issues) for Bing Shopping. **Measure what the ads achieved** — Google Analytics 4 closes the loop. Every other connector here reports what an ad *cost*; this is the one that reports what it *did*. `analytics_report` breaks sessions, users, conversions and revenue down by channel, source/medium, campaign, landing page, country, device or date, so the campaign Hermoso built and the revenue it drove sit in one conversation. `analytics_realtime` shows who is on the site right now. Start at `list_analytics_properties` — the tools take a numeric property id, not the `G-XXXXXXXXX` Measurement ID from your tracking snippet, and this is what resolves one from the other. It writes as well as reads: `create_analytics_key_event` marks an event GA4 already collects as a key event — which is what makes it importable into Google Ads as a conversion — and `create_analytics_custom_dimension` registers an event parameter so reports can break down by it, with `list_analytics_definitions` showing what the property already measures. It signs in with the same Google account as Google Ads, YouTube and Drive, but it is its own connection. *GA4 only — the API has no Universal Analytics surface. A custom dimension can be archived but never deleted, and a property holds 50 event-scoped ones.* **Files** — Google Drive CRUD (`save_to_drive`, `list_drive_files`, `update_drive_file`, `delete_drive_file`, `create_drive_folder`), Google Sheets (`create_sheet`, `append_to_sheet`, `read_sheet`), Google Docs (`create_doc`, `append_to_doc`), and OneDrive (`save_to_onedrive` + full CRUD). **Workspace & account** — profiles (`list_brands`, `create_brand`, `use_brand`, `update_brand`, `delete_brand`; one account holds many profiles, each a brand, a client, a creator or a personal workspace, so an agency runs every client through here), memory (`remember`, `forget`, `list_memory`), custom skills (`save_skill`, `get_skill`, `list_skills`, `delete_skill` — the one library, which absorbed the old AI-Employee personas), team (`list_team`, `invite_member`, `remove_member`, `set_role`), settings (`get_settings`, `update_settings` — including the **language** every ad, script and plan is written in), connectors (`list_connectors`, `list_connector_accounts`, `set_connector_accounts`, `disconnect_connector`), and billing (`hermoso_credits`, `billing_status`, `buy_credits`, `upgrade_plan`, `set_auto_reload`), plus `list_jobs` / `get_job` for async renders. **Connector accounts are picked, not guessed.** One person often administers several Facebook Pages, Google Ads customers or LinkedIn company Pages. Only the accounts ticked for a profile are usable — enforced server-side, and an empty selection shares nothing. Linking a *new* account is the one step that is not headless (it is an OAuth consent screen, so the user does it in the app). Render jobs queue server-side and poll to completion, returning a served URL. ## 2. CLI: the context-free path for terminal agents `bin/hermoso.mjs` exposes the full MCP toolset as subprocess commands, so an agent can shell out instead of carrying a fat tool manifest. ```bash npm install -g hermoso # installs `hermoso` hermoso capabilities # valid model ids + costs (run first) hermoso create --brand "YourBrand" --product "your best-selling product" --format image hermoso generate image --prompt "…" --ref ./product.png --wait hermoso generate video --prompt "…" --duration 8 --wait hermoso competitors yourbrand.com hermoso research "Liquid Death’s longest-running ads" ``` Add `--json` to any command for machine output. **Those shortcuts are the common path, not the limit.** Every tool the MCP server has is reachable here too, including the ad-campaign and analytics groups a connector leaves out of its default roster: ```bash hermoso tools # every tool, grouped, name + one line hermoso tools --group ads --search reddit # narrow it hermoso tools create_meta_campaign # that tool's full argument schema hermoso call create_meta_campaign --json '{"name":"…"}' # run it hermoso create_meta_campaign --name "…" # same thing, shorter ``` `call` goes through the same handler, the same argument validation and the same confirm/spend gates the MCP server uses, so there is no second implementation to drift. `tools` and `tools ` read a registry bundled in the package, so they need no key, no network and no sign-in. ## 3. Skills: what a coding agent installs `skills/` holds five installable skills: | Skill | What it does | | --- | --- | | `hermoso-research` | Find competitors, pull their real running ads, surface the hooks worth copying | | `hermoso-generate` | A prompt to a finished image, video, avatar clip or stitched cut | | `hermoso-ad-from-brand` | A brand or domain to one on-brand ad, concept and copy included | | `hermoso-product-photoshoot` | A real product photo composited into studio, lifestyle or hero scenes | | `hermoso-marketing` | The whole loop: research, create, publish and schedule, paid campaigns, measure | They are what every one-command install at the top of this page adds, in Claude Code, Codex, Gemini CLI and through `npx skills add`. From a clone, copying works too: ```bash cp -r skills/* ~/.claude/skills/ ``` Then invoke `/hermoso-ad-from-brand an ad for yourbrand.com, our hero product`. ### Ask for it in your own words The skills pick themselves. These are whole prompts, not commands: - *Find my top 5 competitors for [product + URL], pull their best Meta and TikTok ads from the last 90 days, and tell me the 3 hooks and 2 formats worth stealing, with the evidence.* - *Make this week's ads for [brand]: two hooks in two formats, one UGC and one product visual, 9:16. Score them and policy check them before I ship.* - *Here is a competitor ad: [link]. Break down why it works, then rebuild the structure with my product, my branding and a fresh hook.* - *Fill my social queue for the next 7 days across Instagram, TikTok, X and LinkedIn, repurposed from my best post, with per-channel captions.* - *Take last week's winner and build a $20/day test campaign on Meta and TikTok, three ad sets, one angle each. Leave it paused and read the tree back so I can check it.* - *Pull last month's campaign performance across every platform. Which two creatives won, why, and what should next month's brief say?* ## Configuration | Env | Meaning | | --- | --- | | `HERMOSO_API_BASE` | The Hermoso API origin (default `https://app.hermoso.ai` — set `http://localhost:3000` if you run the app yourself) | | `HERMOSO_TOKEN` | Bearer agent key (`hmk_…`) — required against the hosted app | | `HERMOSO_PROFILE` | Profile id, for accounts with multiple profiles | | `HERMOSO_OWNER` | Only for a profile **another account shared with you** (a team workspace): the owning account id. Set it together with `HERMOSO_PROFILE`, and set `HERMOSO_PROFILE` to that workspace's **profileUuid** (a profile's short slug is refused). Run `list_brands` (or `hermoso list_brands` from the CLI) to print both values for every workspace you can enter. The server re-authorizes the pair on every request, so a wrong value is refused, never trusted. | `mcp/http.mjs` is the hosted remote-connector transport (paste-a-URL into Claude.ai → Connectors). It ships in this repo for transparency and refuses to mount without authenticated identity — no anonymous spend, ever. ## License MIT © Hermoso