MCP server intelligence profile

automatelab-ai-seo MCP Server

Vendor-agnostic MCP server that audits, scores, and rewrites web pages for AI-citation eligibility. No API keys. No registration. Works in Claude Desktop, Cursor, Cline, Windsurf, VS Code (Copilot / Continue), and any client that speaks the Model Context Protocol

Local OnlyOfficial distributionAutomateLab-tech
Verified cleanNpm · 1.0.0

Our scanner tested version 1.0.0 without proving a finding in the methods exercised. This is not a guarantee that every deployment is secure.

1Distribution channel
20Independently observed tools
0Linked remote endpoints
AvailableVersion intelligence

Install and connect

Installation and connection instructions are shown only when supported by retained package, repository, or endpoint evidence.

Install @automatelab/ai-seo-mcp from npm

Version 1.0.0 declares 1 executable entrypoint.

npm install --save-exact @automatelab/ai-seo-mcp@1.0.0
npx -y -p @automatelab/ai-seo-mcp@1.0.0 @automatelab/ai-seo-mcp
MCP client configuration example
{
  "mcpServers": {
    "@automatelab/ai-seo-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "-p",
        "@automatelab/ai-seo-mcp@1.0.0",
        "@automatelab/ai-seo-mcp"
      ]
    }
  }
}

Identity

Canonical slugautomatelab-ai-seo-bec3f790DeploymentLocal Only
Canonical packagenpm:@automatelab/ai-seo-mcpRepositoryAutomateLab-tech/ai-seo-mcp
First publishedLatest release
Last security verificationClassification confidence90%
PublicationPublishedOfficial distributionYes

Distributions

ChannelIdentifierCurrent versionVersionsSource
npm@automatelab/ai-seo-mcp1.0.01Repository

Current release

PackageVersionPublished / observedInventorySecurity scan
npm@automatelab/ai-seo-mcp1.0.0CurrentSep 5, 202620 toolsSucceeded · 2 resources · 5 promptsFailed
Enterprise protection

Continuously monitor this MCP for security risk

Independently scan the exact version your agents use, receive alerts when its risk changes, and investigate every finding with retained version evidence.

  • Independent exact-version security scans
  • Continuous release and vulnerability monitoring
  • Risk-change alerts with capability context
  • Historical evidence and API exports
Custom pricingContact salesTailored to your organization, integrations, data needs, and support requirements.

Current version evidence

Provenanceartifact_hash_verifiedSignature
MCP SDK@modelcontextprotocol/sdk Artifact SHA-2569c21f28b1308480b844786e2cf193f0e1b85dc3d7a71d896c8face338df67c2c
Scannermcp-proof-engine 0.1.0Scan completedAug 23, 2026
Security rating44 / 100Methodologyversion-rating-1.0
Executable entrypoints
[
  "@automatelab/ai-seo-mcp"
]

Current protocol inventory

2025-06-18Negotiated protocol
@automatelab/ai-seo-mcpServer-reported name
3Capability groups
Aug 22, 2026Observed

Tools 20

ToolCategoryAnnotationsRisk
audit_canonicalAudit a page's canonical link integrity: presence, self-reference, cross-domain mismatches, trailing-slash hygiene, and og:url consistency. Read-only. One HTTP GET to fetch the HEAD section. Deterministic, rule-based; no LLM. When to use: a focused canonical-only audit (e.g. debugging a duplicate-content issue). For a full HEAD audit including OpenGraph, hreflang, noindex, title, use `check_technical`. For everything-on-a-page, use `audit_page`.
Input schema
{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "format": "uri",
      "description": "Public URL whose canonical link tag and og:url consistency you want to audit. Must be a fully-qualified http(s) URL. The tool fetches the URL (following redirects) and inspects only the <head> section; the body is not parsed."
    },
    "respect_robots": {
      "type": "boolean",
      "default": true,
      "description": "If true (default), respect robots.txt before fetching. Set false only for auditing your own site where you've intentionally blocked crawlers."
    }
  },
  "required": [
    "url"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Output schema
{
  "type": "object",
  "properties": {
    "url": {
      "type": "string"
    },
    "fetched_at": {
      "type": "string"
    },
    "canonical": {
      "type": [
        "string",
        "null"
      ]
    },
    "og_url": {
      "type": [
        "string",
        "null"
      ]
    },
    "self_referencing": {
      "type": "boolean",
      "description": "Whether the canonical points to the audited URL."
    },
    "cross_domain": {
      "type": "boolean",
      "description": "Whether the canonical points to a different domain."
    },
    "findings": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "severity": {
            "type": "string",
            "enum": [
              "critical",
              "warning",
              "info"
            ],
            "description": "Triage priority: critical blocks AI citation, warning hurts probability, info is nice-to-have."
          },
          "category": {
            "type": "string",
            "enum": [
              "schema",
              "robots",
              "technical",
              "freshness",
              "structure",
              "authority",
              "presence",
              "sitemap",
              "llms_txt",
              "citation",
              "evidence",
              "trust",
              "entity",
              "content"
            ],
            "description": "Finding category - which AI-SEO dimension it relates to."
          },
          "where": {
            "type": "string",
            "description": "Location of the issue (CSS selector, JSON-LD path, robots.txt line, or 'page-level')."
          },
          "message": {
            "type": "string",
            "description": "Human-readable description of the issue."
          },
          "fix": {
            "type": "string",
            "description": "Concrete, copy-pasteable fix."
          },
          "estimated_impact": {
            "type": "string",
            "enum": [
              "high",
              "medium",
              "low"
            ],
            "description": "Estimated impact on AI citation probability when resolved."
          },
          "failure_signal": {
            "type": "string",
            "description": "Falsifiability: the observable signal that would prove the fix did NOT work."
          },
          "leading_indicator": {
            "type": "string",
            "description": "Falsifiability: the leading indicator to monitor to confirm the fix is landing."
          }
        },
        "required": [
          "severity",
          "category",
          "where",
          "message",
          "fix"
        ],
        "additionalProperties": false
      }
    }
  },
  "required": [
    "url",
    "fetched_at",
    "canonical",
    "og_url",
    "self_referencing",
    "cross_domain",
    "findings"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "title": "Audit canonical link integrity",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
Read onlyNon-destructiveIdempotentOpen world
audit_pageFull AI-SEO audit of a single URL: returns categorized findings (info/warning/error) with severity, fix instructions, and a 0-100 composite score plus per-dimension subscores. Read-only. Fetches the URL once and runs every sub-audit (schema, robots, technical, sitemap, AI-Overview eligibility) against the response. No writes, no third-party APIs, no auth required, no rate limits beyond polite per-host throttling. Deterministic, rule-based scoring; no LLM calls. Same URL + same input flags returns the same score. Supports `render: "static" | "headless"`. Default `static` (fast, raw HTML only). Use `headless` for React/Vue/Angular SPAs — adds 3-10s and requires the optional `playwright-core` peer dep plus a one-time `npx playwright install chromium`. When to use: the default entry point for `audit any page`. Use this instead of calling check_technical / audit_schema / check_robots / check_sitemap / score_ai_overview_eligibility individually unless you specifically need only one dimension - this tool composes all of them.
Input schema
{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "format": "uri",
      "description": "Public URL to audit. Must be a fully-qualified http(s) URL that returns HTTP 200 (redirects are followed). The tool fetches this URL once and runs every sub-audit (schema, robots, technical, sitemap, AI-Overview eligibility) against the response."
    },
    "include_raw_html": {
      "type": "boolean",
      "default": false,
      "description": "If true, return the full raw HTML in the response under `raw_html`. Default false. Set true only when you need to inspect markup that wasn't captured by the structured findings; the payload can be large."
    },
    "respect_robots": {
      "type": "boolean",
      "default": true,
      "description": "If true (default), the tool checks robots.txt before fetching and skips disallowed paths, returning a robots_blocked finding instead. Set to false ONLY for auditing your own site where you've intentionally blocked crawlers and need the audit to bypass that block."
    },
    "generate_report": {
      "type": "boolean",
      "default": false,
      "description": "If true, return a standalone HTML scorecard in the `report_html` field. The HTML is self-contained (no external dependencies) and can be saved as a .html file or pasted to Gist/CodePen. Default false to keep audits cheap."
    },
    "render": {
      "type": "string",
      "enum": [
        "static",
        "headless"
      ],
      "default": "static",
      "description": "Rendering mode. `static` (default) fetches raw HTML via HTTP — fast (<1s) but misses JS-rendered content typical of SPAs (React/Vue/Angular landing pages). `headless` spins up Playwright Chromium, waits for networkidle, and audits the rendered DOM — adds 3-10s per audit and requires `playwright-core` installed plus a one-time `npx playwright install chromium`. Use `headless` when the static audit shows `content_quality: \"spa_empty\"` or you know the target is JS-rendered."
    }
  },
  "required": [
    "url"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Output schema
{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "description": "The URL that was audited."
    },
    "fetched_at": {
      "type": "string",
      "description": "UTC ISO-8601 timestamp of the fetch."
    },
    "score": {
      "type": "number",
      "minimum": 0,
      "maximum": 100,
      "description": "Composite 0-100 AI-citation score."
    },
    "grade": {
      "type": "string",
      "enum": [
        "A",
        "B",
        "C",
        "D",
        "F"
      ],
      "description": "Letter grade derived from the numeric score."
    },
    "findings": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "severity": {
            "type": "string",
            "enum": [
              "critical",
              "warning",
              "info"
            ],
            "description": "Triage priority: critical blocks AI citation, warning hurts probability, info is nice-to-have."
          },
          "category": {
            "type": "string",
            "enum": [
              "schema",
              "robots",
              "technical",
              "freshness",
              "structure",
              "authority",
              "presence",
              "sitemap",
              "llms_txt",
              "citation",
              "evidence",
              "trust",
              "entity",
              "content"
            ],
            "description": "Finding category - which AI-SEO dimension it relates to."
          },
          "where": {
            "type": "string",
            "description": "Location of the issue (CSS selector, JSON-LD path, robots.txt line, or 'page-level')."
          },
          "message": {
            "type": "string",
            "description": "Human-readable description of the issue."
          },
          "fix": {
            "type": "string",
            "description": "Concrete, copy-pasteable fix."
          },
          "estimated_impact": {
            "type": "string",
            "enum": [
              "high",
              "medium",
              "low"
            ],
            "description": "Estimated impact on AI citation probability when resolved."
          },
          "failure_signal": {
            "type": "string",
            "description": "Falsifiability: the observable signal that would prove the fix did NOT work."
          },
          "leading_indicator": {
            "type": "string",
            "description": "Falsifiability: the leading indicator to monitor to confirm the fix is landing."
          }
        },
        "required": [
          "severity",
          "category",
          "where",
          "message",
          "fix"
        ],
        "additionalProperties": false
      },
      "description": "All findings emitted by the sub-audits, deduplicated."
    },
    "citation_verdict": {
      "type": "object",
      "properties": {
        "will_ai_cite": {
          "type": "string",
          "enum": [
            "unlikely",
            "marginal",
            "likely"
          ],
          "description": "Coarse verdict from the composite score."
        },
        "top_3_blockers": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "category": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "fix": {
                "type": "string"
              },
              "estimated_impact": {
                "type": "string",
                "enum": [
                  "high",
                  "medium",
                  "low"
                ]
              }
            },
            "required": [
              "category",
              "message",
              "fix"
            ],
            "additionalProperties": false
          },
          "description": "Top three highest-impact issues blocking AI citation."
        },
        "one_line_summary": {
          "type": "string",
          "description": "Single-sentence explanation suitable for headlines/dashboards."
        }
      },
      "required": [
        "will_ai_cite",
        "top_3_blockers",
        "one_line_summary"
      ],
      "additionalProperties": false,
      "description": "Prepended block summarizing whether AI assistants will cite this page and why."
    },
    "dimension_scores": {
      "type": "object",
      "properties": {
        "schema": {
          "type": "number"
        },
        "robots": {
          "type": "number"
        },
        "technical": {
          "type": "number"
        },
        "freshness": {
          "type": "number"
        },
        "structure": {
          "type": "number"
        },
        "authority": {
          "type": "number"
        },
        "entity_density": {
          "type": "number"
        },
        "sitemap": {
          "type": "number"
        },
        "citability": {
          "type": "number",
          "description": "Passage-level extractability: share of sections in the 134-167 word citable band."
        },
        "evidence": {
          "type": "number",
          "description": "Citations / statistics / quotations density (Princeton GEO weighting)."
        },
        "trust": {
          "type": "number",
          "description": "E-E-A-T trust signals: author, dates, contact/policy pages, HTTPS."
        }
      },
      "required": [
        "schema",
        "robots",
        "technical",
        "freshness",
        "structure",
        "authority",
        "entity_density",
        "sitemap",
        "citability",
        "evidence",
        "trust"
      ],
      "additionalProperties": false,
      "description": "Per-dimension 0-100 subscores. The composite score is a weighted blend of these."
    },
    "platform_readiness": {
      "type": "object",
      "properties": {
        "chatgpt": {
          "type": "object",
          "properties": {
            "score": {
              "type": "number"
            },
            "label": {
              "type": "string",
              "enum": [
                "ready",
                "partial",
                "weak"
              ]
            }
          },
          "required": [
            "score",
            "label"
          ],
          "additionalProperties": false
        },
        "perplexity": {
          "type": "object",
          "properties": {
            "score": {
              "type": "number"
            },
            "label": {
              "type": "string",
              "enum": [
                "ready",
                "partial",
                "weak"
              ]
            }
          },
          "required": [
            "score",
            "label"
          ],
          "additionalProperties": false
        },
        "google_ai_overview": {
          "type": "object",
          "properties": {
            "score": {
              "type": "number"
            },
            "label": {
              "type": "string",
              "enum": [
                "ready",
                "partial",
                "weak"
              ]
            }
          },
          "required": [
            "score",
            "label"
          ],
          "additionalProperties": false
        },
        "gemini": {
          "type": "object",
          "properties": {
            "score": {
              "type": "number"
            },
            "label": {
              "type": "string",
              "enum": [
                "ready",
                "partial",
                "weak"
              ]
            }
          },
          "required": [
            "score",
            "label"
          ],
          "additionalProperties": false
        }
      },
      "required": [
        "chatgpt",
        "perplexity",
        "google_ai_overview",
        "gemini"
      ],
      "additionalProperties": false,
      "description": "Per-engine readiness derived from the dimensions; engines reward different signals."
    },
    "score_caps": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Hard blockers that capped the composite score (e.g. noindex, AI bots blocked). Empty when none fired."
    },
    "content_quality": {
      "type": "string",
      "enum": [
        "static_html",
        "ssr_likely",
        "spa_empty"
      ],
      "description": "Classification of the fetched HTML's readiness. spa_empty means audit results are degraded."
    },
    "raw_html": {
      "type": "string",
      "description": "Full raw HTML response. Present only when include_raw_html=true."
    },
    "report_html": {
      "type": "string",
      "description": "Self-contained HTML scorecard. Present only when generate_report=true."
    }
  },
  "required": [
    "url",
    "fetched_at",
    "score",
    "grade",
    "findings",
    "citation_verdict",
    "dimension_scores",
    "platform_readiness",
    "score_caps",
    "content_quality"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "title": "Audit page (full)",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
Read onlyNon-destructiveIdempotentOpen world
audit_schemaValidate JSON-LD structured data against Schema.org rules and AI-citation best practices. Accepts either a URL (fetched) or a raw JSON string (parsed directly). Read-only when given `url` (one HTTP GET). Zero network when given `schema_json`. No writes. Deterministic, rule-based; no LLM. Validates required/recommended properties, @context correctness, sameAs links, and AI-search-friendly patterns. When to use: focused JSON-LD audits, or to validate a schema block you're about to ship. For a full page audit that includes schema + everything else, use `audit_page` instead. Either `url` or `schema_json` must be provided (not both). If both are provided, `schema_json` wins and no fetch happens.
Input schema
{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "format": "uri",
      "description": "Public URL to fetch and audit. Either this OR `schema_json` is required. Read-only HTTP GET."
    },
    "schema_json": {
      "type": "string",
      "description": "Raw JSON-LD as a string (the contents of a `<script type=\"application/ld+json\">` block). Use this to validate a schema block offline without fetching a URL. Either this OR `url` is required."
    },
    "respect_robots": {
      "type": "boolean",
      "default": true,
      "description": "If true (default), respect robots.txt before fetching `url`. Ignored when `schema_json` is used."
    }
  },
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Output schema
{
  "type": "object",
  "properties": {
    "source": {
      "type": "string",
      "enum": [
        "url",
        "inline"
      ],
      "description": "Where the JSON-LD came from."
    },
    "url": {
      "type": [
        "string",
        "null"
      ],
      "description": "Source URL (null when source=inline)."
    },
    "fetched_at": {
      "type": [
        "string",
        "null"
      ]
    },
    "found_types": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Schema.org @type values discovered across all JSON-LD blocks."
    },
    "ai_citation_readiness_score": {
      "type": "number",
      "minimum": 0,
      "maximum": 100,
      "description": "0-100 score for the JSON-LD's AI-citation readiness."
    },
    "findings": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "severity": {
            "type": "string",
            "enum": [
              "critical",
              "warning",
              "info"
            ],
            "description": "Triage priority: critical blocks AI citation, warning hurts probability, info is nice-to-have."
          },
          "category": {
            "type": "string",
            "enum": [
              "schema",
              "robots",
              "technical",
              "freshness",
              "structure",
              "authority",
              "presence",
              "sitemap",
              "llms_txt",
              "citation",
              "evidence",
              "trust",
              "entity",
              "content"
            ],
            "description": "Finding category - which AI-SEO dimension it relates to."
          },
          "where": {
            "type": "string",
            "description": "Location of the issue (CSS selector, JSON-LD path, robots.txt line, or 'page-level')."
          },
          "message": {
            "type": "string",
            "description": "Human-readable description of the issue."
          },
          "fix": {
            "type": "string",
            "description": "Concrete, copy-pasteable fix."
          },
          "estimated_impact": {
            "type": "string",
            "enum": [
              "high",
              "medium",
              "low"
            ],
            "description": "Estimated impact on AI citation probability when resolved."
          },
          "failure_signal": {
            "type": "string",
            "description": "Falsifiability: the observable signal that would prove the fix did NOT work."
          },
          "leading_indicator": {
            "type": "string",
            "description": "Falsifiability: the leading indicator to monitor to confirm the fix is landing."
          }
        },
        "required": [
          "severity",
          "category",
          "where",
          "message",
          "fix"
        ],
        "additionalProperties": false
      }
    }
  },
  "required": [
    "source",
    "url",
    "fetched_at",
    "found_types",
    "ai_citation_readiness_score",
    "findings"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "title": "Audit JSON-LD schema",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
Read onlyNon-destructiveIdempotentOpen world
audit_siteSingle-call site sweep: runs audit_page (homepage), check_robots, check_sitemap, and audit_schema in parallel and returns an overall grade (A–F) plus top-5 highest-impact fixes. Read-only. Issues several HTTP GETs against the domain (homepage fetch, robots.txt, sitemap.xml, and up to 50 sitemap URL HEAD checks); no writes, no auth required, no rate limits beyond polite per-host throttling. The homepage GET is deduplicated across audit_page and audit_schema (~2 network fetches for 4 logical checks). Deterministic, rule-based scoring; no LLM calls. Same domain returns the same grade on repeated runs given unchanged content. Output: domain, homepage_url, fetched_at, overall_score (0–100), overall_grade, top_5_fixes (Finding[]), and a parts breakdown with individual audit_page, check_robots, check_sitemap, and audit_schema results — each may be a full result or { error: string } when that sub-audit fails. When to use: quick 'how does this site look overall?' — use when you want a single consolidated score and actionable fix list without calling 4 tools individually. Distinct from audit_sitemap (samples N pages from the sitemap, not just the homepage) and audit_page (single-URL deep dive with all findings, not just top-5).
Input schema
{
  "type": "object",
  "properties": {
    "domain": {
      "type": "string",
      "minLength": 3,
      "description": "Hostname or origin to audit. Examples: `example.com`, `https://example.com`. The tool resolves the homepage and runs audit_page + check_robots + check_sitemap + audit_schema in parallel against it, then returns an overall grade plus top-5 fixes. Issues several HTTP GETs against the domain."
    },
    "respect_robots": {
      "type": "boolean",
      "default": true,
      "description": "If true (default), respect robots.txt before fetching the homepage. Set false ONLY to audit a site you own that has temporarily blocked crawlers."
    }
  },
  "required": [
    "domain"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Output schema
{
  "type": "object",
  "properties": {
    "domain": {
      "type": "string"
    },
    "homepage_url": {
      "type": "string"
    },
    "fetched_at": {
      "type": "string"
    },
    "overall_score": {
      "type": "number",
      "minimum": 0,
      "maximum": 100
    },
    "overall_grade": {
      "type": "string",
      "enum": [
        "A",
        "B",
        "C",
        "D",
        "F"
      ],
      "description": "Letter grade derived from the numeric score."
    },
    "top_5_fixes": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "severity": {
            "type": "string",
            "enum": [
              "critical",
              "warning",
              "info"
            ],
            "description": "Triage priority: critical blocks AI citation, warning hurts probability, info is nice-to-have."
          },
          "category": {
            "type": "string",
            "enum": [
              "schema",
              "robots",
              "technical",
              "freshness",
              "structure",
              "authority",
              "presence",
              "sitemap",
              "llms_txt",
              "citation",
              "evidence",
              "trust",
              "entity",
              "content"
            ],
            "description": "Finding category - which AI-SEO dimension it relates to."
          },
          "where": {
            "type": "string",
            "description": "Location of the issue (CSS selector, JSON-LD path, robots.txt line, or 'page-level')."
          },
          "message": {
            "type": "string",
            "description": "Human-readable description of the issue."
          },
          "fix": {
            "type": "string",
            "description": "Concrete, copy-pasteable fix."
          },
          "estimated_impact": {
            "type": "string",
            "enum": [
              "high",
              "medium",
              "low"
            ],
            "description": "Estimated impact on AI citation probability when resolved."
          },
          "failure_signal": {
            "type": "string",
            "description": "Falsifiability: the observable signal that would prove the fix did NOT work."
          },
          "leading_indicator": {
            "type": "string",
            "description": "Falsifiability: the leading indicator to monitor to confirm the fix is landing."
          }
        },
        "required": [
          "severity",
          "category",
          "where",
          "message",
          "fix"
        ],
        "additionalProperties": false
      },
      "description": "Up to five highest-impact findings across all sub-audits."
    },
    "parts": {
      "type": "object",
      "properties": {
        "audit_page": {
          "type": "object",
          "additionalProperties": {},
          "description": "Result of the homepage audit (or { error } on failure)."
        },
        "check_robots": {
          "type": "object",
          "additionalProperties": {}
        },
        "check_sitemap": {
          "type": "object",
          "additionalProperties": {}
        },
        "audit_schema": {
          "type": "object",
          "additionalProperties": {}
        }
      },
      "required": [
        "audit_page",
        "check_robots",
        "check_sitemap",
        "audit_schema"
      ],
      "additionalProperties": false,
      "description": "Raw sub-audit results, for callers who want to drill in."
    }
  },
  "required": [
    "domain",
    "homepage_url",
    "fetched_at",
    "overall_score",
    "overall_grade",
    "top_5_fixes",
    "parts"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "title": "Audit site (homepage + robots + sitemap + schema)",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
Read onlyNon-destructiveIdempotentOpen world
audit_sitemapSite-wide content audit: discovers the sitemap, samples N URLs by deterministic uniform stride, runs audit_page on each, and returns score distribution + worst pages + most-common findings. Read-only. One HTTP GET for sitemap discovery, optionally a few more for sitemap-index children, then `sample_size` × audit_page calls (each one HTTP GET + parsing). Polite throttling is enforced per host. Deterministic — same domain + same sample_size returns the same set of URLs (uniform-stride sampling). Per-page scoring is rule-based; no LLM. When to use: portfolio-level health check across a site ("how does our content score on average?"). Distinct from `audit_site` (homepage-only composite) and `check_sitemap` (validates sitemap.xml structure, not page content).
Input schema
{
  "type": "object",
  "properties": {
    "domain": {
      "type": "string",
      "minLength": 3,
      "description": "Hostname or origin to audit. Examples: `example.com`, `https://example.com`. The tool discovers the sitemap, samples N URLs by uniform stride, and runs audit_page on each."
    },
    "sample_size": {
      "type": "integer",
      "minimum": 1,
      "maximum": 50,
      "default": 10,
      "description": "Number of URLs to sample from the sitemap. Default 10. Max 50 (sampling caps to avoid runaway audits — each sample is one full audit_page call, ~1-3s with polite throttling). Sampling is deterministic uniform-stride: if the sitemap has 1000 URLs and sample_size=10, every 100th URL is picked."
    },
    "respect_robots": {
      "type": "boolean",
      "default": true,
      "description": "If true (default), respect robots.txt for each sampled URL. Set false only for self-audits where you've intentionally blocked crawlers."
    },
    "concurrency": {
      "type": "integer",
      "minimum": 1,
      "maximum": 5,
      "default": 2,
      "description": "Parallel audit_page calls. Default 2 (gentle). Max 5. The shared politeFetch host-delay is still enforced, so this is per-batch dispatch concurrency, not bypass."
    }
  },
  "required": [
    "domain"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Output schema
{
  "type": "object",
  "properties": {
    "domain": {
      "type": "string",
      "description": "The domain audited."
    },
    "sitemap_url": {
      "type": [
        "string",
        "null"
      ],
      "description": "Resolved sitemap URL (null when discovery failed)."
    },
    "total_urls_in_sitemap": {
      "type": "number",
      "description": "Total URLs declared across the sitemap and any indexed children."
    },
    "urls_sampled": {
      "type": "number",
      "description": "Number of URLs picked via uniform-stride sampling."
    },
    "sampling": {
      "type": "string",
      "const": "uniform_stride",
      "description": "Sampling strategy. Deterministic uniform stride: every Nth URL is picked."
    },
    "audited": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string"
          },
          "score": {
            "type": "number"
          },
          "grade": {
            "type": "string",
            "enum": [
              "A",
              "B",
              "C",
              "D",
              "F"
            ],
            "description": "Letter grade derived from the numeric score."
          },
          "top_issue": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "url",
          "score",
          "grade",
          "top_issue"
        ],
        "additionalProperties": false
      },
      "description": "Per-page audit results that completed successfully."
    },
    "failed": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string"
          },
          "error": {
            "type": "string"
          }
        },
        "required": [
          "url",
          "error"
        ],
        "additionalProperties": false
      },
      "description": "URLs whose audit failed, with the error message."
    },
    "score_distribution": {
      "type": "object",
      "properties": {
        "avg": {
          "type": "number"
        },
        "median": {
          "type": "number"
        },
        "min": {
          "type": "number"
        },
        "max": {
          "type": "number"
        },
        "p25": {
          "type": "number"
        },
        "p75": {
          "type": "number"
        }
      },
      "required": [
        "avg",
        "median",
        "min",
        "max",
        "p25",
        "p75"
      ],
      "additionalProperties": false,
      "description": "Summary statistics across the audited sample."
    },
    "grade_distribution": {
      "type": "object",
      "properties": {
        "A": {
          "type": "number"
        },
        "B": {
          "type": "number"
        },
        "C": {
          "type": "number"
        },
        "D": {
          "type": "number"
        },
        "F": {
          "type": "number"
        }
      },
      "required": [
        "A",
        "B",
        "C",
        "D",
        "F"
      ],
      "additionalProperties": false,
      "description": "Count of pages per letter grade."
    },
    "worst_pages": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string"
          },
          "score": {
            "type": "number"
          },
          "grade": {
            "$ref": "#/properties/audited/items/properties/grade"
          },
          "top_issue": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "url",
          "score",
          "grade",
          "top_issue"
        ],
        "additionalProperties": false
      },
      "description": "Lowest-scoring pages from the sample, worst first."
    },
    "top_findings": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "severity": {
            "type": "string",
            "enum": [
              "critical",
              "warning",
              "info"
            ]
          },
          "count": {
            "type": "number",
            "description": "How many pages in the sample had this finding."
          },
          "fix": {
            "type": "string"
          }
        },
        "required": [
          "message",
          "category",
          "severity",
          "count",
          "fix"
        ],
        "additionalProperties": false
      },
      "description": "Most-common findings across all sampled pages, sorted by occurrence count desc."
    },
    "fetched_at": {
      "type": "string",
      "description": "UTC ISO-8601 timestamp of the audit."
    }
  },
  "required": [
    "domain",
    "sitemap_url",
    "total_urls_in_sitemap",
    "urls_sampled",
    "sampling",
    "audited",
    "failed",
    "score_distribution",
    "grade_distribution",
    "worst_pages",
    "top_findings",
    "fetched_at"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "title": "Audit a site's content by sampling its sitemap",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
Read onlyNon-destructiveIdempotentOpen world
check_robotsFetch and parse a domain's robots.txt; report per-crawler allow/disallow posture for every known AI training crawler (GPTBot, CCBot, Anthropic-AI, Google-Extended, etc.), AI search crawlers (ChatGPT-User, PerplexityBot, OAI-SearchBot), and user-triggered fetchers. Read-only. One HTTP GET to /robots.txt. No auth, no rate limits applied. Deterministic, rule-based; no LLM. Returns structured findings with per-crawler status. When to use: figuring out which AI crawlers a site blocks vs allows. Combine with `check_sitemap` for a full pre-crawl audit. Distinct from `audit_page` which evaluates a single URL; this evaluates a whole-domain policy.
Input schema
{
  "type": "object",
  "properties": {
    "domain": {
      "type": "string",
      "minLength": 3,
      "description": "Hostname or origin to inspect. Examples: `example.com`, `https://example.com`, `https://example.com/`. The tool fetches `https://<domain>/robots.txt` and reports per-crawler allow/disallow posture for all known AI training crawlers (GPTBot, CCBot, etc.), AI search crawlers (ChatGPT-User, PerplexityBot), and user-triggered fetchers. Read-only HTTP GET to /robots.txt only."
    }
  },
  "required": [
    "domain"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Output schema
{
  "type": "object",
  "properties": {
    "robots_url": {
      "type": "string",
      "description": "The robots.txt URL that was fetched."
    },
    "fetched_at": {
      "type": "string",
      "description": "UTC ISO-8601 timestamp of the fetch."
    },
    "training_crawlers": {
      "type": "object",
      "additionalProperties": {
        "type": "object",
        "properties": {
          "allowed": {
            "type": "boolean",
            "description": "Whether this crawler is allowed to fetch the site root."
          },
          "match_source": {
            "type": "string",
            "description": "The robots.txt rule line that produced this verdict, if any."
          }
        },
        "required": [
          "allowed"
        ],
        "additionalProperties": false
      },
      "description": "Allow/disallow posture per known AI training crawler (GPTBot, ClaudeBot, CCBot, etc.)."
    },
    "search_crawlers": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/properties/training_crawlers/additionalProperties"
      },
      "description": "Allow/disallow posture per known AI search crawler (OAI-SearchBot, PerplexityBot, etc.)."
    },
    "user_triggered": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/properties/training_crawlers/additionalProperties"
      },
      "description": "Allow/disallow posture per user-triggered fetcher (ChatGPT-User, Claude-User, etc.)."
    },
    "findings": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "severity": {
            "type": "string",
            "enum": [
              "critical",
              "warning",
              "info"
            ],
            "description": "Triage priority: critical blocks AI citation, warning hurts probability, info is nice-to-have."
          },
          "category": {
            "type": "string",
            "enum": [
              "schema",
              "robots",
              "technical",
              "freshness",
              "structure",
              "authority",
              "presence",
              "sitemap",
              "llms_txt",
              "citation",
              "evidence",
              "trust",
              "entity",
              "content"
            ],
            "description": "Finding category - which AI-SEO dimension it relates to."
          },
          "where": {
            "type": "string",
            "description": "Location of the issue (CSS selector, JSON-LD path, robots.txt line, or 'page-level')."
          },
          "message": {
            "type": "string",
            "description": "Human-readable description of the issue."
          },
          "fix": {
            "type": "string",
            "description": "Concrete, copy-pasteable fix."
          },
          "estimated_impact": {
            "type": "string",
            "enum": [
              "high",
              "medium",
              "low"
            ],
            "description": "Estimated impact on AI citation probability when resolved."
          },
          "failure_signal": {
            "type": "string",
            "description": "Falsifiability: the observable signal that would prove the fix did NOT work."
          },
          "leading_indicator": {
            "type": "string",
            "description": "Falsifiability: the leading indicator to monitor to confirm the fix is landing."
          }
        },
        "required": [
          "severity",
          "category",
          "where",
          "message",
          "fix"
        ],
        "additionalProperties": false
      },
      "description": "Per-crawler findings explaining why the posture matters."
    },
    "recommended_posture": {
      "type": "string",
      "enum": [
        "block_training_allow_search",
        "allow_all",
        "block_all",
        "custom"
      ],
      "description": "Suggested posture given the current rules."
    }
  },
  "required": [
    "robots_url",
    "fetched_at",
    "training_crawlers",
    "search_crawlers",
    "user_triggered",
    "findings",
    "recommended_posture"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "title": "Check robots.txt crawler posture",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
Read onlyNon-destructiveIdempotentOpen world
check_sitemapValidate a domain's XML sitemap: presence, accessibility, URL count, lastmod freshness, sitemap-index handling, and image/video sitemap extensions. Read-only. Issues N+1 HTTP GETs: one for robots.txt + sitemap, then up to `max_urls_to_check` HEADs against sampled URLs. Deterministic, rule-based; no LLM. When to use: site-wide indexing audits. Pair with `check_robots` for a full pre-crawl picture. For per-page checks, use `audit_page` or `check_technical` instead.
Input schema
{
  "type": "object",
  "properties": {
    "domain": {
      "type": "string",
      "minLength": 3,
      "description": "Hostname or origin to inspect. Examples: `example.com`, `https://example.com`. The tool tries `/sitemap.xml` then the sitemap URL declared in robots.txt; follows sitemap index files one level deep. Read-only HTTP GETs against the domain only."
    },
    "max_urls_to_check": {
      "type": "integer",
      "minimum": 1,
      "maximum": 500,
      "default": 100,
      "description": "Cap on how many URLs from the sitemap to sample for lastmod, image/video extension, and structural checks. Default 100. Increase up to 500 for large sites where you want a more representative sample; each extra URL is one HTTP HEAD."
    }
  },
  "required": [
    "domain"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Output schema
{
  "type": "object",
  "properties": {
    "domain": {
      "type": "string",
      "description": "The hostname the sitemap was checked for."
    },
    "fetched_at": {
      "type": "string",
      "description": "UTC ISO-8601 timestamp of the check."
    },
    "status": {
      "type": "string",
      "enum": [
        "found",
        "missing",
        "error"
      ],
      "description": "Outcome of the sitemap lookup."
    },
    "sitemap_url": {
      "type": [
        "string",
        "null"
      ],
      "description": "Resolved sitemap URL (null when status != found)."
    },
    "total_urls": {
      "type": "number",
      "description": "Total URLs declared across the sitemap (and indexed children)."
    },
    "urls_with_lastmod": {
      "type": "number",
      "description": "Count of URLs that carry a lastmod attribute."
    },
    "findings": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "severity": {
            "type": "string",
            "enum": [
              "critical",
              "warning",
              "info"
            ],
            "description": "Triage priority: critical blocks AI citation, warning hurts probability, info is nice-to-have."
          },
          "category": {
            "type": "string",
            "enum": [
              "schema",
              "robots",
              "technical",
              "freshness",
              "structure",
              "authority",
              "presence",
              "sitemap",
              "llms_txt",
              "citation",
              "evidence",
              "trust",
              "entity",
              "content"
            ],
            "description": "Finding category - which AI-SEO dimension it relates to."
          },
          "where": {
            "type": "string",
            "description": "Location of the issue (CSS selector, JSON-LD path, robots.txt line, or 'page-level')."
          },
          "message": {
            "type": "string",
            "description": "Human-readable description of the issue."
          },
          "fix": {
            "type": "string",
            "description": "Concrete, copy-pasteable fix."
          },
          "estimated_impact": {
            "type": "string",
            "enum": [
              "high",
              "medium",
              "low"
            ],
            "description": "Estimated impact on AI citation probability when resolved."
          },
          "failure_signal": {
            "type": "string",
            "description": "Falsifiability: the observable signal that would prove the fix did NOT work."
          },
          "leading_indicator": {
            "type": "string",
            "description": "Falsifiability: the leading indicator to monitor to confirm the fix is landing."
          }
        },
        "required": [
          "severity",
          "category",
          "where",
          "message",
          "fix"
        ],
        "additionalProperties": false
      }
    }
  },
  "required": [
    "domain",
    "fetched_at",
    "status",
    "sitemap_url",
    "total_urls",
    "urls_with_lastmod",
    "findings"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "title": "Check XML sitemap health",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
Read onlyNon-destructiveIdempotentOpen world
check_technicalAudit a page's HEAD section for technical signals relevant to AI crawlers: HTTPS, canonical, OpenGraph, Twitter Card, hreflang, noindex, and title-vs-H1 hygiene. Read-only. One HTTP GET, inspects HEAD only (body is not parsed). Deterministic, rule-based; no LLM. When to use: when you specifically need HEAD-tag audit findings. For the full page including schema and AI-Overview scoring, use `audit_page`. For canonical-only, use `audit_canonical`.
Input schema
{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "format": "uri",
      "description": "Public URL to audit. The tool fetches the URL once and inspects HEAD-section signals: HTTPS, canonical, OpenGraph, Twitter Card, hreflang, noindex, title length and overlap with H1. Body content is not parsed. Read-only HTTP GET."
    },
    "respect_robots": {
      "type": "boolean",
      "default": true,
      "description": "If true (default), respect robots.txt before fetching. Set false only for auditing your own site where you've intentionally blocked crawlers."
    }
  },
  "required": [
    "url"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Output schema
{
  "type": "object",
  "properties": {
    "url": {
      "type": "string"
    },
    "fetched_at": {
      "type": "string"
    },
    "https": {
      "type": "boolean",
      "description": "Whether the URL is served over HTTPS after redirects."
    },
    "canonical": {
      "type": [
        "string",
        "null"
      ],
      "description": "Canonical link href, if present."
    },
    "og_url": {
      "type": [
        "string",
        "null"
      ],
      "description": "OpenGraph og:url, if present."
    },
    "noindex": {
      "type": "boolean",
      "description": "Whether meta robots includes noindex."
    },
    "title": {
      "type": [
        "string",
        "null"
      ],
      "description": "Page title text."
    },
    "h1": {
      "type": [
        "string",
        "null"
      ],
      "description": "First H1 text."
    },
    "findings": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "severity": {
            "type": "string",
            "enum": [
              "critical",
              "warning",
              "info"
            ],
            "description": "Triage priority: critical blocks AI citation, warning hurts probability, info is nice-to-have."
          },
          "category": {
            "type": "string",
            "enum": [
              "schema",
              "robots",
              "technical",
              "freshness",
              "structure",
              "authority",
              "presence",
              "sitemap",
              "llms_txt",
              "citation",
              "evidence",
              "trust",
              "entity",
              "content"
            ],
            "description": "Finding category - which AI-SEO dimension it relates to."
          },
          "where": {
            "type": "string",
            "description": "Location of the issue (CSS selector, JSON-LD path, robots.txt line, or 'page-level')."
          },
          "message": {
            "type": "string",
            "description": "Human-readable description of the issue."
          },
          "fix": {
            "type": "string",
            "description": "Concrete, copy-pasteable fix."
          },
          "estimated_impact": {
            "type": "string",
            "enum": [
              "high",
              "medium",
              "low"
            ],
            "description": "Estimated impact on AI citation probability when resolved."
          },
          "failure_signal": {
            "type": "string",
            "description": "Falsifiability: the observable signal that would prove the fix did NOT work."
          },
          "leading_indicator": {
            "type": "string",
            "description": "Falsifiability: the leading indicator to monitor to confirm the fix is landing."
          }
        },
        "required": [
          "severity",
          "category",
          "where",
          "message",
          "fix"
        ],
        "additionalProperties": false
      }
    }
  },
  "required": [
    "url",
    "fetched_at",
    "https",
    "canonical",
    "og_url",
    "noindex",
    "title",
    "h1",
    "findings"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "title": "Check technical HEAD signals",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
Read onlyNon-destructiveIdempotentOpen world
diff_pagesCompare two URLs for AI citation-worthiness and return a structured breakdown of which page is more likely to be cited and why. Typical use: your page (url_a) vs a competitor's page (url_b). Read-only. Runs audit_page on both URLs in parallel (2 HTTP fetches per URL), then diffs dimension_scores and findings. No new fetch logic beyond what audit_page already does. Deterministic, rule-based; no LLM calls. Same two URLs return the same comparison on repeated runs. When to use: competitive gap analysis - understand exactly which dimensions (schema, structure, robots, entity density, freshness, technical, authority, sitemap) put a competitor ahead, and get prioritized fix_recommendations_for_a to close the gap. For a single-URL audit, use audit_page. For overall scoring of one page, use score_citation_worthiness. Capped at 2 URLs per call. Heuristic verdict - does not claim to know what AI assistants actually cite; verdict matches audit_page's existing rubric.
Input schema
{
  "type": "object",
  "properties": {
    "url_a": {
      "type": "string",
      "format": "uri",
      "description": "First URL to compare - typically your own page. Must be a fully-qualified http(s) URL that returns HTTP 200 (redirects are followed)."
    },
    "url_b": {
      "type": "string",
      "format": "uri",
      "description": "Second URL to compare - typically a competitor's page. Must be a fully-qualified http(s) URL that returns HTTP 200 (redirects are followed)."
    },
    "query": {
      "type": "string",
      "description": "Optional target search query both pages are competing for (e.g. 'how to connect Zapier to Notion'). When provided, it is surfaced in fix_recommendations_for_a as context. Does not alter the scoring algorithm - scoring is based on audit_page's existing rubric."
    },
    "respect_robots": {
      "type": "boolean",
      "default": true,
      "description": "If true (default), respect robots.txt before fetching each URL. Set false only when auditing your own sites where you have intentionally blocked crawlers."
    }
  },
  "required": [
    "url_a",
    "url_b"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Output schema
{
  "type": "object",
  "properties": {
    "url_a": {
      "type": "string"
    },
    "url_b": {
      "type": "string"
    },
    "query": {
      "type": [
        "string",
        "null"
      ]
    },
    "better_for_citation": {
      "type": "string",
      "enum": [
        "a",
        "b",
        "tie"
      ]
    },
    "scores": {
      "type": "object",
      "properties": {
        "a": {
          "type": "number"
        },
        "b": {
          "type": "number"
        }
      },
      "required": [
        "a",
        "b"
      ],
      "additionalProperties": false
    },
    "delta": {
      "type": "object",
      "additionalProperties": {
        "type": "object",
        "properties": {
          "a": {
            "type": "number"
          },
          "b": {
            "type": "number"
          },
          "advantage": {
            "type": "string",
            "enum": [
              "a",
              "b",
              "tie"
            ]
          }
        },
        "required": [
          "a",
          "b",
          "advantage"
        ],
        "additionalProperties": false
      }
    },
    "missing_in_a": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "missing_in_b": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "fix_recommendations_for_a": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "category": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "fix": {
            "type": "string"
          }
        },
        "required": [
          "category",
          "message",
          "fix"
        ],
        "additionalProperties": false
      }
    }
  },
  "required": [
    "url_a",
    "url_b",
    "query",
    "better_for_citation",
    "scores",
    "delta",
    "missing_in_a",
    "missing_in_b",
    "fix_recommendations_for_a"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "title": "Diff two pages for citation-worthiness",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
Read onlyNon-destructiveIdempotentOpen world
extract_entitiesExtract named entities, linked concepts, and sameAs graph nodes from a page's content and structured data. Combines body-text NER with JSON-LD `@type` / `sameAs` walking. Read-only when given `url` (one HTTP GET). Zero network when given `text`. Primary path: MCP sampling - the host LLM does the NER and returns typed entities with sameAs URIs. Fallback path: deterministic regex-based extractor when sampling is unavailable. The result includes `mode: "sampling" | "regex_fallback"` so callers can tell which path ran. When to use: building an entity map for schema generation, or auditing whether a page's entities match its target topic. To validate the JSON-LD itself, use `audit_schema`. Either `url` or `text` must be provided.
Input schema
{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "format": "uri",
      "description": "Public URL to fetch and analyze. Either this OR `text` is required."
    },
    "text": {
      "type": "string",
      "description": "Raw text/HTML to analyze directly. Either this OR `url` is required."
    },
    "respect_robots": {
      "type": "boolean",
      "default": true,
      "description": "If true (default), respect robots.txt when fetching `url`. Ignored when `text` is used."
    },
    "render": {
      "type": "string",
      "enum": [
        "static",
        "headless"
      ],
      "default": "static",
      "description": "Rendering mode for `url`. `static` (default) reads raw HTML. `headless` runs Playwright Chromium to capture JS-rendered content (adds 3-10s; requires `playwright-core` + `npx playwright install chromium`). Ignored when `text` is used."
    }
  },
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Output schema
{
  "type": "object",
  "properties": {
    "source": {
      "type": "string",
      "enum": [
        "url",
        "text"
      ]
    },
    "url": {
      "type": [
        "string",
        "null"
      ]
    },
    "entity_count": {
      "type": "number"
    },
    "entities": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "confidence": {
            "type": "number"
          },
          "same_as": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "name"
        ],
        "additionalProperties": false
      }
    },
    "citation_density_score": {
      "type": "number",
      "minimum": 0,
      "maximum": 100
    }
  },
  "required": [
    "source",
    "url",
    "entity_count",
    "entities",
    "citation_density_score"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "title": "Extract named entities and sameAs links",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": false,
  "openWorldHint": true
}
Read onlyNon-destructiveNon-idempotentOpen world
llms_txt_generateGenerate a spec-compliant llms.txt (and optionally llms-full.txt) for a domain by reading its sitemap, sampling up to `max_pages` pages, and synthesizing a grouped, sectioned summary. Read-only. Issues one HTTP GET for the sitemap then one per sampled page. Deterministic; no LLM. Output is the file content as a string - this tool does NOT write to disk or upload anywhere. The caller is responsible for hosting the resulting file at `https://<domain>/llms.txt`. When to use: bootstrapping llms.txt for a site you own. To check an existing llms.txt, use `llms_txt_validate` instead.
Input schema
{
  "type": "object",
  "properties": {
    "domain": {
      "type": "string",
      "minLength": 3,
      "description": "Hostname or origin to generate llms.txt for. Examples: `example.com`, `https://example.com`. The tool reads the domain's sitemap, fetches up to `max_pages` of them, and synthesizes a spec-compliant llms.txt grouped by section. Issues N+1 HTTP GETs: one for the sitemap, then one per sampled page. Read-only."
    },
    "max_pages": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100,
      "default": 30,
      "description": "How many pages to sample from the sitemap when building section groupings. Default 30. Each page is fetched (one HTTP GET per page) - keep this low for large sites or rate-limited hosts."
    },
    "include_full": {
      "type": "boolean",
      "default": false,
      "description": "If true, also generate llms-full.txt (the expanded variant containing full page text, not just URLs and titles). Default false. The llms-full.txt output can be large; only enable when you actually plan to host both files."
    },
    "site_name": {
      "type": "string",
      "description": "Override the site name used in the generated llms.txt header. If omitted, inferred from the homepage's <title> tag."
    },
    "site_description": {
      "type": "string",
      "description": "Override the site description used in the generated llms.txt header. If omitted, inferred from the homepage's meta description."
    }
  },
  "required": [
    "domain"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Output schema
{
  "type": "object",
  "properties": {
    "domain": {
      "type": "string"
    },
    "llms_txt": {
      "type": "string",
      "description": "The generated llms.txt file content. Caller is responsible for hosting it."
    },
    "llms_full_txt": {
      "type": [
        "string",
        "null"
      ],
      "description": "The generated llms-full.txt content. Null unless include_full=true."
    },
    "pages_indexed": {
      "type": "number",
      "description": "Number of pages successfully sampled from the sitemap."
    }
  },
  "required": [
    "domain",
    "llms_txt",
    "pages_indexed"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "title": "Generate llms.txt",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
Read onlyNon-destructiveIdempotentOpen world
llms_txt_validateValidate an existing llms.txt or llms-full.txt against the spec: structure, section ordering, link format, and (optionally) broken-link detection. Read-only. One HTTP GET when given `url`; zero network when given `content`. Optional link-check issues HEAD requests against each link if `check_links` is true. Deterministic; no LLM. When to use: auditing an llms.txt you already have. To generate one from scratch, use `llms_txt_generate`. Either `url` or `content` must be provided.
Input schema
{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "format": "uri",
      "description": "Public URL of an existing llms.txt or llms-full.txt to validate (e.g. `https://example.com/llms.txt`). Either this OR `content` is required."
    },
    "content": {
      "type": "string",
      "description": "Raw llms.txt content as a string. Use this to validate a file offline without fetching. Either this OR `url` is required."
    },
    "check_links": {
      "type": "boolean",
      "default": true,
      "description": "If true (default), HEAD each linked URL to detect broken links. Set false to skip link checks for faster, network-light validation of just the structural rules."
    }
  },
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Output schema
{
  "type": "object",
  "properties": {
    "source": {
      "type": "string",
      "enum": [
        "url",
        "content"
      ]
    },
    "url": {
      "type": [
        "string",
        "null"
      ]
    },
    "valid": {
      "type": "boolean",
      "description": "Whether the file passes structural and link rules."
    },
    "findings": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "severity": {
            "type": "string",
            "enum": [
              "critical",
              "warning",
              "info"
            ],
            "description": "Triage priority: critical blocks AI citation, warning hurts probability, info is nice-to-have."
          },
          "category": {
            "type": "string",
            "enum": [
              "schema",
              "robots",
              "technical",
              "freshness",
              "structure",
              "authority",
              "presence",
              "sitemap",
              "llms_txt",
              "citation",
              "evidence",
              "trust",
              "entity",
              "content"
            ],
            "description": "Finding category - which AI-SEO dimension it relates to."
          },
          "where": {
            "type": "string",
            "description": "Location of the issue (CSS selector, JSON-LD path, robots.txt line, or 'page-level')."
          },
          "message": {
            "type": "string",
            "description": "Human-readable description of the issue."
          },
          "fix": {
            "type": "string",
            "description": "Concrete, copy-pasteable fix."
          },
          "estimated_impact": {
            "type": "string",
            "enum": [
              "high",
              "medium",
              "low"
            ],
            "description": "Estimated impact on AI citation probability when resolved."
          },
          "failure_signal": {
            "type": "string",
            "description": "Falsifiability: the observable signal that would prove the fix did NOT work."
          },
          "leading_indicator": {
            "type": "string",
            "description": "Falsifiability: the leading indicator to monitor to confirm the fix is landing."
          }
        },
        "required": [
          "severity",
          "category",
          "where",
          "message",
          "fix"
        ],
        "additionalProperties": false
      }
    }
  },
  "required": [
    "source",
    "url",
    "valid",
    "findings"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "title": "Validate llms.txt",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
Read onlyNon-destructiveIdempotentOpen world
pricing_generateGenerate a machine-readable /pricing.md for AI shopping/agent flows. Finds the site's pricing page (or uses `pricing_url`), extracts named tiers and price lines, and returns the file content as a string. Read-only. Issues a few HTTP GETs probing common pricing paths. Deterministic; no LLM. Does NOT write or upload — the caller hosts the file at `https://<domain>/pricing.md`. When to use: a SaaS/e-commerce site that wants agents to read pricing without parsing a JS-rendered table. Falls back to a fill-in template when no prices are detectable.
Input schema
{
  "type": "object",
  "properties": {
    "domain": {
      "type": "string",
      "minLength": 3,
      "description": "Hostname or origin to generate pricing.md for, e.g. `example.com`. The tool finds the pricing page (or uses `pricing_url`), extracts tiers and prices, and returns a machine-readable pricing.md string. Read-only."
    },
    "pricing_url": {
      "type": "string",
      "format": "uri",
      "description": "Explicit pricing page URL. If omitted, the tool probes common paths (/pricing, /plans, /pricing/)."
    }
  },
  "required": [
    "domain"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Output schema
{
  "type": "object",
  "properties": {
    "domain": {
      "type": "string"
    },
    "pricing_md": {
      "type": "string",
      "description": "The generated pricing.md content. Caller hosts it at /pricing.md."
    },
    "source_url": {
      "type": [
        "string",
        "null"
      ],
      "description": "The pricing page the content was derived from (null when none was found)."
    },
    "tiers_detected": {
      "type": "number",
      "description": "Number of pricing tiers extracted."
    },
    "validation_issues": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "severity": {
            "type": "string",
            "enum": [
              "critical",
              "warning",
              "info"
            ],
            "description": "Triage priority: critical blocks AI citation, warning hurts probability, info is nice-to-have."
          },
          "category": {
            "type": "string",
            "enum": [
              "schema",
              "robots",
              "technical",
              "freshness",
              "structure",
              "authority",
              "presence",
              "sitemap",
              "llms_txt",
              "citation",
              "evidence",
              "trust",
              "entity",
              "content"
            ],
            "description": "Finding category - which AI-SEO dimension it relates to."
          },
          "where": {
            "type": "string",
            "description": "Location of the issue (CSS selector, JSON-LD path, robots.txt line, or 'page-level')."
          },
          "message": {
            "type": "string",
            "description": "Human-readable description of the issue."
          },
          "fix": {
            "type": "string",
            "description": "Concrete, copy-pasteable fix."
          },
          "estimated_impact": {
            "type": "string",
            "enum": [
              "high",
              "medium",
              "low"
            ],
            "description": "Estimated impact on AI citation probability when resolved."
          },
          "failure_signal": {
            "type": "string",
            "description": "Falsifiability: the observable signal that would prove the fix did NOT work."
          },
          "leading_indicator": {
            "type": "string",
            "description": "Falsifiability: the leading indicator to monitor to confirm the fix is landing."
          }
        },
        "required": [
          "severity",
          "category",
          "where",
          "message",
          "fix"
        ],
        "additionalProperties": false
      },
      "description": "Issues encountered while deriving the file."
    },
    "suggested_path": {
      "type": "string",
      "const": "/pricing.md"
    }
  },
  "required": [
    "domain",
    "pricing_md",
    "source_url",
    "tiers_detected",
    "validation_issues",
    "suggested_path"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "title": "Generate pricing.md",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
Read onlyNon-destructiveIdempotentOpen world
report_saveRender an audit_page or audit_site result as a Markdown report and write it to a file under MCP_WORKSPACE_ROOT (defaults to cwd).
Input schema
{
  "type": "object",
  "properties": {
    "audit_result": {
      "description": "The return value of `audit_page` or `audit_site`. Pass the structured result verbatim - the tool detects which shape it is and renders the matching Markdown report."
    },
    "path": {
      "type": "string",
      "minLength": 1,
      "description": "Target file path. May be relative to MCP_WORKSPACE_ROOT (or cwd if unset). Paths that escape the workspace root are rejected."
    },
    "overwrite": {
      "type": "boolean",
      "default": true,
      "description": "If true (default), overwrite an existing file. If false, the write fails when the target already exists."
    }
  },
  "required": [
    "path"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Output schema
{
  "type": "object",
  "properties": {
    "saved_to": {
      "type": "string",
      "description": "Absolute path of the file that was written."
    },
    "bytes_written": {
      "type": "number"
    },
    "format": {
      "type": "string",
      "enum": [
        "audit_page",
        "audit_site"
      ],
      "description": "Which input shape the report was rendered for."
    }
  },
  "required": [
    "saved_to",
    "bytes_written",
    "format"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "title": "Save audit report to disk",
  "readOnlyHint": false,
  "destructiveHint": true,
  "idempotentHint": true,
  "openWorldHint": false
}
WritesDestructiveIdempotentClosed world
rewrite_aeoRewrite a content block for Answer Engine Optimization. Adds a BLUF opening, FAQ structure, schema additions, and concise question-shaped headings tuned for ChatGPT / Perplexity / Google AI Overviews. Read-only when given `url` (one HTTP GET). Zero network when given `text`. The tool does NOT write back to the URL - it only returns the rewritten content as a string. No side effects on the source. This tool delegates the actual rewrite to the calling LLM via MCP sampling - it does not call any external API itself. The MCP host's model produces the rewrite. Same input may produce different output across runs (model-dependent). When to use: optimizing content for direct-answer surfaces (definitions, how-tos, FAQs). For Generative Engine Optimization (entity-rich, comparison-ready synthesis), use `rewrite_geo` instead. Either `url` or `text` must be provided. `target_query` is required.
Input schema
{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "format": "uri",
      "description": "Public URL whose content should be fetched and rewritten. Either this OR `text` is required."
    },
    "text": {
      "type": "string",
      "description": "Raw content (markdown or HTML) to rewrite directly. Either this OR `url` is required."
    },
    "target_query": {
      "type": "string",
      "description": "The user query the rewrite should answer (e.g. `what is RAG`, `how to deploy Ghost to Docker`). Required - drives heading shape and BLUF wording."
    },
    "format": {
      "type": "string",
      "enum": [
        "article",
        "faq",
        "howto",
        "comparison"
      ],
      "default": "article",
      "description": "Output shape. `article` for prose-with-headings. `faq` for Q&A list. `howto` for numbered-step procedural content with HowTo schema hints. `comparison` for X-vs-Y tables. Default `article`."
    },
    "max_words": {
      "type": "integer",
      "minimum": 100,
      "maximum": 5000,
      "default": 1500,
      "description": "Soft word budget for the rewrite. Default 1500. Range 100-5000. The rewrite tries to stay under this; very small budgets may force truncation."
    },
    "respect_robots": {
      "type": "boolean",
      "default": true,
      "description": "If true (default), respect robots.txt when fetching `url`. Ignored when `text` is used."
    }
  },
  "required": [
    "target_query"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Output schema
{
  "type": "object",
  "properties": {
    "source": {
      "type": "string",
      "enum": [
        "url",
        "text"
      ]
    },
    "url": {
      "type": [
        "string",
        "null"
      ]
    },
    "target_query": {
      "type": "string"
    },
    "format": {
      "type": "string",
      "description": "Output format (article, faq, howto, comparison)."
    },
    "rewritten": {
      "type": "string",
      "description": "The rewritten content. The caller decides where to publish it."
    },
    "notes": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Notes from the rewrite (e.g. truncations, format adjustments)."
    }
  },
  "required": [
    "source",
    "url",
    "target_query",
    "rewritten",
    "notes"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "title": "Rewrite for Answer Engine Optimization",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": false,
  "openWorldHint": true
}
Read onlyNon-destructiveNon-idempotentOpen world
rewrite_geoRewrite a content block for Generative Engine Optimization: entity-rich, comparison-ready, synthesis-friendly. Tuned for surfaces that summarize across sources (Perplexity, Google AI Mode, Claude search). Read-only on input. Does NOT write back to the source URL - returns the rewritten content as a string. This tool delegates the actual rewrite to the calling LLM via MCP sampling - it does not call any external API itself. The MCP host's model produces the rewrite. Output may vary across runs (model-dependent). When to use: optimizing for synthesis-style answers across multiple sources. For direct-answer (BLUF + FAQ) optimization on a single page, use `rewrite_aeo` instead. Either `url` or `text` must be provided. `target_query` is required.
Input schema
{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "format": "uri",
      "description": "Public URL whose content should be fetched and rewritten. Either this OR `text` is required."
    },
    "text": {
      "type": "string",
      "description": "Raw content to rewrite directly. Either this OR `url` is required."
    },
    "target_query": {
      "type": "string",
      "description": "The user query the rewrite should answer. Required - drives entity selection and comparison framing."
    },
    "add_comparison_table": {
      "type": "boolean",
      "default": false,
      "description": "If true, inject an explicit X-vs-Y comparison table into the rewrite (useful for `X vs Y` queries). Default false."
    },
    "max_words": {
      "type": "integer",
      "minimum": 100,
      "maximum": 5000,
      "default": 1500,
      "description": "Soft word budget. Default 1500. Range 100-5000."
    },
    "respect_robots": {
      "type": "boolean",
      "default": true,
      "description": "If true (default), respect robots.txt when fetching `url`. Ignored when `text` is used."
    }
  },
  "required": [
    "target_query"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Output schema
{
  "type": "object",
  "properties": {
    "source": {
      "type": "string",
      "enum": [
        "url",
        "text"
      ]
    },
    "url": {
      "type": [
        "string",
        "null"
      ]
    },
    "target_query": {
      "type": "string"
    },
    "format": {
      "type": "string",
      "description": "Output format (article, faq, howto, comparison)."
    },
    "rewritten": {
      "type": "string",
      "description": "The rewritten content. The caller decides where to publish it."
    },
    "notes": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Notes from the rewrite (e.g. truncations, format adjustments)."
    }
  },
  "required": [
    "source",
    "url",
    "target_query",
    "rewritten",
    "notes"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "title": "Rewrite for Generative Engine Optimization",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": false,
  "openWorldHint": true
}
Read onlyNon-destructiveNon-idempotentOpen world
score_agentic_browsingScore a page against the four signals Google added to the Lighthouse "Agentic Browsing" category in May 2026: presence of an llms.txt, WebMCP integration, accessibility-tree integrity, and layout stability. Returns an overall 0-100 score, a letter grade, and a per-factor breakdown. Read-only. One HTTP GET for the page plus one for /llms.txt (skip with check_llms_txt=false). Pass `html` instead of `url` to score markup offline (llms.txt is then treated as absent). Deterministic, rule-based heuristics over the fetched HTML; no LLM and no headless render required. This approximates Lighthouse's runtime signals from static markup - it does not execute Lighthouse. When to use: checking whether a site is ready for AI agents / agentic browsers, or tracking the new Lighthouse Agentic Browsing category. For citation-eligibility of content, use `score_citation_worthiness`; for a full page audit, use `audit_page`.
Input schema
{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "format": "uri",
      "description": "Public URL to fetch and score. Either this OR `html` is required."
    },
    "html": {
      "type": "string",
      "description": "Raw HTML to score offline without fetching. Either this OR `url` is required. llms.txt is treated as absent in this mode."
    },
    "respect_robots": {
      "type": "boolean",
      "default": true,
      "description": "If true (default), respect robots.txt when fetching `url`. Ignored when `html` is used."
    },
    "render": {
      "type": "string",
      "enum": [
        "static",
        "headless"
      ],
      "default": "static",
      "description": "Rendering mode for `url`. `static` (default) reads raw HTML; `headless` runs Playwright Chromium (adds 3-10s; requires `playwright-core`). Ignored when `html` is used."
    },
    "check_llms_txt": {
      "type": "boolean",
      "default": true,
      "description": "If true (default), probe /llms.txt for the host to score the llms.txt factor. Set false to skip that extra HTTP GET."
    }
  },
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Output schema
{
  "type": "object",
  "properties": {
    "url": {
      "type": [
        "string",
        "null"
      ],
      "description": "The URL scored (null when scoring raw html)."
    },
    "fetched_at": {
      "type": "string",
      "description": "UTC ISO-8601 timestamp."
    },
    "score": {
      "type": "number",
      "minimum": 0,
      "maximum": 100,
      "description": "Weighted 0-100 Agentic Browsing score (accessibility 40%, layout 35%, webmcp 15%, llms.txt 10%)."
    },
    "grade": {
      "type": "string",
      "enum": [
        "A",
        "B",
        "C",
        "D",
        "F"
      ],
      "description": "Letter grade derived from the numeric score."
    },
    "factors": {
      "type": "object",
      "properties": {
        "llms_txt": {
          "type": "object",
          "properties": {
            "score": {
              "type": "number",
              "minimum": 0,
              "maximum": 100,
              "description": "0-100 subscore for this signal."
            },
            "detail": {
              "type": "string",
              "description": "One-line description of what was measured."
            }
          },
          "required": [
            "score",
            "detail"
          ],
          "additionalProperties": false
        },
        "webmcp": {
          "$ref": "#/properties/factors/properties/llms_txt"
        },
        "accessibility_tree": {
          "$ref": "#/properties/factors/properties/llms_txt"
        },
        "layout_stability": {
          "$ref": "#/properties/factors/properties/llms_txt"
        }
      },
      "required": [
        "llms_txt",
        "webmcp",
        "accessibility_tree",
        "layout_stability"
      ],
      "additionalProperties": false,
      "description": "The four Lighthouse Agentic Browsing signals, scored 0-100 each."
    },
    "findings": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "severity": {
            "type": "string",
            "enum": [
              "critical",
              "warning",
              "info"
            ],
            "description": "Triage priority: critical blocks AI citation, warning hurts probability, info is nice-to-have."
          },
          "category": {
            "type": "string",
            "enum": [
              "schema",
              "robots",
              "technical",
              "freshness",
              "structure",
              "authority",
              "presence",
              "sitemap",
              "llms_txt",
              "citation",
              "evidence",
              "trust",
              "entity",
              "content"
            ],
            "description": "Finding category - which AI-SEO dimension it relates to."
          },
          "where": {
            "type": "string",
            "description": "Location of the issue (CSS selector, JSON-LD path, robots.txt line, or 'page-level')."
          },
          "message": {
            "type": "string",
            "description": "Human-readable description of the issue."
          },
          "fix": {
            "type": "string",
            "description": "Concrete, copy-pasteable fix."
          },
          "estimated_impact": {
            "type": "string",
            "enum": [
              "high",
              "medium",
              "low"
            ],
            "description": "Estimated impact on AI citation probability when resolved."
          },
          "failure_signal": {
            "type": "string",
            "description": "Falsifiability: the observable signal that would prove the fix did NOT work."
          },
          "leading_indicator": {
            "type": "string",
            "description": "Falsifiability: the leading indicator to monitor to confirm the fix is landing."
          }
        },
        "required": [
          "severity",
          "category",
          "where",
          "message",
          "fix"
        ],
        "additionalProperties": false
      }
    }
  },
  "required": [
    "url",
    "fetched_at",
    "score",
    "grade",
    "factors",
    "findings"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "title": "Score Agentic Browsing readiness",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
Read onlyNon-destructiveIdempotentOpen world
score_ai_overview_eligibilityScore a page's probability of appearing in Google AI Overviews. Returns an overall 0-100 score plus six factor subscores: semantic completeness, structured data, E-E-A-T signals, entity density, freshness, and technical hygiene. Read-only. One HTTP GET. Deterministic, rule-based scoring derived from published 2025-2026 AI-Overview correlation studies. No LLM calls. Same URL returns the same score on repeated runs. When to use: AI-Overview-specific prioritization. For a multi-dimensional audit that includes this scoring plus everything else, use `audit_page`. For citation-worthiness of a specific text passage (rather than a URL ranking probability), use `score_citation_worthiness`.
Input schema
{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "format": "uri",
      "description": "Public URL to score. The tool fetches the URL once and runs deterministic, rule-based scoring across six factors (semantic completeness, structured data, E-E-A-T signals, entity density, freshness, technical hygiene) using published 2025-2026 correlation studies. No LLM calls. Read-only HTTP GET."
    },
    "respect_robots": {
      "type": "boolean",
      "default": true,
      "description": "If true (default), respect robots.txt before fetching. Set false only for auditing your own site where you've intentionally blocked crawlers."
    }
  },
  "required": [
    "url"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Output schema
{
  "type": "object",
  "properties": {
    "url": {
      "type": "string"
    },
    "fetched_at": {
      "type": "string"
    },
    "overall_eligibility_score": {
      "type": "number",
      "minimum": 0,
      "maximum": 100
    },
    "factors": {
      "type": "object",
      "properties": {
        "semantic_completeness": {
          "type": "number"
        },
        "structured_data": {
          "type": "number"
        },
        "eeat_signals": {
          "type": "number"
        },
        "entity_density": {
          "type": "number"
        },
        "freshness": {
          "type": "number"
        },
        "technical_hygiene": {
          "type": "number"
        }
      },
      "required": [
        "semantic_completeness",
        "structured_data",
        "eeat_signals",
        "entity_density",
        "freshness",
        "technical_hygiene"
      ],
      "additionalProperties": false,
      "description": "Per-factor 0-100 subscores."
    },
    "top_improvements": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "factor": {
            "type": "string"
          },
          "suggestion": {
            "type": "string"
          }
        },
        "required": [
          "factor",
          "suggestion"
        ],
        "additionalProperties": false
      }
    }
  },
  "required": [
    "url",
    "fetched_at",
    "overall_eligibility_score",
    "factors",
    "top_improvements"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "title": "Score AI Overview eligibility",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
Read onlyNon-destructiveIdempotentOpen world
score_citation_worthinessScore how citable a page or text block is for AI engines (ChatGPT, Claude, Perplexity, Google AI Overviews). Evaluates BLUF (bottom-line-up-front) opening, FAQ patterns, statistic density, entity clarity, and answer-shape fit for the optional `target_query`. Also returns `extractability_score` plus per-section `chunk_analysis`: how cleanly an LLM can lift a self-contained answer from each heading-delimited section (length band, lead-sentence directness, anaphora, concrete anchors). This is the GEO mechanic - it pinpoints the exact sections to tighten, with `most_extractable` / `least_extractable` called out. Read-only when given `url` (one HTTP GET). Zero network when given `text`. No writes. Deterministic, rule-based; no LLM calls. Returns reproducible scores. When to use: pre-publish content QA, or to triage which existing pages are worth optimizing for AI citation first. Distinct from `score_ai_overview_eligibility` which scores Google-AI-Overview ranking probability for a URL; this scores the inherent citability of a text passage regardless of host. Either `url` or `text` must be provided.
Input schema
{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "format": "uri",
      "description": "Public URL to fetch and score. Either this OR `text` is required."
    },
    "text": {
      "type": "string",
      "description": "Raw text/markdown/HTML to score directly without fetching. Either this OR `url` is required."
    },
    "target_query": {
      "type": "string",
      "description": "Optional target search query the content is supposed to answer (e.g. `how to fix CORS errors in Next.js`). When provided, scoring weights answer-shape fit and query-term coverage. Omit if you want a query-agnostic citability score."
    },
    "respect_robots": {
      "type": "boolean",
      "default": true,
      "description": "If true (default), respect robots.txt when fetching `url`. Ignored when `text` is used."
    }
  },
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Output schema
{
  "type": "object",
  "properties": {
    "source": {
      "type": "string",
      "enum": [
        "url",
        "text"
      ]
    },
    "url": {
      "type": [
        "string",
        "null"
      ]
    },
    "target_query": {
      "type": [
        "string",
        "null"
      ]
    },
    "overall_score": {
      "type": "number",
      "minimum": 0,
      "maximum": 100
    },
    "engine_scores": {
      "type": "object",
      "properties": {
        "perplexity": {
          "type": "number"
        },
        "chatgpt": {
          "type": "number"
        },
        "google_ai_overviews": {
          "type": "number"
        },
        "claude": {
          "type": "number"
        }
      },
      "required": [
        "perplexity",
        "chatgpt",
        "google_ai_overviews",
        "claude"
      ],
      "additionalProperties": false
    },
    "signals": {
      "type": "object",
      "additionalProperties": {
        "type": "number"
      },
      "description": "Per-signal subscores (bluf, faq, stats, entities, etc.)."
    },
    "suggestions": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "extractability_score": {
      "type": "number",
      "minimum": 0,
      "maximum": 100,
      "description": "Length-weighted mean of per-section extractability scores."
    },
    "chunk_analysis": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "heading": {
            "type": "string"
          },
          "level": {
            "type": "number"
          },
          "word_count": {
            "type": "number"
          },
          "score": {
            "type": "number",
            "minimum": 0,
            "maximum": 100
          },
          "issues": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "heading",
          "level",
          "word_count",
          "score",
          "issues"
        ],
        "additionalProperties": false
      },
      "description": "Per-section extractability: how cleanly an LLM can lift a standalone answer from each chunk."
    },
    "most_extractable": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "heading": {
              "type": "string"
            },
            "score": {
              "type": "number"
            }
          },
          "required": [
            "heading",
            "score"
          ],
          "additionalProperties": false
        },
        {
          "type": "null"
        }
      ]
    },
    "least_extractable": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "heading": {
              "type": "string"
            },
            "score": {
              "type": "number"
            }
          },
          "required": [
            "heading",
            "score"
          ],
          "additionalProperties": false
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "required": [
    "source",
    "url",
    "target_query",
    "overall_score",
    "engine_scores",
    "signals",
    "suggestions"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "title": "Score AI citation worthiness",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
Read onlyNon-destructiveIdempotentOpen world
score_test_citationSimulate `would an AI engine cite this page for this query?`. The host LLM role-plays the chosen engine (chatgpt / claude / perplexity / google_ai_overviews / any), reads the page content, and returns a cite/no-cite verdict with the verbatim excerpt it would surface plus ranked improvements. Read-only when given `url` (one HTTP GET). Zero network when given `text`. Primary path uses MCP sampling. If the host doesn't support sampling, falls back to a deterministic heuristic derived from `score_citation_worthiness` (overall_score + per-engine subscore must both clear thresholds). The result includes `mode: "sampling" | "static_heuristic"` so callers can tell which path ran. When to use: pre-publish gut-check for a specific query, or auditing whether existing content earns citation surface. Distinct from `score_citation_worthiness` (deterministic 0-100 score) and `audit_page` (whole-page rubric); this returns a binary cite/no-cite verdict tied to one query. Either `url` or `text` must be provided. `target_query` is required.
Input schema
{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "format": "uri",
      "description": "Public URL to fetch and test. Either this OR `text` is required."
    },
    "text": {
      "type": "string",
      "description": "Raw text/HTML to test directly. Either this OR `url` is required."
    },
    "target_query": {
      "type": "string",
      "minLength": 3,
      "description": "The user query the engine is answering. Required. Example: `how to add JSON-LD to a Next.js app`."
    },
    "engine": {
      "type": "string",
      "enum": [
        "chatgpt",
        "claude",
        "perplexity",
        "google_ai_overviews",
        "any"
      ],
      "default": "any",
      "description": "Which engine to simulate. `any` (default) uses a generic AI-search persona. Specific engines tune the cite criteria (e.g. perplexity favors statistic-dense excerpts; google_ai_overviews favors schema + freshness)."
    },
    "respect_robots": {
      "type": "boolean",
      "default": true,
      "description": "If true (default), respect robots.txt when fetching `url`. Ignored when `text` is used."
    }
  },
  "required": [
    "target_query"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Output schema
{
  "type": "object",
  "properties": {
    "target_query": {
      "type": "string",
      "description": "The query the engine simulation answered."
    },
    "engine": {
      "type": "string",
      "enum": [
        "chatgpt",
        "claude",
        "perplexity",
        "google_ai_overviews",
        "any"
      ],
      "description": "Which engine persona produced the verdict."
    },
    "would_cite": {
      "type": "boolean",
      "description": "Binary verdict: would the simulated engine cite this page for the query?"
    },
    "confidence": {
      "type": "number",
      "minimum": 0,
      "maximum": 100,
      "description": "How likely a real engine is to surface this page (0-100)."
    },
    "citation_excerpt": {
      "type": [
        "string",
        "null"
      ],
      "description": "If would_cite=true, the 20-60 word verbatim excerpt the engine would surface; otherwise null."
    },
    "reasoning": {
      "type": "string",
      "description": "Plain-language explanation of the verdict."
    },
    "blocking_issues": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Concrete reasons the page is (or is not) citable. Empty if would_cite=true and excerpt is clearly attributable."
    },
    "improvements": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "change": {
            "type": "string",
            "description": "Specific edit the author should make."
          },
          "estimated_impact": {
            "type": "string",
            "enum": [
              "high",
              "medium",
              "low"
            ],
            "description": "Estimated impact of this change on citation probability."
          }
        },
        "required": [
          "change",
          "estimated_impact"
        ],
        "additionalProperties": false
      },
      "description": "Ranked, specific edits to improve citation probability."
    },
    "mode": {
      "type": "string",
      "enum": [
        "sampling",
        "static_heuristic"
      ],
      "description": "Which code path produced the result: MCP sampling (host LLM) or deterministic heuristic fallback."
    }
  },
  "required": [
    "target_query",
    "engine",
    "would_cite",
    "confidence",
    "citation_excerpt",
    "reasoning",
    "blocking_issues",
    "improvements",
    "mode"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "title": "Test whether an AI engine would cite this page",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": false,
  "openWorldHint": true
}
Read onlyNon-destructiveNon-idempotentOpen world

Resources 2

  • ai-citation-signalsai-citation://signals

    The 13 signals AI assistants use to decide what to cite, with examples.

  • ai-crawlersai-citation://crawlers

    Catalog of AI training, search, and user-triggered crawlers with robots.txt syntax.

Resource templates 0

  • None observed.

Prompts 5

  • audit_my_homepageaudit_my_homepage

    Run a full AI-SEO audit of a site's homepage.

  • check_ai_crawler_accesscheck_ai_crawler_access

    Report which AI training and search crawlers can access a domain.

  • find_citation_blockersfind_citation_blockers

    Audit a URL and surface only the critical findings blocking AI citations.

  • generate_llms_txt_for_domaingenerate_llms_txt_for_domain

    Generate a valid llms.txt for a domain.

  • score_my_citation_worthinessscore_my_citation_worthiness

    Score how citable a URL is for AI engines and recommend improvements.

Remote endpoints

EndpointTransportAuthenticationHealthObserved
No verified remote endpoint is linked.

automatelab-ai-seo MCP Server questions

How do I install automatelab-ai-seo MCP Server?

Install the selected package version with: npm install --save-exact @automatelab/ai-seo-mcp@1.0.0

What tools does automatelab-ai-seo MCP Server provide?

automatelab-ai-seo MCP Server exposed 20 tools during independent protocol observation, including audit_canonical, audit_page, audit_schema, audit_site, audit_sitemap, check_robots, check_sitemap, check_technical, and others.

Is automatelab-ai-seo MCP Server secure?

Our scanner tested version 1.0.0 without proving a finding in the methods exercised. This is not a guarantee that every deployment is secure.

Explore related MCP server guides

Curated product and capability guides containing this catalog record.

Official vs Community MCP Servers

Let’s talk about MCP security.

Share your details and our security team will contact you.