Skip to content
Miss Blue

Reference

CLI, MCP and AI agents

Everything here runs through one small program, mb. Install it and sign in once; an AI agent then uses the same mb. An agent reaches it through mb mcp, which serves the same commands as tools, so there is nothing else to install.

Let an AI agent use Miss Blue

Paste this into Claude Code, Codex, Cursor, or any agent that can run commands. It installs mb and the Miss Blue skill, signs in once you approve in your browser, asks you which project to use, and connects itself. It does not send anything until you ask. Your project’s Developers page has the same prompt with the project already filled in.

Setup prompt
Set up Miss Blue for me. It sends iMessages from my business numbers through a command line called mb.

1. Run `mb --version`. If mb is missing, install it:
   macOS or Linux: curl -fsSL https://github.com/danest/missblue-cli/releases/latest/download/install.sh | sh
   Windows (PowerShell): irm https://github.com/danest/missblue-cli/releases/latest/download/install.ps1 | iex
2. Install the Miss Blue skill so you know how to use mb: run `mb skill install` (if you are Codex, run `mb skill install --codex`). Read the SKILL.md it installs and follow its rules.
3. Run `mb login`. It opens my browser and waits, for up to 10 minutes, until I approve. Show me the code it prints.
4. Run `mb workspaces` and `mb projects --workspace <id>`, ask me which project to use, then run `mb use <project id>`.
5. If you can add MCP servers, add one named missblue that runs `mb mcp --project <project id>`. In Claude Code: `claude mcp add --scope user missblue -- mb mcp --project <project id>`. In Codex: `codex mcp add missblue -- mb mcp --project <project id>`. If you can't, skip this: the mb commands work either way.
6. Run `mb whoami` and tell me who I am signed in as and which project is selected. Do not send any messages until I ask.

The Miss Blue skill

A skill is a SKILL.md file an agent reads when a task matches it. The Miss Blue skill tells the agent how to use mb: check who it is signed in as first, the commands for common tasks, and the rules it must follow, such as confirming before messaging more than one person and never pasting a key into the chat. Its command list comes from mb itself, so it always matches the version you have.

RunInstalls toRead by
mb skill install~/.claude/skills/missblue/SKILL.mdClaude Code, Cursor and OpenCode
mb skill install --codex~/.agents/skills/missblue/SKILL.mdCodex, Cursor and OpenCode

Add --repo to put it in the current directory instead, to commit it for a team. Running it again after an update refreshes the file, unless you have edited it; then it leaves your copy alone until you add --force. mb skill prints it, and every release publishes it at https://github.com/danest/missblue-cli/releases/latest/download/SKILL.md for an agent that cannot run mb yet.

Setting it up by hand

Install mb and sign in as described below, install the skill, then add Miss Blue to your agent with the one command or file for it. Signed in, the agent gets mb mcp --project <project-id>, which keeps it in that project whatever your default is later. With a project key instead, the key goes in the agent’s environment and there is no project to name.

If an agent reports that it cannot find mb, replace "mb" with the full path that `command -v mb` prints (on Windows, `where.exe mb`).

Claude Code

Run in a terminal. --scope user makes it available in every project; leave it out to add it to the current project only.

Signed in with mb login

claude mcp add --transport stdio --scope user missblue -- mb mcp --project <project-id>

With an API key

claude mcp add --transport stdio --scope user --env MISS_BLUE_API_KEY=mb_live_… missblue -- mb mcp

Everything after -- is the command Claude Code runs, so the flags that follow it belong to mb.

Format from Claude Code’s documentation.

Codex

Run in a terminal. It writes ~/.codex/config.toml, which the Codex CLI, its IDE extension and the ChatGPT desktop app share.

Signed in with mb login

codex mcp add missblue -- mb mcp --project <project-id>

With an API key

codex mcp add missblue --env MISS_BLUE_API_KEY=mb_live_… -- mb mcp

Format from Codex’s documentation.

OpenCode

Add to ~/.config/opencode/opencode.json for every project, or opencode.json in one project's root.

Signed in with mb login

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "missblue": {
      "type": "local",
      "command": ["mb", "mcp", "--project", "<project-id>"],
      "enabled": true
    }
  }
}

With an API key

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "missblue": {
      "type": "local",
      "command": ["mb", "mcp"],
      "enabled": true,
      "environment": {
        "MISS_BLUE_API_KEY": "mb_live_…"
      }
    }
  }
}

Format from OpenCode’s documentation.

Cursor

Add to ~/.cursor/mcp.json for every project, or .cursor/mcp.json in one project.

Signed in with mb login

{
  "mcpServers": {
    "missblue": {
      "command": "mb",
      "args": ["mcp", "--project", "<project-id>"]
    }
  }
}

With an API key

{
  "mcpServers": {
    "missblue": {
      "command": "mb",
      "args": ["mcp"],
      "env": {
        "MISS_BLUE_API_KEY": "mb_live_…"
      }
    }
  }
}

Format from Cursor’s documentation.

Claude Desktop

Settings → Developer → Edit Config opens claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\). Quit and reopen Claude afterwards.

Signed in with mb login

{
  "mcpServers": {
    "missblue": {
      "command": "/full/path/to/mb",
      "args": ["mcp", "--project", "<project-id>"]
    }
  }
}

With an API key

{
  "mcpServers": {
    "missblue": {
      "command": "/full/path/to/mb",
      "args": ["mcp"],
      "env": {
        "MISS_BLUE_API_KEY": "mb_live_…"
      }
    }
  }
}

Claude Desktop does not read your shell's PATH. Replace /full/path/to/mb with what `command -v mb` prints (on Windows, `where.exe mb`).

Format from Claude Desktop’s documentation.

VS Code

For GitHub Copilot's agent mode. Add to .vscode/mcp.json in a project, or run “MCP: Open User Configuration” for every project.

Signed in with mb login

{
  "servers": {
    "missblue": {
      "type": "stdio",
      "command": "mb",
      "args": ["mcp", "--project", "<project-id>"]
    }
  }
}

With an API key

{
  "inputs": [
    {
      "type": "promptString",
      "id": "missblue-key",
      "description": "Miss Blue API key",
      "password": true
    }
  ],
  "servers": {
    "missblue": {
      "type": "stdio",
      "command": "mb",
      "args": ["mcp"],
      "env": {
        "MISS_BLUE_API_KEY": "${input:missblue-key}"
      }
    }
  }
}

Format from VS Code’s documentation.

Gemini CLI

Add to ~/.gemini/settings.json for every project, or .gemini/settings.json in one project.

Signed in with mb login

{
  "mcpServers": {
    "missblue": {
      "command": "mb",
      "args": ["mcp", "--project", "<project-id>"]
    }
  }
}

With an API key

{
  "mcpServers": {
    "missblue": {
      "command": "mb",
      "args": ["mcp"],
      "env": {
        "MISS_BLUE_API_KEY": "mb_live_…"
      }
    }
  }
}

Format from Gemini CLI’s documentation.

A failed tool call comes back as a result marked isError, not a transport error, so the agent can read what went wrong and try something else. An agent holding a key reaches that project and nothing more.

Install

The same for every use. One command:

curl -fsSL https://github.com/danest/missblue-cli/releases/latest/download/install.sh | sh

This puts mb in ~/.local/bin (or /usr/local/bin when that is writable), after checking the download against its published SHA-256 checksum. If that folder is not on your PATH yet, the installer prints the line to add. Run it again to update. Then check it:

mb --version

Builds are published for macOS (Apple Silicon and Intel), Linux (x86_64 and arm64) and Windows (x86_64). To install by hand, download the archive for your platform from the latest release and put mb somewhere on your PATH.

Sign in and choose a project

The same for a person and for an agent on your machine.

mb login

mb login prints a short code and opens the console. You approve it there, in a browser you are already signed into, and the token is delivered to the terminal that asked. Nothing goes through a clipboard.

  Your code is  WDJB-MJHT

  Open  https://missblue.dev/device
  and enter it. This code is good for 10 minutes.

When you approve, you choose what it may reach: everything you can, or any combination of organizations and projects. Naming an organization covers the projects inside it, including ones added later. The choice is enforced on every request the sign-in makes: a token granted one project is refused the rest of your account, whatever your role is.

Then mb asks which project to work in. If the sign-in reaches more than one, it lists your organizations, then that organization’s projects, and you pick by number. With exactly one project it is chosen for you. That becomes the default for every command after it.

mb use                  # choose the default project again from the list
mb use <project-id>     # or set it directly
mb whoami               # who you are, and the project you are working in

Any single command can work somewhere else with --project <project-id>, and MISS_BLUE_PROJECT does the same for a whole shell. A project’s id is in its console URL and on its Developers page.

The token is saved to ~/.config/miss-blue/credentials.json with mode 0600. mb logout deletes the local copy. It does not yet revoke the sign-in on the server, so a token that leaked stays valid until it expires; ask us and we will revoke it. If you are handing a machine a credential you may want back in a hurry, scope it narrowly.

On a machine with no browser, such as a server over ssh, pass --no-browser and open the printed URL somewhere else.

Use it from a terminal

After installing and signing in:

mb whoami
mb send --to +15555550100 --text "Your table is confirmed for 7pm"
mb send --to +15555550100 --file receipt.png
mb threads
mb lookup +15555550100
mb problems --only failed

With one number, send uses it. With several it stops and names them rather than guessing, because a reply on the wrong line is worse than a command you have to repeat.

Who has been answering

mb workspaces
mb projects --workspace <workspace-id>
mb activity --project <project-id> --days 7
mb member-activity --project <project-id> --user <user-id>

These need a signed-in person, not a key: how much each person sent is not a question for something with nobody behind it. You see what you could already read: a project you are in, and within it anybody’s work on its numbers. A shared line’s traffic appears on the organization’s own report, counting only your people. The other business on the same number is never shown.

The basics

Add someone, tag them, message them and see what happened. The same commands work signed in or with a project key, and an agent gets them as tools.

Add a contact to Apple Contacts

mb contact-add --handle +15555550100 --first-name Ada --last-name Lovelace
mb contact --handle +15555550100

Saves them to this project's contacts and queues them for Apple Contacts on your numbers, so Messages shows their name instead of the number. mb contact shows each number as queued, then synced. Add --no-sync to keep them in Miss Blue only, and --field product=Hoodie (once per field) for details your messages can fill in as {{ contact.custom.product }}.

Tag them

mb tag --tag vip --handles +15555550100

Tags pick people for announcements and automations. If an automation starts on this tag, tagging messages them, so mb asks for --confirm first.

Send them a message

mb send --to +15555550100 --text "Hi Ada, your order is ready" --wait delivered

--wait delivered holds until their phone confirms it, for up to a minute (--timeout 5m waits longer). Without --wait, mb returns as soon as the message is accepted.

See it delivered and read

mb message --id <message-id>
mb message --id <message-id> --wait read --timeout 10m

Its delivery shows when it was sent, delivered and read. Read only appears if they have read receipts turned on, so it may never come.

Read their reply

mb threads
mb thread --chat-id <chat-id>

threads lists conversations, newest first, and the send's answer carries the chat_id too. thread prints every message in the conversation, their replies included.

Announcements, scheduled messages and automations

Everything the console’s campaign tools do, mb does too, signed in or with a project key, and an agent gets the same commands as tools. The rules are the console’s: people who opted out are left out, people who have never messaged your number are paced, and a project’s first announcement is read by a person at Miss Blue before it goes out.

Announce to a list

mb announce --text "We open at nine from Monday" --list "Spring customers"
mb announce-send --id <announcement-id> --confirm

The first command sends nothing. It prints how many people it reaches, how many have never messaged your number (those go out at up to 50 a day) and who is left out because they opted out. Nothing goes until the second command, with --confirm.

Schedule a message for their morning

mb schedule --to +15555550100 --text "See you at ten" --at 2026-10-02T09:00:00-05:00 --time-zone America/Chicago

Give the time with the recipient's UTC offset, so nine means nine where they are.

Welcome new customers, then follow up

mb automation-create --name Welcome --tag new-customer --text "Welcome aboard!" --wait 2d --follow-up "Any questions so far?"
mb automation-on --id <automation-id>
mb tag --tag new-customer --handles +15555550100

Created switched off. With no --from it sends from Auto, so each person gets the best of your numbers. A reply ends their run, and the follow-up only goes to people who have not answered the welcome; --stop-on-reply false and --follow-up-if change that. Once it is on, tagging somebody messages them, so mb asks for --confirm first.

Lists and tags: mb lists, mb list-create, mb list-add, mb tags, mb tag. What is queued or running: mb announcements, mb scheduled, mb automation-runs, and for one person, mb automation-status --handle: which automations they are in, how the last ones ended, and which would start for them. The skill tells an agent to show you the preview and get your yes before any announcement, never to automate messages to people who have not opted in, and to schedule for the recipient’s local time.

Change one thing about an automation without restating the rest: mb automation-update --id <id> --stop-on-reply false keeps it going after a reply, and --from auto or --from <number-id> moves it between Auto and one number. If a number it was pinned to leaves your project, it moves to another of your numbers, or is switched off when there is none, and mb automation shows a note saying which.

Business hours

mb automation-create --name Welcome --tag new-customer --text "Welcome aboard!" \
  --hours 08:00-18:00 --days mon-fri
mb automation-update --id <id> --time-zone America/Chicago
mb automation-update --id <id> --any-time

--hours keeps an automation to business hours: Eastern time unless you pass --time-zone, every day unless you pass --days (mon-fri, mon,wed,fri, weekends). A tag added at 11 PM still starts the automation then; its message waits for 8 AM. An update changes only the part you name, and --any-time clears the hours.

How an automation is doing

mb automation-stats --id <id>             # the last 30 days, step by step
mb automation-stats --id <id> --all
mb automation-replies --id <id> --step 4  # who answered step 4, and what they said

automation-stats gives each step’s sent, delivered, read (opened), replied and opted out, with reply and opt-out rates, and how people’s runs ended. Read only counts people with read receipts on, so it is at least that many. automation-replies lists every reply, newest first, with the message it answered and a link to the conversation.

A/B/C tests

mb automation-create --name Tour --tag toured --text "Thanks for coming by!" \
  --text-b "Want a second look?" --weights 50,50 --wait 1d \
  --follow-up "Still thinking it over?" --follow-up-b "Happy to set up another visit."
mb automation-stats --id <id>                                  # each version, and a verdict
mb variant-use --automation <id> --step 1 --letter B           # everybody new gets B
mb variant-weights --automation <id> --step 1 --weights 70,30
mb announce --text "Open house Saturday." --text-b "Come see it Saturday?" \
  --list Leads --test-first 20% --pick-after 4h

--text is version A; --text-b and --text-c add versions, split by --weights or evenly. Each person keeps their version for the follow-up. automation-stats puts the versions side by side and says whether one is ahead, or how many more people it needs first. variant-use sends one version to everybody who reaches that step from now on. variant-weights changes the split on the first step with versions, for people given a version from now on; later steps follow it. An announcement with --test-first tries the versions on that share of the list, then sends the rest the one with the best reply rate.

Run it on a server or in CI

Nobody can approve a sign-in there, so use a project key instead of mb login. A key comes from a project’s Developers page, under API keys, and belongs to that one project. Install mb as above, then:

export MISS_BLUE_API_KEY=mb_live_…
mb whoami
mb send --to +15555550100 --text "Your order has shipped"

MISS_BLUE_API_KEY wins over a saved sign-in. Keep it in your CI or server secrets, never in a file you commit.

Every command

The same list in both places. A CLI command and an MCP tool of the same name do the same thing and take the same arguments: --allow-duplicate on the command line is allow_duplicate to an agent.

whoamiWhat this key is, and which project it holds.
numbersThe numbers this project holds.
sendSend an iMessage.
  • --to* Phone number, Apple ID email, or a chat_id.
  • --text The message. Optional only when sending a file.
  • --from Number id to send from. Defaults to your only number.
  • --file A file to send. Uploaded first, then sent.
  • --allow-duplicate Send although the same text went there moments ago.
  • --manual Send now like a person typing in the inbox: not held by the line's daily total. Opt-outs, blocks and the new-people limit still apply. Use for one-off human-initiated sends, not bulk.
  • --wait Wait until it is `sent`, `delivered` or `read`, then print it. Exits with an error if that has not happened in time.
  • --timeout How long --wait waits: 90s, 5m. A minute by default, at most 10 minutes.
threadsConversations, most recent first.
threadEvery message in one conversation.
  • --chat-id* From `threads`.
messagesRecent messages across this project's numbers.
messageOne message, including when it was sent, delivered and read, and the Mac build that handled it.
  • --id* The message id.
  • --wait Wait until it is `sent`, `delivered` or `read`. Exits with an error if that has not happened in time.
  • --timeout How long --wait waits: 90s, 5m. A minute by default, at most 10 minutes.
workspacesThe businesses you belong to.
projectsThe projects in a workspace.
  • --workspace* Workspace id, from `workspaces`.
activityWho has been answering a project's numbers, and how much.
  • --project* Project id, from `projects`.
  • --days How far back to count. 1 to 365, 30 by default.
member-activityOne person: what they sent, who to, and the messages.
  • --project* Project id, from `projects`.
  • --user* Whose work to report, from `activity`.
  • --days How far back to count. 1 to 365, 30 by default.
problemsSends that failed, or are still waiting for a Mac.
  • --only `queued` or `failed`.
lookupWhether iMessage is known to reach a handle. Answered from your own traffic, not from Apple.
  • --handle* Phone number or Apple ID email.
typingShow or hide the typing bubble in a conversation.
  • --chat-id* The conversation.
  • --off Hide it rather than show it.
readTell the customer their message was seen. Only when a human has looked.
  • --chat-id* The conversation.
  • --unread Mark unread again.
reactAdd or remove a tapback on a message.
  • --id* The message id.
  • --reaction heart, like, dislike, laugh, emphasize, question. Defaults to heart.
  • --remove Take it back.
unsendUnsend a message, inside Apple's two-minute window.
  • --id* The message id.
editChange what a sent message says, inside Apple's fifteen-minute window.
  • --id* The message id.
  • --text* The replacement text. An empty edit is not an unsend, and is refused.
labelName a number, so threads say which line they arrived on.
  • --id* The number id.
  • --label Empty clears it back to the bare handle.
contactsNames this project has given handles. Shared by everyone on it.
nameName a handle, or rename one. contact-add does the same and says what it queued for Apple Contacts.
  • --handle* Phone number or Apple ID email.
  • --name* What to call them.
contact-addAdd a contact, or rename one, and queue them for Apple Contacts on this project's numbers, so Messages shows their name. Prints what was queued and how to check. --field sets their custom fields for messages to use.
  • --handle* Phone number or Apple ID email.
  • --name Their full name. Or give --first-name and --last-name.
  • --first-name Their first name.
  • --last-name Their last name.
  • --field A custom field, as name=value. Repeat it for more: --field product=Hoodie --field amount=$48. Sets those fields and keeps the others; name= with nothing or only spaces after it removes one. Messages read them as {{ contact.custom.product }}.
  • --no-sync Save them in Miss Blue only, not in Apple Contacts.
contactOne contact, and whether Apple Contacts on each of this project's numbers has them yet: queued, synced or failed.
  • --handle* Phone number or Apple ID email.
contact-syncPut a saved contact in Apple Contacts again, on each of this project's numbers or one of them, and wait for each to answer. For a number that did not take it.
  • --handle* Phone number or Apple ID email.
  • --from Only this number id. Every number of this project by default.
forgetRemove a name from the project's book.
  • --id* The contact id, from `contacts`.
webhooksThe endpoints this project sends events to.
webhook-addRegister where events should go.
  • --url* https, and not a private address.
webhook-rmStop sending to an endpoint.
  • --id* The endpoint id.
deliveriesWhat we tried to send an endpoint, and what came back.
  • --id* The endpoint id.
announcementsAnnouncements (blasts) in this project, with how each is going.
announceDraft an announcement (one message to many people) and preview it. Sends nothing. Show the user the preview (how many people, how many are first contacts and how long their pacing takes, who is left out) and the exact text before `announce-send`.
  • --text* The message. Everybody gets the same words.
  • --to Phone numbers or emails, separated by commas.
  • --list List ids or names, separated by commas. Everybody on them now.
  • --tag Tags, separated by commas. Everybody carrying them now.
  • --from Number id to send from. Defaults to your only number.
  • --title An internal name. Nobody receiving it sees this.
  • --at When to start, with a UTC offset: 2026-10-02T09:00:00-05:00. Otherwise when sent.
  • --time-zone The zone --at was chosen in, like America/Chicago. Shown in the console.
  • --reply-window-hours How long a reply still counts as a reply to it. 1 to 720, 72 by default.
announce-sendSend a drafted announcement. Prints the preview again. Only after the user has seen the preview and the text and explicitly said yes: pass confirm. Without it nothing is sent.
  • --id* The announcement id, from `announce` or `announcements`.
  • --confirm The user said yes to this preview. Without it, nothing is sent.
announce-cancelCancel an announcement. One already sending stops; what went out stays out.
  • --id* The announcement id.
scheduledMessages scheduled for later, and what became of them.
scheduleSchedule one message for later. Pick a time that suits the recipient where they are.
  • --to* Phone number or Apple ID email.
  • --text* The message.
  • --at* When, with the recipient's UTC offset: 2026-10-02T09:00:00-05:00.
  • --time-zone The zone the time was chosen in, like America/Chicago. Shown in the console.
  • --from Number id to send from. Defaults to your only number.
schedule-cancelCancel a scheduled message that has not gone yet.
  • --id* The scheduled message id, from `scheduled`.
automationsAutomations in this project: what starts each, its steps, and whether it is on.
automationOne automation, and what switching it on would do: who it reaches now and how long first contacts take.
  • --id* The automation id, from `automations`.
automation-createCreate an automation, switched off. A keyword reply, or a message when somebody joins a list or gets a tag, then a wait, then a follow-up only if they did not reply. A list or tag automation sends from Auto unless given a number. --hours keeps it to business hours. Only for people who asked to hear from this business.
  • --name What to call it. Required unless --file has one.
  • --file A JSON file with the whole automation, as the API takes it. Other flags are ignored.
  • --keyword Reply when somebody texts one of these words. Separated by commas.
  • --list Start when somebody joins this list. Id or name.
  • --tag Start when somebody gets this tag.
  • --trigger Or `first_message` (somebody new writes) or `conversation_opened` (any message).
  • --text The first message it sends. Required unless --file.
  • --wait How long before the follow-up: 30m, 36h, 2d. Up to 31 days.
  • --follow-up A second message after --wait. By default only if they have not replied since the first.
  • --follow-up-if When the follow-up goes: `not_replied_since_last` (the default), `not_replied` (since it started), `replied_since_last` or `replied`.
  • --follow-up-anyway Send the follow-up whether or not they replied.
  • --from Number id it sends from. A list or tag automation without one sends from Auto: each person gets the best of this project's numbers.
  • --stop-on-reply End a person's run as soon as they reply. On unless you pass --stop-on-reply false.
  • --allow-repeat Let the same person go through it more than once.
  • --hours Only send between these times, like 08:00-18:00 or 9am-5pm. A message due outside them waits until they open; what starts it still starts it at any time.
  • --time-zone The zone --hours are in, like America/Chicago. Eastern (America/New_York) unless given.
  • --days The days it sends on, with --hours: mon-fri, mon,wed,fri or weekends. Every day unless given.
  • --any-time Send at any hour, with no --hours. The default.
automation-updateChange an automation. Pass only what changes: --name, --from, --stop-on-reply, --allow-repeat or the hours flags alone keep its trigger and steps; a trigger flag replaces the trigger; --text and the follow-up flags replace the steps; --file replaces the whole thing. People partway through keep their step number.
  • --id* The automation id.
  • --file A JSON file with the whole automation, as the API takes it.
  • --name A new name.
  • --keyword Reply when somebody texts one of these words. Separated by commas.
  • --list Start when somebody joins this list. Id or name.
  • --tag Start when somebody gets this tag.
  • --trigger Or `first_message` (somebody new writes) or `conversation_opened` (any message).
  • --text A new first message. Replaces the steps, with the follow-up flags.
  • --wait How long before the follow-up: 30m, 36h, 2d. Up to 31 days.
  • --follow-up A second message after --wait. By default only if they have not replied since the first.
  • --follow-up-if When the follow-up goes: `not_replied_since_last` (the default), `not_replied` (since it started), `replied_since_last` or `replied`.
  • --follow-up-anyway Send the follow-up whether or not they replied.
  • --from Number id it sends from, or `auto` for Auto.
  • --stop-on-reply End a person's run as soon as they reply: true or false. Absent keeps what it has.
  • --allow-repeat Let the same person go through it more than once.
  • --hours Only send between these times, like 08:00-18:00 or 9am-5pm. Keeps its zone and days unless you change them.
  • --time-zone The zone its hours are in, like America/Chicago. Eastern (America/New_York) for new hours unless given.
  • --days The days it sends on: mon-fri, mon,wed,fri or weekends. Needs hours, given now or already set.
  • --any-time Clear its hours: send at any time again.
automation-onSwitch an automation on. Show the user what it will send and who it reaches first. With include_existing it also messages everybody already on the list or tag, which needs confirm after the user says yes.
  • --id* The automation id.
  • --include-existing Also start it for everybody already on the list or carrying the tag.
  • --confirm The user said yes to messaging everybody already there.
automation-offSwitch an automation off. Everybody partway through it stops.
  • --id* The automation id.
automation-deleteDelete an automation and everything partway through it. Ask the user first.
  • --id* The automation id.
automation-runsWho is in an automation and how far they got, or which automations are messaging one person.
  • --id The automation id. Required unless --handle.
  • --status Only `running`, `done`, `stopped` or `failed`.
  • --handle Instead: what is running for this person right now, across automations.
  • --limit How many to show. 1 to 500, 100 by default.
  • --offset How many to skip, for the next page.
automation-statsHow an automation is doing, step by step: sent, delivered, read (opened), replied and opted out, with reply and opt-out rates, and how people's runs ended. Read only counts people with read receipts on, so it is at least that many.
  • --id* The automation id, from `automations`.
  • --days Count messages sent in the last this many days. 1 to 365, 30 by default.
  • --all Count everything since the automation began, instead of --days.
  • --variant Only this version of each step's text, for A/B/C tests.
automation-repliesWhich texts got the replies: who answered an automation, what they said and when, the message they answered, and a link to the conversation. Newest first.
  • --id* The automation id, from `automations`.
  • --step Only replies to this step's messages: its number, from 1, as `automation-stats` numbers it.
  • --days Only replies to messages sent in the last this many days. All of them by default.
  • --variant Only replies to this version of the text, for A/B/C tests.
  • --limit How many to show. 1 to 100, 25 by default.
  • --cursor `next_cursor` from the page before, for the next page.
automation-stopTake one person out of one automation. Everybody else carries on.
  • --id* The automation id.
  • --handle* Their phone number or email.
listsLists in this project, and how many people are on each.
list-createMake a list.
  • --name* Unique in this project.
  • --description What it is for.
list-membersWho is on a list, newest first.
  • --list* List id or name.
list-addAdd people to a list. If an automation starts on this list, each new person is messaged, so that needs confirm after the user says yes.
  • --list* List id or name.
  • --handles* Phone numbers or emails, separated by commas.
  • --confirm The user said yes to the automation messaging them.
list-removeTake somebody off a list. An automation they are in carries on.
  • --list* List id or name.
  • --handle* Their phone number or email.
tagsTags in this project, and how many people carry each.
tagTag people. If an automation starts on this tag, each newly tagged person is messaged, so that needs confirm after the user says yes.
  • --tag* The tag. Case and extra spaces do not matter.
  • --handles* Phone numbers or emails, separated by commas.
  • --confirm The user said yes to the automation messaging them.
untagTake a tag off somebody.
  • --tag* The tag.
  • --handle* Their phone number or email.
mcpServe every command above as MCP tools over stdio.
skillPrint the Miss Blue skill. mb skill install installs it; see the skill.

* required. Signing in and choosing a project (login, logout, use) are above.

NextErrorsOne shape, and what each status means.