Atribu
MCP Server

Available Tools

37 MCP tools: performance summaries, funnel analysis, traffic breakdowns, campaign drill-downs, customer journeys, workspace creative intelligence, forecasting, recommendations, and Meta CAPI write-back

The Atribu MCP server exposes 37 tools. Every tool returns a structured response with a data object and a meta object containing request metadata, data freshness, and attribution context.

Shared parameters

Most tools accept these common parameters:

ParameterTypeRequiredDescription
workspace_idUUIDNoWhich workspace to query. Inferred if you have exactly one.
profile_idUUIDNoWhich profile to query. Inferred if the workspace has exactly one.
window_startYYYY-MM-DDYesStart of the date range
window_endYYYY-MM-DDYesEnd of the date range
modelstringNoAttribution model. Default: last_touch

Available attribution models: last_touch, first_touch, split_50_50, linear, position_based, time_decay, last_non_direct, custom_weighted, engagement_weighted

Two scope grains. Most tools are profile-scoped: they operate on one profile (workspace_id + profile_id, both inferred when unambiguous). The workspace creative-intelligence, forecasting, and recommendation tools below are workspace-scoped: they take only workspace_id and read across every profile you can access in that workspace. Workspace-scoped tools are marked with Scope: workspace. Instead of window_start/window_end, they use a pre-aggregated score_window (7d | 14d | 28d | lifetime, default 28d).


Discovery tools

whoami

Identity, usage, and effective settings for the current MCP token. Returns scopes, units used vs cap, your workspaces, and (when scope is unambiguous) active workspace settings (pii_mode, mcp_writeback_enabled, your role) and the active profile's currency. Always call once per session — it tells you upfront whether PII unmask or write-back will work, so the AI tool can guide the user correctly without trial-and-error calls.

ParameterTypeRequiredDescription
workspace_idUUIDNoOptional. If passed (or you have one workspace), active_workspace is populated.
profile_idUUIDNoOptional. If passed (or workspace has one profile), active_profile is populated.

Cost: 0 units

Returns: { token, usage, user, workspaces[], active_workspace, active_profile, server_version }. active_workspace and active_profile are null when scope is ambiguous.


list_workspaces

List all workspaces you have access to. Use the returned id values as workspace_id in subsequent calls.

ParameterTypeRequired

Cost: 0 units

Returns: Array of { id, name, role } objects.


list_profiles

List all profiles within a workspace. Use the returned id values as profile_id in subsequent calls.

ParameterTypeRequiredDescription
workspace_idUUIDNoInferred if you have one workspace

Cost: 0 units

Returns: Array of { id, name, workspace_id } objects.


Performance tools

get_performance_summary

Headline KPIs for a date window plus the equivalent prior period. Returns three buckets: cash (real revenue, drives ROAS), pipeline (CRM deal counts + raw value_amount sum — NOT revenue), and leads (top of funnel).

ParameterTypeRequiredDefault
window_startdateYes
window_enddateYes
modelstringNolast_touch

Cost: 1 unit

Returns:

Example response (data, current_period)
{
  "spend": { "amount": 1032.42 },
  "cash": {
    "attributed_revenue": { "amount": 4000 },
    "attributed_conversions": 6,
    "total_conversions": 17,
    "collected": { "amount": 9749 },
    "roas": { "value": 3.87, "formatted": "3.87x" }
  },
  "pipeline": {
    "appointments_booked": 38,
    "closed_won": 0,
    "crm_value_amount_sum": {
      "attributed": { "amount": 76600 },
      "total": { "amount": 79600 }
    },
    "note": "Counts are concrete events. crm_value_amount_sum is the raw sum of whatever the agency entered in their CRM's deal value field — NOT revenue. Never present as a revenue claim without confirming the CRM convention."
  },
  "leads": { "count": 409, "note": "Top of funnel events with no revenue." },
  "traffic": { "visitors": 1550, "pageviews": 2386, "bounce_rate_percent": 87.3 }
}

Pipeline crm_value_amount_sum is NOT revenue

The CRM value_amount field means whatever the agency configured it to mean — deal target, customer lifetime value estimate, retainer size, or arbitrary. Use counts (appointments_booked, closed_won) as the primary signal. Only mention the sum with explicit context. Never include crm_value_amount_sum in ROAS calculations or call it "revenue" or "projected revenue".


compare_periods

Compare two arbitrary date windows side by side. Useful for year-over-year, pre/post campaign launch, or seasonal comparisons.

ParameterTypeRequiredDefault
window_startdateYes
window_enddateYes
prev_window_startdateYes
prev_window_enddateYes
modelstringNolast_touch

Cost: 1 unit

Returns: Same structure as get_performance_summary with current and previous objects representing the two windows.


Campaign tools

top_campaigns

Top campaigns ranked by attributed revenue within a date window.

ParameterTypeRequiredDefault
window_startdateYes
window_enddateYes
modelstringNolast_touch
limitnumberNo10 (max 50)

Cost: 1 unit

Returns: Array of campaigns with name, platform_id, spend, revenue, roas, conversions, clicks, impressions.

platform_id

Each campaign includes a platform_id which you can pass to explain_campaign for a deep dive.


top_ad_sets

Top ad sets ranked by attributed cash revenue. Sits between top_campaigns (broader) and top_creatives (narrower) — answers "which audience/placement is delivering?" before drilling into individual creatives.

ParameterTypeRequiredDefault
window_startdateYes
window_enddateYes
modelstringNolast_touch
limitnumberNo10 (max 50)

Cost: 1 unit

Requires: Meta Ads connection

Returns: Array of ad sets with ad_set_name, campaign_name (parent), spend, attributed_revenue, roas, attributed_conversions, cac, ctr_percent, impressions, clicks, avg_engagement_score.


top_creatives

Top individual ads ranked by ROAS, with creative details (thumbnail URLs, headlines, body text).

ParameterTypeRequiredDefault
window_startdateYes
window_enddateYes
modelstringNolast_touch
limitnumberNo10 (max 50)

Cost: 1 unit

Requires: Meta Ads connection

Returns: Array of ads with name, spend, revenue, roas, ctr, thumbnail_url, headline, body.


explain_campaign

Deep dive into a single campaign: headline metrics, daily trend, and constituent ads.

ParameterTypeRequiredDefault
campaign_idstringYes
window_startdateYes
window_enddateYes
modelstringNolast_touch

Cost: 2 units

The campaign_id can be a UUID (internal ID), a Meta platform_id, or a campaign name. The tool resolves it automatically.

Returns:

Example response (data)
{
  "summary": {
    "name": "Summer Sale - Retargeting",
    "platform_id": "23851234567890",
    "spend": 1200.00,
    "revenue": 5400.00,
    "roas": 4.50,
    "conversions": 28,
    "clicks": 1840,
    "impressions": 42000
  },
  "daily_trend": [
    { "date": "2026-04-01", "spend": 180, "revenue": 720, "clicks": 260 }
  ],
  "ads": [
    { "name": "Video - Testimonial", "spend": 600, "revenue": 3200, "roas": 5.33 }
  ]
}

Customer tools

explain_customer_journey

Full event timeline for a single customer: ad clicks, page views, form fills, conversions, and payments.

ParameterTypeRequiredDefault
customer_profile_idUUIDYes
include_sensitivebooleanNofalse
cursor_timestringNo
cursor_idUUIDNo
limitnumberNo50 (max 100)

Cost: 2 units

Pagination is cursor-based: pass the cursor_time and cursor_id from the previous response's next_cursor to get the next page. There is no date-window filter — the tool walks the customer's full timeline.

Returns: Customer info (name, masked email/phone) plus an array of timeline events ordered chronologically.

PII masking

By default, email and phone are masked (e.g. j***@e****.com). To see unmasked values, pass include_sensitive: true -- requires mcp:read_pii scope and workspace PII mode set to full_default. See Privacy & PII.


Analysis tools

compare_attribution_models

Run the same date window through multiple attribution models to see how credit distribution shifts.

ParameterTypeRequiredDefault
window_startdateYes
window_enddateYes
modelsstring[]No["last_touch", "first_touch", "linear", "position_based", "time_decay"]
top_campaigns_limitnumberNo5 (max 20)

Cost: 5 units

Returns: One result set per model, each with the same campaign-level metrics. Compare to understand which channels are undervalued by single-touch models.


creative_fatigue_check

Detect ads showing fatigue signals: declining CTR, rising CPM, or audience saturation compared to the prior equal-length window.

ParameterTypeRequiredDefault
window_startdateYes
window_enddateYes
modelstringNolast_touch

Cost: 2 units

Requires: Meta Ads connection

Returns: Array of ads with current vs prior period metrics and fatigue indicators.


find_anomalies

Flag unusual daily spikes or drops in spend, revenue, or traffic using z-score analysis (median + MAD).

ParameterTypeRequiredDefault
window_startdateYes
window_enddateYes
metricsstring[]No["spend", "cash_revenue", "visitors"]
threshold_sigmanumberNo2.0
modelstringNolast_touch

Cost: 2 units

Returns: Array of anomalous days with the metric name, observed value, expected range, and z-score magnitude.


get_funnel

Goal-driven conversion funnel for the date window. Walks the canonical lead-gen progression lead_created → appointment_booked → showed → qualified → closed_won with per-stage counts, stage-to-stage conversion rates, and drop-off counts. Also returns negative-outcome buckets (disqualified, no_show, closed_lost).

ParameterTypeRequiredDefault
window_startdateYes
window_enddateYes
scopeall | pipeline_only | contact_onlyNoall

Cost: 1 unit

scope=pipeline_only restricts to events linked to a CRM pipeline (deals in a stage). scope=contact_only restricts to events without one (lead-only / form fills).

Returns:

Example response (data)
{
  "scope": "all",
  "window": { "start": "2026-04-01", "end": "2026-04-30" },
  "main_chain": [
    { "key": "lead_created", "label": "Leads", "count": 409, "conversion_rate_from_previous_pct": null, "drop_off_from_previous_count": 0 },
    { "key": "appointment_booked", "label": "Booked", "count": 38, "conversion_rate_from_previous_pct": 9.29, "drop_off_from_previous_count": 371 },
    { "key": "showed", "label": "Showed", "count": 24, "conversion_rate_from_previous_pct": 63.16, "drop_off_from_previous_count": 14 },
    { "key": "qualified", "label": "Qualified", "count": 12, "conversion_rate_from_previous_pct": 50.00, "drop_off_from_previous_count": 12 },
    { "key": "closed_won", "label": "Closed Won", "count": 0, "conversion_rate_from_previous_pct": 0, "drop_off_from_previous_count": 12 }
  ],
  "drop_off_outcomes": [
    { "key": "disqualified", "label": "Disqualified", "count": 7 },
    { "key": "no_show", "label": "No Show", "count": 5 },
    { "key": "closed_lost", "label": "Closed Lost", "count": 3 }
  ],
  "totals": {
    "all_events": 498,
    "leads": 409,
    "closed_won": 0,
    "lead_to_closed_won_rate_pct": 0
  }
}

Counts are events, not unique customers

One customer can appear at multiple stages. Don't compute customer-level rates from these event counts. Stage-to-stage conversion rates assume customers progress linearly — in reality customers can skip stages or be re-classified.

Stages only show events that are also conversions

Counts include only events whose event_key is mapped under Settings → Outcomes → Conversion Definitions. If a CRM stage like disqualified shows 0 but your team uses it (e.g. labels "Descualificado", "Lead Abandonado"), the conversion definition is missing. Map the key in Conversion Definitions to make those events appear in the funnel.


get_tracking_breakdown

Top values per traffic-dimension (channel, country, page, browser, device, OS, referrer, campaign, etc.) ranked by visitors. Returns up to 6 dimensions in one call.

ParameterTypeRequiredDefault
window_startdateYes
window_enddateYes
dimensionsstring[]No["channel", "country", "page", "browser"]
limitnumberNo10 (max 50)

Available dimensions: channel, referrer, campaign, page, entry_page, exit_page, country, region, city, device, browser, os

Cost: 1 unit

Returns:

Example response (data)
{
  "breakdowns": {
    "channel": [
      { "dimension_value_key": "paid_social", "label": "Paid Social", "visitors": 820, "visits": 1120, "pageviews": 2400, "bounce_rate_pct": 62.4, "conversions": 14, "conversion_rate_pct": 1.71, "cash_revenue": { "amount": 3200 } }
    ],
    "country": [
      { "dimension_value_key": "US", "label": "United States", "visitors": 540, "visits": 720, "pageviews": 1820, "bounce_rate_pct": 58.1, "conversions": 12, "conversion_rate_pct": 2.22, "cash_revenue": { "amount": 2800 } }
    ]
  },
  "window": { "start": "2026-04-01", "end": "2026-04-30" },
  "dimensions_requested": ["channel", "country"],
  "limit_per_dimension": 10
}

Revenue is cash only

The cash_revenue field uses revenue_type='cash' only — same definition the dashboard uses for ROAS. Pipeline / CRM deal values are NOT included here.


list_conversions

Paginated list of conversions for a date window, ordered by conversion_time DESC. Each row carries the customer (masked PII by default), first-touch channel, time-to-complete, revenue, plus the customer's lifetime totals.

ParameterTypeRequiredDefault
window_startdateYes
window_enddateYes
goalstringNopayment_received
searchstringNo
cursor_timestringNo
cursor_idstringNo
limitnumberNo25 (max 100)
include_sensitivebooleanNofalse

Cost: 1 unit

goal filters by event_type (e.g. payment_received, lead_created, appointment_booked, closed_won). Pass all to include every conversion type. Use next_cursor from the response for the next page.

For a SINGLE customer's full event timeline, use explain_customer_journey instead.


list_visitors

Paginated visitor roster (identified + anonymous) for a date window, ordered by last_seen_at DESC. Each row carries last-seen timestamp, session count, total cash revenue, channel/source from the latest session, and device/geo.

ParameterTypeRequiredDefault
window_startdateYes
window_enddateYes
searchstringNo
cursor_timestringNo
cursor_idstringNo
limitnumberNo25 (max 100)
include_sensitivebooleanNofalse

Cost: 1 unit

is_identified=true means the visitor has a customer_profile_id (matched via identify() or a server-side event). False means anonymous-only. total_revenue is cash only (revenue_type='cash') and reflects the customer's lifetime sum.


get_attribution_quality

Diagnostic — how trustworthy is attribution data for this date window? Returns the share of conversion-related events with full UTMs (best), with fbclid only (Meta click but no UTMs), and with no tracking at all (worst).

ParameterTypeRequiredDefault
window_startdateYes
window_enddateYes

Cost: 1 unit

Returns:

Example response (data)
{
  "window": { "start": "2026-04-01", "end": "2026-04-30" },
  "totals": {
    "total_events": 409,
    "with_full_utms": 248,
    "with_fbclid_only": 102,
    "with_no_tracking": 59
  },
  "percentages": {
    "full_utms_pct": 60.6,
    "fbclid_only_pct": 24.9,
    "no_tracking_pct": 14.4,
    "attributable_coverage_pct": 85.5
  }
}

Heuristic

attributable_coverage_pct above 80% is healthy. Between 50–80% means attribution numbers should be treated cautiously. Below 50% indicates UTM tagging gaps — recommend an audit before trusting campaign-level reports.


get_engagement_summary

Site-wide engagement quality for the date window: scroll depth, time on page, rage clicks, dead clicks, form completion, video completion, JS errors, and Core Web Vitals (LCP/FCP/CLS/INP/TTFB). Optional breakdown by page (top N most-engaged) or day (timeline).

ParameterTypeRequiredDefault
window_startdateYes
window_enddateYes
breakdown_bynone | page | dayNonone
page_limitnumberNo10 (max 50)

Cost: 1 unit

Returns: summary.attention (scroll depth, time on page), summary.frustration (rage/dead clicks, JS errors), summary.forms (submitted/abandoned + completion rate), summary.video (plays/completions + completion rate), summary.web_vitals (avg LCP/FCP/CLS/INP/TTFB + LCP good/poor pct). With breakdown_by='page' adds pages[]. With breakdown_by='day' adds daily[].

Different from get_tracking_breakdown

get_tracking_breakdown is about traffic mix (which channels, countries, pages bring users). get_engagement_summary is about UX quality (are users engaging? Are they frustrated? Is the site fast?). Engagement events are display-only — they NEVER become conversions and are never included in attribution credit.


ad_funnel_diagnosis

Per-ad funnel diagnosis — "where in this ad's funnel is the problem?" Returns one row per funnel layer (delivery → attention → retention → click_intent → postclick_messaging → attributed_revenue → platform_diagnostics, the same layers the composite score is built from).

ParameterTypeRequiredDefault
profile_idUUIDNoInferred if the workspace has exactly one
ad_external_idstringYes
score_window7d | 14d | 28d | lifetimeNo28d

Cost: 1 unit

Returns: Per layer: the ad's percentile within its cohort, the underlying smoothed_metric, sample_n, is_weakest_layer (the bottleneck — lowest percentile when below the 25th), machine-readable diagnostic_codes[], and a recommended_priority — one of fix_offer_or_audience, fix_landing_or_offer, fix_hook, improve_creative_clarity, increase_spend, rework_offer_or_landing, or maintain.

Daily freshness

meta.data_as_of reflects the daily creative-score rebuild, not the connector sync time — funnel percentiles update once per day even when Meta data synced minutes ago.


Messaging tools

whatsapp_attribution_summary

Revenue and conversions attributed to WhatsApp touchpoints (Click-to-WhatsApp ads or WhatsApp-sourced traffic).

ParameterTypeRequiredDefault
window_startdateYes
window_enddateYes

Cost: 2 units

Requires: WhatsApp integration

Returns: Conversation counts, conversion counts, revenue attributed to WhatsApp touchpoints.


top_dm_ads

Messaging-ad (DM Ads) leaderboard for a profile, ranked by cost per high-intent conversation. Covers Click-to-Message channels: ig_ctm, wa_ctwa, lead_dm.

ParameterTypeRequiredDefault
profile_idUUIDYes
date_fromYYYY-MM-DDNo28 days ago
date_toYYYY-MM-DDNotoday
sort_bystringNocost_per_high_intent (high_intent_rate, composite_score, spend, high_intent_conversations)
limitnumberNo10 (max 50)

Cost: 1 unit

Returns: Array of ads with high_intent_conversations (pricing / consultation / demo intents), high_intent_rate + high_intent_band (Wilson sample confidence: low / medium / high), cost_per_high_intent (the hero metric), cost_per_conversation, reply-depth rates, attributed revenue/ROAS, booked appointments, closed deals, data_quality_tier, intent breakdown, and any open recommendations targeting the ad. PII in sample conversations is server-side redacted.


Workspace creative intelligence

The tools in this section (and the forecasting and recommendation sections below) are workspace-scoped: pass workspace_id (inferred when you have exactly one) and they read across every profile you can access in the workspace. They are backed by the creative feature store, which is re-scored daily — meta.data_as_of reflects the last workspace re-score, not connector sync time.

top_workspace_performers

The best-performing ads across ALL client profiles in a workspace, scored against comparable creative (cohort-normalized, smoothed, maturity-staged).

ParameterTypeRequiredDefault
score_window7d | 14d | 28d | lifetimeNo28d
limitnumberNo10 (max 50)
profile_idsUUID[]No
objectivesstring[]No
truth_gradesstring[]No— (predicted, attributed, lift)
outcome_kindsstring[]No— (cash, pipeline, messaging, meta, none)
formatsstring[]No
min_spendnumberNo
has_videobooleanNo
fatigue_risk_tiersstring[]No— (low, medium, high, critical)
fatigue_statesstring[]No— (active, paused, degraded)

Cost: 1 unit

Scope: workspace

Returns: Each ad carries three distinct measures — never merge them:

  1. composite_score (0–100) — a transparent rule-based blend of cohort percentiles
  2. top_performer_likelihood (0–1) — a probability (a likelihood, not a guarantee): the calibrated ML-ranker output when score_source='model', otherwise derived from composite_score. Never ROAS.
  3. attributed_revenue / roas — real cash attribution (present when truth_grade='attributed')

Plus primary_outcome_kind (which metric to headline per ad: cash → revenue/ROAS, pipeline → attributed pipeline outcomes, messaging → conversations started, meta → Meta's own reported conversions — always labeled as Meta's attribution, none → composite score only), maturity_stage (coldearlymaturecalibrated), reason_codes[] explaining why the ad ranks, and forecast + fatigue blocks (NULL until the prediction pass has scored the ad).


top_workspace_creative_patterns_v2

Workspace-level creative pattern miner: which structural patterns (archetype cluster, narrative arc, dominant-third role combo, role presence, social-proof duration bucket, hook×claim×CTA) win MORE than the workspace baseline.

ParameterTypeRequiredDefault
score_window7d | 14d | 28d | lifetimeNo28d
min_cluster_sizenumberNo3 (min 3, max 50)
profile_idsUUID[]No
objectivesstring[]No
truth_gradesstring[]No
outcome_kindsstring[]No
formatsstring[]No
min_spendnumberNo
has_videobooleanNo

Cost: 1 unit

Scope: workspace

Returns: One row per (pattern_dim, pattern_value) with sample_n, winner_n, win_rate, workspace_baseline_win_rate, lift_vs_workspace, Wilson 95% confidence-interval bounds, and exemplar_ad_external_ids (top 5 ads embodying the pattern). A pattern whose confidence interval straddles the baseline is sampling noise, not signal. This is a pattern-level win-rate signal, NOT cash ROAS — pair with top_workspace_performers for per-ad cash impact.


top_workspace_archetype_summary

The workspace's creative archetype clusters — named via LLM from exemplars — ranked by lift over the workspace baseline. Use as the "replicate these patterns" headline; use top_workspace_creative_patterns_v2 for finer-grain dimensions.

ParameterTypeRequiredDefault
score_window7d | 14d | 28d | lifetimeNo28d

Cost: 1 unit

Scope: workspace

Returns: One row per archetype cluster with label, description, winning_signal, n_ads, n_winners, win_rate, workspace_baseline_win_rate, lift_vs_workspace, Wilson 95% CI bounds, and top-5 exemplar ads.


top_workspace_experiments

Meta Conversion-Lift / Split-Test experiments tracked for the workspace.

ParameterTypeRequiredDefault
experiment_idUUIDNo— (pass to get the full detail document for one experiment)

Cost: 1 unit

Scope: workspace

Returns (list mode): One row per experiment with type (LIFT, CONTINUOUS_LIFT_CONFIG, GEO_LIFT, SPLIT_TEST, SPLIT_TEST_V2), derived_state (scheduled / running / observing / results_pending / complete / canceled — derived from Meta timestamps), best_grade (A/B/C), and the primary lift point estimate + CI bounds. Detail mode (with experiment_id) adds cells, objectives, latest results, and the top-10 modeled creative attributions.

Lift is cell-level; split tests are Atribu-computed

Meta returns lift only at the cell level — per-creative lift is always modeled. SPLIT_TEST results are computed by Atribu from its own fact tables (Meta exposes no results endpoint for split tests).


top_workspace_fatigue_risk

Which ads are most likely to pause in the next 30 days, ranked by hazard_30d_pause × spend — the budget at risk if the ad pauses. Only active ads in high / critical fatigue tiers appear.

ParameterTypeRequiredDefault
score_window7d | 14d | 28d | lifetimeNo28d
top_nnumberNo20 (max 50)
min_spendnumberNo100 (pass 0 to include all)

Cost: 1 unit

Scope: workspace

Returns: Ranked ads with hazard_30d_pause and hazard_30d_degradation (Cox survival-model 30-day probabilities — likelihoods, not deterministic timers), expected_lifespan_days, fatigue_risk_tier, plus workspace totals total_budget_at_risk (spend across the listed ads) and total_expected_pause_loss_30d (sum of hazard × spend — a distinct quantity, don't conflate the two).


workspace_pattern_gaps

Cross-profile pattern-coverage analysis: for each winning workspace pattern, which profiles have NO ad expressing it. Answers "what test should I run next?" with concrete cross-profile replication opportunities.

ParameterTypeRequiredDefault
score_window7d | 14d | 28d | lifetimeNo28d
limitnumberNo10 (max 50)
min_liftnumberNo0.05 (minimum lift_vs_workspace to qualify; 0–2)

Cost: 1 unit

Scope: workspace

Returns: Rows ordered by lift_vs_workspace DESC, each with pattern_dim / pattern_value, the lift + CI lower bound, source_profile_ids (where the pattern lives), gap_profile_ids (profiles missing it), and exemplar ads.


workspace_historical_lift_band

Historical lift distribution from graduated Conversion-Lift / Split-Test experiments in the workspace. Anchors expectations before committing to a new lift study.

ParameterTypeRequiredDefault
profile_idUUIDNo— (narrow to one client's history)
lookback_daysnumberNo365 (min 30, max 1095)

Cost: 1 unit

Scope: workspace

Returns: min / p25 / p50 / p75 / max of relative_uplift (% lift over the comparison cell) across experiments with derived_state complete or results_pending, plus the 5 most recent exemplars. Returns n_experiments: 0 when there's no graduated history.


experiment_power_calc

Statistical power calculator for a Conversion-Lift study (one cell + holdout). Pure math — reads no data.

ParameterTypeRequiredDefault
baseline_ratenumberYes— (0 < p < 1, e.g. 0.024 for 2.4%)
daily_spendnumberYes
cost_per_samplenumberYes
holdout_pctnumberNo0.2 (0.05–0.5)
days_to_runnumberNo14 (1–180)

Cost: 1 unit

Scope: workspace

Returns: The minimum detectable effect (MDE) at 80% power / two-sided α = 0.05, days-to-read, 0.5× and 2× spend comparison scenarios, and a recommendation (keep spend / double spend / cohort too sparse for this design).


Forecasting tools

forecast_workspace_outlook

Portfolio-grain forecast for the next 7 days — the "what's the week ahead" lookup.

ParameterTypeRequiredDefault
score_window7d | 14d | 28d | lifetimeNo28d

Cost: 1 unit

Scope: workspace

Returns: Projected total impressions + attributed outcomes with 80% prediction-interval bands (split-conformal calibration), projected average cost-per-outcome, counts of emerging top performers (worth scaling) and at-risk top performers (in high/critical fatigue), a per-tier fatigue histogram, and projected_budget_at_risk (total spend across high + critical fatigue ads).

Cold-start behavior

Forecast and fatigue fields come from the prediction-pass cron. Ads under the cold-start gate (fewer than 7 days of history) have no forecast; workspaces where the pass hasn't run return empty results with an explanatory interpretation.


forecast_ad_trajectory

Per-ad detail: current scores plus the 7-day forecast, fatigue hazards, and recent delivery history — "what does this ad look like next week?"

ParameterTypeRequiredDefault
profile_idUUIDYes
ad_external_idstringYes
score_window7d | 14d | 28d | lifetimeNo28d

Cost: 1 unit

Scope: workspace (profile_id is required because the same ad_external_id can appear across multiple profiles in an agency workspace)

Returns: The ad's latest feature-store row (spend, impressions, scores), 7-day projected outcomes / impressions / cost-per-outcome with 80% prediction-interval bands, the 30-day pause + degradation hazards and expected lifespan, the last 14 days of daily delivery, and lifecycle events (born / paused / revived / degraded). Forecast/fatigue fields are NULL for cold-start or unscored ads — the interpretation field explains which case applies.


compare_forecast_scenarios

What-if simulator: feeds modified spend / frequency values through the forecaster to project "if I 2× the budget on this ad, what's the expected 7-day outcome count?"

ParameterTypeRequiredDefault
profile_idUUIDYes
ad_external_idstringYes
score_window7d | 14d | 28d | lifetimeNo28d
scenariosobject[]Yes1–5 of { name, spend_7d_override?, frequency_override? }

Cost: 2 units

Scope: workspace (profile_id required)

Returns: The base prediction plus per-scenario point estimate + 80% prediction-interval band + delta vs base + an out_of_range flag — true when the scenario spend is more than 2× or less than 0.5× the ad's current trailing-7d spend (the model is extrapolating; treat the result as directional only). Returns a null base + per-scenario gated_reason when the ad is cold-start / paused / degraded.


Recommendation tools

list_workspace_recommendations

The AI media buyer's recommendations across all profiles in a workspace, ranked by expected impact.

ParameterTypeRequiredDefault
profile_idsUUID[]No
statusesstring[]No["open"] (open, applied, dismissed, superseded, expired, rolled_back)
kindsstring[]No— (scale_winner, pause_underperformer, budget_reallocate_winners, creative_refresh_pre_fatigue)
risk_tiersstring[]No— (safe, medium, manual_only)
cohort_objectivestringNo— (messaging, sales, leads, traffic, awareness)
score_window7d | 14d | 28d | lifetimeNo28d
limitnumberNo20 (max 100)

Cost: 1 unit

Scope: workspace

Returns: Recommendations with kind, risk_tier (safe = auto-applicable if the workspace opted in, medium = always requires explicit confirm, manual_only = no Meta call — handoff to Ads Lab), rationale_text + structured rationale_jsonb, suggested_modifications (action + params), expected_impact_dollars (directional projection, not a forecast), confidence (0–1), and lifecycle timestamps.


diagnose_recommendation

Full diagnostic for a single recommendation — "what happened with this recommendation?" Use before apply_recommendation to understand prior attempts.

ParameterTypeRequiredDefault
recommendation_idUUIDYes

Cost: 1 unit

Scope: workspace

Returns: The recommendation row (kind / risk tier / status / rationale / suggested modifications / target / impact / confidence / lifecycle), the most recent application if any (with pre-change and post-change Meta state, the Meta API result, verification and rollback timestamps), and the related write-back audit chain, most recent first.


apply_recommendation

Apply a recommendation against Meta. This is a write tool with the same three-step safety flow and gates as send_meta_conversions — see the Write-Back guide.

ParameterTypeRequiredDefault
recommendation_idUUIDYes
modepreview | dry_run | confirmYes
idempotency_keystringNoAuto-derived per (user, recommendation, day) when omitted
applied_byUUIDNo

Cost: 10 units

Scope: workspace

Requires (for dry_run and confirm): mcp:write scope, workspace write-back enabled, workspace owner/admin role. preview needs none of these. confirm additionally requires the recommendation to be open and unexpired.

preview shows what the worker would do (target ad/ad-set, planned Meta calls, budget % delta) with no side effects. dry_run records an audit row capturing intent. confirm enqueues the job for the pipeline worker, which captures pre-change Meta state, executes the write, and verifies the change landed ~5 minutes later. Replaying confirm with the same idempotency key returns the existing application — no double-write.


Write-back tools

send_meta_conversions

Push attributed conversions to Meta Conversions API (CAPI) for ad delivery optimization. This tool has a three-step safety flow: preview, dry-run, confirm.

See the dedicated Write-Back guide for the full flow, safety rails, and examples. apply_recommendation (above) is the second write tool — same gates, same audit trail.

ParameterTypeRequiredDefault
modepreview | dry_run | confirmYes
window_startdateYes
window_enddateYes
event_typesstring[]Yes
pixel_idstringFor dry_run/confirm
idempotency_keystringFor confirm
test_event_codestringNo
max_eventsnumberNo500 (max 500)

Cost: 10 units

Requires: mcp:write scope, Meta Ads connection, workspace write-back enabled, workspace admin role.


Response envelope

Every tool returns a consistent envelope:

Response structure
{
  "data": { },
  "meta": {
    "request_id": "01968a3b-...",
    "workspace_id": "...",
    "profile_id": "...",
    "window_start": "2026-04-01",
    "window_end": "2026-04-14",
    "attribution_model": "last_touch",
    "currency": "USD",
    "data_as_of": "2026-04-14T18:30:00Z",
    "freshness_by_provider": {
      "meta": "2026-04-14T18:30:00Z",
      "ghl": "2026-04-14T17:00:00Z"
    },
    "data_freshness_warning": null,
    "record_count": 12,
    "pii_level_applied": "masked"
  }
}
Meta fieldDescription
request_idUnique ID for debugging and support
data_as_ofOldest sync timestamp across required providers
freshness_by_providerPer-provider last sync time
data_freshness_warningHuman-readable warning if data is stale (>6 hours)
pii_level_appliedmasked or full -- what PII level was actually used

On this page