What you can do where
Herald has four ways in: the app's own windows, the local HTTP API, the herald command-line tool and the MCP server for agents. This page answers one question: "I can do this in the app; how do I do it over HTTP, from the command line and through MCP?" Find the thing you do in the app in the first column, then follow the link in the column you want.
Every MCP tool wraps one HTTP route, and every CLI command is one or two HTTP requests, so a capability that exists in MCP exists in HTTP. The CLI covers the routes that are natural at a prompt, so it has the fewest. A cell reads none when that way in cannot do it, and UI only when it is a view state such as a selection or a zoom level, with nothing stored to read or set. A task that must stay with a person at the Mac is listed under the table of its area and in What only a person can do.
| Way in | Who uses it | Needs |
|---|---|---|
| The app's windows | A person at the Mac. | Herald running. |
| HTTP API | Any program on the Mac. | The bearer token. |
| CLI | A person or script at a terminal. | Herald running. |
| MCP server | An agent. | An MCP client with herald-mcp installed. |
Notifications and banners#
Show, close and snooze banners, and read what the user typed into them. The app column names the menu, the Quick send window or the Designer.
| What you do in the app | HTTP | CLI | MCP |
|---|---|---|---|
| Compose... (Quick send), then send | POST /v1/notify | herald notify | send_notification |
| Send test in the Designer | POST /v1/notify | herald notify | send_test |
| Speak in Settings > Voice | POST /v1/speak | herald speak | speak |
| Close button on a banner | POST /v1/dismiss | herald dismiss | dismiss |
| Dismiss All | POST / | herald dismiss-all | dismiss |
| Clock menu on a banner | POST /v1/snooze | herald snooze | snooze |
| Bring a snoozed banner back | POST /v1/unsnooze | herald unsnooze | snooze |
| Click a stack to see its list | GET /v1/stacks | herald stacks | list_stacks |
| Click a stack to open or close it | POST / | none | expand_stack |
| Read a reply in History | GET /v1/replies | none | get_replies |
| Wait for a reply to one banner | GET / | none | wait_for_reply |
| Menu: Compose... | POST /v1/compose | herald compose | none |
Only in some places:
- Press a banner button exists only in the app. A button runs code or sends data on the user's behalf, so no API, command or tool presses one. An agent can send a button and read the answer.
Templates#
A template is one JSON document, and every edit the Designer makes rewrites it. Saving a template therefore covers every edit, and the same validation runs on both sides.
Only in some places:
- Problems button: the app and MCP check a draft without saving it. Over HTTP and the CLI,
PUT /v1/templatesvalidates as it saves. - Selection, undo, redo, zoom and drag are view state of the Designer window. A saved template holds the result.
Previews and checks#
See what a banner looks like, and check that Herald is up, without opening a window.
| What you do in the app | HTTP | CLI | MCP |
|---|---|---|---|
| Live preview, light or dark | POST /v1/preview | none | render_preview |
| Last real in the preview header | POST /v1/preview | none | render_preview |
| Preview a stack or a confirmation | POST /v1/preview | none | render_preview |
| Look at the whole Designer | GET / | none | designer_snapshot |
| Rive details in the Cell tab | POST / | none | rive_check |
| The bell in the menu bar | GET /v1/health | herald health | herald_status |
Manifests and assets#
What a manifest holds is in Manifests.
| What you do in the app | HTTP | CLI | MCP |
|---|---|---|---|
| Fields in the Designer palette | GET /v1/manifests | none | list_manifests |
| Open one app's fields | GET /v1/manifest | none | get_manifest |
| Apps send a manifest themselves | PUT /v1/manifest | none | put_manifest |
| Remove an app's manifest | DELETE / | herald manifest delete | delete_manifest |
| Assets in the Designer palette | GET /v1/assets | herald assets list | list_assets |
| Add... under Assets | POST /v1/assets | herald assets add | upload_asset |
| Remove... under Assets | DELETE /v1/assets | herald assets rm | delete_asset |
Only in some places:
- Saving a manifest has no app window and no CLI command: a manifest comes from the app that sends it. Use
PUT /v1/manifestorput_manifest.
History#
Past notifications, kept per app.
| What you do in the app | HTTP | CLI | MCP |
|---|---|---|---|
| History window | GET /v1/history | herald history | list_history |
| A follow-up's line in a History row | GET /v1/history | herald history | list_history |
| The search field | GET / | herald history search | history_search |
| Re-show as Banner | POST / | herald history reshow | reshow_ |
| Delete on one item | DELETE / | herald history delete | delete_history |
| Clear NAME History... | DELETE /v1/history | herald history delete | delete_history |
| Export JSON... | GET / | herald history export | export_history |
Settings and apps#
The app column names the Settings tab. The keys and their values are in the settings API and the apps API.
Only in some places:
- Registering an app has no window: an app registers itself, and Settings > Apps then lists it.
- Removing an app has no CLI command. Use
DELETE /v1/apps/{id}ordelete_app. - Revealing a file in Finder is a button in the app. The files are plain paths in
~/Library/Application Support/Herald/.
Approvals#
An approval is the user's permission for something that runs code or sends data off the Mac. What each one covers is in Approvals.
| What you do in the app | HTTP | CLI | MCP |
|---|---|---|---|
| See an app's command and callback approvals | GET / | herald apps settings | list_apps |
| Revoke with Allow this app to run commands, scripts and Shortcuts | PUT / | herald apps set | update_ |
| See a follow-up's approval state | GET / | herald approvals | list_approvals |
| See a template's code approvals, Settings > Actions | GET / | herald approvals | list_approvals |
| Revoke a template's approval | DELETE / | herald approvals revoke | revoke_approval |
| Grant any approval | none | none | none |
Only in some places:
- Granting an approval exists only in the app, by design: the program that holds the token is the one the approval protects against, so it must not approve itself. Reading and revoking are open.
Cloud relay#
The relay lets agents that run elsewhere send notifications to this Mac. The app window is Settings > Cloud. Cloud explains the relay and these controls. The CLI has no relay commands.
Only in some places:
- Approving a connector happens only on the Mac, by design: the connector's request is answered in the app with the code the agent printed.
- Reading the stored Cloudflare token is not possible anywhere. It is written once and never read back.
What only a person can do#
These are left out of the API, the CLI and MCP on purpose.
| Task | Why it stays with the user |
|---|---|
| Grant an approval: an app's command permission, a callback host, a template's code. | The program that holds the token is the one the approval protects against, so it must not approve itself. Reading and revoking are open. |
| Press a banner button. | A button runs code or sends data on the user's behalf. |
| Approve a connector's request to use the relay. | The request is answered on the Mac, with the code the agent printed. |
| Read the stored Cloudflare token. | The token is a secret that is written once and never read back. |
| Open the Designer, Quick send, History or Settings windows. | The API never activates a window or takes focus. Previews and snapshots give an agent what a person would look at. |
| Mark a notification as opened, as a banner click does. | It would act as a click the user did not make. |
Settings are validated against one table#
Every general setting is one row in a single table. An unknown key, a wrong type or a value out of range gets 400, and
nothing is changed. GET /v1/settings returns the same table as schema, so an agent
can discover the keys and their limits without a document.