{"name":"io.github.houtini-ai/seo-audit-console","slug":"houtini-ai-seo-audit-console","title":null,"description":"Technical SEO in Claude: GSC + crawl + DataForSEO - audit, market sizing, content recon.","url":"https://mcp.market/server/houtini-ai-seo-audit-console","rating":null,"grade":"A","score":85,"certified":false,"status":"active","category":"seo","tags":["seo","scraping"],"presence":{"score":36,"stars":21,"forks":1,"downloads_week":51,"last_push_at":"2026-09-21T20:27:27.000Z","license":"Apache-2.0"},"uptime":null,"claimed":false,"transport":"npm","callable_via_gateway":false,"default_price_micros":0,"repository":"https://github.com/houtini-ai/seo-audit","website":null,"version":"0.8.0","remotes":[],"packages":[{"registryType":"npm","identifier":"@houtini/seo-audit-console","version":"0.8.0","transport":{"type":"stdio"},"environmentVariables":[{"description":"Path to the Google service-account JSON key with Search Console access.","isRequired":true,"format":"string","name":"GOOGLE_APPLICATION_CREDENTIALS"},{"description":"Directory for per-property SQLite databases and reports. Defaults to ~/Documents/seo-audit-console.","format":"string","name":"SAC_DATA_DIR"},{"description":"DataForSEO API username (optional, enables SERP/keyword/domain/market/recon checks).","format":"string","name":"DATAFORSEO_USERNAME"},{"description":"DataForSEO API password (optional).","format":"string","isSecret":true,"name":"DATAFORSEO_PASSWORD"},{"description":"TTL for the DataForSEO response cache, in days. Default 7.","format":"string","name":"DATAFORSEO_CACHE_DAYS"},{"description":"Firecrawl API key (optional). Lets content recon scrape competitor pages. Get one at https://firecrawl.link/2d1PLD8","format":"string","isSecret":true,"name":"FIRECRAWL_API_KEY"},{"description":"Supadata API key (optional). Lets content recon transcribe the ranking videos (YouTube/TikTok/X).","format":"string","isSecret":true,"name":"SUPADATA_API_KEY"},{"description":"Majestic API key (optional). Enriches link_intersect with Trust Flow + Topical Trust Flow and re-sorts prospects by real authority.","format":"string","isSecret":true,"name":"MAJESTIC_API_KEY"},{"description":"TTL for the Majestic response cache, in days. Default 30.","format":"string","name":"MAJESTIC_CACHE_DAYS"}]}],"tools":[{"name":"check_agent_readiness","description":"Probe a site for AI-agent readiness — the signals agents use to discover and use it: robots.txt AI-bot rules + Content Signals, sitemap, Link headers, llms.txt, agents.md, Markdown content negotiation, Web Bot Auth, MCP server card, Agent Skills, API Catalog, OAuth discovery. Returns a 0–100 score, a level (Basic web presence → Agent-native), and a per-check checklist with copy-paste fixes. Live H","write_action":false,"price_micros":0,"input_schema":null},{"name":"check_crawl_status","description":"Poll a crawl job by id, or omit to list recent jobs.","write_action":false,"price_micros":0,"input_schema":null},{"name":"check_sync_status","description":"Poll a sync job by id, or omit to list recent jobs.","write_action":false,"price_micros":0,"input_schema":null},{"name":"competitors_domain","description":"[Paid: Labs, cheap, cached 20d | Use for: naming the real competitor set - the opening move of competitive work] Discover the domains competing with a target for the same organic keywords (ranked by keyword overlap), with intersection counts and organic traffic estimates. The seed list for content-gap analysis (feed these into page_intersection). Labs call, cached 20 days. Pass location + language","write_action":false,"price_micros":0,"input_schema":null},{"name":"composition_cookbook","description":"The full data-surface map (every source: grain, dimensions, join keys, freshness, cost) plus worked multi-source recipes and novel combinations, in this server's actual tool and table names. Static — no API calls, no cost. Call this BEFORE planning any complex question that spans more than one data source.","write_action":false,"price_micros":0,"input_schema":null},{"name":"content_opportunities","description":"The content marketer's report, composed entirely from stored data - NO paid calls. Four sections: WRITE NEXT (new pages proposed from queries you already earn impressions for but have no winning page - suggest_pages), REFRESH NOW (pages that lost 20%+ of their clicks vs the prior period - content decay), REWRITE SNIPPETS (page-1 rankings earning far below expected CTR - title/meta rewrites, the fa","write_action":false,"price_micros":0,"input_schema":null},{"name":"data_location","description":"No args: report the folder where per-property crawl/audit databases are saved. With `path`: set it (persisted to ~/.seo-audit-console.json) — restart Claude Desktop to apply. Default is your Documents folder; the SAC_DATA_DIR env var overrides everything.","write_action":false,"price_micros":0,"input_schema":null},{"name":"data_storage","description":"","write_action":false,"price_micros":0,"input_schema":null},{"name":"detect_changes","description":"Compare the two most recent crawls and report what changed per URL — status code, indexability, canonical, robots/noindex, title, meta, H1, schema, large content swings — each classified by severity (critical → info). This is the monitor: run refresh_property on different days to build history, then this surfaces regressions (a page that went noindex, a canonical that flipped, a 200 that became a ","write_action":false,"price_micros":0,"input_schema":null},{"name":"domain_visibility","description":"[Paid: Labs, cheap, cached 20d | Use for: visibility-over-time trend, any domain, no GSC needed] Monthly organic visibility for ANY domain or subdomain — no Search Console access needed: ranking-keyword totals, position distribution (1–3 / 4–10 / 11–20 / 21–100) and estimated traffic value (ETV) per month, plus a trend verdict. The Semrush-style \"organic overview / visibility over time\" for you or","write_action":false,"price_micros":0,"input_schema":null},{"name":"draft_content","description":"Assemble a GROUNDED writing brief for a page so YOU (the assistant) can draft the fix — no bundled LLM. Returns the ranking-query gap, the page's OWN passages as voice exemplars (match tone/pace/lexicon), and the most query-relevant existing passages (selected by the reranker) as facts to ground in. Use it on a weak-passage-answer / not-front-loaded page to write a self-contained answer passage in","write_action":false,"price_micros":0,"input_schema":null},{"name":"export_report","description":"Write a self-contained, interactive dashboard HTML for a property (all data + charts inlined) to the reports folder, and return the file path. Open it in any browser or send it to a client — no server, no MCP-App host support needed. Run refresh_property (+ run_audit for findings) first.","write_action":true,"price_micros":0,"input_schema":null},{"name":"fix_finding","description":"Turn an audit finding into a concrete, paste-ready remediation: JSON-LD for missing structured data, a 301 rule for broken / redirecting internal links, or internal-link suggestions for orphan / striking-distance pages. Other checks return their deterministic fix guidance. Dry-run — returns artifacts, never writes to your site. Identify the finding by findingId (from run_audit) or by check + url.","write_action":false,"price_micros":0,"input_schema":null},{"name":"inspect_urls","description":"Update just the GSC URL Inspection data (coverage, indexing, Google-vs-declared canonical, last crawl) for top URLs into url_inspection. Quota-limited — samples top pages by clicks. Async job. For a full refresh use refresh_property. Grain: one row per inspected URL. Joins: url_key → pages/GSC.","write_action":true,"price_micros":0,"input_schema":null},{"name":"keyword_list","description":"","write_action":false,"price_micros":0,"input_schema":null},{"name":"keyword_volume","description":"[Paid: Keywords API, cheap, cached 20d | Use for: demand sizing] True monthly search volume + CPC + competition for keywords (DataForSEO KEYWORDS_DATA). Served from a 20-day cache; live calls are serialised. Default location: United States (2840).","write_action":false,"price_micros":0,"input_schema":null},{"name":"link_intersect","description":"","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_checks","description":"List the technical-SEO check categories this server can evaluate.","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_properties","description":"List Google Search Console properties accessible to the service account.","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_templates","description":"Cluster the crawled pages into templates (by URL morphology + JSON-LD @type) and return each template with its page count and a representative exemplar URL. A single template-level fix corrects every page in the cluster — this is the map for per-template analysis. Needs a crawl (run refresh_property / start_crawl first).","write_action":false,"price_micros":0,"input_schema":null},{"name":"market_sizing","description":"","write_action":false,"price_micros":0,"input_schema":null},{"name":"news_discovery","description":"[Google News is FREE (no key); DataForSEO adds a paid, richer Google News SERP | Use for: what has been PUBLISHED on a topic — freshness, \"what changed since {date}\", competitor coverage] Recent news for a keyword from Google News (the free RSS search feed — Google's old News API is retired) and/or the DataForSEO Google News SERP. Returns title, source, publish time, URL. Default source \"both\" mer","write_action":false,"price_micros":0,"input_schema":null},{"name":"normalize_url","description":"Return the canonical url_key used to join GSC data to crawl data.","write_action":false,"price_micros":0,"input_schema":null},{"name":"page_intersection","description":"[Paid: Labs, cheap, cached 20d | Use for: page-level content gap vs named rival URLs] Find keywords that competitor pages rank for but your page does NOT (the content gap). Pass competitor URLs as `competitorUrls` (max 20; wildcards like https://site.com/blog/* allowed) and your own URL(s) in `excludePages` (max 10) to subtract. Returns gap keywords sorted by search volume, with each competitor’s ","write_action":false,"price_micros":0,"input_schema":null},{"name":"page_lighthouse","description":"[Paid: On-Page, ONE URL per call | Use for: CWV evidence on a page that earns clicks] Run a live Lighthouse audit for ONE url: lab Core Web Vitals (LCP, CLS, TBT, FCP, Speed Index), category scores (performance/SEO/best-practices/accessibility), and the top time-saving opportunities. Complements GSC/CrUX field data (aggregate + delayed) with on-demand lab data. Pass siteUrl to persist the CWV so r","write_action":false,"price_micros":0,"input_schema":null},{"name":"pull_backlinks","description":"[Paid: Backlinks subscription (separate - 40204 = not activated), cached 20d | Use for: authority + dead-backlink recovery] Fetch the property’s backlink profile (overall summary — total backlinks, referring domains, Domain Rank, broken backlinks/pages, nofollow share — plus per-page backlink/referring-domain counts) into page_backlinks, and resolve each backlinked page’s live HTTP status so run_a","write_action":false,"price_micros":0,"input_schema":null},{"name":"query_audit","description":"Run a single named check (see list_checks) and return its affected URLs + evidence. Token discipline: `columns` narrows evidence to the named keys, string evidence values are truncated at 120 chars (trailing …), `offset` + `limit` page through large result sets (the footer states showing X–Y of TOTAL). Grain: finding per URL with evidence JSON. Joins: url_key across all sources.","write_action":true,"price_micros":0,"input_schema":null},{"name":"query_data","description":"","write_action":false,"price_micros":0,"input_schema":null},{"name":"ranked_keywords","description":"","write_action":false,"price_micros":0,"input_schema":null},{"name":"recon_targets","description":"","write_action":false,"price_micros":0,"input_schema":null},{"name":"recon_todos","description":"The content-recon to-do board. With no id: list to-dos (optionally filter by page or status), grouped by page with each page's verdict — the pick-a-page-to-work-on surface, and the hand-off to content-machine. With id: update one to-do — set status (open → researching → drafted → shipped → dismissed) and/or append a dated annotation note (your own observations, the history). On status:shipped with","write_action":false,"price_micros":0,"input_schema":null},{"name":"related_terms","description":"[Paid: SERP call PER KEYWORD - only for clicked/explicit keywords, never lists | Use for: the SERP context of a single keyword] People Also Ask questions and related searches for a keyword (DataForSEO SERP). Powers click-through \"related terms\" on the keyword charts. SERP call — cached 20 days.","write_action":false,"price_micros":0,"input_schema":null},{"name":"resolve_entities","description":"Heuristically resolve each top page’s primary entity (by H1, fallback title) to a Wikidata QID, and store subclass-of / part-of relationships between them. Unlocks the entity-internal-link-gap finding (suggests internal links a topical mesh implies). Heuristic — those findings are judgement (N), shown only with includeJudgement. Free (public Wikidata API), cached ~45 days, on-demand. Async job — p","write_action":false,"price_micros":0,"input_schema":null},{"name":"run_audit","description":"Run the technical-SEO checks against synced data and return scored findings, ranked by expected clicks per dev-hour — Priority = (T × Y × C) / E (T = clicks at stake from real GSC data, Y = expected yield, C = certainty, E = effort hours). Crawl + GSC + URL-inspection checks. Set includeJudgement=true to include heuristic (N) checks.","write_action":true,"price_micros":0,"input_schema":null},{"name":"save_recon_todo","description":"Write content-recon findings back into the trackable ledger for a page — the gaps and originality the research session found by diffing competitors (firecrawl) and videos (supadata) against our content. Each to-do is an action with a type (content-gap / originality / schema / freshness / format), rationale and evidence. Snapshots the page baseline so the fix's effect on rank/AIO-citation is measur","write_action":true,"price_micros":0,"input_schema":null},{"name":"score_passages","description":"","write_action":false,"price_micros":0,"input_schema":null},{"name":"search_intent","description":"[Paid: Labs, cheap, cached 20d, up to 1000 kw/call | Use for: intent mapping before content planning] Classify the search intent (informational / navigational / commercial / transactional) of keywords — primary label + probability + secondary intents. Use it to spot intent mismatch: e.g. a transactional product page ranking for an informational query (a common cause of high impressions / low CTR).","write_action":false,"price_micros":0,"input_schema":null},{"name":"seo_audit_help","description":"Overview of every tool/feature with an example prompt for each. Start here.","write_action":false,"price_micros":0,"input_schema":null},{"name":"serp_features","description":"","write_action":false,"price_micros":0,"input_schema":null},{"name":"serve_dashboard","description":"Start a localhost-only webserver and return a URL that opens the full interactive dashboard in your browser — live data straight from the local database (always current, unlike export_report snapshots), a property switcher, working CSV downloads, and no host widget limits. The server stays up while the MCP server runs; call again with stop=true to shut it down. Localhost only — nothing is exposed ","write_action":false,"price_micros":0,"input_schema":null},{"name":"start_crawl","description":"Update just the crawl: fetch the site into the local database (async job — poll with check_crawl_status). HTTP crawl; respects robots.txt; asset file-types are HEAD-only (no body download); internal-search / cart / wp-json / builder junk URLs are skipped by default. For a full refresh use refresh_property. excludePatterns adds extra URL regexes to skip (e.g. [\"/author/\",\"/tag/\",\"/page/\"]) to keep ","write_action":true,"price_micros":0,"input_schema":null},{"name":"suggest_pages","description":"Propose NEW pages grounded in real Search Console demand: queries you already get impressions for but rank 11+ (no winning page), after subtracting demand you already satisfy (you rank ≤10, or a page already covers the query, or one URL owns it). Survivors are clustered into one proposed page per intent and scored by impressions × intent. Returns evidence + the nearest existing page to link the ne","write_action":false,"price_micros":0,"input_schema":null},{"name":"sync_gsc","description":"Update just the GSC search-analytics history (async job — poll with check_sync_status). Incremental: the first sync pulls the range (default last 90 days; pass startDate to go deeper), later syncs only fetch new days — set full=true to force a full re-pull. Lite by default (date×query×page); set segments=true (or pass dimensions) to also pull device/country. For a full refresh use refresh_property","write_action":true,"price_micros":0,"input_schema":null},{"name":"top_pages","description":"[Paid: Labs, cheap, cached 20d | Use for: where rival traffic actually lands] The top organic pages of ANY domain or subdomain, ranked by estimated traffic value (ETV): page, ranking-keyword count, ETV and top-3 / top-10 keyword counts. The Semrush-style \"top pages\" view — works on competitors, no crawl or GSC needed. Labs call, cached 20 days. Pass location for the right market. Grain: page × dom","write_action":false,"price_micros":0,"input_schema":null},{"name":"topic_gaps","description":"","write_action":false,"price_micros":0,"input_schema":null},{"name":"topic_trend","description":"[Paid: Keywords API, cheap, cached 20d | Use for: seasonality + \"is this rising or fading\" — should we update now, when to publish] Google Trends relative interest (0–100) over time for up to 5 keywords (DataForSEO KEYWORDS_DATA / google_trends). Returns a per-keyword time series plus a rising/falling/flat read, so you can see direction and seasonality. timeRange: past_7_days | past_30_days | past","write_action":false,"price_micros":0,"input_schema":null},{"name":"track_ranks","description":"Ingest the DataForSEO over-time sequence (monthly rank distribution + ETV) into rank_history, so rank charts have a real time axis reconciled with GSC. DataForSEO Labs call — cached 20 days. Pass location once (e.g. \"Australia\", \"United Kingdom\") — it is saved per property. Async job.","write_action":false,"price_micros":0,"input_schema":null},{"name":"youtube_discovery","description":"[Paid: SERP call PER KEYWORD, cached 20d | Use for: finding the videos that rank for a topic — content research, competitor video scan, freshness] The ranking YouTube videos for a keyword (DataForSEO YouTube organic SERP). Returns title, URL, channel, view count, publish date, duration and shorts/live flags, in rank order. Pair with a transcript tool (Supadata) to read what the winning videos actu","write_action":false,"price_micros":0,"input_schema":null}],"scan":{"score":85,"grade":"A","scanned_at":"2026-09-21T22:09:33.914Z","report":{"scannerVersion":"0.1.9","scannedAt":"2026-09-21T22:09:33.952Z","components":{"code":{"score":25,"max":25,"notes":["112 source files scanned"]},"reliability":{"score":-1,"max":20,"notes":["no gateway calls yet and no remote to probe"]},"poisoning":{"score":-1,"max":15,"notes":["tools not inspected (local package is not executed); not counted"]},"auth":{"score":6,"max":15,"notes":["static API keys via environment variables"]},"maintenance":{"score":15,"max":15,"notes":["last push 0 days ago"]},"identity":{"score":9,"max":10,"notes":["registry namespace matches repository owner","GitHub account older than a year"]}},"findings":[],"inputs":{"packages":[{"registryType":"npm","identifier":"@houtini/seo-audit-console","version":"0.8.0","found":true,"license":"Apache-2.0","hasInstallScripts":false,"dependencyCount":11,"publishedAt":"2026-08-21T17:09:14.756Z","repositoryUrl":"git+https://github.com/houtini-ai/seo-audit.git","weeklyDownloads":51}],"repo":{"found":true,"owner":"houtini-ai","repo":"seo-audit","archived":false,"pushedAt":"2026-09-21T20:27:27Z","stars":21,"forks":1,"openIssues":0,"ownerType":"Organization","ownerAvatarUrl":"https://avatars.githubusercontent.com/u/229963303?v=4","ownerCreatedAt":"2025-09-02T13:29:01Z","license":"Apache-2.0"},"icon":{"url":"https://avatars.githubusercontent.com/u/229963303?v=4&s=128","source":"github"},"presence":{"stars":21,"forks":1,"downloadsWeek":51,"license":"Apache-2.0","lastPushAt":"2026-09-21T20:27:27.000Z","score":36}}}},"grade_history":[],"reviews":[]}