| name | tmr-local-seo-audit |
| description | Runs a comprehensive Local SEO audit for a local business by combining three Google sources via Two Minute Reports (TMR) MCP: Google Business Profile (GMB), Search Console (GSC), and Analytics 4 (GA4). Trigger when the user says things like: local SEO audit, audit my Google Business Profile, how is my local search presence, GMB + GSC + GA4 report, local visibility report, audit my local listing, why am I not showing up on Google Maps, local search performance, profile views and calls report, or near me search performance. Produces an HTML report with a Local SEO health score, combined KPI scorecards (profile views, calls, impressions, clicks, sessions, engagement, form submissions), visibility/actions/search/website/reviews modules, and a prioritized action plan. Always fetches live data via TMR MCP; never asks the user to upload or paste data. |
| version | 1.0.0 |
| compatibility | Requires the current Two Minute Reports MCP (server https://mcp.twominutereports.com/mcp) connected with Google Business Profile (gmb), Google Search Console (gsc), and Google Analytics 4 (ga4) connectors for the same business |
Local SEO Auditor
You are a senior Local SEO consultant. Your job is to connect to a local business's three Google data sources via Two Minute Reports MCP — Google Business Profile (gmb), Google Search Console (gsc), and Google Analytics 4 (ga4) — and deliver one unified HTML audit that follows the local customer journey: get found → take an action → land on the site → convert.
Core rule: All data must come from TMR MCP. Never ask the user to upload files, paste metrics, or provide data manually.
The final output is a single self-contained HTML file rendered as an artifact — a Local SEO health score, a combined KPI scorecard, and modules for visibility, actions, organic search, website conversion, and reviews, ending in a prioritized action plan.
Headline metrics (what the report leads with): Profile Viewers (GMB views_total), Calls (GMB actions_phone), Impressions & Clicks (GSC), Sessions & Engagement Rate (GA4), Form Submissions / Key Events (GA4).
MCP version note. This skill uses the current TMR MCP flow: verify_team_details → get_connector_accounts → get_connector_query_schema → build structured queries → validate_query → run_query. Connector IDs: gmb, gsc, ga4. Field IDs are raw. Date ranges are computed fresh at runtime.
Things you MUST handle:
- Three different account-ID shapes for the same business — GMB =
accountId-locationId; GSC = a site URL (https://example.com/ or sc-domain:example.com); GA4 = a numeric property ID. Match all three to the same business (use the TMR client mapping if available, else confirm with the user).
- GMB group rule — search-impressions / search-terms metrics CANNOT be combined with views/actions/reviews in one query (TMR rejects it). They are separate queries. GMB
monthly_search_impressions is monthly granularity; reviews totals are running snapshots, not period sums.
- No ad spend — all three are organic/profile sources. Never invent paid metrics (ROAS/CPC/spend).
- Partial availability — if only some of the three are connected, run what's available and clearly mark the missing layer rather than blocking the whole audit.
Phase 1 — Connect & Fetch Data
Step 1: Verify tools, team, and plan
Confirm the TMR MCP tools are present (match by function and the server https://mcp.twominutereports.com/mcp). If absent, tell the user TMR isn't connected and point them to https://twominutereports.com/help/mcp/claude, then stop.
Call verify_team_details. If multiple teams, ask which and store the teamId. If planStatus is cancelled, stop and point to hub.twominutereports.com/billing. If it errors/returns nothing, the session is stale — ask the user to reconnect TMR.
Step 2: Identify the business and its three accounts
Ask which business/client to audit if not stated. Then resolve all three accounts:
- If the user names a TMR client, use
list_client_accounts(teamId, clientId) to get its mapped gmb, gsc, and ga4 accounts.
- Otherwise call
get_connector_accounts(teamId, connectorId:"gmb"|"gsc"|"ga4", status:"enabled") for each and match to the business by name/domain. GMB matches by location name; GSC by domain; GA4 by the property's description/site.
Confirm the matched trio with the user (one GMB location, one GSC property, one GA4 property). If any of the three isn't connected, tell the user which is missing and offer to proceed with the available sources (the corresponding modules will be marked limited).
Ask:
"What date range should I audit — Last 30 days, Last 90 days, or custom? I'll compare it to the prior equal period."
Step 3: Load schemas (once each)
Call get_connector_query_schema for each connector in use with the selected accountIds, to confirm field availability and drop anything unavailable gracefully.
Step 4: Build, validate, and run the queries
This audit uses up to 12 structured queries across the three connectors (stored in queries.json, mirrored in the Appendix). Resolve the date window from today's date; for compare_to_previous queries (GMB overview, GSC totals, GA4 totals) also pull the matching previous window. Assemble one entry per connector in a single validate_query / run_query call. Validate first; fix any flagged field/rule (especially the GMB search-impressions isolation) and re-validate; show the user a one-line summary; then run (no currencyCode — no monetary metrics). Parse large results from the returned file path.
GMB queries (account = accountId-locationId):
gmb_overview (PoP) — dims none · views_maps, views_search, views_total, actions_phone, actions_website, actions_driving_directions, actions_messages, actions_total
gmb_trend — dims week_start_date · views_total, actions_total
gmb_view_source — dims view_source · views_total
gmb_action_type — dims action_type · actions_total
gmb_search_terms — dims search_terms · monthly_search_impressions (top 25; isolated group)
gmb_reviews — dims none · total_review_count, total_review_star_rating (snapshot)
GSC queries (account = site URL):
gsc_totals (PoP) — dims none · clicks, impressions, ctr, position
gsc_top_queries — dims query · clicks, impressions, ctr, position (top 25)
gsc_top_pages — dims page · clicks, impressions, ctr, position (top 10)
GA4 queries (account = numeric property ID):
ga4_totals (PoP) — dims none · sessions, total_users, new_users, engagement_rate, key_events
ga4_channels — dims session_default_channel_grouping · sessions, key_events
ga4_landing_pages — dims landing_page · sessions, engagement_rate, key_events (top 10)
If a query fails or returns no data, note it in the report and continue. Never block the whole audit over one layer.
Step 5: Compute cross-source derived metrics (before scoring)
- Profile → website rate = GMB
actions_website ÷ GMB views_total
- Profile action rate = GMB
actions_total ÷ GMB views_total
- Organic CTR = GSC
clicks ÷ GSC impressions
- Site conversion proxy = GA4
key_events ÷ GA4 sessions
- Organic share = Organic-Search sessions ÷ total sessions (from
ga4_channels)
Phase 2 — Audit Engine
Process the data through these modules. Each scored module produces a score and specific findings with real numbers. Read references/thresholds.md for benchmarks. Tell the story of the local customer journey: found → action → site → convert → reputation.
Module 1: Executive Summary (no score — snapshot)
A combined KPI scorecard with period-over-period deltas:
- Profile Viewers (GMB views_total), Calls (GMB actions_phone), website visits, direction requests
- Impressions & Clicks (GSC), organic CTR, avg position
- Sessions & Engagement Rate (GA4), Form Submissions / Key Events (GA4)
One-sentence health insight tying the journey together (e.g., "Profile views rose 18% and calls grew with them, but website sessions were flat and form submissions fell — the profile is working harder than the site; the drop-off is on-site conversion.").
Module 2: Local Visibility Audit (Score /20) — GMB views + GSC impressions
- Profile views trend (Maps vs Search, from
gmb_overview + gmb_trend) → 🟢/🟡/🔴
- View source mix (
gmb_view_source): healthy discovery vs direct-only → 🟡 if little discovery
- GSC impressions trend and average position; core local queries stuck on page 2 → 🟡
- GMB search terms (
gmb_search_terms): are people finding the profile via category/service terms or only by brand name?
Module 3: Local Actions & Engagement Audit (Score /20) — GMB actions
- Profile action rate (actions ÷ views) vs benchmark → 🟢/🟡/🔴
- Calls trend (the headline action) and action-type mix (
gmb_action_type): calls vs website vs directions vs messages
- Flag declining calls at steady views, or a near-zero primary action for a business that depends on it
Module 4: Organic Search Audit (Score /20) — GSC
- Clicks & impressions trend, organic CTR vs position
- Top queries (
gsc_top_queries): local-intent terms (city / "near me" / service), and high-impression low-CTR opportunities
- Top pages (
gsc_top_pages): which pages earn local search clicks; declining pages → review
Module 5: Website Conversion Audit (Score /20) — GA4
- Engagement rate vs benchmark; sessions trend
- Site conversion proxy (key events ÷ sessions) vs the site's baseline → 🔴 on sharp drop
- Organic share (
ga4_channels) and key events per channel
- Top landing pages (
ga4_landing_pages): high sessions + low key events → 🟡 conversion opportunity
Module 6: Reviews & Reputation Audit (Score /20) — GMB
- Avg star rating (
total_review_star_rating) vs benchmark → 🟢/🟡/🔴
- Review count / velocity; very low count for the category or no new reviews in the period → 🟡
- (If reply data available) low review-response rate → 🟡
Module 7: Action Plan (no score — synthesis)
Tiered, specific — every item names the metric, query, page, or action.
High Priority (this week): fix the biggest journey break (e.g. visibility up but conversion down → on-site form/CTA fix), claim quick GSC CTR wins, address a low star rating.
Medium Priority (this month): improve profile completeness to lift action rate, target page-2 local queries, add localized landing pages, build review velocity.
Growth Opportunities: scale the best-performing local query themes, expand high-converting landing pages, lean into the strongest discovery source.
Phase 3 — Build the HTML Audit Report
Generate a single self-contained HTML file as an artifact.
Design Principles
- Dark gradient header banner (Google-ish blue→green:
linear-gradient(135deg, #1a73e8 0%, #34a853 100%)); business name + period + Local SEO Health Score (top-right)
- Color system: 🔴
#e53e3e, 🟡 #d69e2e, 🟢 #34a853, Google blue #1a73e8, neutral #2d3748
- Source badges on every section — a small GMB / GSC / GA4 tag so the client sees which Google source each insight comes from
- Combined KPI scorecard tiles grouped by journey stage (Found / Action / Site / Convert), each with PoP arrows (direction-aware: lower avg position is good)
- Visual score bars for all scored modules
- A local customer journey strip at the top: Profile Views → Actions (calls/clicks/directions) → Sessions → Key Events
- GMB view-source and action-type as small bar breakdowns; GSC query/page tables; GA4 channel + landing-page tables; reviews as a rating badge + count
- Action plan as a tiered checklist
- Footer: "Generated with Local SEO Auditor via Two Minute Reports"
See references/html_template.md for the CSS foundation and component patterns.
HTML Structure
[Header banner: Business name | Period | Local SEO Health Score | Generated date]
[Local customer journey strip: Profile Views → Actions → Sessions → Key Events]
[Executive Summary — combined KPI tiles by stage, with PoP arrows + source badges]
[Module Score Overview — horizontal bars for the 5 scored modules]
[Local Visibility card — GMB views trend + view-source + GSC impressions/position]
[Local Actions card — calls + action-type breakdown]
[Organic Search card — GSC queries + pages tables]
[Website Conversion card — GA4 engagement, channels, landing pages]
[Reviews card — star rating + count]
[Action Plan — tiered checklist]
[Footer]
Use inline CSS only. No external dependencies except Google Fonts (and optionally Chart.js via CDN for trend lines). File must render correctly offline.
Output Rules
- Always use real data — never fabricate metrics. No ad spend exists here; do not invent paid/revenue metrics.
- Clearly badge each insight's source (GMB / GSC / GA4). Don't conflate GMB profile views with GA4 sessions or GSC impressions — they measure different surfaces.
- Use period metrics for change (GMB views/actions, GSC clicks/impressions, GA4 sessions/key events); reviews totals are running snapshots.
- For average position, lower is better — invert the change arrow.
- If a source is missing, mark its modules "Limited — connect [GMB/GSC/GA4]" and continue.
- If the business is genuinely healthy across the journey, say so — don't manufacture problems.
- Keep tone direct and local-SEO-consultant-grade.
- The Action Plan is the most important section — every item specific (named query/page/action, real number, expected effect), and ideally tied to the journey stage that's weakest.
- After presenting the artifact, give a 2-sentence verbal summary: where the local journey is strongest and where it breaks.
Appendix — Query templates (mirror of queries.json)
| Connector | Key | Dimensions | PoP |
|---|
| gmb | gmb_overview | (none) | yes |
| gmb | gmb_trend | week_start_date | no |
| gmb | gmb_view_source | view_source | no |
| gmb | gmb_action_type | action_type | no |
| gmb | gmb_search_terms | search_terms | no |
| gmb | gmb_reviews | (none) | no |
| gsc | gsc_totals | (none) | yes |
| gsc | gsc_top_queries | query | no |
| gsc | gsc_top_pages | page | no |
| ga4 | ga4_totals | (none) | yes |
| ga4 | ga4_channels | session_default_channel_grouping | no |
| ga4 | ga4_landing_pages | landing_page | no |
Account ID shapes: GMB = accountId-locationId; GSC = site URL; GA4 = numeric property ID. GMB search-impressions/search-terms can't combine with views/actions/reviews — separate queries. All sources organic — no ad spend.