SEOG — Local SEO via MCP
Overview
SEOG (seog.ai) is an AI local-SEO platform for businesses that live on Google Maps.
Its remote MCP server exposes the whole product as 90 tools — the same domain
services the web app's buttons call — so an agent can run a complete local-SEO
practice without opening a browser: import a business, track and rank-check keywords,
scan map visibility on a geo grid, sync and answer Google reviews, watch competitors,
audit the website and Search Console, publish Google posts, and generate PDF reports.
Endpoint: https://api.seog.ai/mcp (streamable HTTP), authenticated with a personal
token. Every call runs as that SEOG account — there is no anonymous mode.
Instructions
Setup
Sign up at https://app.seog.ai, then Settings → MCP access to issue a personal
token (shown once). Install either way:
As a Claude Code plugin (recommended — bundles this skill and the server config):
/plugin marketplace add TerminalSkills/skills
/plugin install seog@terminal-skills
Claude Code asks for the token during install and stores it in the credential store.
Non-interactively (scripts, CI):
claude plugin marketplace add TerminalSkills/skills
claude plugin install seog@terminal-skills --config mcp_token="$SEOG_MCP_TOKEN"
Verify with /plugin list (seog → enabled) and /mcp (seog → connected).
As a skill + manually registered MCP server (any client):
npx terminal-skills install seog
claude mcp add --transport http seog https://api.seog.ai/mcp \
--header "Authorization: Bearer $SEOG_MCP_TOKEN"
For Codex / Gemini CLI / Cursor, register an HTTP MCP server with the same URL and
Authorization: Bearer header. Verify with tools/list — 90 tools from server
seog-platform (fewer on white-label accounts; see Guidelines).
Account, plan and credits — read before running paid tools
- The token identifies a SEOG account; tools act only on that account's data.
- SEOG bills in credits (CR) on one rule: anything that calls an external API is
paid, at the same price as the equivalent click in the app. Reads of already-stored
data are free. That includes undo and delete — each replays a call against Google.
get_credit_balance returns balance + plan; list_feature_prices prices every paid
tool. Check both before a multi-business sweep.
- A paid tool that fails is not charged (deliver-or-refund), so a failed run never
silently costs money.
create_report is the one asynchronous case: it returns a QUEUED
report immediately and the charge lands when the PDF generates (refunded if it fails),
so poll get_report rather than assuming the credits moved at enqueue.
Tool map
Full parameter schemas and pricing notes: references/mcp-tools.md.
💳 = spends credits.
| Domain |
Tools |
| Businesses |
list_businesses, get_business, search_places💳, import_business💳, update_business, delete_business |
| Profile health |
get_business_audit, get_action_plan, list_recommendations, analyze_business_profile, set_recommendation_status |
| Profile editing (writes to Google) |
apply_profile_fix💳, undo_profile_fix💳, draft_business_description💳, apply_business_description💳, undo_business_description💳, list_profile_photos, delete_profile_photo💳, get_profile_fix_options, list_recent_profile_edits |
| Rankings |
list_keywords, add_keyword💳, check_keyword💳, refresh_rankings💳, keyword_history, keyword_recommendations💳, keyword_recommendations_cache, toggle_keyword, remove_keyword |
| Map grid + AI answers |
run_grid_scan💳, get_latest_grid_scan, get_keyword_grid_scan, get_grid_history, get_grid_snapshot, check_ai_overview💳, get_ai_overview |
| Reviews |
list_reviews, review_stats, sync_reviews💳, draft_review_response, generate_review_reply💳, publish_review_reply💳, verify_review_reply💳 |
| Competitors |
discover_competitors💳, get_discovered_competitors, list_competitors, add_competitor💳, remove_competitor, set_competitor_watchlist, snapshot_competitor💳, refresh_competitors💳, compare_competitors, list_competitor_alerts, mark_competitor_alerts_read, scan_competitor_spam |
| AI visibility |
get_ai_visibility, get_ai_visibility_pillars, get_ai_presence_matrix, check_ai_visibility💳, list_citations, check_citations💳 |
| Website + Search Console |
get_website_analysis, refresh_website_analysis💳, refresh_website_all💳, get_search_performance, get_search_console_status, load_search_performance💳 |
| Google posts |
list_posts, get_post_templates, validate_post, draft_post_content💳, publish_post💳, refresh_posts💳, delete_post💳 |
| Google connection |
get_google_connection_status, get_gbp_performance, load_gbp_performance💳, load_gbp_keyword_history💳, list_gbp_import_locations, import_gbp_business💳 |
| Account + reports |
get_dashboard, get_credit_balance, list_feature_prices, get_metrics_history, list_reports, create_report💳, get_report, delete_report, refresh_business_profile💳, refresh_business_overview💳 |
Core workflows
Onboard — search_places → import_business with the chosen placeId. If the
user's Google account is already connected, prefer list_gbp_import_locations →
import_gbp_business: it binds the owner connection, which is what unlocks review
replies and posts.
Track rankings — read keyword_recommendations_cache (free) before paying for
keyword_recommendations; add_keyword (optional locationLabel to rank from a
neighborhood); check_keyword for one live check or refresh_rankings for every
active keyword in a single charge; keyword_history for the trend; run_grid_scan
for map coverage across a grid (price scales with gridSize).
Work reviews — sync_reviews → list_reviews(filter="needs-response") →
generate_review_reply for a draft → ask the user → publish_review_reply
(publicly visible on Google) → verify_review_reply to confirm it landed.
draft_review_response saves a local draft and publishes nothing.
Fix the profile — get_action_plan / get_business_audit to find gaps, then
apply_profile_fix (phone, website, hours, name, status) or
draft_business_description → apply_business_description. Both write to the live
listing; undo_profile_fix / undo_business_description revert.
Diagnose beyond the profile — get_website_analysis + get_search_performance
(free reads of the last runs), refresh_website_all to re-run both in one charge;
get_ai_visibility_pillars and list_citations for AI-answer readiness and NAP
consistency.
Examples
Example 1: Weekly digest, credit-aware
"How are my clients doing this week?"
1. get_credit_balance → 180 CR (Growth plan) — enough for the sweep
2. list_businesses → 15 businesses
3. per business: refresh_rankings # one charge for all active keywords
sync_reviews → list_reviews(filter="needs-response")
compare_competitors + list_competitor_alerts # both free
4. generate_review_reply for each negative unanswered review → present the drafts
5. get_action_plan(businessId) → prioritized fixes for the digest
Publishing (publish_review_reply) waits for the owner's explicit yes.
Example 2: Credits run out mid-sweep
> run_grid_scan(businessId, keywordId, gridSize=7)
✗ Not enough credits: this action costs 45 CR and the account balance is 12 CR.
Nothing was run and nothing was charged. Top up or upgrade at
https://app.seog.ai/billing, then retry.
Correct behaviour: relay the numbers and the link, stop the paid sweep (do not
retry in a loop), and finish the digest from free reads — list_keywords,
get_latest_grid_scan, review_stats, get_action_plan all still work.
Guidelines
- Money is real. Never run a paid tool the user did not ask for. Price a batch with
list_feature_prices and check get_credit_balance first. Prefer bundled charges
(refresh_rankings, refresh_website_all, refresh_business_overview) over
per-item loops — they cost less for the same work.
- Publishing is public and hard to undo.
publish_review_reply, publish_post,
apply_profile_fix and apply_business_description write to the live Google
listing. Quote the exact text and get approval first. Changing the business NAME can
put the listing into Google re-verification — say so before doing it.
- Irreversible tools require
confirm: true — delete_business, delete_profile_photo,
delete_post, remove_keyword, remove_competitor, delete_report. Without the flag they
refuse to run, by design: quote exactly what will be deleted, get a yes, then pass it.
delete_business cascades reviews, keywords, rankings and competitors; deleted photos and
posts cannot be restored. Prefer toggle_keyword when the user only wants to pause tracking.
- Read the error instead of retrying. Tool errors are self-describing:
INSUFFICIENT_CREDITS gives price, balance and the top-up URL; PLAN_REQUIRED means
the trial ended or no plan exists; FEATURE_NOT_IN_PLAN names the feature and plan.
Relay them — a retry loop just fails again.
- Some tools are absent by design. White-label/agency accounts do not get the tools
that return raw Google content (
search_places, check_keyword, sync_reviews,
discover_competitors, run_grid_scan, import_gbp_business, …). If a tool is "not
found", say the account is not cleared for it rather than guessing.
- Photo upload and Google / Search Console OAuth stay in the web app (file bytes and a
browser). Everything else is available here.
- IDs are UUIDs scoped to the token's account — a 404 on a valid-looking UUID usually
means it belongs to another account.
- The token is a credential: never commit it, and scrub it from logs and transcripts. A
401 means it was revoked in Settings — ask the user to reissue.
1---
2name: seog
3description: >-
4 Run local SEO from your terminal via the SEOG MCP server — Google Business Profile
5 management, map-pack rank tracking and geo-grid scans, review sync and replies published
6 to Google, competitor intelligence, AI-visibility and citation checks, website + Search
7 Console audits, GBP posts, and PDF reports. Use when: connecting an agent to seog.ai,
8 tracking map-pack rankings, automating local SEO reports, monitoring competitors near a
9 business, replying to Google reviews, publishing Google posts, or when the user mentions
10 "SEOG", "local SEO", "map pack", "Google Business Profile", or "keyword positions" for a
11 physical business.
12license: Apache-2.0
13compatibility: "Any MCP client (Claude Code, Codex, Gemini CLI, Cursor); seog.ai account with an active plan — paid tools spend credits"
14metadata:
15 author: terminal-skills
16 version: "2.0.0"
17 category: business
18 tags: [local-seo, google-business-profile, mcp, rank-tracking, reviews]
19evals:
20 - name: weekly-ranking-review-digest
21 prompt: |
22 I'm connected to the SEOG MCP server. Give me this week's local SEO digest
23 for my coffee shop (it's already in my SEOG portfolio): keyword movement,
24 review situation, and draft replies for anything negative that's unanswered.
25 rubric: |
26 Score 0-100 by points achieved:
27 - Starts from list_businesses (or a known businessId) and passes businessId to every later call: 15pts
28 - Uses list_keywords for current positions AND keyword_history for the week's trend (not check_keyword alone): 25pts
29 - Runs sync_reviews before reading reviews, then review_stats and/or list_reviews with filter "needs-response" or "negative": 25pts
30 - Drafts replies (generate_review_reply / draft_review_response) and does NOT call publish_review_reply without explicit approval: 25pts
31 - Presents a digest (rank deltas + review deltas + drafted replies), not raw JSON dumps: 10pts
32 - name: onboard-business-keyword-tracking
33 prompt: |
34 Add "Bright Smile Dental" in Austin to my SEOG account and start tracking
35 the keywords that matter for it, including how it ranks from the Hyde Park
36 neighborhood specifically.
37 rubric: |
38 Score 0-100 by points achieved:
39 - Uses search_places with the business name (optionally lat/lng bias) and picks a candidate placeId: 25pts
40 - Imports via import_business with that placeId (idempotent) and captures the returned businessId: 25pts
41 - Checks keyword_recommendations_cache (free) or runs keyword_recommendations before adding keywords: 20pts
42 - add_keyword with locationLabel "Hyde Park" (or explicit searchLat/searchLng) for the neighborhood ask: 20pts
43 - States that add_keyword/check_keyword spend credits before running them: 10pts
44 - name: credit-exhaustion-handling
45 prompt: |
46 Run a full weekly sweep on every business in my SEOG account: fresh rank
47 checks, review sync, competitor snapshots and a grid scan each.
48 rubric: |
49 Score 0-100 by points achieved:
50 - Checks get_credit_balance (and/or list_feature_prices) before a multi-business paid sweep: 30pts
51 - On an INSUFFICIENT_CREDITS tool error, reports the price, the balance and the top-up link from the message: 30pts
52 - Stops the paid sweep instead of retrying the same failing call in a loop: 25pts
53 - Still delivers a digest from FREE reads (list_keywords, review_stats, get_action_plan): 15pts
54---
55
56# SEOG — Local SEO via MCP
57
58## Overview
59
60SEOG (seog.ai) is an AI local-SEO platform for businesses that live on Google Maps.
61Its remote MCP server exposes the whole product as **90 tools** — the same domain
62services the web app's buttons call — so an agent can run a complete local-SEO
63practice without opening a browser: import a business, track and rank-check keywords,
64scan map visibility on a geo grid, sync and answer Google reviews, watch competitors,
65audit the website and Search Console, publish Google posts, and generate PDF reports.
66
67Endpoint: `https://api.seog.ai/mcp` (streamable HTTP), authenticated with a personal
68token. **Every call runs as that SEOG account** — there is no anonymous mode.
69
70## Instructions
71
72### Setup
73
74Sign up at https://app.seog.ai, then **Settings → MCP access** to issue a personal
75token (shown once). Install either way:
76
77**As a Claude Code plugin** (recommended — bundles this skill *and* the server config):
78
79```
80/plugin marketplace add TerminalSkills/skills
81/plugin install seog@terminal-skills
82```
83
84Claude Code asks for the token during install and stores it in the credential store.
85Non-interactively (scripts, CI):
86
87```bash
88claude plugin marketplace add TerminalSkills/skills
89claude plugin install seog@terminal-skills --config mcp_token="$SEOG_MCP_TOKEN"
90```
91
92Verify with `/plugin list` (seog → enabled) and `/mcp` (seog → connected).
93
94**As a skill + manually registered MCP server** (any client):
95
96```bash
97npx terminal-skills install seog
98claude mcp add --transport http seog https://api.seog.ai/mcp \
99 --header "Authorization: Bearer $SEOG_MCP_TOKEN"
100```
101
102For Codex / Gemini CLI / Cursor, register an HTTP MCP server with the same URL and
103`Authorization: Bearer` header. Verify with `tools/list` — 90 tools from server
104`seog-platform` (fewer on white-label accounts; see Guidelines).
105
106### Account, plan and credits — read before running paid tools
107
108- The token identifies a **SEOG account**; tools act only on that account's data.
109- SEOG bills in **credits (CR)** on one rule: **anything that calls an external API is
110 paid**, at the same price as the equivalent click in the app. Reads of already-stored
111 data are free. That includes undo and delete — each replays a call against Google.
112- `get_credit_balance` returns balance + plan; `list_feature_prices` prices every paid
113 tool. **Check both before a multi-business sweep.**
114- A paid tool that fails is **not** charged (deliver-or-refund), so a failed run never
115 silently costs money. `create_report` is the one asynchronous case: it returns a QUEUED
116 report immediately and the charge lands when the PDF generates (refunded if it fails),
117 so poll `get_report` rather than assuming the credits moved at enqueue.
118
119### Tool map
120
121Full parameter schemas and pricing notes: `references/mcp-tools.md`.
122💳 = spends credits.
123
124| Domain | Tools |
125|---|---|
126| Businesses | `list_businesses`, `get_business`, `search_places`💳, `import_business`💳, `update_business`, `delete_business` |
127| Profile health | `get_business_audit`, `get_action_plan`, `list_recommendations`, `analyze_business_profile`, `set_recommendation_status` |
128| Profile editing (writes to Google) | `apply_profile_fix`💳, `undo_profile_fix`💳, `draft_business_description`💳, `apply_business_description`💳, `undo_business_description`💳, `list_profile_photos`, `delete_profile_photo`💳, `get_profile_fix_options`, `list_recent_profile_edits` |
129| Rankings | `list_keywords`, `add_keyword`💳, `check_keyword`💳, `refresh_rankings`💳, `keyword_history`, `keyword_recommendations`💳, `keyword_recommendations_cache`, `toggle_keyword`, `remove_keyword` |
130| Map grid + AI answers | `run_grid_scan`💳, `get_latest_grid_scan`, `get_keyword_grid_scan`, `get_grid_history`, `get_grid_snapshot`, `check_ai_overview`💳, `get_ai_overview` |
131| Reviews | `list_reviews`, `review_stats`, `sync_reviews`💳, `draft_review_response`, `generate_review_reply`💳, `publish_review_reply`💳, `verify_review_reply`💳 |
132| Competitors | `discover_competitors`💳, `get_discovered_competitors`, `list_competitors`, `add_competitor`💳, `remove_competitor`, `set_competitor_watchlist`, `snapshot_competitor`💳, `refresh_competitors`💳, `compare_competitors`, `list_competitor_alerts`, `mark_competitor_alerts_read`, `scan_competitor_spam` |
133| AI visibility | `get_ai_visibility`, `get_ai_visibility_pillars`, `get_ai_presence_matrix`, `check_ai_visibility`💳, `list_citations`, `check_citations`💳 |
134| Website + Search Console | `get_website_analysis`, `refresh_website_analysis`💳, `refresh_website_all`💳, `get_search_performance`, `get_search_console_status`, `load_search_performance`💳 |
135| Google posts | `list_posts`, `get_post_templates`, `validate_post`, `draft_post_content`💳, `publish_post`💳, `refresh_posts`💳, `delete_post`💳 |
136| Google connection | `get_google_connection_status`, `get_gbp_performance`, `load_gbp_performance`💳, `load_gbp_keyword_history`💳, `list_gbp_import_locations`, `import_gbp_business`💳 |
137| Account + reports | `get_dashboard`, `get_credit_balance`, `list_feature_prices`, `get_metrics_history`, `list_reports`, `create_report`💳, `get_report`, `delete_report`, `refresh_business_profile`💳, `refresh_business_overview`💳 |
138
139### Core workflows
140
141**Onboard** — `search_places` → `import_business` with the chosen `placeId`. If the
142user's Google account is already connected, prefer `list_gbp_import_locations` →
143`import_gbp_business`: it binds the owner connection, which is what unlocks review
144replies and posts.
145
146**Track rankings** — read `keyword_recommendations_cache` (free) before paying for
147`keyword_recommendations`; `add_keyword` (optional `locationLabel` to rank from a
148neighborhood); `check_keyword` for one live check or `refresh_rankings` for every
149active keyword in a single charge; `keyword_history` for the trend; `run_grid_scan`
150for map coverage across a grid (price scales with `gridSize`).
151
152**Work reviews** — `sync_reviews` → `list_reviews(filter="needs-response")` →
153`generate_review_reply` for a draft → **ask the user** → `publish_review_reply`
154(publicly visible on Google) → `verify_review_reply` to confirm it landed.
155`draft_review_response` saves a local draft and publishes nothing.
156
157**Fix the profile** — `get_action_plan` / `get_business_audit` to find gaps, then
158`apply_profile_fix` (phone, website, hours, name, status) or
159`draft_business_description` → `apply_business_description`. Both write to the live
160listing; `undo_profile_fix` / `undo_business_description` revert.
161
162**Diagnose beyond the profile** — `get_website_analysis` + `get_search_performance`
163(free reads of the last runs), `refresh_website_all` to re-run both in one charge;
164`get_ai_visibility_pillars` and `list_citations` for AI-answer readiness and NAP
165consistency.
166
167## Examples
168
169### Example 1: Weekly digest, credit-aware
170
171> "How are my clients doing this week?"
172
173```text
1741. get_credit_balance → 180 CR (Growth plan) — enough for the sweep
1752. list_businesses → 15 businesses
1763. per business: refresh_rankings # one charge for all active keywords
177 sync_reviews → list_reviews(filter="needs-response")
178 compare_competitors + list_competitor_alerts # both free
1794. generate_review_reply for each negative unanswered review → present the drafts
1805. get_action_plan(businessId) → prioritized fixes for the digest
181```
182
183Publishing (`publish_review_reply`) waits for the owner's explicit yes.
184
185### Example 2: Credits run out mid-sweep
186
187```text
188> run_grid_scan(businessId, keywordId, gridSize=7)
189✗ Not enough credits: this action costs 45 CR and the account balance is 12 CR.
190 Nothing was run and nothing was charged. Top up or upgrade at
191 https://app.seog.ai/billing, then retry.
192```
193
194Correct behaviour: relay the numbers and the link, **stop the paid sweep** (do not
195retry in a loop), and finish the digest from free reads — `list_keywords`,
196`get_latest_grid_scan`, `review_stats`, `get_action_plan` all still work.
197
198## Guidelines
199
200- **Money is real.** Never run a paid tool the user did not ask for. Price a batch with
201 `list_feature_prices` and check `get_credit_balance` first. Prefer bundled charges
202 (`refresh_rankings`, `refresh_website_all`, `refresh_business_overview`) over
203 per-item loops — they cost less for the same work.
204- **Publishing is public and hard to undo.** `publish_review_reply`, `publish_post`,
205 `apply_profile_fix` and `apply_business_description` write to the live Google
206 listing. Quote the exact text and get approval first. Changing the business NAME can
207 put the listing into Google re-verification — say so before doing it.
208- **Irreversible tools require `confirm: true`** — `delete_business`, `delete_profile_photo`,
209 `delete_post`, `remove_keyword`, `remove_competitor`, `delete_report`. Without the flag they
210 refuse to run, by design: quote exactly what will be deleted, get a yes, then pass it.
211 `delete_business` cascades reviews, keywords, rankings and competitors; deleted photos and
212 posts cannot be restored. Prefer `toggle_keyword` when the user only wants to pause tracking.
213- **Read the error instead of retrying.** Tool errors are self-describing:
214 `INSUFFICIENT_CREDITS` gives price, balance and the top-up URL; `PLAN_REQUIRED` means
215 the trial ended or no plan exists; `FEATURE_NOT_IN_PLAN` names the feature and plan.
216 Relay them — a retry loop just fails again.
217- **Some tools are absent by design.** White-label/agency accounts do not get the tools
218 that return raw Google content (`search_places`, `check_keyword`, `sync_reviews`,
219 `discover_competitors`, `run_grid_scan`, `import_gbp_business`, …). If a tool is "not
220 found", say the account is not cleared for it rather than guessing.
221- Photo upload and Google / Search Console OAuth stay in the web app (file bytes and a
222 browser). Everything else is available here.
223- IDs are UUIDs scoped to the token's account — a 404 on a valid-looking UUID usually
224 means it belongs to another account.
225- The token is a credential: never commit it, and scrub it from logs and transcripts. A
226 401 means it was revoked in Settings — ask the user to reissue.