> ## Documentation Index
> Fetch the complete documentation index at: https://docs.heralded.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Connect an MCP client

> Give an AI assistant or agent read access to Heralded with an API key.

Heralded runs an MCP server at:

```text theme={null}
https://api.heralded.ai/v1/mcp
```

It speaks Streamable HTTP and accepts an [API key](/api-keys) as a bearer token. Any client that can send a header with a remote server can connect.

## Set up your client

<Tabs>
  <Tab title="Claude Code">
    ```bash theme={null}
    claude mcp add --transport http heralded https://api.heralded.ai/v1/mcp \
      --header "Authorization: Bearer hrld_..."
    ```
  </Tab>

  <Tab title="Cursor">
    Add the server to `~/.cursor/mcp.json`, or to `.cursor/mcp.json` in a project:

    ```json theme={null}
    {
      "mcpServers": {
        "heralded": {
          "url": "https://api.heralded.ai/v1/mcp",
          "headers": { "Authorization": "Bearer hrld_..." }
        }
      }
    }
    ```
  </Tab>

  <Tab title="VS Code">
    Add the server to `.vscode/mcp.json`. The input keeps the key out of the file: VS Code asks for it once and stores it securely.

    ```json theme={null}
    {
      "inputs": [
        { "type": "promptString", "id": "heralded-key", "description": "Heralded API key", "password": true }
      ],
      "servers": {
        "heralded": {
          "type": "http",
          "url": "https://api.heralded.ai/v1/mcp",
          "headers": { "Authorization": "Bearer ${input:heralded-key}" }
        }
      }
    }
    ```
  </Tab>

  <Tab title="Other clients">
    Point the client at `https://api.heralded.ai/v1/mcp` over Streamable HTTP, with the header `Authorization: Bearer hrld_...`.
  </Tab>
</Tabs>

Claude, ChatGPT, Cursor, VS Code and Claude Code can connect by signing in instead, with no key to copy. See [Connect an AI assistant](/assistants).

## Tools

Every tool is read-only. Start with `list_brands`. Brand tools take `brand`, either the id `list_brands` returns or the brand's domain, such as `acme.com`. `get_action` takes an `action_id` returned by `list_actions`.

`get_leaderboards` reads public monthly measurements without a tracked brand. Select filters, facets, a brand slug or a source domain. See [Leaderboards](/concepts/leaderboards#read-through-the-api-or-an-assistant) for parameters and examples. It uses the same token authentication as the other tools.

| Tool | Reads | Same data as |
| - | - | - |
| `list_brands` | The brands the key reads | [`GET /v1/brands`](/api-reference/v1/get-brands) |
| `get_brand_overview` | A brand's period figures with ranges, states, change and trends, the latest report's status line and citation metrics, top competitors, most cited sources, newest open actions, the next weekly and daily scan times, the daily scans since the last weekly report, the open action count, the readiness counts, the score's band and what it was read from, its move since the first weekly report and the tasks verified as paying off; `with_diagnosis` adds what competitors win over the last week | [`GET /v1/brands/{brand_id}/overview`](/api-reference/v1/get-overview) |
| `get_perception` | The statement, positioning, claims, negatives and best quotes; pass `claim` for one claim's verdicts, prompts, engines and pages | [`GET /v1/brands/{brand_id}/perception`](/api-reference/v1/get-perception), [`/perception/claims/{claim}`](/api-reference/v1/get-perception-claim) |
| `get_scores` | All five figures over the selected period, with ranges, states, change and weekly trends, under engine, type, intent, topic, segment and prompt filters, and per group under `group_by` | [`GET /v1/brands/{brand_id}/scores`](/api-reference/v1/get-scores) |
| `list_prompts` | The tracked prompts and how each engine's latest answer treated the brand | [`GET /v1/brands/{brand_id}/prompts`](/api-reference/v1/get-prompts) |
| `get_prompt` | One prompt’s period score and trend, each engine’s named latest answer and four measured states, competitors, top sources, tracking date and status | [`GET /v1/brands/{brand_id}/prompts/{prompt_uid}`](/api-reference/v1/get-prompt) |
| `list_answers` | The engines' answers, newest first, filtered by prompt, engine or a brand they name | [`GET /v1/brands/{brand_id}/answers`](/api-reference/v1/get-answers) |
| `get_answer` | One answer's full text, the URLs it cited and the rivals it named | [`GET /v1/brands/{brand_id}/answers/{answer_id}`](/api-reference/v1/get-answer) |
| `list_competitors` | The brand and its tracked rivals ranked by Heralded Score, with Mentioned, Recommended and share of voice; discovered brands' scores over the same period and channels listed separately | [`GET /v1/brands/{brand_id}/competitors`](/api-reference/v1/get-competitors) |
| `get_competitor` | One competitor's score, trend, head-to-head figures, prompts won and lost, engines, cited pages and tracked since | [`GET /v1/brands/{brand_id}/competitors/{key}`](/api-reference/v1/get-competitor) |
| `list_sources` | The domains the engines cited over the selected period, daily answers included | [`GET /v1/brands/{brand_id}/sources`](/api-reference/v1/get-sources) |
| `get_cited_page` | One cited page under the period and shared filters, with citations, weekly counts, prompts, engines, whether it names you and an Answers link | [`GET /v1/brands/{brand_id}/cited-page`](/api-reference/v1/get-cited-page) |
| `list_ai_visits` | Your pages ordered by period citations, with Visits from AI from the latest 28-day GA4 read and its separate coverage dates | [`GET /v1/brands/{brand_id}/ai-visits`](/api-reference/v1/get-ai-visits) |
| `get_source` | One site's facts, including pages, prompts, engines and citation history | [`GET /v1/brands/{brand_id}/sources/{domain}`](/api-reference/v1/get-source) |
| `list_cited_pages` | Cited-page rows and site and page totals | [`GET /v1/brands/{brand_id}/cited-pages`](/api-reference/v1/get-cited-pages) |
| `get_conversation` | The shared conversation with the Writer, Publicist or Engineer | [`GET /v1/brands/{brand_id}/conversations/{member}`](/api-reference/v1/get-conversation) |
| `list_conversations` | Your standing threads, shared chats and private chats, including archived chats | [`GET /v1/brands/{brand_id}/conversations`](/api-reference/v1/list-conversations) |
| `get_conversation_by_id` | One visible conversation's messages, paged by sequence number | [`GET /v1/brands/{brand_id}/conversations/{conversation_id}/messages`](/api-reference/v1/get-conversation-by-id) |
| `list_changes` | Home's changes, including new competitors | [`GET /v1/brands/{brand_id}/changes`](/api-reference/v1/get-changes) |
| `list_prompt_suggestions` | Discover recommendations with provenance, form and demand | [`GET /v1/brands/{brand_id}/prompt-suggestions`](/api-reference/v1/get-prompt-suggestions) |
| `list_actions` | The actions Heralded proposed or is working on | [`GET /v1/brands/{brand_id}/actions`](/api-reference/v1/get-actions) |
| `get_action` | One task as its pane shows it: state, verbs, job, costs, assignee, steps, thread, draft versions, application state, the reports that raised it, evidence and current content-piece draft | [`GET /v1/actions/{action_id}`](/api-reference/v1/get-action) |
| `get_work` | The brand's agent jobs, next scan, weekly tallies and Herald's week | [`GET /v1/brands/{brand_id}/work`](/api-reference/v1/get-work) |
| `get_settings` | Profile, tracked competitors, owned domains, autonomy, connection status and segments | [`GET /v1/brands/{brand_id}/settings`](/api-reference/v1/get-brand-settings) |
| `get_usage` | Organization prompt use, content-credit pool and each brand's credits left | [`GET /v1/organizations/{organization_id}/usage`](/api-reference/v1/get-organization-usage) |
| `list_portfolio` | The organization's brands with last-week score, axes, change and actions waiting, and the scan each row read | [`GET /v1/organizations/{organization_id}/brands`](/api-reference/v1/get-organization-brands) |
| `get_page` | Your pages by period citations with the [page funnel](/figures#pages-topics-and-audit), Visits from AI, crawlers and the rubric score, or one page in detail | [`GET /v1/brands/{brand_id}/pages`](/api-reference/v1/get-pages), [`/pages/{page_id}`](/api-reference/v1/get-page) |
| `get_topics` | Content's topics with your page for each and its status, or one topic in detail | [`GET /v1/brands/{brand_id}/topics`](/api-reference/v1/get-topics), [`/topics/{topic_id}`](/api-reference/v1/get-topic) |
| `get_audit` | The latest crawl's readiness, site checks and pages, or a Snapshot's or Audit's Content read | [`GET /v1/brands/{brand_id}/audit`](/api-reference/v1/get-audit), [`GET /v1/scans/{scan_id}/audit`](/api-reference/v1/get-scan-audit) |
| `get_scan` | A brand's scans with the score each issued, or one scan's progress and issued figures | [`GET /v1/brands/{brand_id}/scans`](/api-reference/v1/get-scans), [`GET /v1/scans/{scan_id}`](/api-reference/v1/get-scan) |

`list_changes` returns Home's changes since the latest weekly scan, including new competitors, insights and verification outcomes. Each item carries its timestamp, sentence and navigation target. Without `as_of`, the changes include the daily updates since that weekly report; with a weekly report's id, they stop at that report. `writing` tells you the scan's changes are still being written. Reading leaves Home's seen state untouched, and viewer markers stay in the app.

`list_prompt_suggestions` returns Discover's ranked recommendations with `sources`, `reason`, `form` and `demand`. A row can carry several sources, such as Heralded and Search Console. Demand states whether its value is Search Console impressions, monthly keyword search volume or the number of engines that searched the phrase. Unknown demand stays null. The response includes source availability and the tracked prompt pool. `segment` takes a segment label and selects which recommendations are marked `best_to_track`. `suggestions` lists the shorter set the app offers when you add a prompt, each with `text`, `intent_label` and `reason`. It is empty before the first scan, and `limit` and `offset` do not page it.

Both tools take `limit` from 1 to 100, default 20, and `offset`, default 0. `total` counts items before pagination. Track recommendations in the app.

`list_prompt_suggestions`, `list_prompts` and `get_prompt` return the same keyword `measurement` context as REST, including market, language and current `coverage.keyword_research` and `coverage.search_volume`, each `available`, `unavailable` or `unknown`. A row overrides the response's context where it differs. [Keyword measurements](/figures#keyword-measurements) explains the fields and Discover's unavailable state.

`get_conversation` takes `member`, one of `writer`, `publicist` or `engineer`. It returns the newest 50 messages, oldest first, with authors, task references, quoted replies and suggestions. Set `limit` from 1 to 100, use `before` with a message id to read older messages, or filter by `task_id`. The unread count includes every stored message after the read position of the person whose credential you use, including their own posts. Reading does not mark messages seen. Anyone who can read the brand can read its standing conversations. Posting and clicking suggestions stay in the app.

In the per-member read, each message's `suggestions` holds task actions with a `task_id` and `expected_state`. Its `proposals` holds prompt, competitor, correction, page-fix and content-order cards without a task. Both include the card's target, usage and saved result or hide state. REST returns the same fields.

`list_conversations` takes `brand` and returns the four standing threads, shared chats and your own private chats. Archived chats remain readable. Owners and admins cannot read someone else's private chat. The API key's owner or the person who connected the assistant determines which private chats and read positions you see.

`get_conversation_by_id` takes `brand` and a `conversation_id` from that list. Messages carry `seq`, rich `parts`, quoted replies and `suggestions`, including cards without a task. Messages arrive in sequence order, starting after your read position. Set `after=0` to start at the beginning, `after=<seq>` to read newer messages, or `before=<seq>` to read older ones. Both cursors are exclusive; choose one per request. `limit` is 1 to 100, default 50. `last_seq`, `last_read_seq`, `unread`, `has_older` and `has_newer` describe the conversation and page. Reading never advances your read position. A conversation you cannot see returns `not_found`. Posting and confirming stay in the app.

`get_scan` lists the scans of `brand`, newest first. Pass `scan_id` instead for one scan, returned under `scan` rather than `scans`; a Snapshot you ran needs no `brand`. A shared report has no tool: read it through [`GET /v1/shared/scans/{share_id}`](/api-reference/v1/get-shared-scan).

```json theme={null}
{ "scan_id": "3e5a7c9b-1d2f-4a6b-8c0d-4f6a8b0c2e4a" }
```

`get_page` and `get_topics` list without an id. Pass `page_id` or `topic_id` from the list for one page or topic, returned under `page` or `topic` instead of `pages` or `topics`. Pages and Audit use the same [frozen crawler window](/figures#pages-topics-and-audit), `crawler_hits_days`, 28 days ending two days before the newest weekly report through `as_of` started. `get_audit` has no period: its page citations come from the last weekly report, named in `citations_scan`. Pass `scan_id` instead of `brand` for the Content read of a Snapshot or Audit you ran, with the fields of [`GET /v1/scans/{scan_id}/audit`](/figures#scans). For example:

```json theme={null}
{ "scan_id": "3e5a7c9b-1d2f-4a6b-8c0d-4f6a8b0c2e4a" }
```

Scores, overview, prompt detail, competitors, sources, cited pages, AI visits, pages and topics take `period`, one of `1w`, `4w`, `12w` or `all`, with `1w` as the default. Each returns the period descriptor. The visits' own `coverage.start` and `coverage.end` describe their GA4 dates; they are not totals for the selected period.

`get_competitor` takes a competitor's brand key or name as `key`, plus `period` and the figure filters. For example:

```json theme={null}
{ "brand": "acme.com", "key": "linear", "period": "4w" }
```

[Competitors in the API](/figures#competitors) explains the response fields.

`get_cited_page` takes `key`, the cited URL, canonical document key or document id. Its filters are `engine`, `type`, `intent`, `topic`, `segment` and `prompt`. The citation counts include pooled daily answers. Its reports chart up to twelve weekly reports under the same filters. `prompts_limit` and `prompts_offset` page through the prompts that cite it. `names_you` is null for your own page or when Heralded has not read the page. The Answers link opens the app under the same page and filters. A page absent from the selected answers returns `not_found`.

`list_sources`, `get_source` and `list_cited_pages` accept the same shared filters. `get_source` also takes `domain`, with `www` and ports folded. `read_pages_naming_you` counts read citations naming your brand. The deprecated `citations_naming_you` field keeps its all-citations meaning, including unread pages. The opportunity score and its authority and answers-citing inputs are returned with the source facts.

`list_sources` accepts `sort=priority` for the sites worth pursuing first. Each site's `priority` is its 1-based position among those sites, or `null` outside that set; `priority_reason` says why it is worth pursuing. `with_summary=true` adds up to three actionable suggestions in `worth_pursuing` and their full count in `worth_pursuing_total`. See [Sources in the API](/figures#sources).

Each tool returns the route's JSON body as structured content, and its output schema is the route's response schema. The server's instructions tell the model what each figure means and how to judge change; [Figures in the API](/figures) says the same for people.

Example inputs for the action and work tools:

```json theme={null}
{"action_id": "9a7b5c3d-1e2f-4a6b-8c0d-2e4f6a8b0c1d"}
```

```json theme={null}
{"brand": "acme.com"}
```

`get_action` returns shared task facts without the caller's unread state or read markers. `get_work` returns the same weekly answer and page tallies as Home's **Team activity** and the same Herald's week as the Actions team. See [Task fields](/concepts/actions#task-fields).

Use the `id` from `list_prompts` as `prompt_uid` for `get_prompt`. Its score, trend, competitors and sources follow `period`. Each engine shows its name, latest answer's state and four measured states, answer id and read date, including daily updates since the last weekly report. Those daily updates do not join the period figures until a weekly report pools them. Engines without an answer have an `unmeasured` state and null answer id and read date. `as_of` pins these facts to the selected scan.

`get_settings` takes a brand id or domain. For example:

```json theme={null}
{"brand": "acme.com"}
```

It returns the profile and tracked competitors, owned domains, autonomy, provider connection status and segment configuration with engines, markets and prompt counts. Connection credentials, connection-account administration and organization members are excluded.

`get_usage` takes an optional `organization_id`. Omit it to read the credential's organization. For example:

```json theme={null}
{"organization_id": "8f2c1f4e-5a0b-4c7e-9d3a-2b6e1c0f9a11"}
```

It requires organization membership. A brand grant alone returns `not_found`. The prompt meter counts slots against the organization's pool. Each brand's `credits_left` is what it can spend, capped by its remaining reservation and the pool balance. Settings and usage are live reads, so `meta.data_as_of` is null.

`list_portfolio` takes an optional `organization_id`, `limit` and `cursor`. Omit `organization_id` to read the credential's organization. Each brand row's `data_as_of` is the newest weekly scan its figures read, or `null` before one. Pass its `id` as `as_of` to that brand's other tools to keep them on the same scan. The portfolio itself is a live read, so `meta.data_as_of` is null. It lists the organization's brands; `managed=true` is REST only.

## Protocol

The server is stateless and answers MCP 2026-07-28, 2025-11-25, 2025-06-18, 2025-03-26 and 2024-11-05 clients. A failure inside a tool call, such as an unknown brand or a bad argument, comes back as a tool result with `isError` set, so the model can correct the call. A missing, revoked or expired key is an HTTP 401, and a key past its rate limit an HTTP 429 with `Retry-After`. [Errors and limits](/errors-and-limits) has the details.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.