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
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.comPython >=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).
| Category | Weight | Checks |
|---|---|---|
| Access & Discovery | 25 | 10 |
| Machine Understanding | 25 | 12 |
| Agent Interfaces | 20 | 9 |
| Trust & Commerce | 15 | 7 |
| Operability & Efficiency | 15 | 7 |
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.
| Capability | Core | Cloud |
|---|---|---|
| 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
| ID | Title | Category | Status |
|---|---|---|---|
| CORE-ACCESS-001 | HTTPS reachability | access | stable |
| CORE-ACCESS-002 | robots.txt availability and syntax | access | stable |
| CORE-ACCESS-003 | AI search crawler policy | access | stable |
| CORE-ACCESS-004 | Training vs. search crawler separation | access | stable |
| CORE-ACCESS-005 | Sitemap availability | access | stable |
| CORE-ACCESS-006 | Sitemap freshness | access | stable |
| CORE-ACCESS-007 | Canonical URL integrity | access | stable |
| CORE-ACCESS-008 | Indexability | access | stable |
| CORE-ACCESS-009 | llms.txt presence and integrity | access | stable |
| CORE-ACCESS-010 | Content-Signal declaration | access | stable |
| CORE-INTERFACE-001 | MCP discovery presence | interfaces | stable |
| CORE-INTERFACE-002 | MCP server declaration quality | interfaces | stable |
| CORE-INTERFACE-003 | WebMCP static presence | interfaces | stable |
| CORE-INTERFACE-004 | WebMCP tool declaration quality | interfaces | experimental |
| CORE-INTERFACE-005 | OpenAPI discovery | interfaces | stable |
| CORE-INTERFACE-006 | OAuth authorization-server metadata | interfaces | stable |
| CORE-INTERFACE-007 | OAuth protected-resource metadata | interfaces | stable |
| CORE-INTERFACE-008 | UCP profile validity | interfaces | experimental |
| CORE-INTERFACE-009 | Agent discovery surface presence | interfaces | experimental |
| CORE-MACHINE-001 | JSON-LD parseability | machine | stable |
| CORE-MACHINE-002 | Organization entity | machine | stable |
| CORE-MACHINE-003 | WebSite/WebPage entity | machine | stable |
| CORE-MACHINE-004 | Product structured data | machine | stable |
| CORE-MACHINE-005 | Offer price, currency, and availability | machine | stable |
| CORE-MACHINE-006 | Product identifier count | machine | stable |
| CORE-MACHINE-007 | Breadcrumbs | machine | stable |
| CORE-MACHINE-008 | Metadata quality | machine | stable |
| CORE-MACHINE-009 | Heading structure | machine | stable |
| CORE-MACHINE-010 | Language declaration | machine | stable |
| CORE-MACHINE-011 | Image alt coverage | machine | stable |
| CORE-MACHINE-012 | Visible vs. structured price | machine | experimental |
| CORE-OPERABILITY-001 | Server-rendered core content | operability | stable |
| CORE-OPERABILITY-002 | Redirect chain complexity | operability | stable |
| CORE-OPERABILITY-003 | Cache validators | operability | stable |
| CORE-OPERABILITY-004 | Broken machine-consumable endpoints | operability | stable |
| CORE-OPERABILITY-005 | Agent parse cost | operability | stable |
| CORE-OPERABILITY-006 | Form/control labels | operability | stable |
| CORE-OPERABILITY-007 | Machine reference integrity | operability | experimental |
| CORE-TRUST-001 | Contact/support discoverability | trust | stable |
| CORE-TRUST-002 | Shipping policy discoverability | trust | stable |
| CORE-TRUST-003 | Returns/refund policy discoverability | trust | stable |
| CORE-TRUST-004 | Privacy policy discoverability | trust | stable |
| CORE-TRUST-005 | Terms/conditions discoverability | trust | stable |
| CORE-TRUST-006 | security.txt discoverability | trust | stable |
| CORE-TRUST-007 | Pricing discoverability | trust | stable |
Want the full picture — real AI agents on your real flows, monitored on every deploy?
Run a free scan