Skip to main content
Glama
AKzar1el

Web Validator by DigestSEO

Web Validator by DigestSEO

npm version CI License: MIT Indexed on TensorBlock MCP Index mcp-web-validator MCP server

An MCP server for HTML and CSS validation, technical SEO and accessibility checks, JSON-LD syntax validation, broken-link checks, and responsive screenshots. It is part of the DigestSEO suite of open-source SEO tools.

Choose the right surface

This repository contains two deliberately separate MCP surfaces:

Surface

Transport

Best for

Access and side effects

Local npm server

stdio

Claude Desktop, Cursor, and other local MCP clients

Can read user-selected workspace files, contact validation and link targets, and write screenshot files.

Hosted app

Streamable HTTP

ChatGPT and remote MCP clients

Can fetch one authorized public HTML page, run a bounded sitemap-first site audit, or process supplied markup. It cannot access local files, authenticate, recursively crawl links, execute page JavaScript, or create screenshots.

Local installation:

npx -y mcp-web-validator

Hosted endpoint:

https://web-validator-mcp.digestseo.com/mcp

Related MCP server: aria51 MCP Server

Requirements

  • Node.js 22.12.0 or newer

  • An MCP client that supports stdio, or a client that supports Streamable HTTP for the hosted endpoint

The validation, SEO, schema, link, and report tools do not download a browser during installation. The local screenshot.capture tool installs its pinned headless browser into Puppeteer's cache on first use, then reuses that browser for later screenshots. Set PUPPETEER_CACHE_DIR if you need a custom cache location.

Tools

The npm package exposes these exact runtime tool names:

Tool

Purpose

Network or filesystem behavior

html.local

Validate a local HTML or XHTML file.

Reads the selected file and submits its markup to the external W3C Nu HTML Checker at validator.w3.org/nu/; .xhtml paths use application/xhtml+xml parsing semantics.

html.url

Validate the markup returned by a public URL.

Fetches the URL, then submits the returned markup to the external Nu checker.

css.local

Validate a local CSS file.

Reads the selected file and submits its CSS to the external W3C Jigsaw CSS Validator.

seo.metadata

Audit titles, descriptions, canonical tags, robots noindex directives, headings, viewport metadata, image alt attributes, and Open Graph metadata.

Processes supplied HTML locally.

links.broken

Check links extracted from supplied HTML.

Sends bounded HTTP requests to eligible public links.

schema.markup

Parse JSON-LD blocks and report JSON syntax errors.

Processes supplied HTML locally.

report.validation

Combine HTML/XHTML, optional CSS, SEO, JSON-LD, and bounded link checks in a Markdown report.

Reads selected files, contacts the validators, and checks eligible public links found in the markup; .xhtml inputs use XHTML parsing semantics for Nu validation.

screenshot.capture

Capture desktop, tablet, mobile, or custom viewport screenshots.

Opens a selected local file or eligible public URL and writes PNG files to the selected output directory; existing matching files may be replaced.

Hosted app tools

The hosted app exposes eight tools:

Tool

Purpose

audit_public_webpage

Fetch one authorized public HTML page and run the combined HTML, SEO/accessibility-signal, and JSON-LD syntax audit. Link checks are optional.

audit_public_site

Run a bounded sitemap-first audit of up to eight authorized, same-origin public pages. It respects robots.txt, returns compact page coverage and deduplicated findings, and does not run site-wide link checks.

validate_html

Validate raw HTML markup already supplied in the conversation.

validate_css

Parse supplied CSS for syntax errors inside the Worker.

audit_seo_metadata

Audit supplied HTML for covered on-page SEO, robots noindex, and accessibility signals.

validate_schema_markup

Check JSON-LD blocks in supplied HTML for JSON syntax errors.

check_broken_links

Check up to 20 authorized public links extracted from supplied HTML.

generate_validation_report

Combine the checks for supplied markup; base_url resolves relative links but does not fetch a page.

audit_public_webpage follows at most three validated redirects, accepts a bounded text/html response, and records the final URL. It does not crawl additional pages, execute JavaScript, authenticate, or fetch linked stylesheets and assets. audit_public_site first locks the final public origin, then reads bounded robots.txt plus same-origin XML Sitemap, RSS 2.0, Atom 1.0, and plain-text sitemap representations before auditing at most eight eligible sitemap pages in one call. Robots discovery may follow up to five validated public redirects across authorities, as defined by the robots protocol; the resulting rules and relative Sitemap directives are still interpreted for the originally audited authority. Sitemap entries and audited pages remain same-origin, and private/reserved destinations, credentials, custom ports, service self-fetches, and HTTPS-to-HTTP redirect downgrades are rejected. The tool never follows HTML links or external sitemap entries; use page_offset when the response says more eligible pages remain. The fetched HTML is sent to https://html5.validator.nu/, the same external Nu HTML Checker used by validate_html and the report tool. CSS parsing, SEO analysis, and JSON-LD parsing run inside the DigestSEO Worker. Optional link checks make capped HEAD requests, with a bounded GET fallback where necessary, to eligible public HTTP(S) URLs; link redirects are reported but not followed. The site tool intentionally does not perform site-wide link checking. The hosted app does not retain tool inputs, fetched HTML, or results.

Privacy Policy

Only validate files, markup, and public webpages that you own or are authorized to inspect. Public page URLs can contain sensitive query values, so remove tokens and private identifiers before submitting them. Do not submit passwords, API keys, access tokens, payment data, health data, private source code, or other sensitive personal data.

The local server runs with the same operating-system permissions as its MCP client. Review tool inputs before approving file access, outbound validation, link checking, or screenshot creation. The hosted app has no access to your local filesystem.

See the published privacy policy for data-handling details and SECURITY.md for private vulnerability reporting.

Configure a local client

Claude Desktop

Add the server to claude_desktop_config.json:

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "mcp-web-validator": {
      "command": "npx",
      "args": ["-y", "mcp-web-validator"]
    }
  }
}

Restart Claude Desktop after saving the configuration.

Cursor and compatible clients

Create a command/stdio MCP server with:

npx -y mcp-web-validator

This repository also includes a Cursor Marketplace plugin manifest. After the plugin is published, install Web Validator by DigestSEO from Cursor's Marketplace or add the repository from Cursor's plugin UI. The plugin bundles the same local stdio server and does not require API keys or environment variables.

OpenAI Codex

Codex CLI can add the published local stdio package directly:

codex mcp add mcp-web-validator -- npx -y mcp-web-validator

Or add the existing hosted Streamable HTTP surface instead:

codex mcp add mcp-web-validator-hosted --url https://web-validator-mcp.digestseo.com/mcp

Verify either configuration with:

codex mcp list

The local package includes workspace-file validation and responsive screenshot capture. The hosted surface is remote-only and cannot access local files or create screenshots.

Gemini CLI

Gemini CLI supports local stdio MCP servers. Add the published package with:

gemini mcp add mcp-web-validator npx -y mcp-web-validator

This writes the server definition to Gemini CLI's MCP configuration. No API keys or environment variables are required by Web Validator.

GitHub Copilot CLI

Add the published local stdio server with:

copilot mcp add mcp-web-validator -- npx -y mcp-web-validator

When Copilot CLI is started inside a clone of this repository, it can also discover the checked-in root .mcp.json, which already points mcp-web-validator at npx -y mcp-web-validator.

Kiro

Add to Kiro

This installs the local stdio package, preserving its workspace-file and screenshot capabilities. Node.js 22.12.0+ is required.

Development

Clone the repository and install the locked dependencies:

git clone https://github.com/AKzar1el/mcp-web-validator.git
cd mcp-web-validator
npm ci

Run the local quality gates:

npm run check
npm test
npm run build
npm pack --dry-run

Run the local stdio server:

npm start

Validate the hosted Worker separately:

cd chatgpt-plugin
npm ci
npm run check
npm test
npm run deploy:dry-run

See CONTRIBUTING.md for contribution expectations. Deployment and marketplace-review notes live in chatgpt-plugin/SUBMISSION.md. For agent-assisted installation, see llms-install.md.

Ecosystem

License

Licensed under the MIT License.

Available Tools

8 tools
css.localValidate local CSSA
Read-onlyIdempotent
Inspect

Reads a bounded local CSS file and sends it to the W3C Jigsaw CSS Validator. Use only files the user is authorized to share.

ParametersJSON Schema
NameRequiredDescriptionDefault
filePathYesAbsolute or workspace-relative path to a CSS file.

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNo
errorsYes
warningsNo
truncatedYes
totalMessagesYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, non-destructive, idempotent behavior, so the description adds meaningful context by revealing the external W3C Jigsaw validation step and the authorization requirement. This goes beyond what annotations alone would convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences with no filler. The core action is front-loaded, and the important authorization caveat is placed second without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple with one parameter, full schema coverage, rich annotations, and an output schema. The description covers the critical behavioral and authorization context, leaving no essential gap for an agent to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema covers the single parameter fully at 100%, describing filePath as a CSS file path. The description adds no extra semantics beyond the schema, which matches the baseline for fully documented schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Reads') and resource ('a bounded local CSS file') and clarifies the tool's purpose: sending the file to the W3C Jigsaw CSS Validator. This distinguishes it from sibling tools like html.url or links.broken.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'Use only files the user is authorized to share' provides clear usage context and a constraint on acceptable inputs. It does not explicitly name alternatives or when-not-to-use conditions, but the local CSS scope and sibling tool names imply the boundary.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

html.localValidate local HTMLA
Read-onlyIdempotent
Inspect

Reads a bounded local HTML or .xhtml file and sends its markup to the W3C Nu HTML Checker. .xhtml files use application/xhtml+xml parsing semantics. Use only files the user is authorized to share.

ParametersJSON Schema
NameRequiredDescriptionDefault
filePathYesAbsolute or workspace-relative path to an HTML or .xhtml file.

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNo
errorsYes
truncatedYes
totalMessagesYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, open-world, idempotent, and non-destructive. The description adds that the file's markup is sent to an external service (W3C), that .xhtml uses application/xhtml+xml parsing, and that content must be shareable, disclosing external data transmission and parsing semantics beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences with no filler. The first states the core operation, the second adds a specific parsing detail, and the third adds a critical usage constraint. All earn their place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter tool with a rich output schema and annotations, the description covers the input, the external validation behavior, parsing semantics, and an authorization constraint. There are no significant gaps for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already documents filePath as an absolute or workspace-relative path; the description adds that it must be bounded, local, and only for authorized files, and clarifies .xhtml parsing behavior, enriching the parameter's meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action (reads a local HTML or .xhtml file and sends it to the W3C Nu HTML Checker), names the resource, and the title reinforces validation. The 'local' qualifier distinguishes it from html.url and other siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context: use with local HTML/.xhtml files, and only files the user is authorized to share. It does not explicitly name alternatives like html.url, but the 'local' scope and authorization constraint effectively guide selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

html.urlValidate a public URLA
Read-onlyIdempotent
Inspect

Fetches a bounded public HTTP(S) page, then sends its markup to the W3C Nu HTML Checker. Private, reserved, credentialed, and nonstandard-port destinations are rejected.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesPublic HTTP(S) URL on port 80 or 443.

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNo
errorsYes
truncatedYes
fetchedUrlNo
totalMessagesYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false. The description adds meaningful context beyond those hints: the fetch is bounded, it delegates to the W3C Nu HTML Checker, and specific destination classes are rejected. No contradiction with annotations is present.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tightly scoped sentences that front-load the core mechanism and then state rejection constraints. Every sentence earns its place with no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter tool with a full output schema, the description covers the operation, the external checker dependency, and the boundary conditions. Nothing an agent needs in order to correctly select and invoke this tool for a public URL is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the input schema already documents the url parameter as a public HTTP(S) URL on port 80 or 443. The description reinforces this constraint but adds no substantial new parameter-level semantics beyond what the schema states, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description opens with a concrete action—fetching a bounded public HTTP(S) page and sending its markup to the W3C Nu HTML Checker—and the title 'Validate a public URL' reinforces the operation. The explicit focus on remote public pages distinguishes it from local and CSS-specific sibling validators like html.local and css.local.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly states when to use the tool: validating a public HTTP(S) URL. It also gives explicit when-not conditions by rejecting private, reserved, credentialed, and nonstandard-port destinations. It stops short of explicitly naming sibling alternatives such as html.local, so it is not a full routing guide.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

links.brokenCheck public linksA
Read-onlyIdempotent
Inspect

Resolves and checks up to 25 public HTTP(S) links in supplied HTML. Redirects are reported but not followed, and response bodies are discarded.

ParametersJSON Schema
NameRequiredDescriptionDefault
baseUrlNoOptional public HTTP(S) base URL used to resolve relative links.
maxLinksNoMaximum number of public HTTP(S) links to check, from 1 to 25.
htmlContentYesRaw HTML markup containing links to check.

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNo
linksYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond annotations, the description adds meaningful behavioral details: redirects are reported but not followed, and response bodies are discarded. These are important for understanding how links are checked and align with readOnlyHint and idempotentHint. No contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the core purpose and followed by concise behavioral constraints. Every clause adds information, and there is no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema exists, return values don't need description. The description covers limit, redirect handling, and body handling, which are the key operational details an agent needs before invoking. It doesn't mention possible errors or network dependencies, but annotations and schema cover much of that context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description does not directly explain parameters but reinforces maxLinks ('up to 25') and htmlContent ('supplied HTML'), while baseUrl is left to the schema. No extra value beyond schema, but no gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool checks public HTTP(S) links in supplied HTML, with a precise verb ('checks') and resource ('up to 25 public HTTP(S) links'). It also distinguishes itself by noting redirects are reported but not followed and response bodies are discarded, making its function specific and unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for link checking in HTML but does not explicitly state when to prefer this tool over alternatives or when not to use it. It doesn't mention sibling tools like html.url or report.validation, leaving the selection partly to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

report.validationGenerate a validation reportA
Read-onlyIdempotent
Inspect

Combines W3C HTML/CSS validation, local SEO/accessibility checks, JSON-LD syntax checks, and a bounded public-link check into a Markdown and structured report.

ParametersJSON Schema
NameRequiredDescriptionDefault
baseUrlNoOptional public HTTP(S) base URL used to resolve relative links.
cssFilePathNoOptional absolute or workspace-relative CSS file path.
htmlFilePathYesAbsolute or workspace-relative HTML or .xhtml file path.

Output Schema

ParametersJSON Schema
NameRequiredDescription
linksYes
errorsNo
reportYes
summaryYes
seoIssuesYes
cssMessagesYes
cssTruncatedYes
failedChecksYes
htmlMessagesYes
schemaIssuesYes
seoTruncatedYes
htmlTruncatedYes
seoTotalIssuesYes
schemaTruncatedYes
cssTotalMessagesYes
htmlTotalMessagesYes
schemaTotalIssuesYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnly, openWorld, idempotent, and non-destructive hints, so the description's burden is lighter. It adds meaningful behavior: it performs combined W3C/local/JSON-LD/public-link checks and produces both Markdown and structured output. The 'bounded public-link check' clue also hints at external network behavior without contradicting the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One dense, front-loaded sentence communicates the tool's purpose, scope, and output format with no filler. Every part of the sentence adds useful information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an aggregate validation tool with a rich output schema and strong annotations, the description is largely complete. The main gap is optional-parameter behavior: an agent cannot tell from the description how omitting cssFilePath or baseUrl affects which checks run, nor exactly what 'bounded' means for the public-link check.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description's check categories map loosely to the parameters, but it adds no explicit detail about whether cssFilePath gates CSS validation or whether baseUrl gates the public-link check. The schema itself already carries the parameter meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: it combines validations 'into a Markdown and structured report.' It enumerates the exact check categories, which clearly distinguishes this aggregate tool from single-purpose siblings like html.local, css.local, links.broken, schema.markup, and seo.metadata.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this is the all-in-one validation tool, but it never explicitly says when to prefer report.validation over the individual sibling tools or when not to use it. The aggregation language gives useful context, but the agent must infer the tool-selection logic.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

schema.markupValidate JSON-LD syntaxA
Read-onlyIdempotent
Inspect

Parses JSON-LD blocks in supplied HTML locally and reports empty blocks or JSON syntax errors. It does not validate vocabulary semantics.

ParametersJSON Schema
NameRequiredDescriptionDefault
htmlContentYesRaw HTML containing JSON-LD script blocks.

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNo
countsYes
issuesYes
truncatedYes
totalIssuesYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already convey read-only, idempotent, and non-destructive behavior, so the bar is lower. The description adds useful behavioral context beyond annotations: processing is local, not network-based, and it specifically detects empty blocks and JSON syntax errors. No contradiction exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences carry the core action, output scope, and an important limitation with zero filler. The primary behavior is front-loaded, and every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter tool with rich annotations and an output schema, the description fully covers what the tool does, where it runs, what it reports, and what it deliberately omits. An agent has enough information to invoke it correctly and set expectations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% coverage with a clear description of 'htmlContent' as raw HTML containing JSON-LD script blocks. The tool description mostly restates this relationship and adds context about local parsing and error reporting, but it provides little additional parameter-level meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description specifies a concrete action ('Parses JSON-LD blocks in supplied HTML'), the exact scope ('locally'), and the kinds of results it reports ('empty blocks or JSON syntax errors'). It also distinguishes itself by explicitly stating what it does not do: 'does not validate vocabulary semantics.'

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'in supplied HTML locally' gives a clear context for when to use this tool: when the input is a local HTML string rather than a URL. The explicit non-goal of not validating vocabulary semantics provides a when-not signal, though it does not name any alternative sibling tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

screenshot.captureCapture responsive screenshotsA
DestructiveIdempotent
Inspect

Renders a local HTML file or HTTP(S) URL in a sandboxed local Chromium browser and writes PNG screenshots to the requested directory. Downloads the pinned headless browser on first use if it is not already cached. Existing matching files may be replaced.

ParametersJSON Schema
NameRequiredDescriptionDefault
outputDirNoDirectory where PNG screenshots will be written..mcp-validator/screenshots
viewportsNoOptional viewport definitions; defaults to desktop, tablet, and mobile sizes.
targetPathYesLocal HTML path or HTTP(S) URL to render.

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNo
screenshotsYes
outputDirectoryYes

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds meaningful behavioral details beyond the annotations: sandboxed Chromium, first-use browser download, and possible replacement of existing files. These details enrich the destructiveHint and openWorldHint annotations without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three well-ordered sentences: the core rendering/writing behavior, the runtime browser download behavior, and the destructive caveat. Every sentence earns its place with no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The schema and annotations cover parameter details, safety, and idempotency, while the description adds the non-obvious runtime facts: sandboxing, first-run browser download, and potential file replacement. Nothing essential for invoking the tool correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and each parameter already has a clear description. The description's reference to the 'requested directory' adds little beyond the schema, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the action ('writes PNG screenshots') and the resource ('local HTML file or HTTP(S) URL'), which distinguishes it from sibling tools focused on HTML, CSS, SEO metadata, and validation. However, it does not explicitly contrast itself with any sibling, so it stops just short of full differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description states what inputs are accepted but gives no guidance about when to use screenshot.capture versus the sibling tools. There is no mention of use cases such as visual verification, or exclusions such as 'use html.local for DOM inspection instead.'

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

seo.metadataAudit SEO metadataB
Read-onlyIdempotent
Inspect

Analyzes supplied HTML locally for metadata, heading structure, viewport configuration, image alternatives, and Open Graph fields.

ParametersJSON Schema
NameRequiredDescriptionDefault
htmlContentYesRaw HTML markup to inspect locally.

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNo
countsYes
issuesYes
truncatedYes
totalIssuesYes

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds the behavioral detail that analysis is performed 'locally' (no network calls), which is beyond annotations. However, it does not mention what happens with invalid HTML, output structure, or any edge cases. Given the annotation coverage, a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that front-loads the action ('Analyzes supplied HTML locally') and then lists the specific areas checked. There is no redundant phrasing, and every word contributes to the core purpose. It is exemplary in conciseness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple (one parameter) and an output schema exists, so the description need not explain return values. The description covers the key scope of analysis and the local execution context. It does not mention size limits (covered by schema maxLength) or potential limitations, but given the output schema and simple input, it is sufficiently complete for an agent to invoke correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema provides a full description of the single parameter (htmlContent: 'Raw HTML markup to inspect locally'), so schema coverage is 100%. The tool description adds no additional meaning to the parameter beyond what the schema already states, meeting the baseline for high coverage. It does not elaborate on format constraints or examples.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb (Analyzes) and resource (supplied HTML) and enumerates the exact aspects examined (metadata, heading structure, viewport configuration, image alternatives, Open Graph fields). This is clear and specific, but it does not explicitly differentiate itself from siblings like html.local or schema.markup, so it earns a 4 rather than a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus its alternatives. It does not mention conditions, prerequisites, or exclusions, and it fails to reference any sibling tool. An agent must infer from the title and parameter that this is for SEO auditing, but no explicit routing advice is given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv1.3.40
    • Changedcss.local1 field changed
      • addedOutput schema / properties / warnings
        Added value: +{
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "compatibility": {
        +        "const": "known-validator-limitation",
        +        "type": "string"
        +      },
        +      "context": {
        +        "type": "string"
        +      },
        +      "line": {
        +        "maximum": 9007199254740991,
        +        "minimum": -9007199254740991,
        +        "type": "integer"
        +      },
        +      "message": {
        +        "type": "string"
        +      },
        +      "type": {
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "line",
        +      "type",
        +      "message"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
    • Changedhtml.local1 field changed
      • changedInput schema / properties / filePath / description
        Previous value: -"Absolute or workspace-relative path to an HTML file."New value: +"Absolute or workspace-relative path to an HTML or .xhtml file."
    • Changedreport.validation2 fields changed
      • changedInput schema / properties / htmlFilePath / description
        Previous value: -"Absolute or workspace-relative HTML file path."New value: +"Absolute or workspace-relative HTML or .xhtml file path."
      • addedOutput schema / properties / summary / properties / cssWarnings
        Added value: +{
        +  "maximum": 9007199254740991,
        +  "minimum": 0,
        +  "type": "integer"
        +}
  2. 6 tool updatesv1.3.28
    • Changedcss.local4 fields changed
      • addedOutput schema / properties / errors / items / properties / compatibility
        Added value: +{
        +  "const": "known-validator-limitation",
        +  "type": "string"
        +}
      • addedOutput schema / properties / totalMessages
        Added value: +{
        +  "maximum": 9007199254740991,
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / truncated
        Added value: +{
        +  "type": "boolean"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "errors"
        -]New value: +[
        +  "errors",
        +  "totalMessages",
        +  "truncated"
        +]
    • Changedhtml.local4 fields changed
      • addedOutput schema / properties / errors / items / properties / subType
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / totalMessages
        Added value: +{
        +  "maximum": 9007199254740991,
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / truncated
        Added value: +{
        +  "type": "boolean"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "errors"
        -]New value: +[
        +  "errors",
        +  "totalMessages",
        +  "truncated"
        +]
    • Changedhtml.url4 fields changed
      • addedOutput schema / properties / errors / items / properties / subType
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / totalMessages
        Added value: +{
        +  "maximum": 9007199254740991,
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / truncated
        Added value: +{
        +  "type": "boolean"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "errors"
        -]New value: +[
        +  "errors",
        +  "totalMessages",
        +  "truncated"
        +]
    • Changedreport.validation17 fields changed
      • addedOutput schema / properties / cssMessages / items / properties / compatibility
        Added value: +{
        +  "const": "known-validator-limitation",
        +  "type": "string"
        +}
      • addedOutput schema / properties / cssTotalMessages
        Added value: +{
        +  "maximum": 9007199254740991,
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / cssTruncated
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / htmlMessages / items / properties / subType
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / htmlTotalMessages
        Added value: +{
        +  "maximum": 9007199254740991,
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / htmlTruncated
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / schemaIssues / items / properties / code
        Added value: +{
        +  "description": "Stable machine-readable audit rule identifier.",
        +  "type": "string"
        +}
      • changedOutput schema / properties / schemaIssues / items / required
        Previous value: -[
        -  "severity",
        -  "category",
        -  "message"
        -]New value: +[
        +  "code",
        +  "severity",
        +  "category",
        +  "message"
        +]
      • addedOutput schema / properties / schemaTotalIssues
        Added value: +{
        +  "maximum": 9007199254740991,
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / schemaTruncated
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / seoIssues / items / properties / code
        Added value: +{
        +  "description": "Stable machine-readable audit rule identifier.",
        +  "type": "string"
        +}
      • changedOutput schema / properties / seoIssues / items / required
        Previous value: -[
        -  "severity",
        -  "category",
        -  "message"
        -]New value: +[
        +  "code",
        +  "severity",
        +  "category",
        +  "message"
        +]
      • addedOutput schema / properties / seoTotalIssues
        Added value: +{
        +  "maximum": 9007199254740991,
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / seoTruncated
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / summary / properties / cssCompatibilityLimitations
        Added value: +{
        +  "maximum": 9007199254740991,
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • changedOutput schema / properties / summary / required
        Previous value: -[
        -  "overallScore",
        -  "htmlScore",
        -  "cssScore",
        -  "seoScore",
        -  "linkScore",
        -  "htmlErrors",
        -  "htmlWarnings",
        -  "cssErrors",
        -  "seoErrors",
        -  "seoWarnings",
        -  "schemaErrors",
        -  "linksChecked",
        -  "brokenLinks"
        -]New value: +[
        +  "overallScore",
        +  "htmlScore",
        +  "cssScore",
        +  "seoScore",
        +  "linkScore",
        +  "htmlErrors",
        +  "htmlWarnings",
        +  "cssErrors",
        +  "cssCompatibilityLimitations",
        +  "seoErrors",
        +  "seoWarnings",
        +  "schemaErrors",
        +  "linksChecked",
        +  "brokenLinks"
        +]
      • changedOutput schema / required
        Previous value: -[
        -  "report",
        -  "summary",
        -  "htmlMessages",
        -  "cssMessages",
        -  "seoIssues",
        -  "schemaIssues",
        -  "links",
        -  "failedChecks"
        -]New value: +[
        +  "report",
        +  "summary",
        +  "htmlMessages",
        +  "htmlTotalMessages",
        +  "htmlTruncated",
        +  "cssMessages",
        +  "cssTotalMessages",
        +  "cssTruncated",
        +  "seoIssues",
        +  "seoTotalIssues",
        +  "seoTruncated",
        +  "schemaIssues",
        +  "schemaTotalIssues",
        +  "schemaTruncated",
        +  "links",
        +  "failedChecks"
        +]
    • Changedschema.markup4 fields changed
      • addedOutput schema / properties / counts
        Added value: +{
        +  "additionalProperties": false,
        +  "properties": {
        +    "error": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "info": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "warning": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "error",
        +    "warning",
        +    "info"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / properties / issues / items / properties / code
        Added value: +{
        +  "description": "Stable machine-readable audit rule identifier.",
        +  "type": "string"
        +}
      • changedOutput schema / properties / issues / items / required
        Previous value: -[
        -  "severity",
        -  "category",
        -  "message"
        -]New value: +[
        +  "code",
        +  "severity",
        +  "category",
        +  "message"
        +]
      • changedOutput schema / required
        Previous value: -[
        -  "issues",
        -  "totalIssues",
        -  "truncated"
        -]New value: +[
        +  "issues",
        +  "totalIssues",
        +  "truncated",
        +  "counts"
        +]
    • Changedseo.metadata4 fields changed
      • addedOutput schema / properties / counts
        Added value: +{
        +  "additionalProperties": false,
        +  "properties": {
        +    "error": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "info": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "warning": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "error",
        +    "warning",
        +    "info"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / properties / issues / items / properties / code
        Added value: +{
        +  "description": "Stable machine-readable audit rule identifier.",
        +  "type": "string"
        +}
      • changedOutput schema / properties / issues / items / required
        Previous value: -[
        -  "severity",
        -  "category",
        -  "message"
        -]New value: +[
        +  "code",
        +  "severity",
        +  "category",
        +  "message"
        +]
      • changedOutput schema / required
        Previous value: -[
        -  "issues",
        -  "totalIssues",
        -  "truncated"
        -]New value: +[
        +  "issues",
        +  "totalIssues",
        +  "truncated",
        +  "counts"
        +]
  3. 8 tool updatesv1.1.0
    • Addedcss.local
    • Addedhtml.local
    • Addedhtml.url
    • Addedlinks.broken
    • Addedreport.validation
    • Addedschema.markup
    • Addedscreenshot.capture
    • Addedseo.metadata
  4. 7 tool updatesv1.0.1
    • Removedaudit_seo_metadata
    • Removedcheck_broken_links
    • Removedgenerate_validation_report
    • Removedvalidate_local_css
    • Removedvalidate_local_html
    • Removedvalidate_schema_markup
    • Removedvalidate_url
  5. 7 tool updatesv1.0.0
    • First observedaudit_seo_metadata
    • First observedcheck_broken_links
    • First observedgenerate_validation_report
    • First observedvalidate_local_css
    • First observedvalidate_local_html
    • First observedvalidate_schema_markup
    • First observedvalidate_url

TDQS

A4/5.0

Scored across 8 tools

Disambiguation4/5

Each tool targets a distinct validation concern (HTML, CSS, links, schema, SEO, screenshots), and the two HTML validators are clearly separated by local vs. URL source. Minor overlap exists between report.validation and the individual tools it aggregates, but the descriptions make the difference explicit (combined report vs. single-purpose check).

Naming Consistency5/5

All tool names follow a consistent dot-separated pattern where the first segment identifies the resource (html, css, links, schema, seo, report) and the second segment specifies the action or variant (local, url, broken, markup, metadata, validation). This is highly predictable and readable.

Tool Count5/5

Eight tools is well-scoped for a web validation server. Each tool addresses a meaningful aspect of validation or analysis, and none feel redundant or superfluous. The count supports a coherent workflow without overwhelming the agent.

Completeness4/5

The tool surface covers HTML validation from file and URL, CSS file validation, broken link checking, JSON-LD syntax, SEO metadata analysis, screenshots, and an aggregate report. A minor gap is the lack of a CSS URL validation tool, but the core validation workflows are well covered for the apparent domain.

Maintenance

ActivityActive
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Integrates SEO analysis and Google Search Console data directly into Claude Code and Cursor. Performs real-time site audits, detects technical SEO issues, validates meta tags, generates structured data, and provides AI-powered recommendations for both production sites and local development servers.
    19
    135 npm
    3
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    OAuth-protected Google Search Console MCP for analytics, URL inspection, sitemap management, indexing requests, and SEO diagnostics. Open-source Cloudflare Workers implementation with 17 tools.
    17
    1,772 npm
    5
    MIT