Agency Reporting with MCP: A PHI-Safe Weekly Workflow
A weekly agency reporting routine for clinic clients: completed-week KPIs per client, platform vs server-side conversions, anomaly rules, an AI draft and human sign-off.
A PHI-safe weekly agency report pulls last week's aggregate KPIs per client through read-only MCP servers, compares what each ad platform credited with what server-side tracking recorded, flags what moved, and has an AI assistant draft the client note for a named reviewer to sign off. Curve supplies the server-side half: the clinic's own Curve MCP connection returns completed-week figures with small groups withheld, while agency staff ask Curve Analyst inside each client's account, where answers are exact and stay in the app. The signed BAA on every plan covers Curve's processing, not your AI client, so whatever enters that chat must be safe on its own.
The routine: five steps, same day every week
Two seats run it. Your staff pull platform figures through read-only Google Ads and Meta MCP servers and ask Analyst for server-side figures, because only the clinic's own users can be granted its server-side MCP connection. The clinic's team can pull the same KPIs through it in any MCP-capable client, such as Claude, ChatGPT or Cursor, and share them.
Run it early in the week, on the same weekday, one client at a time, so every week has aged the same amount.
- Pull. Last completed week and the last four, from read-only sources, in a conversation for that one client.
- Reconcile. Platform-credited conversions against server-side conversions, campaign by campaign.
- Flag. Apply the client's written anomaly rules and list what tripped.
- Draft. The assistant writes the client note from tool results in that conversation and nothing else.
- Review. A named person checks every figure, every stated cause and the never-list, then sends.
Three ground rules apply throughout:
- Completed weeks only. A partial week compares four days with seven and makes every Thursday look like a collapse.
- Read-only tools only. Meta's Ads MCP server has write tools that create campaigns and, once a user confirms, start spend. A reporting session needs none of them.
- One client per conversation. Name the client and its account IDs first. Leftover context is how the wrong numbers reach the right client, which is why agencies need client data boundaries before automating anything.
Step 1: Pull completed-week KPIs, one client per conversation
Pull last week for the note and the last four for context on spend and traffic; one week of a small clinic is noisy. In the clinic's MCP output, some weekly campaign conversions will come back withheld, and cost per conversion with them. The four-week window is likelier to give those campaigns a number.
Platform figures
- Google Ads. Google's official MCP server is strictly read-only; its
searchtool runs GAQL.SELECT campaign.name, metrics.cost_micros, metrics.clicks, metrics.impressions, metrics.conversions, metrics.conversions_by_conversion_date FROM campaign WHERE segments.date DURING LAST_WEEK_MON_SUNreturns last Monday to Sunday by campaign. For the Step 2 ratio, rerun it for the week before last withsegments.date BETWEENits Monday and Sunday, and read the by-conversion-date column. Cost comes back in micros, so check the assistant divided by a million. - Meta. Meta's Ads MCP server is in open beta and lets you restrict an agent to read-only per asset. Set this client's ad account to read-only before the session, ask for last Monday to Sunday and the week before at campaign level, and note the attribution setting the figures use.
- Credentials. Google's
list_accessible_customersreturns every account the signed-in user can reach, so a manager-account login puts every client one prompt away. Authenticate as a user with access to this client only.
Server-side figures
Pull the same week's visitors, goal completions such as booked consults, funnel steps, and conversions and cost per conversion by campaign: from Analyst for your staff, from MCP for the clinic's team. The MCP weeks run Monday to Sunday in the clinic's reporting time zone, which is why the Google query uses LAST_WEEK_MON_SUN rather than LAST_7_DAYS or LAST_WEEK_SUN_SAT; ask Analyst for the same window. Check that the ad account's time zone matches, or the two weeks start at different midnights.
What stays out of the pull
- Search-term reports. They are strings people typed, and some carry a condition, a drug name or a person's name. Review them in the platform, not the reporting chat.
- CRM, booking and lead tools. A GoHighLevel or HubSpot connection in the same session puts contact records one tool call away from the draft.
- Day-level breakdowns. Days make small groups; weeks are enough.
Step 2: Reconcile platform and server-side conversions
The two counts will not match. They differ for known reasons: Google "reports conversions on the ad impression date" and can report them "up to 90 days after the click," each platform credits by its own windows and view-throughs, and one patient can be claimed by both platforms while server-side last touch counts that person once. Why Meta and Google disagree covers each cause; for the client note, the only question is whether the gap moved.
Compute the ratio on the week before last: the settled week, the same one the in-house routine reconciles. Last week's platform figures are still arriving, so its ratio reads low. Last week stays in the note.
Write the gap per platform and campaign: platform-credited (for Google, by conversion date) divided by server-side. Log it with the pull date and compare it with ratios logged in earlier weeks, not a re-pull of older weeks, which mixes weeks of different ages. A logged ratio that jumps or collapses is a finding; a steady one means nothing changed.
Curve MCP reconciles your server-side campaigns: it puts each campaign's platform-reported spend, clicks and impressions next to the conversions Curve's server-side tracking recorded, with cost per conversion by completed week, and opens the full sent, accepted and matched view inside Curve with one link. Your staff get the same view from Analyst. For Meta the sent figure is platform-level only, because Meta uploads carry no campaign identifier. Sent vs platform credited explains which gaps are normal, and the in-house version of this step is the weekly AI reconciliation routine.
Step 3: Flag anomalies with written rules
Write the rules once per client in the report template, with agreed tolerances, so the assistant and reviewer apply the same test weekly. Six rules cover most weeks; the last two apply only when the clinic shares its Curve MCP output.
- Spend with no server-side conversions. A campaign that usually converts spent normally and shows none. Suspect the site first: a broken form or a swapped booking tool.
- Ratio break. The platform-to-server ratio leaves its logged range. Platform up and server flat suggests a new primary conversion action, a duplicate event or a view-through surge. Server up and platform down suggests the platform stopped receiving or accepting what was sent.
- Visitors steady, goal completions down. The funnel step where the count falls is where to look.
- Pacing. Weekly spend is off plan by more than the agreed tolerance.
- A new "(label hidden)" row. A new or renamed campaign the clinic has not approved; ask its primary user to review the name.
- A withheld count. Not an anomaly. The group was too small to release; report it as below the reporting minimum.
Two traps sit in rules 1 and 6. In MCP output a withheld count covers zero too, so "no conversions at all" is a question for Analyst. And an exact small count from Analyst or Google is still small: a note showing three conversions for a service-line campaign in one week can point at people for anyone holding the clinic's calendar. The floor in Step 4 covers both sides.
How Curve supplies the server-side numbers
Curve records conversions server-side on US-hosted infrastructure and forwards only explicitly mapped fields to each ad platform, with identifiers SHA-256 hashed. So Curve holds a conversion count no ad platform produced: people who converted, each credited once, to one campaign, by last touch. Its MCP server hands that count to any MCP-capable client the clinic uses, from Claude to ChatGPT or Cursor:
- Completed weeks only. Last week or the last 4, 13 or 52 weeks, as totals plus a weekly series, never the current week, so they can trail the dashboard by a week.
- Per campaign. Spend, clicks and impressions as each platform reports them, the last-touch conversions above, and cost per conversion from rounded figures, beside site visitors, goal completions and funnel steps.
- Small groups withheld. It counts people across the window, withholds small groups, rounds what it releases, and withholds any number whose subtraction would expose a small group.
- Approved names only. Unapproved campaign and goal names read "(label hidden)," and no visitor-set string, such as a UTM or page path, is returned.
- Fails closed. The tools are read-only. A final guard blocks any answer that looks like it holds an email, phone number, ID, date or name, and blocks if it cannot run. Every call is logged; no log, no answer.
For the full sent, accepted and matched view, it returns a one-time "open in Curve" link that needs a login and carries no data. Revenue, ROAS and channel, device, region or page breakdowns open the same way. Analyst answers them inside the dashboard from the same records, with exact counts.
Who holds which connection
The MCP connection belongs to the clinic. It is off by default for every user, only the clinic's primary user can switch it on, and each token is bound to one organization. Agency admins can revoke access or switch MCP off but cannot grant it: an agency's AI subscription is the agency's vendor, not one the clinic approved.
So your staff work in Analyst through Managed Accounts, one client per session, where the client has it on. When to use which covers the split.
Steps 4 and 5: Draft the note, then put a person on it
Analyst answers with exact counts because it runs inside Curve under the BAA; your own AI client does not. If you draft there, carry over only the aggregates the note needs, and apply a small-number floor first: write any count below it as "below the reporting minimum," on the platform side too. CMS's cell-size rule for its own data is a usable public benchmark: no cell with a value of 1 to 10 is reported directly.
Then give the assistant standing instructions:
- Use only figures returned in this conversation. If one is missing, write "not pulled" instead of estimating.
- State the window dates at the top.
- Apply the floor to every count, platform and server-side. Never print a total beside all but one of its parts; subtraction gives the missing one back.
- Label every cause as a hypothesis, with the check that would confirm it.
The note fits on one screen:
- Headline. One sentence: what happened and what you are doing about it.
- Numbers. Spend, platform-credited and server-side conversions, and cost per conversion per platform, against your logged prior weeks.
- The gap. The settled week's logged ratio, and whether it held.
- Flags. What tripped and what you checked.
- Next week. Planned changes, and anything you need from the clinic.
Explain once, in the first note, why the two counts differ.
The MCP specification says there "SHOULD always be a human in the loop with the ability to deny tool invocations." Reporting needs the same at the output end: a named reviewer, ideally not the person who ran the session, who checks that:
- every figure traces to a tool result, spot-checked in the platform, because assistants transpose digits and swap campaign rows;
- window dates and time zones match on both sides;
- nothing belongs to another client, including "benchmarks" that name one;
- causes read as hypotheses unless someone checked them;
- nothing from the never-list made it in.
Keep the approved note with the reviewer's name and date: that is your half of the audit trail.
What never goes in the report
HIPAA's minimum necessary standard asks for "reasonable efforts to limit protected health information to the minimum necessary" (45 CFR 164.502(b)). A weekly performance note needs none. Keep these out, even when the client asks:
- Names, emails, phone numbers or addresses of any lead or patient, including "a great lead this week."
- Form answers, intake answers, chat or call transcripts, and appointment notes.
- Screenshots of the CRM, booking tool or inbox.
- Click IDs, IP addresses, device or visitor IDs, and full URLs with query strings.
- Dates or times of individual conversions. A week is a report; "Tuesday at 4pm" is a person.
- Counts under the floor from either side, and any that can be backed out by subtraction.
- Another client's figures, named or recognizable.
The chat history is an artifact too: it holds everything the tools returned, under your AI vendor's retention terms. Section-by-section rules are in the PHI-free client reporting template.
Frequently asked questions
Can the assistant send the note to the client itself?
No. Give the reporting session no send tool. HighLevel's MCP server includes one that sends conversation messages, and an assistant holding a draft plus a send tool is one misread instruction from mailing the wrong clinic. The reviewer sends.
Which conversion number should lead the client note?
Both, labeled, every week. Judge results on the server-side count, where each person counts once; the platform figure explains what the platform sees and optimizes toward.
Should a small clinic get a weekly note at all?
Yes, but a shorter one. When most campaigns fall below the reporting minimum in a single week, send spend and pacing weekly and move conversion and cost-per-conversion commentary to a four-week note, where the counts are large enough to report.
What if the clinic asks which leads came from which campaign?
Answer it inside the dashboard, not in the note. Person-level questions belong in Curve Analyst, where the answer stays under the BAA. The weekly note carries counts; a lead's name, booking time or campaign path turns a count back into a person.
Can we run this routine on Claude Team or ChatGPT Business?
Yes. Curve MCP connects to both, and its output is aggregate by design. The rest of the workspace must be PHI-free, because neither plan can carry a BAA: Anthropic enables HIPAA readiness only on Enterprise, and OpenAI offers no BAA for ChatGPT Business. One CRM connector or pasted lead list breaks it.
Where to start
- Write the anomaly rules, tolerances, small-number floor and never-list into each client's report template this week.
- Split credentials so each client's session sees only that client, with every platform connection read-only.
- Start the ratio log this week, and run one client through all five steps by hand before templating the prompts.
- Check what feeds the ad accounts: run each client site through the free compliance scanner.
To see Curve Analyst's sent-versus-credited answers and Managed Accounts on your own client list, book a demo. We will show what the MCP server returns and withholds, and how your staff run this across every client. More is on the marketing agencies page.
Reviewed September 2026. Sources: the MCP specification, Google Ads and Meta Ads MCP documentation, Anthropic and OpenAI BAA documentation, the CMS cell-size policy and 45 CFR 164.502.
Related articles
Stay Compliant. Scale Confidently.
Join healthcare innovators who trust Curve for HIPAA-compliant ad tracking.Launch in hours, not months. Your growth stack, now HIPAA-safe.
Book a free tracking audit