MCP server
Onboarding and reports: get_onboarding_status and get_client_report
Two read tools over the agency-onboarding flow: get_onboarding_status
tells you how far each of a session's brand slots has gotten (collection,
analysis, reports), and get_client_report reads the stored report bundle
that flow produces. Neither tool triggers anything — collection and
analysis run elsewhere; these two only read what has already happened.
get_onboarding_status
Arguments: workspace_id (optional — defaults to your token's own
workspace; not used to select a brand, only to satisfy the enforcement
chain's authorization check) and the shared optional context string every
tool accepts.
One row per brand slot your token's workspace allowlist can see — a brand
still mid-draft (no workspace provisioned yet) is never filtered out, but a
brand whose workspace your token cannot see is omitted entirely. That
allowlist is applied BEFORE any per-brand read: the underlying
onboardingStatus is handed the visible workspace ids and never opens a
scope for one outside them, so the response's contents and its latency both
depend only on what your token may see.
Columns: slot, workspace_id, workspace_key, display_name,
collection_state (not_started | queued | running | partial | complete | failed | paused), answered, expected, failed, pending (summed
across every platform the brand's baseline run touched), analysis_state
(pending | running | ready | deterministic_fallback | failed), and
reports_ready.
meta:
trial— the organization'sTrialUsage(policy version, state, prompt and daily-slot usage, refresh/attempt-unit/ai-generation ledger counts, whether collection is paused and why), ornullwhen the organization never activated a trial. Carries no cost or usd figure — those live on the internal trial policy, never on this wire shape.checklist—reports_available,assistant_connected,skills_downloaded,first_assistant_report: the same four booleans the studio's own setup checklist shows.next_step— one short, truthful sentence naming the single next action (never a promised outcome or a timeline): finish brand entry, confirm baseline questions, wait on a running collection, wait on analysis, go connect your assistant, or callget_client_report.
get_client_report
Arguments: workspace_id (required), view (one of audit | gaps | weekly | monthly | actions | portfolio, default audit), include_analysis
(default true), and the shared optional context string every tool
accepts.
Reads the workspace's latest stored report bundle — never builds
evidence or runs analysis itself. When no bundle has been stored yet the
whole response is a diagnostic rather than an empty envelope:
{ state: 'pending', next_step, latest_run, answers_in_window, bundle_ever }
— latest_run is { id, status, finished_at } for the newest run or
null, answers_in_window counts answers in the last 30 days, bundle_ever
says whether a report was ever built, and next_step is derived from them
(no run → launch collection from the studio; a running run → its job
progress; a finished run with answers and no bundle → open the report page
in the studio, which builds it; no answers → launch a new collection).
portfolio is refused (invalid_argument) — this tool reads one
workspace's bundle; call get_portfolio_summary for an org-wide summary.
Views
audit(default) — the bundle's unbranded leaderboard:brand_id, brand, is_self, visibility_count, visibility_total, visibility, share_of_voice, sentiment, position, mention_count.gaps— the prompts where a competitor showed and this brand did not:prompt_id, text, engines(each engine's competitors and citations),existing_page_candidates(pages already cited that could be strengthened instead of a new page written).actions— the bundle's ranked next actions:id, kind, source, observation, evidence_refs, action, target, priority_rationale, effort_estimate, limitations, remeasure_question_ids.weekly/monthly— the deltas (brand_id, visibility_delta, share_of_voice_delta, position_delta) against the prior comparable ISO week or calendar month, when one exists with the same prompt cohort, engines and market. When it does not (a baseline report, or the cohort changed), the page comes back with zero rows andmeta.noteset to the same "Baseline report — comparison history is still collecting." banner the exported markdown shows.
meta
header— the honesty header every report surface prints, so an agent can state what a number is measured over without a second call. Byte-for- byte the same facts the Markdown export's header and the studio's report header show for the same bundle:window—{ start, end }, the report window's own dates.cohort—{ unbranded, branded, total }prompt counts. Unbranded and branded metrics are never merged; this is the split behind them.platforms— one entry per engine:{ engine, public_name, answered, expected, missing, no_answer }.missingismax(0, expected - answered)and covers both a platform that failed and one nothing has been collected for yet. It is an absent measurement, never a competitive loss.no_answeris a separate count — an engine that answered without naming anything — and is never summed withmissing; the two describe different things (no measurement vs. a measurement that named nothing).citations_tracked—{ domains, urls }counts.small_sample_note— the caveat sentence when the bundle's ownprovenance.small_sampleis set, elsenull.
provenance—bundle_id, run_ids, generated_at, evidence_version, template_version, failures, answered_total, small_sample.bundle_idis the storedreport_bundles.idthis whole projection came from — the same id REST'sGET /v1/reports/latestreturns asbundle.id— so REST↔MCP parity can be proven directly instead of only by comparing every other provenance/header fact. The rest are from the bundle's own evidence.analysis_state— the bundle'spending | running | ready | deterministic_fallback | failed.analysis— included only wheninclude_analysisis true ANDanalysis_stateisready:executive_summary, strengths, competitor_advantages, recommendations. Adeterministic_fallbackbundle still has real, stored evidence — it just has no LLM narrative to show, soanalysisis omitted rather than filled with placeholder text.analysis_note— present instead ofanalysiswhenever no narrative is shown: one fixed, honest sentence for the bundle's ownanalysis_state/analysis_reason, identical to the one the Markdown export and the studio panel print. Every one of them ends the same way — the rule-derived report never depends on the AI narrative. Fordeterministic_fallback/budget_background_aion a trial it also names what spent the AI attempts: background AI use during collection (the per-answer sentiment judge). A baredeterministic_fallback/budgetmakes no such attribution — the metered wrapper refuses for either dimension, so the job only records the attributed reason when the organization actually has asentiment_judgeledger operation. When the narrative IS ready and the caller passedinclude_analysis: false,analysis_notesays it was omitted at the caller's request and how to ask for it — never that it is unavailable.comparison— present only forweekly/monthly:available, period, prior_bundle_id, deltas(the same rows the page carries when available).