fairquery-web
OfficialSummary: fairquery-web is an MCP server for website tech, SEO, AI-readiness, and security checks, with free local tools plus a paid Apify bulk audit.
Quick URL check: Check 1-20 URLs for HTTP status, redirect chain, response time, content type, server, and title.
Single-page SEO & AI-readiness audit: Get meta/OG/JSON-LD/headings/images,
seo_issues,seo_score(0-100), andai_readiness_score(0-100); output can be saved as a snapshot.AI crawler access: Inspect robots.txt rules for AI bots like GPTBot, ClaudeBot, and PerplexityBot as allowed/partial/blocked, plus llms.txt and llms-full.txt presence/title/links.
Tech stack detection: Identify frameworks, CMS, hosting/CDN, and analytics from HTML/headers with evidence; filter by category and page results.
Sitemap info: Discover XML sitemaps, expand sitemap indexes, and page through URLs with lastmod; filter and sort results.
Security headers: Check HSTS, CSP, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy, and COOP; get a score and grade A-F.
Snapshot comparison: Diff two saved SEO snapshots, a saved snapshot vs a fresh re-audit, or two live URLs; see score deltas, issues added/resolved, and changed fields.
Bulk audit (paid): Run the Fairquery Apify Actor on up to thousands of sites (requires
APIFY_TOKEN); returns per-site tech, SEO, security, robots.txt, sitemap, llms.txt, and scores.Operational notes: Free tools run locally without a token; no JavaScript rendering; SSRF guard and respectful fetching; errors use machine-readable codes.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@fairquery-webcheck stripe.com's tech stack, SEO issues, and llms.txt status"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Website Tech, SEO & llms.txt Check for Agents
Fairquery Apify Actor that returns one structured row per website: tech stack, title/meta/Open Graph/JSON-LD, an SEO issue list with a 0–100 score, robots.txt rules for AI crawlers (GPTBot, ClaudeBot, PerplexityBot, Google-Extended, CCBot, …), XML sitemap, llms.txt / llms-full.txt, security headers, and a 0–100 AI-readiness score. Plain HTTP (no browser), so it's fast and cheap.
When to use this Actor (LLM / tool selection)
Use it when an agent needs to:
Enrich a lead/company list with "what is this site built on?" (CMS, framework, analytics, chat, payments, CDN, hosting)
Run a quick on-page SEO check of homepages or landing pages
Answer "does this site have an llms.txt?" / "does it block GPTBot or ClaudeBot?"
Get a site's title, description, social links, feeds and structured-data types before summarizing it
Do not use it for full-site crawls, JS-rendered content (single-page apps may show THIN_CONTENT), Core Web Vitals, or backlink data.
Related MCP server: AI Tooling Detector MCP Server
How it works
Per site (max 3 in parallel): GET /robots.txt → GET <url> → sitemap (from robots Sitemap: or /sitemap.xml, /sitemap_index.xml) → /llms.txt and /llms-full.txt. Identifies as FairqueryBot/1.0; by default skips pages that robots.txt disallows for generic crawlers. Tech detection uses ~75 HTML/header/cookie/meta-generator signatures from a single response.
Input
Field | Type | Default | Description |
|
|
| Domains or URLs |
|
|
| robots.txt + AI-bot access map |
|
|
| Find sitemap and count URLs |
|
|
| Check |
|
|
| Skip URLs disallowed for generic crawlers |
|
|
| Safety cap per run |
{ "urls": ["stripe.com", "https://www.example.org/pricing"], "checkSitemap": false }Output
Every row has schema_version (1.0.0), type (site | error), source_url (final fetched URL), checked_at.
{
"type": "site", "domain": "vercel.com", "status_code": 200, "https": true, "response_ms": 310,
"title": "Agentic Infrastructure - Vercel", "meta_description": "…", "canonical": "https://vercel.com/", "lang": "en",
"h1": ["…"], "word_count": 256, "open_graph": { "title": "…", "image": "…" }, "json_ld_types": ["Organization", "WebSite"],
"technologies": [{ "name": "Next.js", "category": "JS framework", "evidence": "html \"/_next/static\"" }, { "name": "Vercel", "category": "Hosting", "evidence": "header x-vercel-id" }],
"security_headers": { "strict_transport_security": true, "content_security_policy": true },
"robots_txt_found": true, "ai_bots": { "GPTBot": "partial", "ClaudeBot": "partial" },
"sitemap_found": true, "sitemap_url_count": 8787, "llms_txt_found": true, "llms_txt_title": "Vercel",
"seo_score": 100, "seo_issues": [], "ai_readiness_score": 85
}ai_bots[bot]:allowed(no rules),partial(some paths disallowed),blocked(root disallowed).seo_issues[]:{code, severity, message}; codes includeNO_HTTPS,MISSING_TITLE,TITLE_TOO_LONG,MISSING_META_DESCRIPTION,MISSING_H1,MULTIPLE_H1,MISSING_CANONICAL,MISSING_LANG,MISSING_VIEWPORT,NOINDEX,MISSING_OPEN_GRAPH,MISSING_STRUCTURED_DATA,IMAGES_MISSING_ALT,THIN_CONTENT,MISSING_ROBOTS_TXT,MISSING_SITEMAP. Score = 100 − 15/8/3 per high/medium/low issue.ai_readiness_score: llms.txt 25, llms-full.txt 5, AI bots allowed up to 20, JSON-LD 15, ≥150 words of server-rendered text 15, sitemap 10, meta description 10; −30 ifnoindex.
Error rows (machine-readable, never charged)
{ "type": "error", "code": "BLOCKED_OR_RATE_LIMITED", "message": "GET https://x.com/ returned HTTP 403.", "retryable": false, "status_code": 403, "input": "x.com" }Codes: INPUT_EMPTY, INVALID_URL, MAX_SITES_EXCEEDED, ROBOTS_DISALLOWED, FETCH_FAILED, HTTP_ERROR, BLOCKED_OR_RATE_LIMITED.
Run summary
Key-value store record RUN_SUMMARY: sites checked, errors, HTTP request count, average SEO and AI-readiness scores, llms.txt count, echoed input.
Pricing
Pay per event: site-checked per site row. Error rows are never charged. See the Store pricing tab.
Memory / runtime
Default 256 MB, no browser, no proxy. Typically 1–3 s per site.
MCP / Apify tools
Call from agents via Apify MCP (https://mcp.apify.com, authenticated with your Apify token), Actor fairquery/website-tech-seo-ai-readiness:
{ "actor": "fairquery/website-tech-seo-ai-readiness", "input": { "urls": ["stripe.com"] } }Read dataset items (type == "site") and RUN_SUMMARY. A standalone stdio MCP server lives in the GitHub repo under mcp/.
Local stdio MCP server
This repo ships a stdio MCP server (TypeScript, @modelcontextprotocol/sdk) under mcp/ with single-purpose tools. Seven are free and run locally (no token); one optional bulk tool runs this Actor through the Apify API. initialize and tools/list work without a token.
Tool | What it does | Paging | Cost |
| 1-20 URLs: status, redirect chain, response time, content type, title | – | free |
| One URL: meta/OG/JSON-LD/headings/images, | – | free |
| robots.txt rules per AI bot (GPTBot, ClaudeBot, PerplexityBot, Google-Extended, ...), | – | free |
| Frameworks, CMS, hosting/CDN, analytics with evidence; |
| free |
| Sitemap discovery, index/children, URL list with lastmod; |
| free |
| HSTS, CSP, X-Content-Type-Options, X-Frame-Options, Referrer-/Permissions-Policy, COOP; score + grade A-F | – | free |
| Diff two saved snapshots, a saved snapshot vs a fresh re-audit (follow-up), or two live URLs | – | free |
| Bulk audit of up to thousands of sites via the Apify Actor (formerly | – | pay-per-event, needs |
Errors are named codes: INVALID_URL, BLOCKED_PRIVATE_ADDRESS, DNS_FAILED, FETCH_FAILED, TIMEOUT, TOO_MANY_REDIRECTS, SITEMAP_NOT_FOUND, INVALID_ARGUMENTS, APIFY_TOKEN_MISSING, APIFY_ACTOR_RUN_FAILED.
Respectful fetching: User-Agent FairqueryBot ... Fairquery-MCP, 15 s timeout, 1.5 MB HTML / 10 MB sitemap cap, max 5 redirects, and an SSRF guard that refuses hosts (including redirect targets) resolving to private, loopback, link-local or reserved addresses. If you run behind a fake-IP DNS proxy that maps all hosts into 198.18.0.0/15, set FAIRQUERY_ALLOW_FAKE_IP_DNS=1.
Breaking change in v1.2.0: check_websites → web_batch_audit (same input, same billing); check_llms_txt was removed, use web_ai_crawler_access.
cd mcp && npm install && npm run build
npm run test:live # live test of every free tool, no token
node scripts/smoke-test.mjs # initialize + tools/list, no token
APIFY_TOKEN=... node scripts/smoke-test.mjs --call # real web_batch_audit call{ "mcpServers": { "fairquery-web": { "command": "node", "args": ["/path/to/website-tech-seo-ai-readiness/mcp/dist/index.js"], "env": { "APIFY_TOKEN": "<optional, only for web_batch_audit>" } } } }Docker: docker build -t fairquery-web-mcp . (the repo-root Dockerfile builds this MCP server and is what Glama uses; the Apify Actor image is built from .actor/Dockerfile). glama.json lists fairquery as maintainer.
Links
Apify Store: https://apify.com/fairquery/website-tech-seo-ai-readiness
License: MIT
Local development
npm install
npx apify run # uses input defaults, or storage/key_value_stores/default/INPUT.json
npm testKits & templates
Optional guides from Fairquery for wiring this Actor into agents and automations (the Actor works fine without them):
AI Agent Data Toolkit Quick-Start (PDF): MCP setup for Claude Desktop and Cursor, API calls, recipes, cost estimates.
n8n + Zapier Workflow Template Pack: 10 importable n8n workflows for the four Fairquery Actors, plus Zapier setup guides.
Agent Prompt Pack for Research & Lead Ops: 69 prompts for company research, lead cleaning, SEO and security reviews.
Agent Starter Kit: 10 copy-paste MCP + n8n recipes ($5): 10 copy-paste MCP + n8n recipes, with ready-made Claude/Cursor configs and 3 starter workflows.
Disclaimer
Detection is heuristic (single request, no JS execution). Only publicly served files are read; robots.txt is respected by default.
Available Tools
8 toolsweb_ai_crawler_accessAI crawler access: robots.txt AI-bot rules + llms.txt (free)ARead-onlyIdempotent
Report whether AI crawlers may access a site, from its robots.txt: per bot "allowed" (no Disallow), "partial" (some paths disallowed) or "blocked" (Disallow: /). Default bots: GPTBot, ChatGPT-User, OAI-SearchBot, ClaudeBot, Claude-User, anthropic-ai, PerplexityBot, Google-Extended, CCBot, Bytespider, Applebot-Extended, Meta-ExternalAgent, Amazonbot. Also checks /llms.txt and /llms-full.txt (llmstxt.org): found, HTTP status, bytes, H1 title, link count (HTML soft-404s are not counted), and lists Sitemap: lines. WHEN TO USE: "can ChatGPT/Claude/Perplexity crawl this site?", GEO/AI-visibility checks, llms.txt adoption. Uses only the origin of the URL. Fetching: read-only GETs from this server with User-Agent "FairqueryBot ... Fairquery-MCP", 15 s timeout per request, body capped (1.5 MB HTML), max 5 redirects; URLs resolving to private/loopback/link-local addresses are refused (SSRF guard). Free, no token, no JavaScript rendering. 3 requests per site. RETURNS: one "ai_crawler_access" object: origin, robots_txt_url, robots_txt_found, robots_txt_status, ai_bots{bot: status}, allowed_count, partial_count, blocked_count, note, sitemaps_declared[], llms_txt{url,found,status,bytes,title,links}, llms_full_txt{...}, checked_at. Errors (isError=true, JSON {error, message, retryable}): INVALID_URL, BLOCKED_PRIVATE_ADDRESS, DNS_FAILED, FETCH_FAILED, TIMEOUT, TOO_MANY_REDIRECTS. WHEN NOT TO USE: for full page SEO use web_seo_audit; for sitemap contents use web_sitemap_info; for many sites use web_batch_audit (paid). COST: free - runs locally in this MCP server (direct HTTP GETs), no APIFY_TOKEN, no Apify billing. EXAMPLE: {"url":"nytimes.com","bots":["GPTBot","ClaudeBot"]} -> {ai_bots:{GPTBot:"allowed|partial|blocked", ClaudeBot:...}, blocked_count, llms_txt, ...}
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Required. One public domain or http(s) URL, e.g. "vercel.com" or "https://www.python.org/about/". Bare domains are fetched over https; private/loopback hosts are refused. | |
| bots | No | User-agent tokens to evaluate instead of the default AI-bot list, e.g. ["GPTBot","Googlebot"] |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive), yet the description adds substantial context beyond them: User-Agent string, 15s per-request timeout, 1.5 MB body cap, 5-redirect limit, SSRF guard on private/loopback/link-local addresses, request count per site, and no JS rendering. It also enumerates the error taxonomy with a JSON error shape.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core question answered, then organized under clear WHEN TO USE / RETURNS / WHEN NOT TO USE headers, and it ends with a concrete example. There is mild redundancy, e.g. 'Free, no token' restated in the COST line, but it is dense rather than padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the full burden and does so: it enumerates every field of the returned object, the two llms.txt sub-objects, and the complete error set. Nothing an agent needs to call and interpret the tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so both parameters are already documented, but the description adds the concrete default bot list (GPTBot, ClaudeBot, etc.) and clarifies that only the URL origin is used, which the schema does not state. This goes beyond the baseline 3 without fully defining format nuances.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Report whether AI crawlers may access a site, from its robots.txt') and immediately defines the output vocabulary (allowed/partial/blocked). It also explicitly names sibling tools for adjacent jobs, so an agent can distinguish it without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a dedicated WHEN TO USE ('can ChatGPT/Claude/Perplexity crawl this site?', GEO checks, llms.txt adoption) and WHEN NOT TO USE that routes to three specific siblings (web_seo_audit, web_sitemap_info, web_batch_audit). Both inclusion and exclusion conditions are explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
web_batch_auditBulk website tech, SEO & AI-readiness audit (Apify, paid)ARead-onlyIdempotent
Bulk audit up to thousands of websites in one call via the Fairquery Apify Actor fairquery/website-tech-seo-ai-readiness: technologies, on-page SEO, security headers, robots.txt AI-bot rules, XML sitemap, llms.txt, seo_score and ai_readiness_score per site. WHEN TO USE: lists of 20+ sites (lead enrichment, portfolio/market scans) where you want server-side parallelism and a dataset. For one or a few sites prefer the free tools: web_quick_check, web_seo_audit, web_ai_crawler_access, web_tech_stack, web_sitemap_info, web_security_headers. Rows can be stored and later diffed with web_compare_snapshots. BEHAVIOR: read-only; runs the Actor via the Apify API (run-sync), a few polite GET requests per site, respects robots.txt by default, no JS rendering. Requires APIFY_TOKEN (never logged). Typical 2-10 s per site, parallel. COST: paid (billed to your Apify account, pay-per-event): $0.00005 per run + $0.002 per site row; error rows are free. 50 sites ~ $0.10. RETURNS: {count, items}. site rows: domain, status_code, https, response_ms, title, meta_description, canonical, lang, h1[], word_count, open_graph, json_ld_types, technologies[{name, category, evidence}], security_headers, robots_txt_found, ai_bots{bot: allowed|partial|blocked}, sitemap_found, sitemap_url_count, llms_txt_found, llms_txt_title, seo_score, seo_issues[{code, severity, message}], ai_readiness_score, source_url, checked_at. error rows: code (INPUT_EMPTY, INVALID_URL, MAX_SITES_EXCEEDED, ROBOTS_DISALLOWED, FETCH_FAILED, HTTP_ERROR, BLOCKED_OR_RATE_LIMITED), message, retryable, input. Tool-level errors: APIFY_TOKEN_MISSING, APIFY_ACTOR_RUN_FAILED. WHEN NOT TO USE: for 1-20 sites or interactive questions use the free tools above (same checks, no cost). EXAMPLE: {"urls":["vercel.com","netlify.com"],"checkLlmsTxt":false} -> {count:2, items:[{type:"site", domain:"vercel.com", seo_score:..., ...}, ...]}
| Name | Required | Description | Default |
|---|---|---|---|
| urls | Yes | Domains or URLs, e.g. ["vercel.com","https://www.python.org/about/"]. Bare domains use https. One row per unique URL. | |
| maxSites | No | Safety cap on unique URLs per run (default 500); extras produce a MAX_SITES_EXCEEDED error row | |
| checkRobots | No | Fetch robots.txt and report allow/partial/blocked per AI bot (default true) | |
| checkLlmsTxt | No | Check /llms.txt and /llms-full.txt (default true) | |
| checkSitemap | No | Find the XML sitemap and count URLs (default true) | |
| respectRobotsTxt | No | Skip pages robots.txt disallows for generic crawlers, emitting ROBOTS_DISALLOWED (default true, recommended) |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | Number of rows returned |
| items | Yes | Result rows; each has a "type" field (data rows or machine-readable "error" rows) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing cost model ($0.002/site, error rows free), auth requirement (APIFY_TOKEN, never logged), rate/politeness behavior, no-JS rendering, robots.txt respect, and per-site latency, all of which an agent needs before invoking a paid bulk run.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Labeled sections (WHEN TO USE, BEHAVIOR, COST, RETURNS, WHEN NOT TO USE, EXAMPLE) front-load the routing decision, and every line carries actionable information despite the length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers routing, cost, auth, error taxonomy (INPUT_EMPTY through BLOCKED_OR_RATE_LIMITED plus APIFY_TOKEN_MISSING), and even the return shape, leaving nothing an agent needs to call this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% so the baseline is 3, but the description adds the concrete example invocation (urls + checkLlmsTxt) and ties parameters to outcomes like MAX_SITES_EXCEEDED error rows, giving marginal value above the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (bulk audit) and resource (websites) with explicit scope ('up to thousands in one call') and names the underlying Actor, making it unmistakable what it does versus the single-site siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit WHEN TO USE (20+ sites, lead enrichment, portfolio scans) and WHEN NOT TO USE (1-20 sites or interactive questions) naming six alternative free tools by name, plus the snapshot-diff sibling for follow-up.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
web_compare_snapshotsCompare two SEO audits: before/after or site vs site (free)ARead-onlyIdempotent
Diff two SEO/AI-readiness snapshots field by field: score deltas, issues added/resolved, and changes to title, meta description, canonical, H1s, JSON-LD types, Open Graph, technologies, AI-bot access, llms.txt, sitemap, status and more. Three modes: (1) before + after = two snapshot objects you saved earlier from web_seo_audit (or site rows from web_batch_audit) - no fetching; (2) before + url = historical follow-up: re-audits url now and compares with the saved snapshot; (3) url + compareUrl = audits two live URLs (e.g. competitor vs own site, staging vs production). WHEN TO USE: track SEO regressions/improvements over time, verify a fix, compare competitors. Fetching: read-only GETs from this server with User-Agent "FairqueryBot ... Fairquery-MCP", 15 s timeout per request, body capped (1.5 MB HTML), max 5 redirects; URLs resolving to private/loopback/link-local addresses are refused (SSRF guard). Free, no token, no JavaScript rendering. RETURNS: {summary{before_url, after_url, before_checked_at, after_checked_at, seo_score_before, seo_score_after, seo_score_delta, ai_readiness_score_delta, issues_added, issues_resolved, changed_fields}, changes[{type:"change", field, before, after, delta?, added?, removed?} | {type:"issue_added"|"issue_resolved", code}], before, after (only fetched snapshots are echoed)}. Errors: INVALID_ARGUMENTS (wrong mode combination) plus INVALID_URL, BLOCKED_PRIVATE_ADDRESS, DNS_FAILED, FETCH_FAILED, TIMEOUT, TOO_MANY_REDIRECTS. WHEN NOT TO USE: for a single audit without comparison use web_seo_audit. COST: free (local fetches, no APIFY_TOKEN). EXAMPLE: {"url":"mysite.com","compareUrl":"competitor.com"} -> {summary:{seo_score_delta, issues_added, ...}, changes:[...]}
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | URL to audit live: the "after" side (with before) or the first side (with compareUrl) | |
| after | No | Later snapshot object to compare against before | |
| before | No | Earlier snapshot object (output of web_seo_audit or a web_batch_audit site row) | |
| compareUrl | No | Second live URL to audit and compare against url |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, but the description adds far more: fetch semantics (read-only GETs, User-Agent, 15s timeout, 1.5MB cap, 5 redirects), SSRF guard, no JS rendering, and a full error-code list. This is rich behavioral disclosure well beyond the structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but well-organized with front-loaded mode list and labeled sections (WHEN TO USE, RETURNS, WHEN NOT TO USE, COST, EXAMPLE). Slightly long, but every section carries distinct information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description carries the return-shape burden and does so thoroughly with the summary/changes/before/after structure and error codes. For a 4-param, mode-driven comparison tool, an agent has everything needed to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds value beyond the schema by explaining how the four params combine into three modes (before+after, before+url, url+compareUrl). It clarifies the interaction of params that the schema documents only individually.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (diff) and resource (SEO/AI-readiness snapshots) plus the enumerated dimensions compared (score deltas, issues, title, meta, JSON-LD, etc.). The three numbered modes make it trivially distinguishable from siblings like web_seo_audit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit WHEN TO USE (track regressions, verify a fix, compare competitors) and WHEN NOT TO USE with a named alternative (web_seo_audit for a single audit). Nothing is left to inference about selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
web_quick_checkQuick URL check: status, redirects, title, speed (free)ARead-onlyIdempotent
Lightweight reachability check for 1-20 URLs: final HTTP status, full redirect chain, response time (ms), content type, Server header and . WHEN TO USE: "is this site up?", "where does this domain redirect?", cheap pre-filtering of a lead list before deeper audits. For SEO details use web_seo_audit; for hundreds/thousands of sites use web_batch_audit. Fetching: read-only GETs from this server with User-Agent "FairqueryBot ... Fairquery-MCP", 15 s timeout per request, body capped (1.5 MB HTML), max 5 redirects; URLs resolving to private/loopback/link-local addresses are refused (SSRF guard). Free, no token, no JavaScript rendering. Only the first 300 KB of each page is read. URLs are checked in parallel. RETURNS: {count, items}: one "quick_check" row per input (input, requested_url, final_url, status_code, ok, https, redirect_count, redirects[{url,status}], response_ms, content_type, server, title, checked_at) or an "error" row (input, code, message, retryable) with codes INVALID_URL, BLOCKED_PRIVATE_ADDRESS, DNS_FAILED, FETCH_FAILED, TIMEOUT, TOO_MANY_REDIRECTS. Per-URL errors never fail the whole call. WHEN NOT TO USE: not for SEO/meta analysis (web_seo_audit), security headers (web_security_headers) or >20 URLs (web_batch_audit, paid). COST: free - runs locally in this MCP server (direct HTTP GETs), no APIFY_TOKEN, no Apify billing. EXAMPLE: {"urls":["vercel.com"]} -> {count:1, items:[{type:"quick_check", final_url:"https://vercel.com/", status_code:200, ok:true, ...}]}
| Name | Required | Description | Default |
|---|---|---|---|
| urls | Yes | Required. 1-20 public domains or http(s) URLs (bare domains use https), e.g. ["vercel.com","http://github.com"] |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | Number of rows returned |
| items | Yes | Result rows; each has a "type" field (data rows or machine-readable "error" rows) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnly, idempotent, no destruction), but the description adds substantial operational detail annotations cannot: User-Agent string, 15s timeout, 1.5MB body cap, 300KB read limit, max 5 redirects, SSRF guard refusing private/loopback addresses, parallel execution, and free/no-token/no-JS. This is exactly what behavioral disclosure should add beyond structured hints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then cleanly sectioned into WHEN TO USE / Fetching / RETURNS / WHEN NOT TO USE / COST. Every block earns its place, though the RETURNS field-by-field enumeration is slightly redundant given the output schema exists.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema exists, the description needn't explain return values, yet it does so concisely while also covering the SSRF constraint, per-URL error isolation ('never fail the whole call'), and cost model. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single `urls` param is well-documented in the schema itself. The description restates the 1-20 range and bare-domain-uses-https rule, but adds no syntax beyond what the schema already says. Baseline 3 when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Lightweight reachability check for 1-20 URLs') and enumerates the exact returned fields, distinguishing it from SEO/security siblings by function. An agent can tell it apart from web_seo_audit and web_security_headers without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit WHEN TO USE with example queries ('is this site up?'), named alternatives (web_seo_audit for SEO details, web_batch_audit for >20 URLs), and a WHEN NOT TO USE section listing three siblings and their scopes. Fully routes the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
web_security_headersHTTP security headers check with grade (free)ARead-onlyIdempotent
Check HTTP security response headers of one URL: Strict-Transport-Security (>=180 days), Content-Security-Policy (flags unsafe-inline/unsafe-eval), X-Content-Type-Options (nosniff), X-Frame-Options (or CSP frame-ancestors), Referrer-Policy, Permissions-Policy, Cross-Origin-Opener-Policy; plus information-disclosure headers (Server, X-Powered-By). Weighted score 0-100 and grade A-F (non-HTTPS capped at 40). WHEN TO USE: quick security posture / hygiene check of a site. Not a vulnerability scanner. Fetching: read-only GETs from this server with User-Agent "FairqueryBot ... Fairquery-MCP", 15 s timeout per request, body capped (1.5 MB HTML), max 5 redirects; URLs resolving to private/loopback/link-local addresses are refused (SSRF guard). Free, no token, no JavaScript rendering. One request (after redirects); headers are taken from the final response. RETURNS: one "security_headers" object: input, final_url, status_code, https, score, grade, headers[{header, present, value, warning, weight}], missing[], info_disclosure_headers[{header, value}], checked_at. Errors (isError=true, JSON {error, message, retryable}): INVALID_URL, BLOCKED_PRIVATE_ADDRESS, DNS_FAILED, FETCH_FAILED, TIMEOUT, TOO_MANY_REDIRECTS. WHEN NOT TO USE: not a vulnerability/penetration scan; for dependency CVEs use an OSV tool; for SEO use web_seo_audit. COST: free - runs locally in this MCP server (direct HTTP GETs), no APIFY_TOKEN, no Apify billing. EXAMPLE: {"url":"github.com"} -> {type:"security_headers", score:0-100, grade:"A".."F", missing:[...], ...}
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Required. One public domain or http(s) URL, e.g. "vercel.com" or "https://www.python.org/about/". Bare domains are fetched over https; private/loopback hosts are refused. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnly/openWorld/idempotent annotations by disclosing the User-Agent, 15 s per-request timeout, 1.5 MB body cap, 5-redirect limit, single-request semantics, and an SSRF guard refusing private/loopback/link-local addresses. This is exactly the kind of operational context annotations cannot carry.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then cleanly sectioned (WHEN TO USE / Fetching / RETURNS / WHEN NOT TO USE / COST / EXAMPLE). Some redundancy: COST restates 'free' already implied earlier, and 'not a vulnerability scanner' appears twice, so it is slightly longer than strictly necessary.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description fully specifies the return shape ('security_headers' object with headers, missing, info_disclosure_headers, score, grade, checked_at) and enumerates every error code (INVALID_URL, BLOCKED_PRIVATE_ADDRESS, DNS_FAILED, etc.). Nothing an agent needs to call or interpret results is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single 'url' parameter is already documented in the schema (examples, bare-domain-over-https, private-host refusal). The description's EXAMPLE adds marginal framing but no new parameter meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Check HTTP security response headers of one URL') and enumerates exactly which headers are evaluated and the scoring model (0-100, grade A-F). It is immediately distinguishable from siblings like web_seo_audit and any OSV/dependency tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit WHEN TO USE ('quick security posture / hygiene check'), an explicit WHEN NOT TO USE ('not a vulnerability/penetration scan'), and names concrete alternatives (OSV tools for CVEs, web_seo_audit for SEO). Routing is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
web_seo_auditSingle-page SEO & AI-readiness audit with 0-100 score (free)ARead-onlyIdempotent
Full on-page audit of ONE URL: title, meta description, canonical, lang, meta robots, viewport, H1s, heading/word/link/image counts, images missing alt, Open Graph, Twitter card, JSON-LD @types, hreflang, feeds, social links, detected technologies, robots.txt/sitemap/llms.txt presence and AI-bot access, plus seo_score (0-100, deductions: high 15 / medium 8 / low 3) with seo_issues[{code, severity, message}] and ai_readiness_score (0-100). Issue codes: NO_HTTPS, MISSING_TITLE, TITLE_TOO_LONG, TITLE_TOO_SHORT, MISSING_META_DESCRIPTION, META_DESCRIPTION_TOO_LONG, MISSING_H1, MULTIPLE_H1, MISSING_CANONICAL, MISSING_LANG, MISSING_VIEWPORT, NOINDEX, MISSING_OPEN_GRAPH, MISSING_STRUCTURED_DATA, IMAGES_MISSING_ALT, THIN_CONTENT, MISSING_ROBOTS_TXT, MISSING_SITEMAP. WHEN TO USE: SEO health of a specific page, or to create a snapshot you can store and later pass to web_compare_snapshots for before/after tracking. For just one aspect use web_ai_crawler_access, web_tech_stack, web_sitemap_info or web_security_headers; for many sites use web_batch_audit. Fetching: read-only GETs from this server with User-Agent "FairqueryBot ... Fairquery-MCP", 15 s timeout per request, body capped (1.5 MB HTML), max 5 redirects; URLs resolving to private/loopback/link-local addresses are refused (SSRF guard). Free, no token, no JavaScript rendering. Makes ~5 requests (page, robots.txt, sitemap, llms.txt, llms-full.txt) unless checkRobots=false. RETURNS: one "seo_audit" snapshot object (snapshot_schema "fairquery-web-snapshot/1") with the fields above plus input, final_url, status_code, https, response_ms, html_truncated, checked_at. Errors (isError=true, JSON {error, message, retryable}): INVALID_URL, BLOCKED_PRIVATE_ADDRESS, DNS_FAILED, FETCH_FAILED, TIMEOUT, TOO_MANY_REDIRECTS. WHEN NOT TO USE: only need reachability (web_quick_check), only AI-bot rules (web_ai_crawler_access), only stack (web_tech_stack), or many sites (web_batch_audit, paid). COST: free - runs locally in this MCP server (direct HTTP GETs), no APIFY_TOKEN, no Apify billing. EXAMPLE: {"url":"https://www.python.org/about/"} -> {type:"seo_audit", seo_score:0-100, ai_readiness_score:0-100, issues:[...], ...}
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Required. One public domain or http(s) URL, e.g. "vercel.com" or "https://www.python.org/about/". Bare domains are fetched over https; private/loopback hosts are refused. | |
| checkRobots | No | Also fetch robots.txt, sitemap and llms.txt for AI-bot/sitemap checks and scores (default true). false = page only, faster. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnlyHint, idempotentHint, destructiveHint=false), but the description adds substantial context beyond them: fetching behavior, User-Agent, 15s timeout, body cap, redirect limit, SSRF guard, no JavaScript rendering, number of requests, and full error codes. This is unusually thorough behavioral disclosure for a read-only audit tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with purpose, issue codes, usage, fetching, returns, and costs, and the structure makes it easy to scan. However, some content is repeated: 'free' is stated in the title, the fetching section, and the COST section, and the EXAMPLE duplicates the URL format already in the schema, so it falls short of perfect conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, lack of output schema, and many output fields, the description is complete: it enumerates returned fields, snapshot schema, error shapes, and operational constraints. Together with annotations and the fully described input schema, an agent has everything needed to invoke and interpret the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are already documented in the input schema. The description adds only a minor detail about request count when checkRobots=false; otherwise it does not extend parameter meaning beyond the schema, matching the baseline of 3 for fully covered schemas.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: a full on-page audit of ONE URL, enumerating the exact fields and scores produced. It clearly distinguishes itself from sibling tools by naming the narrower alternatives and the batch alternative.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit WHEN TO USE and WHEN NOT TO USE sections, naming each sibling (web_ai_crawler_access, web_tech_stack, web_sitemap_info, web_security_headers, web_quick_check, web_batch_audit) and the condition that selects it. It also explains the snapshot-then-compare workflow with web_compare_snapshots.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
web_sitemap_infoXML sitemap discovery and URL listing (free, paged)ARead-onlyIdempotent
Find a site's XML sitemap (robots.txt Sitemap: lines, then /sitemap.xml, /sitemap_index.xml, or an explicit sitemapUrl), report whether it is a sitemap index, list child sitemaps, and page through the contained URLs with lastmod. For an index, the first maxChildSitemaps children are expanded. WHEN TO USE: count/inspect indexed pages, find recently modified URLs (filter with contains / sort), feed URLs into web_seo_audit. Not a crawler: only what the sitemap lists. Fetching: read-only GETs from this server with User-Agent "FairqueryBot ... Fairquery-MCP", 15 s timeout per request, body capped (1.5 MB HTML), max 5 redirects; URLs resolving to private/loopback/link-local addresses are refused (SSRF guard). Free, no token, no JavaScript rendering. Sitemap files are capped at 10 MB each (meta.truncated=true when cut). RETURNS: {count, total, offset, hasMore, nextOffset, meta{origin, sitemap_url, declared_in_robots, is_index, child_sitemap_count, child_sitemaps[], expanded_child_sitemaps[], truncated}, items[{type:"url", loc, lastmod, sitemap}]}. Errors: SITEMAP_NOT_FOUND plus INVALID_URL, BLOCKED_PRIVATE_ADDRESS, DNS_FAILED, FETCH_FAILED, TIMEOUT, TOO_MANY_REDIRECTS. WHEN NOT TO USE: not a crawler and does not audit pages - pass selected URLs to web_seo_audit; for AI-bot robots.txt rules use web_ai_crawler_access. COST: free - runs locally in this MCP server (direct HTTP GETs), no APIFY_TOKEN, no Apify billing. EXAMPLE: {"url":"python.org","contains":"/blog/","sort":"lastmod_desc","limit":10} -> paged url rows with loc and lastmod.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Required. One public domain or http(s) URL, e.g. "vercel.com" or "https://www.python.org/about/". Bare domains are fetched over https; private/loopback hosts are refused. | |
| sort | No | "sitemap" = file order (default); "lastmod_desc" = most recently modified first | |
| limit | No | Optional page size: number of items to return, integer 1-1000 (default 100) | |
| offset | No | Zero-based offset into the full result list (default 0); use nextOffset from the previous page | |
| contains | No | Only URLs containing this substring, e.g. "/blog/" | |
| sitemapUrl | No | Explicit sitemap URL to use instead of auto-discovery | |
| maxChildSitemaps | No | For sitemap indexes: how many child sitemaps to fetch and list URLs from (default 3, max 20; 0 = list children only) |
Output Schema
| Name | Required | Description |
|---|---|---|
| meta | No | Tool-specific context (company, source_url, ...) |
| count | Yes | Number of items in this page |
| items | Yes | Result rows for this page |
| total | Yes | Total items matching the filters (before paging) |
| offset | Yes | Offset of the first item in this page |
| hasMore | Yes | True if more items exist after this page |
| nextOffset | Yes | Offset to pass for the next page, or null |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, and the description exceeds them with concrete operational detail: User-Agent string, 15s timeout, 1.5MB body cap, max 5 redirects, SSRF guard refusing private/loopback addresses, 10MB per-sitemap cap with meta.truncated flag, and a full error-code list.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads purpose then groups content under WHEN TO USE / RETURNS / WHEN NOT TO USE / COST / EXAMPLE, so navigation is easy. It is somewhat long, and the RETURNS block partially duplicates the existing output schema, but nearly every sentence carries actionable information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers discovery order, index handling, paging semantics, limits, SSRF/timeout behavior, error conditions, cost/auth, and a concrete example. With an output schema present it did not need to restate return shape, yet nothing an agent needs to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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, but the description adds meaning beyond the schema: explains that for an index only the first maxChildSitemaps children are expanded, that contains/sort drive filtering, and shows a worked example combining url, contains, sort, and limit.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States specific verbs and resource: find a site's XML sitemap, report whether it is an index, list child sitemaps, page through URLs with lastmod. It explicitly differentiates from siblings by declaring 'Not a crawler' and routing to web_seo_audit and web_ai_crawler_access.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Has explicit WHEN TO USE (count/inspect indexed pages, find recently modified URLs, feed into web_seo_audit) and WHEN NOT TO USE (not a crawler, not an auditor; use web_seo_audit for pages, web_ai_crawler_access for robots.txt AI rules). Alternatives and conditions are named outright.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
web_tech_stackDetect website technology stack (free)ARead-onlyIdempotent
Detect technologies used by one page from its HTML and HTTP headers: frameworks (Next.js, Nuxt, React, ...), CMS (WordPress, Shopify, Webflow, ...), hosting/CDN (Vercel, Cloudflare, Netlify, ...), analytics/tag managers, and more, each with category and evidence. WHEN TO USE: lead enrichment ("what stack does this company use?"), competitor research. Signature-based, single request, no JavaScript execution, so client-injected tools may be missed. For many sites use web_batch_audit. Fetching: read-only GETs from this server with User-Agent "FairqueryBot ... Fairquery-MCP", 15 s timeout per request, body capped (1.5 MB HTML), max 5 redirects; URLs resolving to private/loopback/link-local addresses are refused (SSRF guard). Free, no token, no JavaScript rendering. RETURNS: a paged list {count, total, offset, hasMore, nextOffset, meta{input, final_url, status_code, generator, server, x_powered_by, note}, items[{type:"technology", name, category, evidence}]}. Filter with category. Errors (isError=true, JSON {error, message, retryable}): INVALID_URL, BLOCKED_PRIVATE_ADDRESS, DNS_FAILED, FETCH_FAILED, TIMEOUT, TOO_MANY_REDIRECTS. WHEN NOT TO USE: for SEO metadata use web_seo_audit; for security headers use web_security_headers. COST: free - runs locally in this MCP server (direct HTTP GETs), no APIFY_TOKEN, no Apify billing. EXAMPLE: {"url":"vercel.com","category":"hosting"} -> {count:1, items:[{type:"technology", name:"Vercel", category:"hosting", evidence:"..."}], ...}
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Required. One public domain or http(s) URL, e.g. "vercel.com" or "https://www.python.org/about/". Bare domains are fetched over https; private/loopback hosts are refused. | |
| limit | No | Optional page size: number of items to return, integer 1-200 (default 50) | |
| offset | No | Zero-based offset into the full result list (default 0); use nextOffset from the previous page | |
| category | No | Only return technologies whose category contains this text (case-insensitive), e.g. "analytics", "cms", "cdn" |
Output Schema
| Name | Required | Description |
|---|---|---|
| meta | No | Tool-specific context (company, source_url, ...) |
| count | Yes | Number of items in this page |
| items | Yes | Result rows for this page |
| total | Yes | Total items matching the filters (before paging) |
| offset | Yes | Offset of the first item in this page |
| hasMore | Yes | True if more items exist after this page |
| nextOffset | Yes | Offset to pass for the next page, or null |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/openWorld, and the description still adds substantial behavioral context: signature-based detection with no JS execution (so client-injected tools may be missed), identifying User-Agent, 15 s timeout, 1.5 MB body cap, max 5 redirects, SSRF refusal of private/loopback addresses, and free/no-token cost. This is well beyond what the annotations convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Long but front-loaded and sectioned (WHEN TO USE / Fetching / RETURNS / WHEN NOT TO USE / COST / EXAMPLE), so an agent can skim to the needed part. Every block carries operational information with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite an output schema existing, the description still summarizes the return shape and error taxonomy (INVALID_URL, BLOCKED_PRIVATE_ADDRESS, DNS_FAILED, FETCH_FAILED, TIMEOUT, TOO_MANY_REDIRECTS) with the isError/retryable contract. For a single-request fetch tool with SSRF guard and pagination, nothing an agent needs is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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, but the description adds value: it explains the category filter's role, documents the pagination contract via nextOffset, and provides a worked EXAMPLE showing url+category producing a filtered item. It does not, however, add syntax beyond what the schema states for url/limit/offset.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ("Detect technologies used by one page from its HTML and HTTP headers") and enumerates the detectable categories (frameworks, CMS, hosting/CDN, analytics), making the scope concrete. It also names the sibling tools it is NOT (web_seo_audit, web_security_headers, web_batch_audit), so an agent can disambiguate without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit WHEN TO USE with concrete scenarios (lead enrichment, competitor research) plus routing to web_batch_audit for many sites, and a WHEN NOT TO USE section routing to web_seo_audit and web_security_headers. Both inclusion and exclusion conditions are stated.
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.
9 tool updates
v1.2.1- Removed
check_websites - Added
web_ai_crawler_access - Added
web_batch_audit - Added
web_compare_snapshots - Added
web_quick_check - Added
web_security_headers - Added
web_seo_audit - Added
web_sitemap_info - Added
web_tech_stack
1 tool update
v0.1.0- First observed
check_websites
TDQS
Scored across 8 tools
Each tool targets a clearly distinct facet: single-page SEO audit, before/after diffing, lightweight reachability, AI-bot access, tech stack, sitemap, security headers, and bulk auditing. Overlaps (web_seo_audit vs web_batch_audit, or robots checks within the audit) are explicitly disambiguated with WHEN TO USE / WHEN NOT TO USE guidance.
All eight tools use a uniform 'web_' prefix with snake_case noun phrases (web_seo_audit, web_compact_snapshots, web_quick_check, web_ai_crawler_access, web_tech_stack, web_sitemap_info, web_security_headers, web_batch_audit). No camelCase or style mixing, and each name is self-descriptive.
Eight tools is well-scoped for a web-auditing server, with each covering a distinct concern (single, bulk, compare, reachability, AI access, stack, sitemap, security). No redundant or filler tools, and the free-vs-paid split is a clean, purposeful separation.
The surface covers the full auditing lifecycle: discovery (sitemap), reachability (quick_check), deep single-site audit, technology and security inspection, AI-crawler/llms.txt checks, bulk scans, and historical/competitive comparison via snapshots. No obvious operational gap for the stated domain.
Maintenance
Related MCP Connectors
Checks llms.txt, AI crawler access in robots.txt, and sitemap - with a 0-100 AI readiness score.
Live web checks for AI agents: sitemaps, robots.txt, URL status, broken links, feeds, citations.
Scores any public website on how usable it is by AI agents, with per-check evidence.
The website checker for AI agents. One call: verdict, score out of 100, fix list.
Related MCP Servers
- AlicenseAqualityBmaintenanceEnables AI agents to check whether a public website is crawlable, understandable, and ready for AI search workflows through local-only audits of robots.txt, sitemaps, metadata, and llms.txt.345 npm1MIT
- AlicenseAqualityAmaintenanceEnables AI clients to analyze any company domain and determine its AI maturity tier (commercialized, deployed, declared, or none) with supporting evidence, via a single tool backed by an Apify actor.1118 npmMIT

kanto-labs-mcpofficial
AlicenseAqualityAmaintenanceEnables AI assistants to run pay-per-result web data and media tools such as website tech stack detection, document-to-Markdown conversion, SEO audits, OCR, and domain lookups via Apify.14MIT
agentbuiltofficial
AlicenseNot gradedqualityCmaintenanceEnables AI agents to run a free AI-readiness audit of any URL, checking AI crawler rules, JavaScript-free page text, JSON-LD, llms.txt, sitemap, meta description, FAQ schema, and returning a score with findings and fixes. Also exposes the same capability via an A2A agent endpoint.MIT