Open source

Scovant Core

Open-source static agent-readiness scanner

Scovant Core is an open-source passive scanner for machine-facing website signals used by AI agents. It checks crawler policy, structured data, agent discovery surfaces, protocol metadata, commerce signals and basic operability.

Scovant Core measures passive, machine-facing signals. Scovant Cloud verifies how real agents actually behave, across providers, browser runtimes, security layers and time.

Maps to AgentReady v1.0: 12 of 18 requirements measured by Core checks (2 exact, 7 partial, 3 superset). Mapping

GitHubPyPI

Install

uvx --from scovant-core scovant scan https://example.com
pipx run --spec scovant-core scovant scan https://example.com
pip install scovant-core
npx @scovant/core scan https://example.com

Python >=3.12 is required; the npm package is a launcher, not a second engine.

Quick start

$ scovant scan https://example.com
$ scovant scan https://example.com --format html --output report.html

What Core measures

45 checks across 5 categories, 5 of them marked experimental (visible in every report, never counted toward the score).

CategoryWeightChecks
Access & Discovery2510
Machine Understanding2512
Agent Interfaces209
Trust & Commerce157
Operability & Efficiency157

What Cloud adds

Core is a passive scanner: it reads what a site declares and exposes. Scovant Cloud adds what only a real browser and a real AI agent can prove.

CapabilityCoreCloud
HTTP reachability
robots.txt
Sitemap
llms.txt
Structured data (JSON-LD)
Product/Offer data
Static crawler policy
Content-Signal
MCP discovery
WebMCP static presence
OpenAPI presence
OAuth authorization-server / protected-resource metadata
UCP profile validity✅ (experimental)
Agent discovery surface (A2A cards, AI-plugin, agents.json, Agent Skills)✅ (experimental)
Core Score
Cloud = observed, reproducible, cross-provider, longitudinal
Cloud's full compatibility score
Cloud's full production ruleset
Observed WAF/bot-firewall behavior
Real crawler network access
Browser-based agent simulation
Multi-model execution
MCP tool invocation
WebMCP tool execution/state parity
Tool/UI parity checking
Checkout/task completion
CAPTCHA/challenge behavior
Verified-agent access
Failure attribution
Temporal stability / regressions
Scheduled monitoring
Alerts/webhooks
Hosted, shareable reports
Contextual fix plan

Example report

Example from a fixture site — not a real website

# Scovant Core — https://example.com/

## Score

**Scovant Core Static Signal Score:** 100 / 100 · grade A · coverage 100%
**Scope:** CANONICAL · **Status:** OK · **Errors:** 0
**Profile:** commerce (requested auto, confidence 85%)

**Capabilities detected** (descriptive, not scored): mcp: present · webmcp: absent · ucp: present · llms_txt: present · openapi: not_checked · oauth: not_checked · content_signal: present · security_txt: present
**Standards:** AgentReady v1.0 (descriptive, not scored): MUST 3/3 measured — 3 pass · SHOULD 5/12 measured — 5 pass · MAY none measured (0/3) — Mapping: docs/standards/agentready.md

## Categories

| Category | Weight | Score | Evaluated / applicable |
|---|---:|---:|---:|
| Access & Discovery | 25 | 100 | 25 / 25 |
| Machine Understanding | 25 | 100 | 23 / 23 |
| Agent Interfaces | 20 | 100 | 5 / 5 |
| Trust & Commerce | 15 | 100 | 15 / 15 |
| Operability & Efficiency | 15 | 100 | 16 / 16 |

50 checks: 40 PASS, 1 WARN, 0 FAIL, 9 N/A, 0 ERROR

## Top findings

(none)

## Findings

### PASS (37)

- **CORE-ACCESS-001** — HTTPS reachability (info): HTTPS entry URL answered 200.

  <details><summary>evidence</summary>

  ```json
  {
    "final_url": "https://example.com/",
    "input_url": "https://example.com/",
    "redirect_chain": [],
    "redirect_count": 0,
    "status": 200
  }
  ```

  </details>

- **CORE-ACCESS-002** — robots.txt availability and syntax (info): robots.txt answered 200 with a well-formed policy.

  <details><summary>evidence</summary>

  ```json
  {
    "error": null,
    "resource": "https://example.com/robots.txt",
    "served_as_html": false,
    "sha256": "a3b24ab6056572a5c127bc7a4dba409e656da1245ef936633bab52b8b395efcf",
    "sitemap_count": 1,
    "status": 200,
    "unknown_directives": []
  }
  ```

  </details>

- **CORE-ACCESS-003** — AI search crawler policy (info): robots.txt declares all major search and answer-engine crawlers as allowed.

  <details><summary>evidence</summary>

  ```json
  {
    "declared_policy": {
      "Applebot": true,
      "Bingbot": true,
      "Claude-SearchBot": true,
      "Googlebot": true,
      "OAI-SearchBot": true,
      "PerplexityBot": true
    },
    "http_status": 200,
    "resource": "https://example.com/robots.txt",
    "robots_present": true,
    "user_fetch_policy": {
      "ChatGPT-User": true,
      "Claude-User": true,
      "DuckAssistBot": true,
      "Perplexity-User": true
    }
  }
  ```

  </details>

- **CORE-ACCESS-004** — Training vs. search crawler separation (info): Training/content-use crawler(s) GPTBot, Google-Extended are restricted while search/retrieval crawlers remain allowed.

  <details><summary>evidence</summary>

  ```json
  {
    "explicit_separation": true,
    "http_status": 200,
    "resource": "https://example.com/robots.txt",
    "search_blocked": [],
    "training_blocked": [
      "GPTBot",
      "Google-Extended"
    ]
  }
  ```

  </details>

- **CORE-ACCESS-005** — Sitemap availability (info): A valid urlset sitemap was found at https://example.com/sitemap.xml.

  <details><summary>evidence</summary>

  ```json
  {
    "entry_count": 3,
    "exists": true,
    "kind": "urlset",
    "parse_error": null,
    "probe_error": null,
    "probe_status": 200,
    "served_as_html": false,
    "url": "https://example.com/sitemap.xml",
    "valid": true
  }
  ```

  </details>

- **CORE-ACCESS-006** — Sitemap freshness (info): Sitemap lastmod values look plausible.

  <details><summary>evidence</summary>

  ```json
  {
    "dated_entry_count": 3,
    "entry_count": 3,
    "newest": "2026-08-15",
    "oldest": "2026-07-01",
    "url": "https://example.com/sitemap.xml"
  }
  ```

  </details>

- **CORE-ACCESS-007** — Canonical URL integrity (info): The canonical URL matches the entry URL.

  <details><summary>evidence</summary>

  ```json
  {
    "canonical_url": "https://example.com/",
    "entry_url": "https://example.com/"
  }
  ```

  </details>

- **CORE-ACCESS-008** — Indexability (info): The entry page does not declare noindex.

  <details><summary>evidence</summary>

  ```json
  {
    "robots_meta": null,
    "x_robots_tag": null
  }
  ```

  </details>

- **CORE-ACCESS-009** — llms.txt presence and integrity (info): llms.txt is well-formed and its 2 checked references resolve.

  <details><summary>evidence</summary>

  ```json
  {
    "errors": [],
    "references_broken": [],
    "references_checked": 2,
    "references_unresolved": [],
    "resource": "https://example.com/llms.txt",
    "valid": true
  }
  ```

  </details>

- **CORE-ACCESS-010** — Content-Signal declaration (info): Content-Signal is declared and internally consistent.

  <details><summary>evidence</summary>

  ```json
  {
    "declared": true,
    "dimensions": {
      "ai-input": "yes",
      "ai-train": "no",
      "search": "yes"
    },
    "syntax_errors": []
  }
  ```

  </details>

- **CORE-INTERFACE-001** — MCP discovery presence (info): An MCP discovery file is published and well-formed.

  <details><summary>evidence</summary>

  ```json
  {
    "declared_name": "example-shop",
    "endpoints": [
      "https://example.com/mcp"
    ],
    "exists": true,
    "http_status": 200,
    "resource": "https://example.com/.well-known/mcp.json",
    "server_card": false,
    "valid": true
  }
  ```

  </details>

- **CORE-INTERFACE-002** — MCP server declaration quality (info): Every declared MCP server has a name, url, transport, and a real description.

  <details><summary>evidence</summary>

  ```json
  {
    "servers_count": 1
  }
  ```

  </details>

- **CORE-MACHINE-001** — JSON-LD parseability (info): Every JSON-LD block on the sampled pages parses as valid JSON.

  <details><summary>evidence</summary>

  ```json
  {
    "pages": [
      {
        "parsed": 2,
        "raw": 2,
        "url": "https://example.com/"
      },
      {
        "parsed": 2,
        "raw": 2,
        "url": "https://example.com/products/widget"
      },
      {
        "parsed": 0,
        "raw": 0,
        "url": "https://example.com/contact"
      }
    ],
    "parsed_total": 4,
    "raw_total": 4
  }
  ```

  </details>

- **CORE-MACHINE-002** — Organization entity (info): An Organization entity declares name and url.

  <details><summary>evidence</summary>

  ```json
  {
    "found": true,
    "has_description": false,
    "has_logo": true,
    "has_sameAs": false,
    "name": "Example Shop",
    "pages_parsed": 3,
    "url": "https://example.com/"
  }
  ```

  </details>

- **CORE-MACHINE-003** — WebSite/WebPage entity (info): A WebSite or WebPage entity was found on the sampled pages.

  <details><summary>evidence</summary>

  ```json
  {
    "found": true,
    "pages_parsed": 3
  }
  ```

  </details>

- **CORE-MACHINE-004** — Product structured data (info): A sampled product page exposes a Product entity with an identifier.

  <details><summary>evidence</summary>

  ```json
  {
    "has_identifiers": true,
    "pages_parsed": 3,
    "product_pages": [
      "https://example.com/products/widget"
    ]
  }
  ```

  </details>

- **CORE-MACHINE-005** — Offer price, currency, and availability (info): The product's Offer declares price, currency, and availability.

  <details><summary>evidence</summary>

  ```json
  {
    "availability": "https://schema.org/InStock",
    "currency": "USD",
    "missing": [],
    "price": 19.99,
    "url": "https://example.com/products/widget"
  }
  ```

  </details>

- **CORE-MACHINE-006** — Product identifier count (info): Product entities declare two or more stable identifiers.

  <details><summary>evidence</summary>

  ```json
  {
    "count": 2,
    "identifier_keys": [
      "brand",
      "sku"
    ],
    "pages_parsed": 3
  }
  ```

  </details>

- **CORE-MACHINE-007** — Breadcrumbs (info): A sampled non-entry page declares a BreadcrumbList.

  <details><summary>evidence</summary>

  ```json
  {
    "has_breadcrumb": true,
    "non_entry_pages": [
      "https://example.com/products/widget",
      "https://example.com/contact"
    ],
    "non_entry_parsed": 2
  }
  ```

  </details>

- **CORE-MACHINE-008** — Metadata quality (info): The entry page declares title, description, and Open Graph tags.

  <details><summary>evidence</summary>

  ```json
  {
    "entry_url": "https://example.com/",
    "issues": [],
    "meta_description": "Example Shop sells widgets.",
    "missing": [],
    "title": "Example Shop — Widgets"
  }
  ```

  </details>

- **CORE-MACHINE-009** — Heading structure (info): The entry page has a single H1 and no skipped heading levels.

  <details><summary>evidence</summary>

  ```json
  {
    "entry_url": "https://example.com/",
    "h1_count": 1,
    "heading_count": 2,
    "issues": [],
    "levels": [
      "h1",
      "h2"
    ]
  }
  ```

  </details>

- **CORE-MACHINE-010** — Language declaration (info): The entry page declares a valid `lang` attribute.

  <details><summary>evidence</summary>

  ```json
  {
    "entry_url": "https://example.com/",
    "html_lang": "en"
  }
  ```

  </details>

- **CORE-MACHINE-011** — Image alt coverage (info): 1/1 images have an alt attribute (ratio 100%).

  <details><summary>evidence</summary>

  ```json
  {
    "covered": 1,
    "empty_alt": 0,
    "pages_parsed": 3,
    "ratio": 1.0,
    "total": 1,
    "with_alt": 1
  }
  ```

  </details>

- **CORE-OPERABILITY-001** — Server-rendered core content (info): The entry page's static HTML carries 337 chars of visible text.

  <details><summary>evidence</summary>

  ```json
  {
    "entry_url": "https://example.com/",
    "spa_shell_marker": false,
    "visible_text_chars": 337
  }
  ```

  </details>

- **CORE-OPERABILITY-002** — Redirect chain complexity (info): The entry URL redirects 0 time(s) before settling.

  <details><summary>evidence</summary>

  ```json
  {
    "redirect_chain": [],
    "redirect_count": 0
  }
  ```

  </details>

- **CORE-OPERABILITY-003** — Cache validators (info): The entry response carries an ETag or Last-Modified validator.

  <details><summary>evidence</summary>

  ```json
  {
    "cache_control": null,
    "etag": "\"commerce-good-v1\"",
    "last_modified": null
  }
  ```

  </details>

- **CORE-OPERABILITY-004** — Broken machine-consumable endpoints (info): All 6 checked machine-consumable reference(s) resolve.

  <details><summary>evidence</summary>

  ```json
  {
    "broken": [],
    "broken_count": 0,
    "inconclusive": [
      {
        "source": "mcp_endpoint",
        "status": 404,
        "url": "https://example.com/mcp"
      }
    ],
    "refs_checked": 7,
    "refs_resolved": 6,
    "unresolved": []
  }
  ```

  </details>

- **CORE-OPERABILITY-005** — Agent parse cost (info): The entry page's estimated parse cost is ~84 tokens (low).

  <details><summary>evidence</summary>

  ```json
  {
    "dom_nodes": 24,
    "estimated_tokens": 84,
    "html_bytes": 1315,
    "level": "LOW",
    "link_count": 7,
    "script_bytes": 247,
    "script_ratio": 0.18783269961977186,
    "structured_bytes": 247,
    "text_chars": 337,
    "token_chars_ratio": 4
  }
  ```

  </details>

- **CORE-OPERABILITY-008** — Unknown paths return 404 (info): Unknown paths answer with a real 404.

  <details><summary>evidence</summary>

  ```json
  {
    "final_url": "https://example.com/scovant-core-probe-9b580505",
    "probed_url": "https://example.com/scovant-core-probe-9b580505",
    "redirected": false,
    "served_html": false,
    "status": 404
  }
  ```

  </details>

- **CORE-OPERABILITY-010** — Challenge pages are not served as 200 (info): No challenge page is served with HTTP 200.

  <details><summary>evidence</summary>

  ```json
  {
    "honest_challenges": 0,
    "pages": [],
    "pages_checked": 4
  }
  ```

  </details>

- **CORE-TRUST-001** — Contact/support discoverability (info): A contact or support link was found on the entry page.

  <details><summary>evidence</summary>

  ```json
  {
    "contact_url": "https://example.com/contact",
    "kind": "page"
  }
  ```

  </details>

- **CORE-TRUST-002** — Shipping policy discoverability (info): A shipping policy page was found with substantive content.

  <details><summary>evidence</summary>

  ```json
  {
    "served_as_html": true,
    "status": 200,
    "text_chars": 300,
    "url": "https://example.com/shipping"
  }
  ```

  </details>

- **CORE-TRUST-003** — Returns/refund policy discoverability (info): A returns/refund policy page was found with substantive content.

  <details><summary>evidence</summary>

  ```json
  {
    "served_as_html": true,
    "status": 200,
    "text_chars": 312,
    "url": "https://example.com/returns"
  }
  ```

  </details>

- **CORE-TRUST-004** — Privacy policy discoverability (info): A privacy policy page was found with substantive content.

  <details><summary>evidence</summary>

  ```json
  {
    "served_as_html": true,
    "status": 200,
    "text_chars": 303,
    "url": "https://example.com/privacy"
  }
  ```

  </details>

- **CORE-TRUST-005** — Terms/conditions discoverability (info): A terms/conditions page was found with substantive content.

  <details><summary>evidence</summary>

  ```json
  {
    "served_as_html": true,
    "status": 200,
    "text_chars": 334,
    "url": "https://example.com/terms"
  }
  ```

  </details>

- **CORE-TRUST-006** — security.txt discoverability (info): A valid security.txt was found with a contact method.

  <details><summary>evidence</summary>

  ```json
  {
    "contact": true,
    "expires": "2030-01-01T00:00:00Z",
    "expires_valid": true,
    "found_url": "https://example.com/.well-known/security.txt",
    "status": 200
  }
  ```

  </details>

- **CORE-TRUST-007** — Pricing discoverability (info): Prices are exposed as structured product data.

  <details><summary>evidence</summary>

  ```json
  {
    "structured_price": 19.99,
    "url": "https://example.com/products/widget"
  }
  ```

  </details>

### N/A (6)

`CORE-INTERFACE-003`, `CORE-INTERFACE-005`, `CORE-INTERFACE-006`, `CORE-INTERFACE-007`, `CORE-OPERABILITY-006`, `CORE-OPERABILITY-009`

## Experimental (not scored)

- **CORE-ACCESS-011** (PASS) — llms.txt links useful same-origin pages and carries no misplaced policy or template text.
- **CORE-INTERFACE-008** (PASS) — A UCP profile is published and valid.
- **CORE-MACHINE-012** (PASS) — The structured price matches a visible price on the page.
- **CORE-OPERABILITY-011** (WARN) — 3 of 3 machine surface(s) are not linked from anything an agent reads: llms_txt, mcp, ucp.

N/A: `CORE-INTERFACE-004`, `CORE-INTERFACE-009`, `CORE-OPERABILITY-007`

## Not tested by Scovant Core

- Observed WAF access
- Real agent tasks
- MCP tool execution
- WebMCP state parity
- Multi-model reliability
- Regression stability

## Provenance

Core 0.3.0 · ruleset 2026.10 (digest `994a69bc7f12`) · scan `local-golden` · 2026-09-04T00:00:00Z

Verify with real agents: [scovant.com/scan](https://scovant.com/scan?utm_source=scovant-core&utm_medium=cli&utm_campaign=oss)

Methodology

Checks run PASS / WARN / FAIL / N/A / ERROR against a static crawl — no JavaScript execution, no browser, no AI agent. Category weights and status points are published in the package (see the table above); a score reports INSUFFICIENT_EVIDENCE below the coverage floor rather than guessing. Full detail: docs/methodology.md.

Checks

IDTitleCategoryStatus
CORE-ACCESS-001HTTPS reachabilityaccessstable
CORE-ACCESS-002robots.txt availability and syntaxaccessstable
CORE-ACCESS-003AI search crawler policyaccessstable
CORE-ACCESS-004Training vs. search crawler separationaccessstable
CORE-ACCESS-005Sitemap availabilityaccessstable
CORE-ACCESS-006Sitemap freshnessaccessstable
CORE-ACCESS-007Canonical URL integrityaccessstable
CORE-ACCESS-008Indexabilityaccessstable
CORE-ACCESS-009llms.txt presence and integrityaccessstable
CORE-ACCESS-010Content-Signal declarationaccessstable
CORE-INTERFACE-001MCP discovery presenceinterfacesstable
CORE-INTERFACE-002MCP server declaration qualityinterfacesstable
CORE-INTERFACE-003WebMCP static presenceinterfacesstable
CORE-INTERFACE-004WebMCP tool declaration qualityinterfacesexperimental
CORE-INTERFACE-005OpenAPI discoveryinterfacesstable
CORE-INTERFACE-006OAuth authorization-server metadatainterfacesstable
CORE-INTERFACE-007OAuth protected-resource metadatainterfacesstable
CORE-INTERFACE-008UCP profile validityinterfacesexperimental
CORE-INTERFACE-009Agent discovery surface presenceinterfacesexperimental
CORE-MACHINE-001JSON-LD parseabilitymachinestable
CORE-MACHINE-002Organization entitymachinestable
CORE-MACHINE-003WebSite/WebPage entitymachinestable
CORE-MACHINE-004Product structured datamachinestable
CORE-MACHINE-005Offer price, currency, and availabilitymachinestable
CORE-MACHINE-006Product identifier countmachinestable
CORE-MACHINE-007Breadcrumbsmachinestable
CORE-MACHINE-008Metadata qualitymachinestable
CORE-MACHINE-009Heading structuremachinestable
CORE-MACHINE-010Language declarationmachinestable
CORE-MACHINE-011Image alt coveragemachinestable
CORE-MACHINE-012Visible vs. structured pricemachineexperimental
CORE-OPERABILITY-001Server-rendered core contentoperabilitystable
CORE-OPERABILITY-002Redirect chain complexityoperabilitystable
CORE-OPERABILITY-003Cache validatorsoperabilitystable
CORE-OPERABILITY-004Broken machine-consumable endpointsoperabilitystable
CORE-OPERABILITY-005Agent parse costoperabilitystable
CORE-OPERABILITY-006Form/control labelsoperabilitystable
CORE-OPERABILITY-007Machine reference integrityoperabilityexperimental
CORE-TRUST-001Contact/support discoverabilitytruststable
CORE-TRUST-002Shipping policy discoverabilitytruststable
CORE-TRUST-003Returns/refund policy discoverabilitytruststable
CORE-TRUST-004Privacy policy discoverabilitytruststable
CORE-TRUST-005Terms/conditions discoverabilitytruststable
CORE-TRUST-006security.txt discoverabilitytruststable
CORE-TRUST-007Pricing discoverabilitytruststable

Want the full picture — real AI agents on your real flows, monitored on every deploy?

Run a free scan