The Analyst Agent: How Orbit Ingests GA4, PostHog, Mixpanel, Stripe, and Your Database to Build a Full-Funnel View
How Orbit's analyst reads a brand's analytics: which source it asks for first, why conversion definitions come before revenue and revenue comes before product analytics, how it reconciles them into an attribution mix and a visitors-to-retained funnel with revenue from the payment processor, what it writes down as the brand's analytics map, and when it pulls a guide. Present tense for what ships in orbit-mcp today; designed-to for what the agent runtime adds.
every brand orbit connects has the same shape of problem: four or five systems that each know part of the funnel, no shared event names, and a revenue number that lives somewhere none of the ad platforms can see. the analyst's job is to read all of them in a fixed order, reconcile them into one funnel with one revenue source, and write down what it learned so the next question does not start from zero. this guide describes that process as it works in orbit-mcp today and where the agent runtime is designed to take it.
what the analyst actually is
the analyst is a read-only role. it never changes a conversion action, a pixel, or a budget. it reads sources through orbit-mcp tools, compares them, names the gaps, and hands findings to a human or to the other agents. in orbit chat and in any mcp client connected to orbit-mcp, the analyst is the model running the checks below with the tools listed. in the agent runtime, the analyst is designed to run on a schedule as the brand's tracking operator, with a skill file that fixes its judgment rules and an output contract that requires every figure to come from a tool result in that run.
what most "ai analytics" descriptions get wrong is the order. they describe a model that pulls everything and summarizes. the analyst pulls in a sequence, because each source defines what the next one means:
- conversion definitions per platform. what google ads, meta, tiktok, and ga4 each count as a conversion, and whether those definitions describe the same event.
- revenue source of truth. what money was actually collected, from the payment processor, net of discounts, trials, and failed payments.
- product analytics. what users did between arriving and paying: signup, activation, the steps that predict retention.
- warehouse or database. the brand's own tables, for anything the first three cannot answer.
conversion definitions come first because a funnel built on ga4's purchase and meta's Purchase and google's imported purchase is one step described three ways, and the analyst has to know whether they match before it counts anything. revenue comes second because it is the only number the funnel is allowed to end in. product analytics comes third because its events are meaningless until they are pinned between a defined top (a visitor) and a defined bottom (collected revenue).
the fundamental shift: from a dashboard per source to one map per brand
before: ga4 for traffic, an ads dashboard per platform, posthog or mixpanel for product, stripe for finance. each with its own event names, its own attribution, and a person who knew how to read it. a question like "what is our real cac" required a human to open all five and reconcile by hand, and the reconciliation was never written down.
after: one reader with the tools to open all of them and a fixed method for reconciling. the method is the investigation methodology orbit ships as an operating guide: state the problem with numbers, list hypotheses before pulling data, gather evidence one layer at a time, and separate config gaps from data limitations from strategic issues. the ga4 cross-analysis guide adds the rule the analyst applies to every discrepancy: never assume a gap between ga4 and a platform is a configuration problem until the platform setting has been read.
the output of the shift is a brand-level artifact, the analytics map: which source owns which funnel step, what each event is called in each source, which revenue number is canonical, and what the current attribution mix looks like. today that map lives partly in orbit's brand metric aliases, which store per-brand friendly names for raw platform metrics, and partly in the conversation. the agent runtime is designed to store it in a versioned per-brand playbook that every agent reads before it runs.
what this broke in existing accounts
the analyst's first pass on a newly connected brand finds the same six things often enough that they are the checklist.
1. key events that are not the platform's conversion
ga4 marks generate_lead as a key event, google ads bids on an imported form_submit from a different tag, meta optimizes for Lead fired by the pixel on page load. three conversion definitions for one form. the analyst reads all three before it compares any counts. tools: list_ga4_conversion_events, get_conversion_actions, audit_conversion_setup, get_meta_pixel_status, get_tiktok_pixel_status.
2. revenue that means list price
a dashboard mrr computed from subscription list prices counts a 100%-off comped account as full revenue and counts trials as paying. orbit's stripe tool exists because of this: get_stripe_revenue_summary computes mrr as money actually collected, applies coupons and discounts, and splits paying, canceling, at-risk (past due or unpaid), trialing (potential mrr), and comped subscriptions into separate buckets rather than one total.
3. product events named for the developer who wrote them
user_signed_up, signup_completed, and Sign Up in three sources for the same action. the analyst lists event names per source before it builds a funnel. tools: get_ga4_all_events, get_ga4_event_details, mixpanel_list_events (production orbit-mcp), and posthog_exec with an event-definition or property-definition command.
4. funnels that skip the step that matters
a funnel of visit, signup, purchase with no activation step cannot explain a retention problem. the analyst asks what users do between signup and payment using get_ga4_user_journey to find events that co-occur with the target, then confirms the sequence with run_ga4_funnel, which supports simple event-name steps or rich steps with dimension filters such as a page path, open or closed funnel types, and returns step-by-step dropoff.
5. attribution read from the wrong scope
get_ga4_attribution groups conversions and revenue by session source and medium, session campaign, or session default channel group. those are session-scoped dimensions, which means the numbers follow session attribution, not the property's reporting model. it is the right tool for "which channel did the converting session come from" and the wrong tool for "which channel deserves data-driven credit." the ga4 attribution guide explains the difference. the analyst labels the output accordingly.
6. a gap called a tracking break that was a pacing move
conversions down 35%, spend down 38%. that is pacing. the analyst reads spend by day before it reads conversions, every time, using get_spend_by_day, get_meta_spend_by_day, and get_tiktok_spend_by_day.
what the analyst reads, in order
there is no external dataset here. this section is the ingestion order and the tool that performs each step in orbit-mcp today.
step 1, conversion definitions per platform.
- ga4:
list_ga4_properties,list_ga4_data_streams,list_ga4_conversion_events(which events are key events, created when, custom or default),list_ga4_custom_dimensions,list_ga4_linked_accounts. - google ads:
get_conversion_actions,audit_conversion_setup(primary goals present, duplicates, actions with no recent data),diagnose_conversion_tracking. - meta:
get_meta_pixel_status,get_meta_capi_diagnostics,audit_meta_attribution_visibility. - tiktok:
get_tiktok_pixel_status,get_tiktok_capi_diagnostics,get_tiktok_attribution_metrics. - gtm where connected:
diagnose_gtm_container,list_gtm_tags,list_gtm_triggers. - output: a table of conversion name per platform, the event it fires on, and whether the four platforms describe one business event or several.
step 2, revenue source of truth.
- stripe:
get_stripe_revenue_summaryfor mrr and arr as collected money, paying versus canceling versus at-risk versus trial versus comped, and the currencies in play. - shopify orders are not a native orbit-mcp tool today. where a brand runs on shopify, the analyst reads order revenue from ga4
purchasevalue as an observed proxy and labels it as such; the agent runtime is designed to read the order system directly as a second revenue source. - output: one canonical revenue number with its source and its definition, and the gap between it and the sum of platform-attributed revenue.
step 3, product analytics.
- posthog:
posthog_exec, proxied from posthog's own mcp server and covering its query, sql, insight, funnel, retention, cohort, and event-definition commands. every call runs with the user's own posthog key. - mixpanel:
mixpanel_list_events,mixpanel_segmentation,mixpanel_funnels(saved funnels with step conversion and dropoff),mixpanel_retention,mixpanel_engage, in the production orbit-mcp build. - ga4 as product analytics where no dedicated tool exists:
run_ga4_funnel,get_ga4_user_journey,get_ga4_top_pages,get_ga4_by_device. - output: the activation event, the retention definition, and the funnel steps between signup and payment, named per source.
step 4, warehouse or database.
- no native orbit-mcp tool reads a brand's warehouse today.
posthog_execcan run sql against posthog's data warehouse where the brand has connected external sources there. direct reads of a brand's postgres, bigquery, or snowflake are designed, not shipped.
how it reconciles. with the four layers read, the analyst builds two artifacts.
the attribution mix: per channel, three numbers side by side for the same period, platform-claimed conversions, ga4 session-attributed conversions from get_ga4_attribution, and the revenue share from the canonical revenue source. it reports the ratios, not a blended total, following the one-number-per-source rule in the agency reporting stack guide. a gap above 25% between ga4 and a platform for the same period is a lead to investigate, never a count of lost conversions.
the full-funnel view: visitors (ga4 sessions or active users) to signups or leads (the ga4 key event or the product analytics event, whichever the map names canonical) to activation (product analytics) to paid (stripe paying subscriptions, or ga4 purchase as proxy) to retained (mixpanel retention, posthog retention, or a stripe canceling-versus-paying ratio), with revenue at the bottom from the payment processor only. every step names its source. if a step has no source, the funnel shows the hole rather than an estimate.
what it stores. the analytics map, per brand: canonical revenue source and definition; conversion name per platform and the business event each describes; funnel step to source to event name; the attribution mix as of a date; open discrepancies and what was already ruled out. brand metric aliases hold the per-platform friendly names today through get_brand_metric_aliases and set_brand_metric_aliases, so reports use "trial starts" rather than a raw column name. the agent runtime is designed to keep the rest in a versioned brand playbook that the analyst reads at the start of every run and updates at the end.
when it pulls a guide. orbit-mcp exposes find_guides, list_guides, and get_guide. the chat system prompt instructs the model to call find_guides first for any strategy, setup, "what changed," "why did x happen," best-practice, or audit question, or when a metric change could be explained by a platform change, and not for pure data lookups. it then reads the relevant section with get_guide before pulling account data so the fetch plan covers what the guide says to check, and get_guide with the agent-tasks section returns the guide's check, flag, and recommend rules to run against the account. the analyst cites the guide once by title and url when its guidance shapes the answer, and every account-specific number still comes from a tool result in that run.
what changed in 2026 specifically
orbit-mcp, through 2026: the ga4 tool set grew from overview and traffic reports to include run_ga4_funnel with rich filtered steps, get_ga4_user_journey, get_ga4_attribution, and the admin tools for key events and custom dimensions. stripe revenue became a native tool with collected-money semantics. posthog and semrush are proxied with the user's own credentials; mixpanel joined in the production build with both a service-account path and an oauth proxy. the guides library moved into orbit-mcp with keyword search and machine-readable agent tasks.
the agent runtime (designed): a per-brand roster of operators including an analyst for tracking, a media buyer for pacing, an auditor that runs a one-time first look across every connected account when a brand is set up, and a reporter that writes the monday narrative. each has a skill file that fixes what it monitors and how it judges. the analyst's rules in that design: a volume drop with a matching spend drop is pacing, not tracking; a drop with steady spend and a status flip is a tracking break; a ga4 gap alone is informational unless it widened sharply; always state what is unknown and the single check that would settle it; never recommend pausing spend. none of this changes what the analyst reads. it changes how often and where the findings go.
what actually works now
1. run the ingestion in order and write down step 1 before step 2
ask for conversion definitions first. do not count anything until you know whether the platforms are counting the same event. then name the revenue source. then map product events. the order is the method.
2. use the stripe summary, not raw stripe reads
get_stripe_revenue_summary exists because raw stripe listings truncate, double count trials, and price comped accounts at list. for any "how much do we make" question, use the summary and quote its buckets separately.
3. build the funnel from a journey, then confirm it
get_ga4_user_journey for the target event shows which events co-occur before and after it. pick the steps from that, then run_ga4_funnel with those steps, closed funnel type, and filters where a step is a page rather than an event. report dropoff per step with the source named.
4. label attribution output by scope
anything from get_ga4_attribution is session-attributed. say so in the output. put platform-claimed, ga4 session-attributed, and revenue share side by side and never sum them.
5. read spend before conversions
a conversion change is only a tracking finding after spend by day has been read for the same window and found steady.
6. keep the aliases current
when discovery on tiktok or meta surfaces a new raw metric, alias it through set_brand_metric_aliases or the platform's auto-suggest tool so no report ever renders a raw column name. the alias table is the shipped half of the analytics map.
7. pull the guide before the data on any "why" question
find_guides, then get_guide for the section, then the fetch plan. the guides carry thresholds and methods. the account carries the numbers. the answer needs both, in that order.
what to stop doing immediately
- stop building a funnel before reading each platform's conversion definition.
- stop quoting mrr from list prices. use collected money.
- stop treating ga4 session-attributed channel data as data-driven credit.
- stop calling a conversion drop a tracking break before reading spend by day.
- stop summing platform-claimed conversions with ga4 key events.
- stop estimating a funnel step that has no source. show the hole.
- stop rendering raw platform metric names in any report a brand will read.
- stop answering "why did x change" from account data alone when a guide covers the platform change.
the orbit agent instructions
{
"guide": "analyst-agent-analytics-ingestion",
"agent_tasks": {
"audit_source_coverage": {
"check": "for the brand, list which of ga4, google ads, meta, tiktok, stripe, posthog, mixpanel, and gtm are connected and returning data, and map each funnel step (visitors, signups or leads, activation, paid, retained, revenue) to the source that owns it",
"flag": "any funnel step with no connected source, revenue not sourced from a payment processor or order system, or a connected source that returned no data in the run",
"recommend": "name the missing connection per step, label any proxy (such as ga4 purchase value standing in for orders) as a proxy, and show the hole rather than an estimate"
},
"audit_event_name_consistency": {
"check": "list conversion and key event names from ga4 key events, google ads conversion actions, meta pixel or capi events, tiktok events, and product analytics event definitions, and group them by the business event each describes",
"flag": "one business event with different names or firing conditions across sources, a ga4 key event that is not the event google ads imports, or a platform optimization event with no matching ga4 key event",
"recommend": "record the mapping in the brand's analytics map and aliases, and propose the single canonical name per business event for reporting"
},
"reconcile_revenue_sources": {
"check": "for the trailing 30 days, compare collected revenue from the stripe summary (paying bucket only) with ga4 purchase revenue and with the sum of platform-attributed revenue across google ads, meta, and tiktok",
"flag": "platform-attributed revenue above 100% of collected revenue, ga4 purchase revenue differing from collected revenue by more than 15%, or trial and comped mrr included in any total presented as revenue",
"recommend": "present each ratio as a labeled factor, use collected revenue as the only revenue at the bottom of the funnel, and open a tracking check on the ga4 purchase value if it is the source of the gap"
},
"audit_funnel_step_coverage": {
"check": "run the brand's canonical funnel with run_ga4_funnel or the product analytics funnel tool and confirm every step from visitors to retained has counts for the period",
"flag": "a step with zero or missing counts, a funnel with no activation step between signup and paid, or a dropoff above 90% at a single step with no documented reason",
"recommend": "use get_ga4_user_journey to find the missing intermediate event, add it as a step, and record the step-to-source mapping in the analytics map"
},
"monitor_attribution_mix_freshness": {
"check": "compare the stored attribution mix (platform-claimed, ga4 session-attributed, revenue share per channel) against a fresh pull for the same period length, and read the date the mix was last written",
"flag": "a stored mix older than 30 days, any channel whose ga4-versus-platform gap moved more than 10 points since the stored version, or a gap above 25% on any channel",
"recommend": "rewrite the mix with today's date, list what changed per channel, and treat a widened gap as a lead to investigate with the platform's conversion settings read first"
},
"audit_spend_before_conversion_findings": {
"check": "for every conversion volume change above the brand's threshold in the window, read spend by day for the same platform and window before classifying it",
"flag": "a conversion drop with a matching spend drop labeled as tracking, or a conversion drop with steady spend and a pixel or capi status flip not labeled as tracking",
"recommend": "classify pacing versus tracking explicitly, name the event, platform, and first day it moved, and hand pacing findings to the budget review rather than the tracking queue"
}
}
}
the bottom line
the analyst reads in order: conversion definitions, then collected revenue, then product events, then whatever the warehouse can add. it reconciles into an attribution mix that never sums across sources and a funnel that ends only in money the payment processor collected. it writes the mapping down so the next run starts from the map, not from scratch.
everything in the reading order ships in orbit-mcp today. the scheduled analyst, the first-look audit, and the versioned playbook are what the agent runtime is designed to add on top.
built by orbit - the performance marketing intelligence layer. questions? jose@orbitllm.com