<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sergiy Zhytanskyy</title>
    <description>The latest articles on DEV Community by Sergiy Zhytanskyy (@scovant).</description>
    <link>https://dev.to/scovant</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4241382%2F57d5f86e-8ba4-4aaa-b4cb-cf0283214210.png</url>
      <title>DEV Community: Sergiy Zhytanskyy</title>
      <link>https://dev.to/scovant</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/scovant"/>
    <language>en</language>
    <item>
      <title>Scovant Core: open-source scanner for AI-agent readiness</title>
      <dc:creator>Sergiy Zhytanskyy</dc:creator>
      <pubDate>Thu, 12 Nov 2026 20:25:57 +0000</pubDate>
      <link>https://dev.to/scovant/scovant-core-open-source-scanner-for-ai-agent-readiness-1n6l</link>
      <guid>https://dev.to/scovant/scovant-core-open-source-scanner-for-ai-agent-readiness-1n6l</guid>
      <description>&lt;p&gt;Most tools that tell you whether a website is "AI ready" are guessing.&lt;br&gt;
They fetch a page, hit a timeout or a bot wall, and publish their own failure as&lt;br&gt;
a fault of the site. We built Scovant Core because we needed the opposite: a&lt;br&gt;
scanner whose every verdict carries the evidence it came from, and which says&lt;br&gt;
"I could not look" instead of inventing an answer.&lt;/p&gt;

&lt;p&gt;Scovant is an AI agent readiness testing platform that scans, simulates, and continuously monitors websites to determine how reliably AI agents can discover, understand, and interact with them. Scovant Core is the open-source&lt;br&gt;
engine behind the first of those three layers: a passive scanner you can run&lt;br&gt;
yourself, against your own site, with no account.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it checks
&lt;/h2&gt;

&lt;p&gt;69 checks across six categories — 51 readiness checks, eight of them&lt;br&gt;
experimental (reported, but excluded from the score until they are promoted&lt;br&gt;
against published criteria), plus 18 unscored security checks. The five&lt;br&gt;
readiness categories: whether agents can reach and are allowed to&lt;br&gt;
read the site (access); whether the content is machine-understandable&lt;br&gt;
(machine); whether the site exposes an agent interface (interfaces); whether&lt;br&gt;
the trust and commerce surfaces an agent needs are discoverable (trust); and&lt;br&gt;
how expensive the site is for an agent to operate (operability).&lt;/p&gt;

&lt;p&gt;The newest group is HTTP semantics: does a missing page return a real 404 (a&lt;br&gt;
soft-404 fails; an SPA shell warns), does a 429 carry &lt;code&gt;Retry-After&lt;/code&gt;, and is a&lt;br&gt;
challenge page ever served as a 200? Agents act on status codes; a site that&lt;br&gt;
lies in them breaks retry logic silently.&lt;/p&gt;

&lt;p&gt;Every check is passive. Core issues ordinary GETs, never authenticates, never&lt;br&gt;
submits a form, and never invokes a tool it discovers. It is meant to be run&lt;br&gt;
against sites you own or are authorised to test.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evidence, not vibes
&lt;/h2&gt;

&lt;p&gt;Three rules make the output trustworthy, and they are the reason we wrote our&lt;br&gt;
own engine instead of wrapping an existing one.&lt;/p&gt;

&lt;p&gt;A document we could not read is an error, never a finding. If robots.txt times&lt;br&gt;
out, the report says the evidence is missing and the coverage drops — it does&lt;br&gt;
not say the site blocks crawlers.&lt;/p&gt;

&lt;p&gt;Absence is only reported when absence is the answer. A 404 on a page we probed&lt;br&gt;
opportunistically is "not applicable". A missing robots.txt is a real finding,&lt;br&gt;
because its absence is itself the fact.&lt;/p&gt;

&lt;p&gt;A document read only in part says so. Every fetch is capped at a&lt;br&gt;
per-document-kind byte limit, and any verdict drawn from a body cut off&lt;br&gt;
by that cap carries &lt;code&gt;"truncated": true&lt;/code&gt; in its evidence and drops to at&lt;br&gt;
most medium confidence, because anything past the cap is invisible to&lt;br&gt;
us — our limit, not the site's property.&lt;/p&gt;

&lt;h2&gt;
  
  
  The score
&lt;/h2&gt;

&lt;p&gt;Each check is PASS, WARN, FAIL, N/A or ERROR. Since 0.18.0 the headline result&lt;br&gt;
is Technical Readiness: the open R2 rating of the readiness rules Core&lt;br&gt;
evaluates from its own evidence, published in&lt;br&gt;
&lt;a href="https://github.com/Scovant/scovant-core/blob/main/docs/r2.md" rel="noopener noreferrer"&gt;docs/r2.md&lt;/a&gt;.&lt;br&gt;
It is shown with its coverage and names the rules Core could not measure;&lt;br&gt;
when too little was measured you get INSUFFICIENT_EVIDENCE rather than a&lt;br&gt;
number. The checks themselves are diagnostics:&lt;br&gt;
&lt;a href="https://github.com/Scovant/scovant-core/blob/main/docs/crosswalk.md" rel="noopener noreferrer"&gt;docs/crosswalk.md&lt;/a&gt;&lt;br&gt;
maps each one to the readiness rules that read the same signal, and names the&lt;br&gt;
rules only Scovant Cloud can evaluate, because they need a real agent. The&lt;br&gt;
older five-domain score was deprecated in 0.18.0 (kept behind &lt;code&gt;--legacy-score&lt;/code&gt;&lt;br&gt;
in that release only) and is removed in 0.19.0. The rest of the model is in&lt;br&gt;
the methodology document:&lt;br&gt;
&lt;a href="https://github.com/Scovant/scovant-core/blob/main/docs/methodology.md" rel="noopener noreferrer"&gt;docs/methodology.md&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The current ruleset is &lt;code&gt;2026.10&lt;/code&gt;, shipped in 0.3.1. Scores from ruleset 2026.09&lt;br&gt;
and 2026.10 are not comparable — HTTP semantics became required in 2026.10.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Core deliberately does not do
&lt;/h2&gt;

&lt;p&gt;Core does not drive a browser agent, does not run a purchase simulation, and&lt;br&gt;
does not offer multi-model testing. Those live in Scovant Cloud, our&lt;br&gt;
platform, which imports Core's evidence layer as its scanning foundation and&lt;br&gt;
builds the simulation and monitoring layers on top of it — not the other way&lt;br&gt;
around. Core only answers "can an agent discover, read and understand this&lt;br&gt;
site", which is the part you can verify from the outside, deterministically,&lt;br&gt;
in seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;uvx --from scovant-core scovant scan https://example.com
npx @scovant/core scan https://example.com
pip install scovant-core
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The npm package is a thin launcher around the same Python engine: its &lt;code&gt;uvx&lt;/code&gt;&lt;br&gt;
and &lt;code&gt;pipx&lt;/code&gt; paths pin the exact same version as the PyPI release, so those two&lt;br&gt;
give you identical checks and the same ruleset version; if it falls back to&lt;br&gt;
a plain &lt;code&gt;python3&lt;/code&gt; that already has &lt;code&gt;scovant_core&lt;/code&gt; installed, you get whatever&lt;br&gt;
version that interpreter has.&lt;/p&gt;

&lt;p&gt;There is also a composite GitHub Action for running Core on every pull request,&lt;br&gt;
and &lt;code&gt;scovant mcp&lt;/code&gt; starts a stdio MCP server exposing five read-only tools, so an&lt;br&gt;
agent can run the scanner itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contributing scan results is opt-in
&lt;/h2&gt;

&lt;p&gt;Core sends nothing anywhere by default. There is a flag that contributes a&lt;br&gt;
single scan's check statuses and score, together with the scanned site's&lt;br&gt;
domain, to a public research index, and it is off unless you pass it. The&lt;br&gt;
domain is the only part of the URL that is sent: no path, no query string, no&lt;br&gt;
page content, no evidence. The README lists every transmitted field. The&lt;br&gt;
published index carries statuses only, and it is kept separate from the&lt;br&gt;
corpus we scan ourselves.&lt;/p&gt;

&lt;p&gt;Contributed client scores are never authoritative: the published index carries&lt;br&gt;
only rows our own server re-scanned and verified.&lt;/p&gt;

&lt;h2&gt;
  
  
  Licence
&lt;/h2&gt;

&lt;p&gt;Apache-2.0. Every release ships pinned constraints, an SBOM and a signed&lt;br&gt;
release manifest. Issues and pull requests are welcome; the contribution policy&lt;br&gt;
and the rule-admission criteria are in the&lt;br&gt;
&lt;a href="https://github.com/Scovant/scovant-core" rel="noopener noreferrer"&gt;repository&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>webdev</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Scovant Core 0.26.0: MCP endpoint detection that reads real evidence</title>
      <dc:creator>Sergiy Zhytanskyy</dc:creator>
      <pubDate>Thu, 12 Nov 2026 18:48:47 +0000</pubDate>
      <link>https://dev.to/scovant/scovant-core-0260-mcp-endpoint-detection-that-reads-real-evidence-30ln</link>
      <guid>https://dev.to/scovant/scovant-core-0260-mcp-endpoint-detection-that-reads-real-evidence-30ln</guid>
      <description>&lt;p&gt;A scanner that asks "does this site expose an MCP server?" usually starts at&lt;br&gt;
one URL: &lt;code&gt;/.well-known/mcp.json&lt;/code&gt;. Many sites answer that URL with &lt;em&gt;something&lt;/em&gt;: a&lt;br&gt;
catch-all page, a JSON error, a redirect to the homepage. Until this release,&lt;br&gt;
Scovant Core counted an HTTP 200 there as a sign of an endpoint. That was wrong,&lt;br&gt;
so before changing it we measured how wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we measured
&lt;/h2&gt;

&lt;p&gt;In a corpus of 8,523 sites:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;0&lt;/strong&gt; published a valid &lt;code&gt;/.well-known/mcp.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;239&lt;/strong&gt; answered that path with another document&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;33&lt;/strong&gt; published a valid AI Catalog (&lt;code&gt;/.well-known/ai-catalog.json&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;19&lt;/strong&gt; had an MCP server card we could resolve&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the one place everyone looks was, in practice, never the place a real server&lt;br&gt;
was described, while the sites that &lt;em&gt;did&lt;/em&gt; describe an MCP server mostly did it&lt;br&gt;
through a catalog the old check never read.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changes in 0.26.0
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A discovery file has to be one.&lt;/strong&gt; A 200 at &lt;code&gt;/.well-known/mcp.json&lt;/code&gt; that is an&lt;br&gt;
HTML page, or JSON without an &lt;code&gt;mcpServers&lt;/code&gt; server, no longer counts as an&lt;br&gt;
endpoint. The finding now says what was served instead, so the fix is obvious.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Server cards are recognised, not assumed.&lt;/strong&gt; A card at the well-known card&lt;br&gt;
paths counts only when it looks like a server card: a JSON object with a&lt;br&gt;
non-empty &lt;code&gt;name&lt;/code&gt; and a &lt;code&gt;remotes&lt;/code&gt; list, a &lt;code&gt;version&lt;/code&gt; or a &lt;code&gt;$schema&lt;/code&gt;. A JSON error&lt;br&gt;
page at those paths is no card.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The AI Catalog is followed.&lt;/strong&gt; Core reads &lt;code&gt;/.well-known/ai-catalog.json&lt;/code&gt; and&lt;br&gt;
fetches up to three server cards it lists — https and public addresses only,&lt;br&gt;
following up to five redirects on each. A card found that way counts as an MCP&lt;br&gt;
surface, so a site that publishes its server through a catalog stops getting a&lt;br&gt;
false "no MCP endpoint" finding.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No answer is not a "no".&lt;/strong&gt; If the catalog or a listed card times out, answers&lt;br&gt;
429 or 5xx, or is cut off at our read limit before it parses, the rule reports&lt;br&gt;
&lt;em&gt;not measured&lt;/em&gt; instead of a finding. Our failure to read a document is never&lt;br&gt;
evidence about the site — the same rule Core has applied to every other&lt;br&gt;
document since its first release.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it costs
&lt;/h2&gt;

&lt;p&gt;At most four more requests per scan (the catalog and up to three cards), plus&lt;br&gt;
any redirect hops. Core stays passive: ordinary GETs, no authentication, and it&lt;br&gt;
never calls an MCP endpoint or invokes a tool it discovers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Model change
&lt;/h2&gt;

&lt;p&gt;The Technical Readiness model id moves to &lt;code&gt;R2.1@7b46d2ed7f8b&lt;/code&gt;, and the rule&lt;br&gt;
behind this check, &lt;code&gt;MCP_ENDPOINT_ABSENT&lt;/code&gt;, moves to rule version 2.0. Results&lt;br&gt;
produced before and after the release carry different model ids, so a change&lt;br&gt;
in a site's result can always be told apart from a change in how we measure.&lt;br&gt;
Every model change is listed in the&lt;br&gt;
&lt;a href="https://scovant.com/scoring/changelog" rel="noopener noreferrer"&gt;methodology changelog&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Upgrade
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install -U scovant-core
uvx --from scovant-core scovant scan https://example.com
npx @scovant/core scan https://example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The GitHub Action &lt;code&gt;Scovant/scovant-core@v0&lt;/code&gt; picks up 0.26.0 automatically; pin&lt;br&gt;
&lt;code&gt;@v0.26.0&lt;/code&gt; for an exact version. The full list of changes is in the&lt;br&gt;
&lt;a href="https://github.com/Scovant/scovant-core/blob/main/CHANGELOG.md" rel="noopener noreferrer"&gt;changelog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>developertools</category>
      <category>testing</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
