Agencies running 5 to 30 client accounts know that the ROAS reported in Meta Ads Manager never matches the ROAS in Google Ads, and neither matches the revenue declared in GA4. To close the monthly report, the agency opens three interfaces, exports spreadsheets, joins by campaign_name manually, and still has to explain to the client why all three numbers diverge. The central question, "out of every dollar spent on Meta Ads and Google Ads last month, how much became purchaseRevenue in GA4?", is not answered by any of the three platforms in isolation. With real ROAS cross-platform via the Kondado MCP, you ask that question in natural English inside ChatGPT or Claude and get the answer in one sentence, grounded in actual data replicated from all three sources into a single SQL destination.
The Kondado MCP delivers purchaseRevenue from GA4 and cost from Google Ads and Meta Ads into the same SQL destination, and ChatGPT or Claude joins by campaign_name and answers in natural English in the same session. Setup has three steps: replicate GA4, Google Ads, and Meta Ads into a Via Kondado destination, connect the MCP endpoint https://mcp.kondado.io/mcp to the compatible client, and authorize via OAuth. The join is by campaign_name, not by ID, because campaign IDs do not match across platforms and the name matches in most cases when the agency follows a naming convention. The same session also answers cross-channel attribution ("how much did Meta Ads drive in engagedSessions in GA4" and "how much became purchaseRevenue") without opening three tabs.
Why doesn't the ad manager ROAS match GA4?
The ROAS shown in Meta Ads Manager is calculated from Pixel/CAPI events with click-through and view-through attribution, usually in a 7-day-click + 1-day-view window. Google Ads uses its own attribution model, often data-driven, which gives partial credit to multiple touches. GA4 defaults to last-click session attribution and only sees the purchase event fired on the site. The three numbers diverge by design, not by bug. The business question the client asks, "how much of my declared revenue came from paid media, and how much from each platform?", needs a single source that looks at the three data sets side by side. Real ROAS cross-platform via the Kondado MCP delivers that single source.
How do I connect GA4, Google Ads, and Meta Ads to ChatGPT in 3 steps?
-
Replicate the three data sources into a Via Kondado destination. In the Kondado panel, connect GA4 with OAuth
analytics.readonly, Google Ads with read-only OAuth, and Meta Ads with Facebook Business login. Pick the minimum reports for cross-platform ROAS:ga4_ecommerce_revenue_daily,ga4_traffic_acquisition_daily,campaign_performancefrom Google Ads, andad_insightsfrom Meta Ads. Replicate to the SQL destination you prefer, listed in the Kondado destinations catalog. -
Add the MCP data source in ChatGPT or Claude. In the compatible client, paste the URL
https://mcp.kondado.io/mcpand follow the OAuth 2.1 flow that opens the consent page atapp.kondado.com.br. Each session is bound to one Via Kondado, and queries are read-only KSQL over the destination you just configured. Full flow on the Kondado AI and MCP page. -
Ask real ROAS in natural English. In the chat, write: "Compare
purchaseRevenuebysessionCampaignNamein GA4 withcostbycampaign_namein Google Ads and Meta Ads last month. Calculate real ROAS aspurchaseRevenuedivided bycost. List the top 20 campaigns by ROAS." The model assembles the join across the three reports and returns an answer ready to send to the client.
What is the SQL mental model of the GA4 + Google Ads + Meta Ads join?
The query the model generates has two steps. First, sum purchaseRevenue by sessionCampaignName in ga4_ecommerce_revenue_daily for the reference month. Second, sum cost by campaign_name in campaign_performance from Google Ads and in ad_insights from Meta Ads for the same date window. The join is by campaign_name when it matches, or by campaign_id when the agency keeps consistent naming across platforms. The final calculation divides purchaseRevenue by cost, returning real ROAS per campaign. In approximate SQL text, the reading is: sum purchaseRevenue grouped by sessionCampaignName filtered for date between the first and last day of the target month, in ga4_ecommerce_revenue_daily. Union with the sum of cost grouped by campaign_name in campaign_performance filtered by the same dates, and by campaign_name in ad_insights filtered by the same dates. Join the three by campaign_name. Compute ROAS as purchaseRevenue over cost. Order by ROAS descending. That is what the model reads when you send the question in natural English, and that is why the answer comes back correctly on the first try.
Why join by campaign_name and not by campaign_id?
Campaign IDs are unique within each platform, but they do not match across Meta Ads, Google Ads, and GA4. When the agency creates the same promotional campaign in Meta Ads and Google Ads, it appears with completely different IDs on each side, and GA4 only sees what the utm_campaign registered. Joining by ID requires a manual mapping report that the agency has to maintain, which brings back the original intermediate-spreadsheet problem. Joining by campaign_name solves the join at query time, as long as the agency follows a consistent naming convention such as [YYYYMM]_[client]_[platform]_[topic]. The MCP-GA4 cluster research brief documents this point as Learning 104, observed in conversations with agencies in the base. When naming does not match, the model flags the orphan campaigns in the answer and the agency adjusts the convention for the next month.
What real ROAS questions can you answer in the same session?
The same MCP connection that delivers ROAS by campaign answers a list of variants that would normally require separate reports inside each platform. Here are the main ones.
- Which paid channel gave me the highest real ROAS, net of refund? The model queries
ga4_ecommerce_revenue_dailyand usespurchaseRevenueinstead oftotalRevenue, because purchase minus refund is the correct calculation for pure e-commerce. - Which campaigns blew past the target CPA this month, assuming GA4 last-click attribution? The model divides
costbytransactionsgrouped by campaign and orders by CPA descending. - For every dollar spent on Meta Ads last month, how much became an
engagedSessionin GA4 and how much became apurchase? The query filterssessionsourcemediumfor facebook or instagram patterns inga4_traffic_acquisition_daily, joins withad_insightsby date, and returns the two conversion rates side by side. - What is the gap between conversions reported by Meta via Pixel/CAPI and
transactionsin GA4 for the same campaign? The model comparespurchasesfromad_insightswithtransactionsfromga4_ecommerce_revenue_dailyfor the same window. The difference is the classic gap between media-platform attribution and GA4 last-click attribution, and the model helps explain the divergence to the client. - What is the average ticket per cross-joined campaign? Divide
purchaseRevenuebytransactionsgrouped bysessionCampaignNameand order by ticket descending.
Which semantic traps does the model need to know to avoid wrong ROAS?
Three traps appear frequently when the model answers about cross-platform ROAS, and the agency has to know them to audit the answer.
-
purchaseRevenueis nottotalRevenue. For pure e-commerce, usepurchaseRevenue, which already nets out refund.totalRevenuealso sums subscription and ad revenue, which inflates ROAS for accounts with IAP-monetized apps. If the question asks for "e-commerce revenue", the model has to selectpurchaseRevenue. If it defaults tototalRevenue, ROAS comes back inflated by 10% to 40% depending on the revenue mix. -
bounceRategoes from 0 to 100, not from 0 to 1. When the model needs to filter campaigns by engagement before calculating ROAS,bounceRateequal to 94 means a 94% bounce, which is bad. If the model interprets 94 as 0.94, it thinks the page is fine and flips the diagnosis. Always ask the model to treatbounceRateas a percentage. -
GA4 data finalizes in up to 48 hours. Google Analytics 4 only closes the day's numbers within 48h. If the agency asks "yesterday's ROAS", the model should flag that data is not yet finalized and suggest D-2 as a safe cutoff. Kondado replicates your GA4 on the frequency you choose in the pipeline, inside the native GA4 delay.
How do I deliver real ROAS to the client without building a spreadsheet?
Once the model returns real ROAS cross-platform by campaign, the agency has two equally valid paths. The first is to keep the conversation in the chat and ask for ready-to-send copy for the monthly report: "Write a paragraph in English explaining why real ROAS came in below the Meta Ads Manager ROAS, citing the divergence between CAPI attribution and GA4 last-click attribution, and propose two optimization actions." The model writes the paragraph using the numbers it just computed. The second is to ask for a tabular export to drop into a presentation: "List the top 10 campaigns by real ROAS as a numbered list with campaign_name, cost, purchaseRevenue, and ROAS." Either way, the numbers come from the destinations Kondado replicates, not from exports from last Tuesday, and that is what sets the cross-platform report apart from a spreadsheet that becomes stale on the next campaign change.
Why via Kondado and not have ChatGPT read GA4, Google Ads, and Meta Ads directly?
Three practical reasons decide. The first is that GA4, Google Ads, and Meta Ads do not publish an official MCP server: any "direct" connection depends on scrapers or unstable OAuth pipelines that exhaust property quota when the model hits the same session repeatedly. The second is that Kondado replicates the data on the frequency you choose into a destination you control, and the model queries the destination, not the original API. Your quota stays intact, query cost is predictable, and latency stays low. The third is the join: crossing GA4 with Google Ads and Meta Ads "directly" requires three separate connections, three OAuth sessions, and the model still has to assemble the join in the conversation buffer, which breaks at volume. With Kondado, the three data sources live in the same destination and the join is a SQL query the model writes in seconds.
Frequently Asked Questions
Can ChatGPT calculate real ROAS by crossing GA4, Google Ads, and Meta Ads in one session?
Yes, provided that the three data sources are replicated into the same SQL destination via Kondado and the MCP data source is authenticated in the client. ChatGPT queries the destination via read-only KSQL, builds the join by campaign_name, and returns real ROAS, average ticket, and CPA per campaign in the same answer.
How does the Kondado MCP decide what each client can query?
Each MCP OAuth session is bound to a specific Via Kondado. The model only sees the reports and models of that Via Kondado, and all queries are read-only. If the agency manages 20 clients, each client has its own Via Kondado and its own MCP session, with no cross-data contamination.
How do I handle campaigns that do not match by campaign_name across platforms?
The model flags the orphan campaigns in the answer. The agency can ask for a list of unmatched campaigns and adjust the naming convention next month, or create a manual mapping report that becomes a model in the destination. Learning 104 from the MCP-GA4 cluster documents this divergence pattern in agencies in the base.
What is the refresh frequency of the data Kondado replicates?
Frequency is configurable per pipeline in Kondado. You can set it to the cadence that makes sense for your client's report, inside the native delay of each data source. GA4, in particular, finalizes the day's data within 48h, so D-2 is the recommended safe cutoff for daily analyses.
Does Kondado store GA4, Google Ads, and Meta Ads data on its own servers?
No. Data is replicated into the SQL destination you choose and control. The options are listed in the Kondado destinations catalog, and include Google Sheets, Excel, BigQuery, PostgreSQL, MySQL, SQL Server, Redshift, and Amazon S3. The agency continues to own the data in all scenarios.
Does the Kondado MCP work with Claude in addition to ChatGPT?
Yes. The endpoint https://mcp.kondado.io/mcp is the same for every compatible MCP client. Claude, ChatGPT, and any other client that supports MCP with OAuth 2.1 connect the same way, using the authorization steps described in the setup above.
Ready to answer real ROAS in a sentence instead of joining three spreadsheets? Start the Kondado free trial with 30 pipelines and 10 million records for 14 days, no credit card required.
How to connect GA4, Google Ads, and Meta Ads to ChatGPT via the Kondado MCP
Replicate GA4, Google Ads, and Meta Ads into a Via Kondado destination, connect the MCP endpoint to ChatGPT or Claude, and ask real cross-platform ROAS in natural English.
Replicate the three data sources into a Via Kondado destination
In the Kondado panel, connect GA4 with OAuth analytics.readonly, Google Ads with read-only OAuth, and Meta Ads with Facebook Business login. Pick the minimum reports for cross-platform ROAS: ga4_ecommerce_revenue_daily, ga4_traffic_acquisition_daily, campaign_performance from Google Ads, and ad_insights from Meta Ads. Replicate to the SQL destination you prefer.
Add the MCP data source in ChatGPT or Claude
In the compatible client, paste the URL https://mcp.kondado.io/mcp and follow the OAuth 2.1 flow that opens the consent page at app.kondado.com.br. Each session is bound to one Via Kondado, and queries are read-only KSQL over the destination you just configured.
Ask real ROAS in natural English
In the chat, write: Compare purchaseRevenue by sessionCampaignName in GA4 with cost by campaign_name in Google Ads and Meta Ads last month. Calculate real ROAS as purchaseRevenue divided by cost. List the top 20 campaigns by ROAS. The model assembles the join across the three reports and returns an answer ready to send to the client.
