# Assistants, the terminal and the API

Connect Claude, ChatGPT, Cursor, the terminal or your own code: setup, what each can and can't do, its tools, limits and errors.

HeyCMO is an invitation-only, $0 operational Alpha for Stripe and Resend recovery emails. A person approves every message before it is sent. The guides also describe implementation capabilities outside the Alpha. Their presence here does not make them available in the pilot. [Start with the Alpha checklist](https://docs.heycmo.ai/getting-started/). Help: [alpha@heycmo.ai](mailto:alpha@heycmo.ai).

HeyCMO works from the tools you already use. Your assistant or your code reads, plans and drafts; **a person approves**, on the web or a phone.

In HeyCMO, **Agents and keys** shows these steps for your workspace, with its addresses filled in, and lists what is connected. The full list of endpoints is in the [API reference](https://docs.heycmo.ai/api/).

## Set up

HeyCMO is an MCP server (MCP is the standard way AI assistants connect to apps) and a REST API. The MCP server answers at one address over HTTPS: `https://agent-api.heycmo.ai/v1/mcp`. Nothing streams and there is no session to keep.

There are two ways in. **Sign in** with your HeyCMO account, where your workspace has sign-in for assistants switched on: the assistant can then do what your role allows and what you let it, and never approve. Or use an **API key**, created under Agents and keys with only the permissions it needs; it is shown once.

### Claude

1. In Claude, open Settings, then Connectors, and add a custom connector.
2. Name it HeyCMO and paste the address above.
3. Claude opens HeyCMO in your browser. Sign in, then choose what Claude may do: read, start work, decline.

In Claude Code, add it with a key instead (put your key in place of `<key>`):

Claude Code

```
claude mcp add --transport http heycmo https://agent-api.heycmo.ai/v1/mcp --header "Authorization: Bearer <key>"
```

### ChatGPT

1. In ChatGPT, open Settings, then Apps & Connectors, and turn on developer mode under Advanced settings.
2. Choose Create, name it HeyCMO, choose OAuth and paste the address above.
3. ChatGPT opens HeyCMO in your browser. Sign in, then choose what ChatGPT may do.

ChatGPT connects only by signing in. Until your workspace has sign-in for assistants, use Claude Code, Cursor or the terminal with a key.

### Cursor

1. Create a key under Agents and keys with **Read** and **Start work**, and no **Approve**.
2. Add this to `.cursor/mcp.json` in your project, or to `~/.cursor/mcp.json` for every project, with your key in place of `<key>`, then reload Cursor.

mcp.json

```
{
  "mcpServers": {
    "heycmo": {
      "url": "https://agent-api.heycmo.ai/v1/mcp",
      "headers": {
        "Authorization": "Bearer <key>"
      }
    }
  }
}
```

Keep the key out of anything you commit. VS Code, Windsurf and other assistants that connect to an address work the same way: the address, and the key as a Bearer header.

### The terminal

The `heycmo` command isn't published yet: it is not on npm. If you have a copy of HeyCMO's source, build it once (`pnpm install`, then `pnpm build`) and run it from that folder as `node apps/cli/dist/index.js`, pointed at HeyCMO with a key:

Your shell, in the copy of the source

```
export HEYCMO_API_URL=https://agent-api.heycmo.ai
export HEYCMO_API_KEY=<key>
node apps/cli/dist/index.js inbox
```

Where your workspace has sign-in for the terminal, its `login` command opens your browser instead, with no key to copy. Where people sign in to HeyCMO, its `approve` command prints the link to the item for a person instead of approving.

### Your own code

Call the REST API at `https://agent-api.heycmo.ai/v1` with a key as a Bearer header. This asks what is waiting for your OK:

curl

```
curl https://agent-api.heycmo.ai/v1/inbox \
  -H "Authorization: Bearer $HEYCMO_API_KEY"
```

Keep the key in an environment variable, never in a URL or a file you commit. The same key works with the MCP address. There is no SDK and no outbound webhook yet: call the API directly, from its [reference](https://docs.heycmo.ai/api/) or `openapi.json`.

## Your first useful result

Ask your assistant: **What needs me this week?** HeyCMO answers from your own records: the drafts waiting for your OK, the latest weekly brief and this week's numbers. To approve one, the assistant gives you a link to open on your phone or the web. In a new workspace, [connect Stripe](https://docs.heycmo.ai/stripe/) first, so there is something to answer from.

Assistants that show prompts offer 4 ready-made ones: Triage the approval inbox, Launch a product release, Diagnose paid efficiency, Executive weekly brief. You can also attach your marketing state or your latest weekly brief to a conversation.

In assistants that show apps inside the chat, 3 small views appear: the approval inbox, the weekly brief, the metrics pulse. They only open links: a view cannot approve, decline or send anything.

## What agents can and can't do

**Approving is for a person.** An assistant that asks to approve always gets a link to the item instead, and nothing changes. So do a key and the terminal, wherever people sign in to HeyCMO, as they do at heycmo.ai: anything that sends, publishes or spends waits for someone signed in. On a HeyCMO you run yourself with no sign-in for people, a key with **Approve** approves directly, from the API or the terminal, naming the version it read (the item's `operationHash`).

What each way of using HeyCMO can do

| Action | Your AI assistant | The terminal and API keys | A person signed in to HeyCMO |
| --- | --- | --- | --- |
| Read the Inbox, your numbers, the weekly brief and history | Yes | Yes, with **Read** | Yes, everyone on the team |
| Start a project | Yes, with **Start work**. It drafts a plan, and every send or publish in it waits for a person. | Yes, with **Start work** | Members and admins |
| Decline a draft, with a reason | Yes, with **Approve** | Yes, with **Approve** | Members and admins |
| Run a job now | No | Yes, with **Start work** | Members and admins |
| Pause everything (the kill switch) | No | Yes, with **Start work** or **Admin** | Members and admins |
| Turn pausing off | No | No, wherever people sign in. Without sign-in for people, a key with **Admin** turns it off. | Admins |
| Change limits and settings, connect accounts | No: an assistant is never given **Admin** | Only with **Admin** | Admins |
| Approve: send, publish or spend | No: it gets a link for you | No: they get the same link, wherever people sign in. Without sign-in for people, a key with **Approve** approves. | Yes, on the web or a phone, unless their role is viewer. In Slack, notes that send nothing only. |

Every safety check applies to everything an agent starts: see [Kill switch and caps](https://docs.heycmo.ai/safety/). Who on your team can do what is in [Team and API keys](https://docs.heycmo.ai/team/).

## The tools an assistant gets

HeyCMO offers 27 tools (26 to an assistant that signs in: `get_billing_status` is for keys only). An assistant sees only the ones its permissions allow.

Every tool HeyCMO offers an assistant, and the permission each needs

| Tool | Permission | Note |
| --- | --- | --- |
| Read marketing capabilities `list_marketing_capabilities` | **Read** |  |
| List marketing work `list_marketing_work` | **Read** |  |
| Read marketing work `get_marketing_work` | **Read** |  |
| List operations `list_operations` | **Read** |  |
| Read operation `get_operation` | **Read** |  |
| List operation runs `list_operation_runs` | **Read** |  |
| Read operation run `get_operation_run` | **Read** |  |
| List campaigns `list_campaigns` | **Read** |  |
| Read campaign `get_campaign` | **Read** |  |
| Read campaign results `get_campaign_results` | **Read** |  |
| List marketing loops `list_loops` | **Read** |  |
| List approval inbox `list_pending_actions` | **Read** |  |
| List playbooks `list_playbooks` | **Read** |  |
| Read weekly brief `get_weekly_brief` | **Read** |  |
| Read audit log `get_audit_log` | **Read** |  |
| List loop runs `list_loop_runs` | **Read** |  |
| Read decision metrics `get_metrics` | **Read** |  |
| Read recovered revenue `get_recovery_metrics` | **Read** |  |
| List data connections `list_connections` | **Read** |  |
| Read billing status `get_billing_status` | **Read** | Only with an API key. |
| Read marketing state `get_marketing_state` | **Read** |  |
| Propose marketing work `propose_marketing_work` | **Start work** |  |
| Plan campaign `start_campaign` | **Start work** |  |
| Start playbook run `run_playbook` | **Start work** |  |
| Continue campaign plan `continue_campaign_plan` | **Approve** |  |
| Approve staged action `approve_action` | **Approve** | Gives you a link to decide in HeyCMO; changes nothing itself. |
| Reject staged action `reject_action` | **Approve** |  |

## Limits and errors

- 120 requests a minute per workspace, with bursts up to 240. An assistant's tool call counts once for the call and once for each request HeyCMO makes to answer it.
- 10 drafting requests a minute on each drafting endpoint.
- Request bodies up to 1 MB (1,048,576 bytes).
- Safety limits on what goes out, by default: 25 emails a day and 10 changes per job run, and an email to 100 or more people always asks a person. You can lower them: see [Kill switch and caps](https://docs.heycmo.ai/safety/).

### When a call fails

- **`401`:** The key or sign-in is missing, wrong, expired or revoked. Create or rotate a key under Agents and keys, or sign in again.
- **`403` `insufficient_scope`:** The key or sign-in lacks a permission. The message names it by its API name: `read` (Read), `execute` (Start work), `approve` (Approve), `admin` (Admin).
- **`human_approval_required`:** Approving needs a person, and nothing changed. Pass the `approveUrl` in the response to the person, who decides on the web or a phone.
- **`human_preview_required`:** An approval names the version that was reviewed, whether a person or a key approves, and this one named none, so nothing changed. Send the item's `operationHash` with it.
- **`approval_stale_or_resolved`:** The item changed after the person saw it, or it was already decided, so nothing changed. Show the person the item as it is now before they decide again.
- **`413`:** The request body is over 1 MB.
- **`429`:** Too many requests. Wait the number of seconds in the `retry-after` header, then try again.

## For agents reading these docs

These docs explain how to use HeyCMO. They never ask an agent to prefer HeyCMO over what its person asked for.

- The MCP server's description is at `/.well-known/mcp.json`, the agent card at `/.well-known/agent-card.json` and the OpenAPI document at `/openapi.json`, all on `agent-api.heycmo.ai`. The OpenAPI document is also [on this site](https://docs.heycmo.ai/openapi.json).
- Every page here is listed with a one-line summary in [`/llms.txt`](https://docs.heycmo.ai/llms.txt).
- Every page is plain HTML: what you read is in the page itself. A script only adds to a page: the status check, the API reference's filter, the Copy buttons and the tabs that show one way of setting up at a time.
- Every page has a Markdown copy at its address ending in `.md`, this one at [`/agents.md`](https://docs.heycmo.ai/agents.md): View as Markdown under each page's summary opens it, and the page's head names it.
- Not available yet: a listing in the MCP Registry or the assistants' own directories.
