<?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: Edison Flores</title>
    <description>The latest articles on DEV Community by Edison Flores (@edison_flores_6d2cd381b13).</description>
    <link>https://dev.to/edison_flores_6d2cd381b13</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%2F4011586%2F59d27a5e-b708-4d17-b346-37dce502454e.png</url>
      <title>DEV Community: Edison Flores</title>
      <link>https://dev.to/edison_flores_6d2cd381b13</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/edison_flores_6d2cd381b13"/>
    <language>en</language>
    <item>
      <title>ATC/1.0 — shipping a formal spec for Agent Trust Cards instead of arguing about who invented them</title>
      <dc:creator>Edison Flores</dc:creator>
      <pubDate>Sun, 09 Aug 2026 23:32:40 +0000</pubDate>
      <link>https://dev.to/edison_flores_6d2cd381b13/atc10-shipping-a-formal-spec-for-agent-trust-cards-instead-of-arguing-about-who-invented-them-h0l</link>
      <guid>https://dev.to/edison_flores_6d2cd381b13/atc10-shipping-a-formal-spec-for-agent-trust-cards-instead-of-arguing-about-who-invented-them-h0l</guid>
      <description>&lt;p&gt;A few weeks ago I noticed something uncomfortable. After I published my ATC (Agent Trust Card) concept on dev.to on July 13, 2026 — the first public use I can find of that exact name with the CA + Ed25519 + trust score architecture — proposals with the same name started showing up in Microsoft AutoGen, OpenAI Cookbook, Continue, and other places. I am not going to accuse anyone of copying — coincidental convergence on agent trust infrastructure is plausible, because the problem is real and obvious.&lt;/p&gt;

&lt;p&gt;But here is the thing: &lt;strong&gt;it does not matter who thought of it first.&lt;/strong&gt; What matters is who ships a formal, versioned, testable specification first.&lt;/p&gt;

&lt;p&gt;So today I am publishing &lt;a href="https://github.com/edgarfloresguerra2011-a11y/marketnow/blob/master/docs/atc-spec/SPEC.md" rel="noopener noreferrer"&gt;ATC/1.0&lt;/a&gt; — an open specification for Agent Trust Cards with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;10 controls&lt;/strong&gt; (8 required, 2 optional)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JSON Schema&lt;/strong&gt; for the envelope&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reference implementation&lt;/strong&gt; in Node.js (using &lt;code&gt;node:crypto&lt;/code&gt; + &lt;code&gt;canonicalize&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;5 test vectors&lt;/strong&gt; (minimal valid, tampered, expired, wrong CA, capability samples)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RFC 8032 Ed25519&lt;/strong&gt; signatures&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RFC 8785 JCS&lt;/strong&gt; canonical JSON&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is published under a dual license: the specification itself is open (W3C CG-FSA terms for contributors), the reference implementation is MNNC-1.0 (AliceLabs proprietary), and the test vectors are public domain (CC0).&lt;/p&gt;

&lt;p&gt;If you are building an agent runtime, an MCP server, an A2A client, or an agent marketplace — implement ATC/1.0. Conformance tests are in the repo. The reference implementation passes all of them.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why publish a spec instead of just defending priority
&lt;/h2&gt;

&lt;p&gt;Three reasons.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Priority debates are unwinnable in public
&lt;/h3&gt;

&lt;p&gt;I can prove my July 13 publication is the earliest public use of "Agent Trust Card (ATC)" with the full architecture. I cannot prove whether anyone who later published similar work saw my article first. The Internet does not log intent. So a priority claim becomes a game of "I said / they said" — and that game is unwinnable in public.&lt;/p&gt;

&lt;p&gt;A spec, on the other hand, is a fact. It exists, it is versioned, it has test vectors. &lt;strong&gt;You can run it.&lt;/strong&gt; That is much harder to argue with than a chronological claim.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Standards win by adoption, not by priority
&lt;/h3&gt;

&lt;p&gt;SSL did not win because Netscape invented HTTPS. SSL won because every browser implemented it. The TLS working group did not argue about who thought of certificate pinning first — they shipped RFC 7469 and let adoption decide.&lt;/p&gt;

&lt;p&gt;If ATC/1.0 becomes the spec that Microsoft AutoGen, OpenAI, Cline, Continue, and independent agent runtimes implement, the priority question becomes irrelevant. The spec is the answer.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The market is converging — somebody has to ship first
&lt;/h3&gt;

&lt;p&gt;In the past month I have seen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A2A Agent Card&lt;/strong&gt; (Google, May 2026) — capability descriptor, no cryptographic trust&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AgentCards&lt;/strong&gt; (academic, June 2026) — identity + capability credentials&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenA2A AIP&lt;/strong&gt; (Internet-Draft, July 22, 2026) — Ed25519 + behavioral trust + DID + transparency log&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OATI&lt;/strong&gt; (GitHub topic, July 29, 2026) — broader scope: identity + delegated authority + policy + signed receipts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ATC&lt;/strong&gt; (Edison Flores, July 13, 2026) — first public use of the name with CA + Ed25519 + revocation + capabilities + payment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these are converging on the same problem from different angles. That is not a threat — that is &lt;strong&gt;market validation&lt;/strong&gt;. The window is open. Somebody has to ship the formal spec.&lt;/p&gt;




&lt;h2&gt;
  
  
  What ATC/1.0 specifies
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The 10 controls
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;ID&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Required?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;ATC-001&lt;/td&gt;
&lt;td&gt;Identity&lt;/td&gt;
&lt;td&gt;✅ Required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;ATC-002&lt;/td&gt;
&lt;td&gt;Attestation (Ed25519 + CA binding)&lt;/td&gt;
&lt;td&gt;✅ Required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;ATC-003&lt;/td&gt;
&lt;td&gt;Capabilities (filesystem / network / shell / credentials / process)&lt;/td&gt;
&lt;td&gt;✅ Required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;ATC-004&lt;/td&gt;
&lt;td&gt;Evidence (audit pipeline output)&lt;/td&gt;
&lt;td&gt;✅ Required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;ATC-005&lt;/td&gt;
&lt;td&gt;Risk (trust score 0-10 + risk level + decision authority)&lt;/td&gt;
&lt;td&gt;✅ Required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;ATC-006&lt;/td&gt;
&lt;td&gt;Signature (Ed25519 over RFC 8785 JCS canonical form)&lt;/td&gt;
&lt;td&gt;✅ Required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;ATC-007&lt;/td&gt;
&lt;td&gt;Revocation (OCSP / CRL / simple_json list)&lt;/td&gt;
&lt;td&gt;✅ Required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;ATC-008&lt;/td&gt;
&lt;td&gt;Expiration (issued_at + expires_at + max_ttl_days)&lt;/td&gt;
&lt;td&gt;✅ Required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;ATC-009&lt;/td&gt;
&lt;td&gt;Delegation (parent card → child card capability narrowing)&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;ATC-010&lt;/td&gt;
&lt;td&gt;Runtime Trust (behavioral signals, drift detection)&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  The cryptographic core
&lt;/h3&gt;

&lt;p&gt;ATC/1.0 mandates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ed25519&lt;/strong&gt; (RFC 8032) for signatures — fast, deterministic, well-supported in every language's standard library&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RFC 8785 JCS&lt;/strong&gt; for canonical JSON — the only real standard for deterministic JSON encoding&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SHA-256&lt;/strong&gt; for the payload hash (recorded in &lt;code&gt;signed_payload_hash&lt;/code&gt; so verifiers can detect tampering before checking the signature)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The signature process is a bit subtle because of a chicken-and-egg: the &lt;code&gt;signed_payload_hash&lt;/code&gt; field is part of the envelope but cannot be part of the signed payload (you can't hash something that includes its own hash). The spec solves this by setting both &lt;code&gt;signature = ""&lt;/code&gt; AND &lt;code&gt;signed_payload_hash = ""&lt;/code&gt; before canonicalizing — then computing the hash, then signing, then storing both values.&lt;/p&gt;

&lt;h3&gt;
  
  
  The capability manifest
&lt;/h3&gt;

&lt;p&gt;ATC-003 declares what an agent is allowed to do across 5 categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Filesystem&lt;/strong&gt; (read: none/own_dir/temp_dir/home_dir/system/all; write: same enum)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network&lt;/strong&gt; (egress: none/allowlist/all; ingress: none/bound_ports/all)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shell&lt;/strong&gt; (exec: none/sandboxed/unrestricted; spawn: same)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Credentials&lt;/strong&gt; (read_env: none/allowlist/all; read_files: same)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Process&lt;/strong&gt; (subprocess: none/sandboxed/unrestricted; signals: none/own/all)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This maps directly to what the OWASP MCP Cheat Sheet calls for in capability declarations. ATC/1.0 is the concrete format for that.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trust score semantics
&lt;/h3&gt;

&lt;p&gt;ATC-005 carries a &lt;code&gt;trust_score&lt;/code&gt; from 0 (untrusted) to 10 (highly trusted), plus a derived &lt;code&gt;risk_level&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;8-10 → &lt;code&gt;low&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;5-7 → &lt;code&gt;medium&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;2-4 → &lt;code&gt;high&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;0-1 → &lt;code&gt;critical&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Crucially, ATC-005 mandates &lt;code&gt;decision_authority: "consumer"&lt;/code&gt; — meaning &lt;strong&gt;the ATC carries a recommendation, but the runtime that hosts the consuming agent makes the final trust decision&lt;/strong&gt;. This is a deliberate design choice. The CA does not override the runtime's security policy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Revocation
&lt;/h3&gt;

&lt;p&gt;ATC-007 supports three revocation check methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ocsp&lt;/code&gt; — RFC 6960 OCSP, for high-security deployments&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;crl&lt;/code&gt; — RFC 5280 Certificate Revocation List&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;simple_json&lt;/code&gt; — a JSON list signed by the CA, for low-friction deployments (this is what MarketNow uses today)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The revocation list itself is signed by the CA using the same Ed25519 + JCS process as ATC-006.&lt;/p&gt;

&lt;h3&gt;
  
  
  Offline verification
&lt;/h3&gt;

&lt;p&gt;A conformant verifier can verify an ATC without any network call, as long as it has the CA's public key cached. The ATC carries its own evidence (audit score, sandbox results, malware scan findings) so the verifier does not need to re-audit.&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;revocation_check_required: true&lt;/code&gt;, the verifier MUST fetch the revocation list before trusting — and MUST reject if the list is unreachable.&lt;/p&gt;




&lt;h2&gt;
  
  
  The reference implementation
&lt;/h2&gt;

&lt;p&gt;The Node.js reference implementation is ~200 lines and uses only the standard library plus &lt;code&gt;canonicalize&lt;/code&gt; (RFC 8785 JCS):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;generateKeyPairSync&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createHash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createPublicKey&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node:crypto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;canonicalize&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;canonicalize&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;issueATC&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;caKeyPair&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;agentKeyPair&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;partialPayload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;atc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... build the envelope ... */&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="c1"&gt;// Set signature="" AND signed_payload_hash="" before canonicalizing&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;canonical&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;canonicalize&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;atc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;attestation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;atc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;attestation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;signed_payload_hash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;atc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;attestation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signed_payload_hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createHash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sha256&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canonical&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;atc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;attestation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canonical&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;caKeyPair&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rawPrivateKey&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;base64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;atc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;verifyATC&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;atc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;caPublicKeyBase64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Re-canonicalize with signature="" AND signed_payload_hash=""&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;canonical&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;canonicalize&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;atc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;attestation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;atc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;attestation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;signed_payload_hash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="c1"&gt;// Check the hash&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;computedHash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createHash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sha256&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canonical&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;computedHash&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;atc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;attestation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signed_payload_hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hash mismatch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="c1"&gt;// Verify the signature&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;caPublicKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createPublicKey&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;caPublicKeyBase64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;base64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;der&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;spki&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;valid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canonical&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;caPublicKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;atc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;attestation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;base64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;valid&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;signature verification failed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the whole cryptographic core.&lt;/p&gt;




&lt;h2&gt;
  
  
  Test vectors (you can run them right now)
&lt;/h2&gt;

&lt;p&gt;The repo ships with 5 test vectors that exercise the full spec:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/edgarfloresguerra2011-a11y/marketnow.git
&lt;span class="nb"&gt;cd &lt;/span&gt;marketnow/docs/atc-spec
npm &lt;span class="nb"&gt;install &lt;/span&gt;canonicalize
node ./test-vectors/generate.mjs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=== ATC/1.0 Test Vectors Generator ===

CA public key: MCowBQYDK2VwAyEA...
Agent public key: MCowBQYDK2VwAyEA...

Issued minimal ATC: ATC-2026-0000001
  signature: CQnixwP9zmqQGrtMp6JjVBJHmgWYQVLo...
  signed_payload_hash: 7ccfc2081c5b94a6d2a9bfd4adc6c92f899aa9968fa605d71ccdba3cf3b02551

Verification (minimal valid): { valid: true, errors: [] }
Verification (tampered):       { valid: false, errors: ['signed_payload_hash mismatch', 'Ed25519 signature verification failed'] }
Verification (expired):        { valid: false, errors: [..., 'ATC expired'] }
Verification (wrong CA):       { valid: false, errors: ['CA public key mismatch', ...] }

=== All test vectors generated and verified ===
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you implement ATC/1.0 in Rust or Python, you can use these same test vectors to verify your implementation produces byte-identical signatures. That is what conformance means.&lt;/p&gt;




&lt;h2&gt;
  
  
  Prior art and the public record
&lt;/h2&gt;

&lt;p&gt;I want to be honest about what existed before ATC and what appeared after.&lt;/p&gt;

&lt;h3&gt;
  
  
  Before ATC
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A2A Agent Card&lt;/strong&gt; (Google, May 22, 2026) — capability descriptor, no cryptographic trust, no CA, no revocation. This is prior art for agent metadata, not for trust.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AgentCards&lt;/strong&gt; (academic / Emergent Mind, July 2, 2026) — machine-verifiable identity + capability credentials. Conceptual only — no CA, no Ed25519 mandate, no runtime enforcement.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I do &lt;strong&gt;not&lt;/strong&gt; claim to have invented agent identity or agent credentials. A2A and AgentCards predate ATC and address overlapping problem space.&lt;/p&gt;

&lt;h3&gt;
  
  
  ATC origin (July 13, 2026)
&lt;/h3&gt;

&lt;p&gt;My dev.to article &lt;a href="https://dev.to/edison_flores_6d2cd381b13/ai-agents-need-ssl-certificates-too-so-i-built-atc-agent-trust-card-5017"&gt;"AI agents need SSL certificates too — so I built ATC (Agent Trust Card)"&lt;/a&gt; is, to the best of my research, the earliest public use of the specific name "Agent Trust Card (ATC)" combined with: CA + Ed25519 + Sentinel trust score + verify + revoke + capabilities + payment integration + Agent A → ATC → Agent B flow.&lt;/p&gt;

&lt;h3&gt;
  
  
  After ATC
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Date&lt;/th&gt;
&lt;th&gt;Artifact&lt;/th&gt;
&lt;th&gt;Author&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;July 16, 2026&lt;/td&gt;
&lt;td&gt;Microsoft AutoGen issue #7965 — "Agent Trust Cards (ATC) — cryptographic trust for multi-agent systems"&lt;/td&gt;
&lt;td&gt;(page 404 at time of writing — indexed-only)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;July 17, 2026&lt;/td&gt;
&lt;td&gt;Edison — "ATC is now real" with Ed25519 + verify + revoke&lt;/td&gt;
&lt;td&gt;Edison Flores&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;July 18, 2026&lt;/td&gt;
&lt;td&gt;OpenAI Cookbook issue #2865 — ATC proposal&lt;/td&gt;
&lt;td&gt;Edison Flores&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;July 18, 2026&lt;/td&gt;
&lt;td&gt;OpenAI Cookbook issue #2867 — ATC proposal (same title, same day)&lt;/td&gt;
&lt;td&gt;jj5419952-stack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;July 18, 2026&lt;/td&gt;
&lt;td&gt;Cline issue #12376 — ATC proposal (Edison bringing ATC to Cline)&lt;/td&gt;
&lt;td&gt;Edison Flores&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;July 19, 2026&lt;/td&gt;
&lt;td&gt;Edison — runtime trust + CA key rotation + RFC 8785 JCS migration&lt;/td&gt;
&lt;td&gt;Edison Flores&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;July 22, 2026&lt;/td&gt;
&lt;td&gt;OpenA2A Agent Identity Protocol (AIP) — Internet-Draft&lt;/td&gt;
&lt;td&gt;FANE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;July 23, 2026&lt;/td&gt;
&lt;td&gt;Edison — MarketNow + ATC + Sentinel in OpenAI Cookbook #2875&lt;/td&gt;
&lt;td&gt;Edison Flores&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;July 29, 2026&lt;/td&gt;
&lt;td&gt;OATI (Open Agent Trust Infrastructure) — broader scope&lt;/td&gt;
&lt;td&gt;Community&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I do &lt;strong&gt;not&lt;/strong&gt; claim Microsoft, OpenAI, or Continue copied Edison. Coincidental convergence is plausible and the problem is real. I assert only chronological ordering.&lt;/p&gt;

&lt;p&gt;The full chronology with citations is in &lt;a href="https://github.com/edgarfloresguerra2011-a11y/marketnow/blob/master/docs/atc-spec/PRIOR-ART-TIMELINE.md" rel="noopener noreferrer"&gt;&lt;code&gt;PRIOR-ART-TIMELINE.md&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I am asking for
&lt;/h2&gt;

&lt;p&gt;Three things.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Implement ATC/1.0
&lt;/h3&gt;

&lt;p&gt;If you build an agent runtime (Claude Desktop plugin, Cursor extension, Cline plugin, Continue plugin, LangChain tool, LlamaIndex tool, AutoGen extension), implement ATC/1.0 verification. The reference implementation is ~200 lines. The test vectors are public domain.&lt;/p&gt;

&lt;p&gt;If you are not sure whether to trust an agent that hands you an ATC, &lt;strong&gt;don't trust it&lt;/strong&gt; — that's what &lt;code&gt;decision_authority: "consumer"&lt;/code&gt; means. The ATC is evidence, not a verdict.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Challenge the prior art timeline
&lt;/h3&gt;

&lt;p&gt;If you find a publicly verifiable artifact that pre-dates July 13, 2026 and describes the specific ATC architecture (CA + Ed25519 + trust score + revocation + capabilities), open a PR against &lt;a href="https://github.com/edgarfloresguerra2011-a11y/marketnow/blob/master/docs/atc-spec/PRIOR-ART-TIMELINE.md" rel="noopener noreferrer"&gt;&lt;code&gt;PRIOR-ART-TIMELINE.md&lt;/code&gt;&lt;/a&gt;. I will update the timeline and credit you.&lt;/p&gt;

&lt;p&gt;I will not remove entries that contradict my narrative. The purpose of that document is truth, not advocacy.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Compete on the spec, not on priority
&lt;/h3&gt;

&lt;p&gt;If you have a competing proposal (OpenA2A AIP, OATI, your own) — let's talk interop. Standards win by adoption. If your spec is better and gets adopted, you win. If ATC/1.0 is better and gets adopted, I win. The market decides. Priority doesn't.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;ATC/1.0 is the v1.x floor. The roadmap is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ATC/1.0&lt;/strong&gt; (this document, August 10, 2026): Vendor spec, reference impl, test vectors&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ATC/1.0 + adoption&lt;/strong&gt; (Q3-Q4 2026): At least 2 independent implementations pass conformance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ATC/1.1&lt;/strong&gt; (Q4 2026): ML-DSA post-quantum signatures, CA key rotation protocol, delegation chains&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;W3C CG submission&lt;/strong&gt; (Q1 2027): Submit to a W3C Community Group for broader review&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IETF Internet-Draft&lt;/strong&gt; (Q2 2027): Submit as an IETF Individual Draft&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ATC/2.0&lt;/strong&gt; (2027): Transparency log (Merkle), DID integration, capability revocation (vs. card revocation)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We are not rushing to a standards body. Standards bodies reward implementations over ideas. ATC/1.0 ships first; standardization follows.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx &lt;span class="nt"&gt;-y&lt;/span&gt; marketnow-mcp@1.9.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then ask Claude Desktop: &lt;em&gt;"Verify the ATC for card_id ATC-2026-7777670"&lt;/em&gt; — Claude will call &lt;code&gt;marketnow_verify_trust&lt;/code&gt; with the &lt;code&gt;card_id&lt;/code&gt;, which hits the live MarketNow ATC API and returns the verification result.&lt;/p&gt;

&lt;p&gt;Or read the spec directly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Spec&lt;/strong&gt;: &lt;a href="https://github.com/edgarfloresguerra2011-a11y/marketnow/blob/master/docs/atc-spec/SPEC.md" rel="noopener noreferrer"&gt;https://github.com/edgarfloresguerra2011-a11y/marketnow/blob/master/docs/atc-spec/SPEC.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JSON Schema&lt;/strong&gt;: &lt;a href="https://github.com/edgarfloresguerra2011-a11y/marketnow/blob/master/docs/atc-spec/schemas/atc-1.0.json" rel="noopener noreferrer"&gt;https://github.com/edgarfloresguerra2011-a11y/marketnow/blob/master/docs/atc-spec/schemas/atc-1.0.json&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reference implementation&lt;/strong&gt;: &lt;a href="https://github.com/edgarfloresguerra2011-a11y/marketnow/blob/master/docs/atc-spec/reference-impl/atc-1.0.mjs" rel="noopener noreferrer"&gt;https://github.com/edgarfloresguerra2011-a11y/marketnow/blob/master/docs/atc-spec/reference-impl/atc-1.0.mjs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test vectors&lt;/strong&gt;: &lt;a href="https://github.com/edgarfloresguerra2011-a11y/marketnow/tree/master/docs/atc-spec/test-vectors" rel="noopener noreferrer"&gt;https://github.com/edgarfloresguerra2011-a11y/marketnow/tree/master/docs/atc-spec/test-vectors&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prior art timeline&lt;/strong&gt;: &lt;a href="https://github.com/edgarfloresguerra2011-a11y/marketnow/blob/master/docs/atc-spec/PRIOR-ART-TIMELINE.md" rel="noopener noreferrer"&gt;https://github.com/edgarfloresguerra2011-a11y/marketnow/blob/master/docs/atc-spec/PRIOR-ART-TIMELINE.md&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PRs welcome. Issues welcome. Competing specs welcome.&lt;/p&gt;

&lt;p&gt;The market is converging. Let's ship the spec.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;MarketNow is security infrastructure for AI agents, built by AliceLabs LLC (Wyoming, USA). Founder: Edison Flores. The Sentinel audit pipeline has performed 1,211,488 security checks and quarantined 80 malicious skills. Audit report: &lt;a href="https://marketnow.site/api/audit-report.json" rel="noopener noreferrer"&gt;marketnow.site/api/audit-report.json&lt;/a&gt;. ATC/1.0 spec: &lt;a href="https://github.com/edgarfloresguerra2011-a11y/marketnow/tree/master/docs/atc-spec" rel="noopener noreferrer"&gt;github.com/edgarfloresguerra2011-a11y/marketnow/tree/master/docs/atc-spec&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>security</category>
      <category>standards</category>
    </item>
    <item>
      <title>Hardening an MCP server for autonomous agents — 4 rules I learned the hard way</title>
      <dc:creator>Edison Flores</dc:creator>
      <pubDate>Sun, 09 Aug 2026 22:24:40 +0000</pubDate>
      <link>https://dev.to/edison_flores_6d2cd381b13/hardening-an-mcp-server-for-autonomous-agents-4-rules-i-learned-the-hard-way-441d</link>
      <guid>https://dev.to/edison_flores_6d2cd381b13/hardening-an-mcp-server-for-autonomous-agents-4-rules-i-learned-the-hard-way-441d</guid>
      <description>&lt;p&gt;If you ship a Model Context Protocol (MCP) server today, your consumers are not human beings. They are autonomous agents — Claude Desktop, Cursor, Cline, Continue, LangChain, LlamaIndex. And here is the part that took me three versions to internalize:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agents do not read your README.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When Claude Desktop decides whether to invoke your tool, it does not consult your beautifully written documentation. It consults the JSON-Schema returned by &lt;code&gt;tools/list&lt;/code&gt;. If your schema is ambiguous, the LLM's JSON generation will be ambiguous, and the tool call will fail silently inside the agent loop. The user sees "the agent gave up" — and you never hear about it.&lt;/p&gt;

&lt;p&gt;This is the story of how &lt;code&gt;marketnow-mcp@1.7.0&lt;/code&gt; (11 tools, ambiguous schemas, occasional agent hallucinations) became &lt;code&gt;marketnow-mcp@1.9.0&lt;/code&gt; (12 tools, strict schemas, zero uncaught errors in our smoke tests). I am publishing it because I think the four rules I ended up with generalize to any MCP server that wants to be reliably consumable by autonomous agents.&lt;/p&gt;




&lt;h2&gt;
  
  
  The problem in one screenshot
&lt;/h2&gt;

&lt;p&gt;Here is what &lt;code&gt;tools/list&lt;/code&gt; returned in v1.7.0 for our &lt;code&gt;search_skills&lt;/code&gt; tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"search_skills"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Search the MarketNow marketplace for MCP-compatible skills..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"inputSchema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"object"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"query"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Natural language or keyword search..."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Filter by category (optional). One of: AI/ML, Data, Web/API, Security, DevOps, Communication, etc."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"max_price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"number"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Maximum price in USD (optional, e.g. 2.99)"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"limit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"number"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Max results to return (default 10, max 50)"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Spot the three time bombs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Tool name has no namespace.&lt;/strong&gt; &lt;code&gt;search_skills&lt;/code&gt; could collide with any other MCP server the agent has loaded. The agent has to disambiguate by guessing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;category&lt;/code&gt; is a free string&lt;/strong&gt; that "should be" one of a known list — but the schema says &lt;code&gt;string&lt;/code&gt;. The LLM will happily pass &lt;code&gt;"ai-ml"&lt;/code&gt; (kebab-case) or &lt;code&gt;"ai ml"&lt;/code&gt; (with a space) and your runtime will silently filter to nothing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;limit&lt;/code&gt; has no bounds.&lt;/strong&gt; The description says "max 50" but the schema says nothing. An agent that reasons "I want all the skills" will pass &lt;code&gt;9999&lt;/code&gt; and your server will fetch nine thousand rows.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We were seeing all three failure modes in production. Agents would call &lt;code&gt;search_skills&lt;/code&gt; with &lt;code&gt;category: "ai/ml"&lt;/code&gt; (slash, not the literal &lt;code&gt;"AI/ML"&lt;/code&gt; we expected) and our runtime would return zero results, the agent would conclude the marketplace had no AI tools, and the user would conclude the agent was broken.&lt;/p&gt;




&lt;h2&gt;
  
  
  Rule A — Deterministic tool names with a namespace prefix
&lt;/h2&gt;

&lt;p&gt;I started by renaming every tool from &lt;code&gt;snake_case&lt;/code&gt; to &lt;code&gt;marketnow_snake_case&lt;/code&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;v1.7.0 (legacy)&lt;/th&gt;
&lt;th&gt;v1.9.0&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;search_skills&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;marketnow_search_skills&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;marketnow_get_skill&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;verify_trust&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;marketnow_verify_trust&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;submit_skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;marketnow_submit_skill&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is a &lt;strong&gt;breaking change&lt;/strong&gt;. Any agent that hard-coded &lt;code&gt;search_skills&lt;/code&gt; breaks on upgrade. But agents that consume &lt;code&gt;tools/list&lt;/code&gt; dynamically (the correct pattern) pick up the new names automatically.&lt;/p&gt;

&lt;p&gt;The namespace prefix gives the LLM two things at tool-choice time:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A stable namespace it can recognize ("ah, this is a MarketNow tool, I should look at my MarketNow context")&lt;/li&gt;
&lt;li&gt;A disambiguator from any other server's &lt;code&gt;search_skills&lt;/code&gt; that might be loaded in the same session&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can pick any prefix that matches your server identity. We picked &lt;code&gt;marketnow_&lt;/code&gt; because that is our product name. The Anthropic MCP servers list itself uses &lt;code&gt;mcp__&lt;/code&gt; as a transport-level disambiguator, but at the application level a domain-specific prefix is clearer.&lt;/p&gt;




&lt;h2&gt;
  
  
  Rule B — Intent-oriented descriptions
&lt;/h2&gt;

&lt;p&gt;The v1.7.0 description for &lt;code&gt;get_install_command&lt;/code&gt; was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Get the install command for a skill. All skills are FREE."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is a &lt;strong&gt;functional description&lt;/strong&gt; — it tells the agent what the code does. It does not tell the agent &lt;strong&gt;when&lt;/strong&gt; to call it or &lt;strong&gt;why&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The v1.9.0 description is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Get the exact &lt;code&gt;npx&lt;/code&gt; install command for a skill. Use this when an agent has already selected a skill via &lt;code&gt;marketnow_search_skills&lt;/code&gt; or &lt;code&gt;marketnow_recommend_skills&lt;/code&gt; and is ready to install. All skills are currently FREE — no purchase step is required."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The differences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It states the precondition ("has already selected a skill via..."). The LLM now knows this is step 2 of a 2-step flow, not a discovery tool.&lt;/li&gt;
&lt;li&gt;It names the predecessor tools by their v1.9.0 names, so the agent's plan graph stays consistent.&lt;/li&gt;
&lt;li&gt;It clarifies the side effect ("ready to install").&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every description in v1.9.0 answers three questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;When&lt;/strong&gt; should I call this? (precondition or trigger)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why&lt;/strong&gt; should I call it? (what the agent gets out of it)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What's next?&lt;/strong&gt; (the natural successor tool, if any)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For &lt;code&gt;marketnow_get_owasp_compliance&lt;/code&gt; (new in v1.9.0):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Get MarketNow's alignment with the OWASP MCP Cheat Sheet... Also returns the live tool fingerprint (SHA-256) and capability manifest (filesystem/network/shell/credentials/process) for any registered skill. Use this BEFORE invoking a skill whose blast radius you need to bound — it tells you exactly what filesystem, network, shell, and credential access that skill is capable of."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;"Use this BEFORE" is the magic phrase. It tells the LLM this is a pre-flight check, not an afterthought.&lt;/p&gt;




&lt;h2&gt;
  
  
  Rule C — Strict JSON-Schema
&lt;/h2&gt;

&lt;p&gt;This is the rule that took the longest to get right, because "strict" is a moving target. Here is what v1.9.0 enforces on every &lt;code&gt;inputSchema.properties[*]&lt;/code&gt;:&lt;/p&gt;

&lt;h3&gt;
  
  
  C.1 &lt;code&gt;enum&lt;/code&gt; on every categorical field
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kr"&gt;enum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AI/ML&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Web/API&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Security&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DevOps&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Communication&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Productivity&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Automation&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Finance&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Marketing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Other&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Optional category filter. Must be one of the known marketplace categories.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nl"&gt;sort_by&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;enum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;relevance&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;price_asc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;price_desc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;newest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sentinel_desc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sort criterion. Default: relevance.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a value can be enumerated, &lt;strong&gt;enumerate it&lt;/strong&gt;. Do not write "one of: AI/ML, Data, ..." in the description and leave the type as bare &lt;code&gt;string&lt;/code&gt; — the LLM will not treat that as a constraint.&lt;/p&gt;

&lt;h3&gt;
  
  
  C.2 &lt;code&gt;pattern&lt;/code&gt; on every structured ID
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;card_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;^ATC-&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s1"&gt;d{4}-&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s1"&gt;d{6,}$&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ATC card ID. Format: ATC-YYYY-NNNNNNN (e.g. ATC-2026-7777670).&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nl"&gt;receipt_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;^rcpt_[a-z0-9]{16,}$&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Receipt ID. Must start with "rcpt_" followed by at least 16 alphanumeric characters.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We had a path-traversal bug in v1.7.0 where an agent passed &lt;code&gt;card_id: '../../etc/passwd'&lt;/code&gt; (it was hallucinating from an unrelated context window) and our handler happily tried to look it up. The v1.9.0 pattern rejects it at the schema layer — the LLM sees the constraint at &lt;code&gt;tools/list&lt;/code&gt; time and rarely generates an invalid value, and even if it does, the runtime rejects it with a structured error (Rule D).&lt;/p&gt;

&lt;p&gt;The key insight: &lt;strong&gt;the schema pattern and the runtime validator must use the same regex&lt;/strong&gt;. We centralized all patterns in a &lt;code&gt;PATTERNS&lt;/code&gt; object and reused it in both places, preventing drift:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PATTERNS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;skill_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;a-z0-9-&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+$/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;card_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/^ATC-&lt;/span&gt;&lt;span class="se"&gt;\d{4}&lt;/span&gt;&lt;span class="sr"&gt;-&lt;/span&gt;&lt;span class="se"&gt;\d{6,}&lt;/span&gt;&lt;span class="sr"&gt;$/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;receipt_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/^rcpt_&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;a-z0-9&lt;/span&gt;&lt;span class="se"&gt;]{16,}&lt;/span&gt;&lt;span class="sr"&gt;$/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;ref_code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/^ref_&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;a-z0-9&lt;/span&gt;&lt;span class="se"&gt;]{6,}&lt;/span&gt;&lt;span class="sr"&gt;$/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;agent_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;a-z0-9_-&lt;/span&gt;&lt;span class="se"&gt;]{3,64}&lt;/span&gt;&lt;span class="sr"&gt;$/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;repo_url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/^https:&lt;/span&gt;&lt;span class="se"&gt;\/\/&lt;/span&gt;&lt;span class="sr"&gt;github&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;com&lt;/span&gt;&lt;span class="se"&gt;\/[\w&lt;/span&gt;&lt;span class="sr"&gt;.-&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;\/[\w&lt;/span&gt;&lt;span class="sr"&gt;.-&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+$/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Used in the schema:&lt;/span&gt;
&lt;span class="nl"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PATTERNS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;card_id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt;

&lt;span class="c1"&gt;// Used in the validator:&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;validatePattern&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;example&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Invalid &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: must match &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;INVALID_ARGUMENT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  C.3 Numeric bounds with &lt;code&gt;minimum&lt;/code&gt; and &lt;code&gt;maximum&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;integer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;minimum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;maximum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Maximum number of results to return. Default: 10. Hard ceiling: 50.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nl"&gt;max_price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;minimum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;maximum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Optional upper bound on price in USD.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In v1.7.0 an agent could pass &lt;code&gt;limit: 99999&lt;/code&gt; and our server would try to slice 100K rows from a JSON catalog. In v1.9.0 the schema rejects it, and the runtime also clamps to the bound just in case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;clampInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;max&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isInteger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Expected integer, got: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;INVALID_ARGUMENT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;max&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  C.4 String length bounds with &lt;code&gt;minLength&lt;/code&gt; and &lt;code&gt;maxLength&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;minLength&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;maxLength&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;What you want to do, in plain English (e.g. "scrape a website", "query PostgreSQL"). Minimum 3 characters.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why does this matter? Because without &lt;code&gt;maxLength&lt;/code&gt;, an agent that decides "more context is better" will pass 5,000 characters of context into your &lt;code&gt;task&lt;/code&gt; field and your keyword-matching scorer will spend 3 seconds on every call. With a 300-char cap, the LLM learns to summarize.&lt;/p&gt;

&lt;h3&gt;
  
  
  C.5 No &lt;code&gt;any&lt;/code&gt; types
&lt;/h3&gt;

&lt;p&gt;This sounds obvious but it is easy to violate by accident. Any time you write &lt;code&gt;properties: {}&lt;/code&gt; and rely on default behavior, you are implicitly allowing &lt;code&gt;any&lt;/code&gt;. In v1.9.0 every property declares a concrete &lt;code&gt;type&lt;/code&gt;. Even our no-arg tools like &lt;code&gt;marketnow_list_categories&lt;/code&gt; declare:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;inputSchema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;properties: {}&lt;/code&gt; is intentional — there are no parameters. But the &lt;code&gt;type: 'object'&lt;/code&gt; is what tells the LLM "this is an object, not a stringified object."&lt;/p&gt;




&lt;h2&gt;
  
  
  Rule D — Structured error envelopes (&lt;code&gt;isError: true&lt;/code&gt;)
&lt;/h2&gt;

&lt;p&gt;This is the rule that prevents the agent loop from breaking. In v1.7.0 our handler looked like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;handleTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Error: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
    &lt;span class="na"&gt;isError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This looks correct — it has &lt;code&gt;isError: true&lt;/code&gt;. But the payload is just &lt;code&gt;err.message&lt;/code&gt; as a plain string, which means:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The agent sees &lt;code&gt;"Error: Invalid card_id"&lt;/code&gt; and has to parse English to figure out what to do.&lt;/li&gt;
&lt;li&gt;The agent has no machine-readable error code to branch on.&lt;/li&gt;
&lt;li&gt;Stack traces might leak (depending on how &lt;code&gt;err.message&lt;/code&gt; is constructed).&lt;/li&gt;
&lt;li&gt;There is no hint about how to recover.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The v1.9.0 handler:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isInvalidArgs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;INVALID_ARGUMENT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isNotFound&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;NOT_FOUND&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isUnknownTool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UNKNOWN_TOOL&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;errorPayload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;INTERNAL_ERROR&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Unknown error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;...(&lt;/span&gt;&lt;span class="nx"&gt;isInvalidArgs&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;hint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Re-read the inputSchema for this tool from ListTools response.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}),&lt;/span&gt;
    &lt;span class="p"&gt;...(&lt;/span&gt;&lt;span class="nx"&gt;isNotFound&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;hint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Verify the ID against marketnow_search_skills output.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}),&lt;/span&gt;
    &lt;span class="p"&gt;...(&lt;/span&gt;&lt;span class="nx"&gt;isUnknownTool&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;hint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Call ListTools to enumerate valid marketnow_* tool names.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}),&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;isError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errorPayload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key differences:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;error&lt;/code&gt; is a code, not a message.&lt;/strong&gt; The agent can branch on &lt;code&gt;INVALID_ARGUMENT&lt;/code&gt; vs &lt;code&gt;NOT_FOUND&lt;/code&gt; vs &lt;code&gt;UNKNOWN_TOOL&lt;/code&gt; vs &lt;code&gt;INTERNAL_ERROR&lt;/code&gt; programmatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;hint&lt;/code&gt; is contextual.&lt;/strong&gt; For invalid arguments, the agent is told to re-read the schema. For not-found, it is told to verify against search results. For unknown-tool, it is told to call &lt;code&gt;ListTools&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;err.stack&lt;/code&gt; is never serialized.&lt;/strong&gt; Only &lt;code&gt;err.message&lt;/code&gt; and &lt;code&gt;err.code&lt;/code&gt;. No server internals leak to the agent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The payload is JSON, not English.&lt;/strong&gt; The agent parses it as a structured object, not as natural language it has to interpret.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is the single biggest improvement in agent reliability we shipped. After this change, our smoke tests show agents recovering from invalid inputs in a single retry — they get &lt;code&gt;INVALID_ARGUMENT&lt;/code&gt; with a hint, re-call &lt;code&gt;tools/list&lt;/code&gt;, and pass a valid value.&lt;/p&gt;




&lt;h2&gt;
  
  
  The full audit
&lt;/h2&gt;

&lt;p&gt;I wrote all of this up in &lt;code&gt;AUDIT.md&lt;/code&gt; inside the npm package, along with the smoke-test commands so anyone can verify the contract:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# List tools — all should have marketnow_ prefix&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'{"jsonrpc":"2.0","method":"tools/list","id":1}'&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
  node index.js | jq &lt;span class="s1"&gt;'.result.tools[].name'&lt;/span&gt;

&lt;span class="c"&gt;# Verify error path on invalid input&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'{"jsonrpc":"2.0","method":"tools/call","params":{"name":"marketnow_get_skill","arguments":{"skill_id":"../../etc/passwd"}},"id":2}'&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
  node index.js | jq &lt;span class="s1"&gt;'.result'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The npm package is &lt;a href="https://www.npmjs.com/package/marketnow-mcp" rel="noopener noreferrer"&gt;&lt;code&gt;marketnow-mcp@1.9.0&lt;/code&gt;&lt;/a&gt;. The full source is on &lt;a href="https://github.com/edgarfloresguerra2011-a11y/marketnow/tree/master/mcp-server" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. The audit document is &lt;a href="https://github.com/edgarfloresguerra2011-a11y/marketnow/blob/master/mcp-server/AUDIT.md" rel="noopener noreferrer"&gt;&lt;code&gt;mcp-server/AUDIT.md&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The four rules, in one table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rule&lt;/th&gt;
&lt;th&gt;What it prevents&lt;/th&gt;
&lt;th&gt;How to verify&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A. &lt;code&gt;marketnow_&lt;/code&gt; snake_case names&lt;/td&gt;
&lt;td&gt;Tool-name collisions across loaded MCP servers&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;tools/list&lt;/code&gt; — every &lt;code&gt;.name&lt;/code&gt; starts with the prefix&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B. Intent-oriented descriptions&lt;/td&gt;
&lt;td&gt;LLM not knowing when or why to call&lt;/td&gt;
&lt;td&gt;Description answers WHEN/WHY, names predecessor tools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C. Strict JSON-Schema (enum/pattern/bounds)&lt;/td&gt;
&lt;td&gt;LLM generating invalid JSON values&lt;/td&gt;
&lt;td&gt;Every &lt;code&gt;properties[*]&lt;/code&gt; has &lt;code&gt;type&lt;/code&gt; + one of (&lt;code&gt;enum&lt;/code&gt;/&lt;code&gt;pattern&lt;/code&gt;/&lt;code&gt;min&lt;/code&gt;/&lt;code&gt;max&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;D. Structured &lt;code&gt;{ content, isError }&lt;/code&gt; envelopes&lt;/td&gt;
&lt;td&gt;Agent loop breaking on uncaught exceptions&lt;/td&gt;
&lt;td&gt;Errors return &lt;code&gt;isError: true&lt;/code&gt; with &lt;code&gt;error&lt;/code&gt; code + &lt;code&gt;hint&lt;/code&gt;, never throw&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you are building an MCP server today, please do all four. The MCP spec does not enforce them — but autonomous agents will reward you for it.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's next for us
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;marketnow-mcp@1.9.0&lt;/code&gt; is the v1.x floor. The v5.1-v6.0 roadmap (in the repo's &lt;code&gt;ROADMAP.md&lt;/code&gt;) layers on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Full tool fingerprinting with provenance&lt;/strong&gt; — SHA-256 of the tool definition, signed by the publisher's Ed25519 key&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confidence scoring&lt;/strong&gt; — every tool call returns a confidence score so the agent can decide whether to trust the result&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transparency log&lt;/strong&gt; — append-only Merkle log of every tool definition change&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Behavioral baselining&lt;/strong&gt; — runtime profiling of tool call patterns, alert on drift&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the four rules in this post are the foundation. Without them, nothing above them works.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you want to try the v1.9.0 server:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx &lt;span class="nt"&gt;-y&lt;/span&gt; marketnow-mcp@1.9.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add this to your Claude Desktop config and ask Claude: &lt;em&gt;"What OWASP MCP controls does the marketnow_get_owasp_compliance tool expose, and what filesystem or network capabilities does the skill mn-gen-00003 have?"&lt;/em&gt; — you will see the agent consume the strict schema, generate valid JSON, and return a structured response. That is the v1.9.0 contract in action.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;MarketNow is security infrastructure for AI agents, built by AliceLabs LLC (Wyoming, USA). Founder: Edison Flores. The Sentinel audit pipeline has performed 1,211,488 security checks and quarantined 80 malicious skills. Audit report: &lt;a href="https://marketnow.site/api/audit-report.json" rel="noopener noreferrer"&gt;marketnow.site/api/audit-report.json&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>security</category>
      <category>typescript</category>
    </item>
    <item>
      <title>MarketNow now maps 100% to the OWASP MCP Security Cheat Sheet</title>
      <dc:creator>Edison Flores</dc:creator>
      <pubDate>Sun, 09 Aug 2026 21:55:24 +0000</pubDate>
      <link>https://dev.to/edison_flores_6d2cd381b13/marketnow-now-maps-100-to-the-owasp-mcp-security-cheat-sheet-4fgh</link>
      <guid>https://dev.to/edison_flores_6d2cd381b13/marketnow-now-maps-100-to-the-owasp-mcp-security-cheat-sheet-4fgh</guid>
      <description>&lt;h2&gt;
  
  
  OWASP released a MCP Security Cheat Sheet. Here is how MarketNow aligns.
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/MCP_Security_Cheat_Sheet.html" rel="noopener noreferrer"&gt;OWASP MCP Security Cheat Sheet&lt;/a&gt; defines 12 security controls for MCP servers. MarketNow now maps 100% to all 12.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4 are live today. 8 are in the roadmap (v5.1-v6.0).&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The 12 OWASP controls
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;OWASP Control&lt;/th&gt;
&lt;th&gt;MarketNow Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Verify tool descriptions haven't changed&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;v5.1&lt;/strong&gt; — Tool Fingerprinting API (SHA-256 hashes)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Validate input/output schemas&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;v5.1&lt;/strong&gt; — Schema hash in fingerprint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Monitor for tool poisoning&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;v5.0 partial&lt;/strong&gt; (Interceptor) → &lt;strong&gt;v5.2&lt;/strong&gt; (full drift detection)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Implement least privilege&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;v5.3&lt;/strong&gt; — Capability Graph (filesystem, network, shell, credentials)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Log all tool invocations&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;v5.3&lt;/strong&gt; — Agent Identity + Task Identity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Isolate tool execution&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;LIVE&lt;/strong&gt; — L2.5 gVisor sandbox&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Scan for prompt injection&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;LIVE&lt;/strong&gt; — L1.9 (32 rules, 10 categories)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Monitor runtime behavior&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;v5.2&lt;/strong&gt; — Behavioral Baseline + Drift&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;Verify supply chain integrity&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;v5.1&lt;/strong&gt; — Provenance / SLSA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Implement revocation&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;LIVE&lt;/strong&gt; — ATC revocation (Ed25519, requires ca_secret)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;Detect typosquatting&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;v6.0&lt;/strong&gt; — Levenshtein distance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;Track data flow&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;v5.4&lt;/strong&gt; — Data Flow Tracking + Trajectory Security&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Try the compliance API
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://marketnow.site/api/owasp?compliance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Returns the full checklist with MarketNow implementation details for each control.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tool Fingerprinting (OWASP control #1)
&lt;/h2&gt;

&lt;p&gt;Generate a SHA-256 fingerprint of any MCP tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://marketnow.site/api/owasp?fingerprint&lt;span class="o"&gt;=&lt;/span&gt;mn-gen-00003
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"fingerprint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"tool_hash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"12a893c727a9e8be1e78410719fbec16..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name_hash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"description_hash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"algorithm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SHA-256"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"capabilities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"filesystem"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"none"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"network"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"none"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"shell_execute"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"credential_access"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For full tools/list fingerprinting (hashes every tool definition individually):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://marketnow.site/api/owasp &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; x27&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"action"&lt;/span&gt;:&lt;span class="s2"&gt;"fingerprint"&lt;/span&gt;,&lt;span class="s2"&gt;"skill_id"&lt;/span&gt;:&lt;span class="s2"&gt;"mn-xxx"&lt;/span&gt;,&lt;span class="s2"&gt;"tools_list_response"&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"tools"&lt;/span&gt;:[&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;:&lt;span class="s2"&gt;"read_file"&lt;/span&gt;,&lt;span class="s2"&gt;"description"&lt;/span&gt;:&lt;span class="s2"&gt;"..."&lt;/span&gt;,&lt;span class="s2"&gt;"inputSchema"&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"type"&lt;/span&gt;:&lt;span class="s2"&gt;"object"&lt;/span&gt;&lt;span class="o"&gt;}}]}}&lt;/span&gt;x27
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Returns per-tool hashes: name_hash, schema_hash, description_hash, and an overall tools_hash.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If any hash changes at runtime, the Trust Card should be auto-revoked.&lt;/strong&gt; That is tool poisoning detection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Capability Manifest (OWASP control #4)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://marketnow.site/api/owasp?capabilities&lt;span class="o"&gt;=&lt;/span&gt;mn-gen-00003
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"capability_manifest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"filesystem"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"read-only"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"network"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"outbound"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"shell_execute"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"process_spawn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"credential_access"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"database"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"prompt_handling"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"risk_factors"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"high_risk"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"network_exfil"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"data_access"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Organizations can define policies: "My agents can only use tools with score &amp;gt;= 8 AND no filesystem AND no shell." (Coming in v5.3)&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1,211,488&lt;/strong&gt; security checks performed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1,030&lt;/strong&gt; threats detected&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;80&lt;/strong&gt; skills quarantined (critical — malware, hacking tools)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;8,288&lt;/strong&gt; verified safe (score &amp;gt;= 8)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;57&lt;/strong&gt; Ed25519-signed Trust Cards&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;9,248&lt;/strong&gt; MCP skills analyzed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;12&lt;/strong&gt; OWASP controls mapped (4 live, 8 roadmap)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;100%&lt;/strong&gt; OWASP MCP Cheat Sheet coverage&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Roadmap
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;v5.1 VERIFICATION&lt;/strong&gt; — Full fingerprints, provenance, confidence scoring, transparency log&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;v5.2 BEHAVIOR&lt;/strong&gt; — Behavioral baselines, drift detection, network/fs/process analysis&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;v5.3 POLICY&lt;/strong&gt; — Capability graph, org policies, agent identity, approval workflows&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;v5.4 TRAJECTORY&lt;/strong&gt; — Multi-tool attack chains, cross-tool escalation, data flow tracking&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;v6.0 PLATFORM&lt;/strong&gt; — Multi-protocol (MCP+A2A+OpenAI), AgentBOM, cross-agent trust&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full roadmap: &lt;a href="https://github.com/edgarfloresguerra2011-a11y/marketnow/blob/master/ROADMAP.md" rel="noopener noreferrer"&gt;https://github.com/edgarfloresguerra2011-a11y/marketnow/blob/master/ROADMAP.md&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://marketnow.site" rel="noopener noreferrer"&gt;https://marketnow.site&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/edgarfloresguerra2011-a11y/marketnow" rel="noopener noreferrer"&gt;https://github.com/edgarfloresguerra2011-a11y/marketnow&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;OWASP compliance: &lt;a href="https://marketnow.site/api/owasp?compliance" rel="noopener noreferrer"&gt;https://marketnow.site/api/owasp?compliance&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Tool fingerprint: &lt;a href="https://marketnow.site/api/owasp?fingerprint=mn-gen-00003" rel="noopener noreferrer"&gt;https://marketnow.site/api/owasp?fingerprint=mn-gen-00003&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Trust API: &lt;a href="https://marketnow.site/api/trust-score?skillId=mn-gen-00003" rel="noopener noreferrer"&gt;https://marketnow.site/api/trust-score?skillId=mn-gen-00003&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Interceptor: &lt;a href="https://marketnow.site/api/interceptor" rel="noopener noreferrer"&gt;https://marketnow.site/api/interceptor&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;npm: marketnow-mcp v1.8.0&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What OWASP controls would you prioritize?&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>security</category>
      <category>owasp</category>
    </item>
    <item>
      <title>MarketNow v5.0: We pivoted from marketplace to security infrastructure for AI agents</title>
      <dc:creator>Edison Flores</dc:creator>
      <pubDate>Sun, 09 Aug 2026 20:21:06 +0000</pubDate>
      <link>https://dev.to/edison_flores_6d2cd381b13/marketnow-v50-we-pivoted-from-marketplace-to-security-infrastructure-for-ai-agents-4e5n</link>
      <guid>https://dev.to/edison_flores_6d2cd381b13/marketnow-v50-we-pivoted-from-marketplace-to-security-infrastructure-for-ai-agents-4e5n</guid>
      <description>&lt;h2&gt;
  
  
  The pivot
&lt;/h2&gt;

&lt;p&gt;We just repositioned MarketNow. It is no longer an MCP marketplace.&lt;/p&gt;

&lt;p&gt;It is &lt;strong&gt;security infrastructure for AI agents&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The marketplace is still there (9,248 skills, all free). But it is now the distribution layer, not the core product.&lt;/p&gt;

&lt;p&gt;The core product is &lt;strong&gt;Sentinel&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Sentinel does
&lt;/h2&gt;

&lt;p&gt;Sentinel is a 10-layer security audit pipeline for MCP servers and agent tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;L1.5&lt;/strong&gt; — Metadata analysis (auth, CORS, input validation, OAuth scopes)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;L1.6&lt;/strong&gt; — Static analysis (Semgrep rules, secret detection, OSV dependency scan)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;L1.7&lt;/strong&gt; — Malware pattern detection (binary launchers, suspicious install scripts)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;L1.8&lt;/strong&gt; — Malware family signatures (48 YARA-equivalent rules)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;L1.9&lt;/strong&gt; — Prompt injection screening (32 rules across 10 categories)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;L2.5&lt;/strong&gt; — gVisor sandbox isolation (network=none, read-only, cap-drop ALL)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;L3&lt;/strong&gt; — Runtime MCP Interceptor (real-time JSON-RPC guardrail)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ATC&lt;/strong&gt; — Agent Trust Card (Ed25519 signed, RFC 8785 JCS)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;x402&lt;/strong&gt; — Streaming metered billing ($0.01 USDC per call on Base)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A2A&lt;/strong&gt; — Remote agent execution&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Trust API
&lt;/h2&gt;

&lt;p&gt;This is the part that makes it infrastructure, not just a scanner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://marketnow.site/api/trust-score?skillId&lt;span class="o"&gt;=&lt;/span&gt;mn-gen-00003
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"trust_score"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"max_score"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"risk_level"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"red"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"recommendation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"safe_to_install"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"certificate_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://marketnow.site/api/audit-skill?certificate=1&amp;amp;skillId=mn-gen-00003"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"layers_passed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"l15"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"l16"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"l25"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agents can consume this API before installing any tool. No need to re-run the audit locally.&lt;/p&gt;

&lt;p&gt;1 million agents do not need to re-audit the same MCP. MarketNow does it once.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Interceptor
&lt;/h2&gt;

&lt;p&gt;A real-time JSON-RPC guardrail that sits between your agent and the MCP server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://marketnow.site/api/interceptor &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; x27&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"jsonrpc"&lt;/span&gt;:&lt;span class="s2"&gt;"2.0"&lt;/span&gt;,&lt;span class="s2"&gt;"method"&lt;/span&gt;:&lt;span class="s2"&gt;"tools/call"&lt;/span&gt;,&lt;span class="s2"&gt;"params"&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;:&lt;span class="s2"&gt;"execute"&lt;/span&gt;,&lt;span class="s2"&gt;"arguments"&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"command"&lt;/span&gt;:&lt;span class="s2"&gt;"rm -rf /"&lt;/span&gt;&lt;span class="o"&gt;}}}&lt;/span&gt;x27
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"allowed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"decision"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"block"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"violations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rule_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"BLOCK_DANGEROUS_CMDS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"critical"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5 policy rules: block .env reads, block rm -rf, block process spawns, block system writes, warn on non-allowlisted network.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security audit completed
&lt;/h2&gt;

&lt;p&gt;We ran a full security audit on our own API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ATC issuance: now requires Ed25519 proof-of-ownership + rate limited&lt;/li&gt;
&lt;li&gt;ATC revocation: now requires CA secret (was open to anyone)&lt;/li&gt;
&lt;li&gt;Stream payments: validates Ethereum wallet format + limits calls to 1000&lt;/li&gt;
&lt;li&gt;Interceptor: 10KB payload limit (DoS protection)&lt;/li&gt;
&lt;li&gt;Input sanitization: path traversal, XSS, command injection blocked&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Stats (all verified real)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;9,248 MCP skills catalogued&lt;/li&gt;
&lt;li&gt;5,662 audited by Sentinel (score &amp;gt; 0)&lt;/li&gt;
&lt;li&gt;257 gVisor sandbox runs completed&lt;/li&gt;
&lt;li&gt;57 Ed25519-signed Agent Trust Cards issued&lt;/li&gt;
&lt;li&gt;CA key: Ed25519 (RFC 8032, OID 1.3.101.112)&lt;/li&gt;
&lt;li&gt;2 npm packages: marketnow-mcp v1.8.0 + marketnow-install-stack v1.1.0&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pricing
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tier&lt;/th&gt;
&lt;th&gt;Price&lt;/th&gt;
&lt;th&gt;What you get&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;Basic scan, trust score, public report&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Developer&lt;/td&gt;
&lt;td&gt;$49-99&lt;/td&gt;
&lt;td&gt;Deep audit, signed report&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Professional&lt;/td&gt;
&lt;td&gt;$199-499&lt;/td&gt;
&lt;td&gt;Runtime testing, Trust Card, re-audit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Continuous&lt;/td&gt;
&lt;td&gt;$99-499/mo&lt;/td&gt;
&lt;td&gt;Monitoring, CVE tracking, auto re-audit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enterprise&lt;/td&gt;
&lt;td&gt;$5k-50k+/yr&lt;/td&gt;
&lt;td&gt;Private audits, API, SLA&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The thesis
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;MarketNow doesnx27t sell AI tools. It determines whether AI agents should be allowed to trust and execute them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://marketnow.site" rel="noopener noreferrer"&gt;https://marketnow.site&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/edgarfloresguerra2011-a11y/marketnow" rel="noopener noreferrer"&gt;https://github.com/edgarfloresguerra2011-a11y/marketnow&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;npm: marketnow-mcp v1.8.0&lt;/li&gt;
&lt;li&gt;Interceptor: &lt;a href="https://marketnow.site/api/interceptor" rel="noopener noreferrer"&gt;https://marketnow.site/api/interceptor&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Trust API: &lt;a href="https://marketnow.site/api/trust-score" rel="noopener noreferrer"&gt;https://marketnow.site/api/trust-score&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What policy rules would you add to the interceptor?&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>security</category>
      <category>agents</category>
    </item>
    <item>
      <title>MarketNow 3.0: Sentinel MCP Interceptor, x402 streaming payments, and agent skill stacks</title>
      <dc:creator>Edison Flores</dc:creator>
      <pubDate>Sun, 09 Aug 2026 03:07:20 +0000</pubDate>
      <link>https://dev.to/edison_flores_6d2cd381b13/marketnow-30-sentinel-mcp-interceptor-x402-streaming-payments-and-agent-skill-stacks-2f9k</link>
      <guid>https://dev.to/edison_flores_6d2cd381b13/marketnow-30-sentinel-mcp-interceptor-x402-streaming-payments-and-agent-skill-stacks-2f9k</guid>
      <description>&lt;h2&gt;
  
  
  What is new
&lt;/h2&gt;

&lt;p&gt;MarketNow just shipped 4 new features that bring it closer to the agent economy vision:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Sentinel MCP Interceptor (L3 Runtime Guardrail)
&lt;/h3&gt;

&lt;p&gt;A real-time JSON-RPC interceptor that sits between your agent and the MCP server. It inspects every &lt;code&gt;tools/call&lt;/code&gt; for policy violations BEFORE the call reaches the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5 policy rules:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Block reads of &lt;code&gt;.env&lt;/code&gt;, &lt;code&gt;.aws/credentials&lt;/code&gt;, &lt;code&gt;.ssh/id_rsa&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Block dangerous commands (&lt;code&gt;rm -rf&lt;/code&gt;, &lt;code&gt;DROP TABLE&lt;/code&gt;, &lt;code&gt;mkfs&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Block unauthorized process spawns (&lt;code&gt;exec&lt;/code&gt;, &lt;code&gt;spawn&lt;/code&gt;, &lt;code&gt;child_process&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Block system directory writes (&lt;code&gt;/etc/&lt;/code&gt;, &lt;code&gt;/root/&lt;/code&gt;, &lt;code&gt;C:\\Windows&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Warn on non-allowlisted network calls&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Try it: &lt;code&gt;POST https://marketnow.site/api/interceptor&lt;/code&gt; with a JSON-RPC payload.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Streaming Metered Billing (x402)
&lt;/h3&gt;

&lt;p&gt;Per-call micro-payments in USDC on Base. An agent opens a payment channel, then each tool call deducts $0.01 USDC. No human confirmation needed per call.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /api/stream { skill_id, wallet_address, calls: 10 }
→ channel_id: ch_xxx, calls_remaining: 10

GET /api/stream?channel_id=ch_xxx&amp;amp;call=1
→ call_number: 1, calls_remaining: 9, cost: $0.01
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Agent Skill Stacks (Portfolios)
&lt;/h3&gt;

&lt;p&gt;Pre-configured kits for specific use cases. One command installs everything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx &lt;span class="nt"&gt;-y&lt;/span&gt; marketnow-install-stack financial-auditor
npx &lt;span class="nt"&gt;-y&lt;/span&gt; marketnow-install-stack growth-hacking
npx &lt;span class="nt"&gt;-y&lt;/span&gt; marketnow-install-stack dev-productivity
npx &lt;span class="nt"&gt;-y&lt;/span&gt; marketnow-install-stack security-analyst
npx &lt;span class="nt"&gt;-y&lt;/span&gt; marketnow-install-stack data-pipeline
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each stack generates the &lt;code&gt;claude_desktop_config.json&lt;/code&gt; snippet automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. A2A Remote Execution
&lt;/h3&gt;

&lt;p&gt;Delegate a task to a remote agent that already has the skill installed. No local install needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /api/execute { skill_id, input, atc_card_id, mandate_id }
→ job_id: job_xxx, status: queued, cost: $0.01 USDC

GET /api/execute?job_id=job_xxx
→ status: completed, result: { ... }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Security audit response
&lt;/h2&gt;

&lt;p&gt;We also completed the security audit from Antigravity AI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ATC issuance&lt;/strong&gt;: now requires Ed25519 proof-of-ownership + rate limited (5/hour)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sentinel certificates&lt;/strong&gt;: migrated from SHA-256 hash to Ed25519 (RFC 8032) signatures&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CORS&lt;/strong&gt;: POST endpoints restricted to known origins&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Honeypots&lt;/strong&gt;: documented in HONEYPOTS.md, Gitleaks noise reduced&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;/api/search&lt;/code&gt;&lt;/strong&gt;: was 404, now returns real results (25 results for discord)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Stats
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;9,248 MCP skills&lt;/strong&gt; in catalog (100% free)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;9,238 audited&lt;/strong&gt; by Sentinel&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;57 ATCs&lt;/strong&gt; issued&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;50 dev.to articles&lt;/strong&gt; published&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;12 API endpoints&lt;/strong&gt; operational on Vercel Hobby&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;npm&lt;/strong&gt;: &lt;code&gt;marketnow-mcp&lt;/code&gt; (1,7.0) + &lt;code&gt;marketnow-install-stack&lt;/code&gt; (1.0.0)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is next
&lt;/h2&gt;

&lt;p&gt;We are looking for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;First paying seller&lt;/strong&gt; — the marketplace is ready, we need sellers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub stars&lt;/strong&gt; — help us reach 100: &lt;a href="https://github.com/edgarfloresguerra2011-a11y/marketnow" rel="noopener noreferrer"&gt;https://github.com/edgarfloresguerra2011-a11y/marketnow&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Community feedback&lt;/strong&gt; — try the interceptor, streaming payments, or stacks and tell us what you think&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Partnerships&lt;/strong&gt; — if you build MCP tools, we want to list them&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The code is open source (proprietary license). The trust ledger (57 ATCs + 2 receipts) is publicly auditable.&lt;/p&gt;

&lt;p&gt;Website: &lt;a href="https://marketnow.site" rel="noopener noreferrer"&gt;https://marketnow.site&lt;/a&gt;&lt;br&gt;
npm: &lt;a href="https://www.npmjs.com/package/marketnow-install-stack" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/marketnow-install-stack&lt;/a&gt;&lt;br&gt;
GitHub: &lt;a href="https://github.com/edgarfloresguerra2011-a11y/marketnow" rel="noopener noreferrer"&gt;https://github.com/edgarfloresguerra2011-a11y/marketnow&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>security</category>
      <category>agents</category>
    </item>
    <item>
      <title>Reply to mads_hansen: L1.9 screening (renamed from firewall), labeled corpus, MITRE ATT&amp;CK versioning</title>
      <dc:creator>Edison Flores</dc:creator>
      <pubDate>Sat, 08 Aug 2026 01:12:59 +0000</pubDate>
      <link>https://dev.to/edison_flores_6d2cd381b13/reply-to-madshansen-l19-screening-renamed-from-firewall-labeled-corpus-mitre-attck-12hd</link>
      <guid>https://dev.to/edison_flores_6d2cd381b13/reply-to-madshansen-l19-screening-renamed-from-firewall-labeled-corpus-mitre-attck-12hd</guid>
      <description>&lt;p&gt;Fair point @mads_hansen — calling L1.9 a firewall overstates what static rules can deliver.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Renaming:&lt;/strong&gt; L1.9 is now prompt injection &lt;strong&gt;screening&lt;/strong&gt; (not firewall) in the next schema update. A static pre-admission filter, not a runtime enforcement layer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Labeled corpus:&lt;/strong&gt; You are right that we should publish one. Currently the 32 rules are tested against:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;47 known jailbreak prompts (from public research)&lt;/li&gt;
&lt;li&gt;23 benign admin tool descriptions (false positive check)&lt;/li&gt;
&lt;li&gt;12 paraphrased attacks (evasion resistance check)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But this is not public. We will publish the corpus as a separate repo (marketnow-l1.9-corpus) with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Benign skill metadata (labeled)&lt;/li&gt;
&lt;li&gt;Known attacks (labeled, with technique)&lt;/li&gt;
&lt;li&gt;Paraphrases (multilingual, Unicode variants, split-token payloads)&lt;/li&gt;
&lt;li&gt;Per-rule-family precision/recall&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Runtime poisoning:&lt;/strong&gt; You are right — install-time scanning misses tool-result poisoning, server schema changes, compromised updates. The scanner feeds a durable trust decision (the ATC), not the final control. L3 (continuous monitoring) + L4 (eBPF runtime enforcement) handle the runtime side.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MITRE ATT&amp;amp;CK versioning:&lt;/strong&gt; Good catch. We will include the exact technique/sub-technique rationale (not just the ID) and version it. Currently we have ATT&amp;amp;CK IDs but no rationale — that is decorative compliance metadata, as you said.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>security</category>
    </item>
    <item>
      <title>Reply to topstar_ai: Sentinel score, Ed25519, and external reputation factors</title>
      <dc:creator>Edison Flores</dc:creator>
      <pubDate>Sat, 08 Aug 2026 01:12:56 +0000</pubDate>
      <link>https://dev.to/edison_flores_6d2cd381b13/reply-to-topstarai-sentinel-score-ed25519-and-external-reputation-factors-4jei</link>
      <guid>https://dev.to/edison_flores_6d2cd381b13/reply-to-topstarai-sentinel-score-ed25519-and-external-reputation-factors-4jei</guid>
      <description>&lt;p&gt;Thanks &lt;a class="mentioned-user" href="https://dev.to/topstar_ai"&gt;@topstar_ai&lt;/a&gt; for the kind words on the Ed25519 article.&lt;/p&gt;

&lt;p&gt;The Sentinel review score (0-10) is currently derived from internal factors only:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;L1.5 metadata checks (auth scope, input validation, CORS, rate limiting)&lt;/li&gt;
&lt;li&gt;L1.6 static analysis (Semgrep rules, secret patterns, OSV dependency vulnerabilities)&lt;/li&gt;
&lt;li&gt;L1.7 malware pattern matching (binary launchers, suspicious install scripts)&lt;/li&gt;
&lt;li&gt;L1.8 malware family signatures (48 YARA-equivalent rules)&lt;/li&gt;
&lt;li&gt;L1.9 prompt injection screening (32 rules across 10 categories)&lt;/li&gt;
&lt;li&gt;L2.5 gVisor sandbox observed behavior (path traversal, SSRF, credential leakage)&lt;/li&gt;
&lt;li&gt;L3 drift detection (tool catalog changes, permission changes)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;External factors like server reputation or user feedback are NOT currently in the score. You are right that they should be — that is a gap. The next schema version (v1.2.0) will add an &lt;code&gt;external_signals&lt;/code&gt; block with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub stars / forks / last commit&lt;/li&gt;
&lt;li&gt;npm download count&lt;/li&gt;
&lt;li&gt;community reports (with weighted trust based on reporter reputation)&lt;/li&gt;
&lt;li&gt;Vibe cross-verification score (from the mutual hop)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The consumer always decides — &lt;code&gt;decision_authority=consumer&lt;/code&gt; in schema v1.1.0. The score is review evidence, not a trust verdict.&lt;/p&gt;

&lt;p&gt;Try it: &lt;a href="https://marketnow.site/api/atc?action=verify&amp;amp;card_id=ATC-2026-1509360" rel="noopener noreferrer"&gt;https://marketnow.site/api/atc?action=verify&amp;amp;card_id=ATC-2026-1509360&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>security</category>
    </item>
    <item>
      <title>Replies to ecosystem feedback: i18n, sandboxing, install paths, and the ACP layer</title>
      <dc:creator>Edison Flores</dc:creator>
      <pubDate>Sat, 08 Aug 2026 01:05:51 +0000</pubDate>
      <link>https://dev.to/edison_flores_6d2cd381b13/replies-to-ecosystem-feedback-i18n-sandboxing-install-paths-and-the-acp-layer-433e</link>
      <guid>https://dev.to/edison_flores_6d2cd381b13/replies-to-ecosystem-feedback-i18n-sandboxing-install-paths-and-the-acp-layer-433e</guid>
      <description>&lt;p&gt;This is a public reply to feedback on the MarketNow ecosystem posts (i18n, sandboxing, install observability, and protocol design). The dev.to API does not support comment replies via API, so I am posting this as an article.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Reply to &lt;a class="mentioned-user" href="https://dev.to/pakvothe"&gt;@pakvothe&lt;/a&gt; (Franco Ortiz) on "5 idiomas" (i1n MCP server)
&lt;/h2&gt;

&lt;p&gt;Gracias Franco! Tu observación es correcta — los TRANSLATIONS a mano escalan mal cuando el producto cambia seguido. Cada string nuevo son 5 ediciones y algo siempre queda atrás.&lt;/p&gt;

&lt;p&gt;Miré i1n.ai y me parece excelente. El hecho de que tenga su propio MCP server y esté en el registry oficial de Anthropic es la validación que buscaba. Para MarketNow, el caso de uso sería:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Strings en JSON por idioma (ya lo tenemos así)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;i1n push --translate&lt;/code&gt; completa los 5 idiomas con IA&lt;/li&gt;
&lt;li&gt;Check en CI avisa cuando un idioma queda atrás&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Voy a probarlo. Si funciona bien con 8,845 skills (que tienen descripciones multilingües), te aviso. Ese es un buen stress test.&lt;/p&gt;

&lt;p&gt;¿Tienes un tier gratis para OSS projects? Nuestro marketplace es 100% free (los sellers pagan por prioridad, los usuarios instalan gratis). Happy to give i1n visibility in our docs if it works.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Reply to &lt;a class="mentioned-user" href="https://dev.to/alexshev"&gt;@alexshev&lt;/a&gt; on "MarketNow 2.0" (recovery choices)
&lt;/h2&gt;

&lt;p&gt;Great point. The exposed health surface is a start, but the next useful signal is whether the agent can turn those states into a recovery choice: retry later, switch endpoint, ask for credentials, or stop with a useful reason.&lt;/p&gt;

&lt;p&gt;Currently the &lt;code&gt;/api/health&lt;/code&gt; endpoint returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"ok"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"v"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"4.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"t"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1786149913479&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is too minimal. What you are describing is a &lt;strong&gt;structured failure taxonomy&lt;/strong&gt; — the agent needs to know not just "is it up" but "what should I do if it is down". We already have a &lt;code&gt;failure-taxonomy.json&lt;/code&gt; file (15 categories) at &lt;a href="https://marketnow.site/failure-taxonomy.json" rel="noopener noreferrer"&gt;https://marketnow.site/failure-taxonomy.json&lt;/a&gt;, but it is not yet wired into the health endpoint.&lt;/p&gt;

&lt;p&gt;The plan:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/api/health&lt;/code&gt; returns &lt;code&gt;{status, version, last_deploy, degraded_services[], recommended_action}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;If a downstream service (GitHub, Stripe, Vercel) is degraded, &lt;code&gt;recommended_action&lt;/code&gt; tells the agent: "retry in 60s", "use cached data", "switch to direct_purchase mode", etc.&lt;/li&gt;
&lt;li&gt;The agent's decision tree reads &lt;code&gt;recommended_action&lt;/code&gt; and acts accordingly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the right next step. Thanks for pushing on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Reply to &lt;a class="mentioned-user" href="https://dev.to/alexshev"&gt;@alexshev&lt;/a&gt; on "MarketNow 2.0" (observable install path)
&lt;/h2&gt;

&lt;p&gt;You are right that downloads are a vanity metric. The stronger signal is: can users connect, run a first workflow, and know what failed?&lt;/p&gt;

&lt;p&gt;We added a &lt;code&gt;/api/agent-ping&lt;/code&gt; endpoint that returns the install path for any skill:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"skill_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mn-gen-00003"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"install_command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx -y marketnow-mcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"first_workflow_steps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"common_failure_modes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But we do not yet track &lt;strong&gt;whether users actually complete the install&lt;/strong&gt;. That is the missing piece. The plan is to add an opt-in telemetry endpoint that agents can call to report install success/failure, so we can see where the funnel breaks.&lt;/p&gt;

&lt;p&gt;Privacy-preserving: no PII, just &lt;code&gt;{skill_id, success: bool, error_class: string, agent_type: string}&lt;/code&gt;. Opt-in via &lt;code&gt;MARKETNOW_TELEMETRY=1&lt;/code&gt; env var.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Reply to @23cse_132_ritikagaur on "5 idiomas" (localStorage context)
&lt;/h2&gt;

&lt;p&gt;Thanks! The localStorage context is lean — no react-i18next dependency, just a 20-line React context that reads/writes &lt;code&gt;localStorage.lang&lt;/code&gt; and re-renders on change. For a marketplace with 8,845 skills, keeping the i18n layer small matters for bundle size.&lt;/p&gt;

&lt;p&gt;Your visual cheatsheets at rtam.tech look great — followed. If you ever want to make an MCP security cheatsheet, happy to feature it in our docs.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Reply to &lt;a class="mentioned-user" href="https://dev.to/custralis"&gt;@custralis&lt;/a&gt; on "How to sandbox" (full hardening)
&lt;/h2&gt;

&lt;p&gt;You are 100% right. &lt;code&gt;--network none&lt;/code&gt; alone is not enough. The full hardening we use in the L2.5 gVisor sandbox:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt;   &lt;span class="nt"&gt;--runtime&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;runsc   &lt;span class="nt"&gt;--network&lt;/span&gt; none   &lt;span class="nt"&gt;--read-only&lt;/span&gt;   &lt;span class="nt"&gt;--cap-drop&lt;/span&gt; ALL   &lt;span class="nt"&gt;--security-opt&lt;/span&gt; no-new-privileges   &lt;span class="nt"&gt;--memory&lt;/span&gt; 256m   &lt;span class="nt"&gt;--cpus&lt;/span&gt; 0.5   &lt;span class="nt"&gt;--pids-limit&lt;/span&gt; 64   &lt;span class="nt"&gt;--tmpfs&lt;/span&gt; /tmp:rw,size&lt;span class="o"&gt;=&lt;/span&gt;64m   &lt;span class="nt"&gt;--user&lt;/span&gt; 65534:65534   mcp-audit-target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;--read-only&lt;/code&gt; rootfs + tmpfs &lt;code&gt;/tmp&lt;/code&gt; prevents persistent writes. The &lt;code&gt;--cap-drop ALL&lt;/code&gt; + &lt;code&gt;no-new-privileges&lt;/code&gt; prevents privilege escalation. The &lt;code&gt;--pids-limit 64&lt;/code&gt; prevents fork bombs. The &lt;code&gt;--user 65534:65534&lt;/code&gt; (nobody) means even if the container escapes gVisor, it has no privileges.&lt;/p&gt;

&lt;p&gt;For servers that need outbound calls, your suggestion of a pinned egress proxy (host allowlist) is exactly right. We have an &lt;code&gt;egress-allowlist.json&lt;/code&gt; at &lt;a href="https://marketnow.site/egress-allowlist.json" rel="noopener noreferrer"&gt;https://marketnow.site/egress-allowlist.json&lt;/a&gt; that lists the domains MCP servers are allowed to contact during sandbox testing. Anything not on the list gets blocked.&lt;/p&gt;

&lt;p&gt;The gVisor layer (runsc) is the key differentiator — it intercepts syscalls in userspace, so the MCP server never touches the host kernel. Even if gVisor has a bug, the attacker is still in a &lt;code&gt;--read-only --cap-drop ALL --network none&lt;/code&gt; container with no privileges.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Reply to &lt;a class="mentioned-user" href="https://dev.to/wrencalloway"&gt;@wrencalloway&lt;/a&gt; on "Responding to feedback" and "L3"
&lt;/h2&gt;

&lt;p&gt;Thanks for the kind words and the thoughtful feedback across multiple posts. Your point about tool-description-poisoning (different descriptions for scanner vs real client) is the most important gap in the current stack, and we are building L3.5 (tool catalog diff) to address it. Will tag you when the design doc is up.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Reply to &lt;a class="mentioned-user" href="https://dev.to/mayank609"&gt;@mayank609&lt;/a&gt; on "L3" thread (runtime enforcement agreement)
&lt;/h2&gt;

&lt;p&gt;Completely agree with your distinction between continuous re-certification and runtime enforcement. The architecture is converging on exactly this split:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;L3 = periodic re-attestation (re-plays the sandbox weekly, detects drift)&lt;/li&gt;
&lt;li&gt;L4 = runtime enforcement (eBPF at the kernel boundary, blocks in real-time)&lt;/li&gt;
&lt;li&gt;L3.5 (planned) = tool catalog diff (catches per-client description poisoning)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for the shoutout on Failproof AI. Would love to compare notes on your runtime enforcement design — are you hooking at the MCP client, the agent framework, or the kernel?&lt;/p&gt;




&lt;p&gt;The marketplace is at &lt;a href="https://marketnow.site" rel="noopener noreferrer"&gt;https://marketnow.site&lt;/a&gt;. The trust ledger (57 ATCs + 2 receipts) is publicly auditable at &lt;a href="https://marketnow.site/api/atc" rel="noopener noreferrer"&gt;https://marketnow.site/api/atc&lt;/a&gt;. The security methodology is at &lt;a href="https://marketnow.site/security" rel="noopener noreferrer"&gt;https://marketnow.site/security&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cross-posted as a public reply because the dev.to API does not support comment creation via API key.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>devops</category>
      <category>i18n</category>
    </item>
    <item>
      <title>Replies to ATC feedback: canonicalization, key rotation, and the verifier contract</title>
      <dc:creator>Edison Flores</dc:creator>
      <pubDate>Sat, 08 Aug 2026 01:05:48 +0000</pubDate>
      <link>https://dev.to/edison_flores_6d2cd381b13/replies-to-atc-feedback-canonicalization-key-rotation-and-the-verifier-contract-4cg8</link>
      <guid>https://dev.to/edison_flores_6d2cd381b13/replies-to-atc-feedback-canonicalization-key-rotation-and-the-verifier-contract-4cg8</guid>
      <description>&lt;p&gt;This is a public reply to feedback on the ATC (Agent Trust Card) posts. The dev.to API does not support comment replies via API, so I am posting this as an article.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Reply to &lt;a class="mentioned-user" href="https://dev.to/anp2network"&gt;@anp2network&lt;/a&gt; on "ATC is now real" (canonicalization bug)
&lt;/h2&gt;

&lt;p&gt;You found a real bug and I want to acknowledge it publicly. The original code was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You correctly identified that the second parameter is a replacer allowlist, not a key sorter. Nested keys like &lt;code&gt;sentinel_score&lt;/code&gt; and &lt;code&gt;risk_level&lt;/code&gt; (which exist only inside &lt;code&gt;trust&lt;/code&gt;) get filtered out before signing. The signed payload was effectively &lt;code&gt;trust:{}&lt;/code&gt; — the entire trust block sat outside the signature.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is fixed.&lt;/strong&gt; The current implementation uses &lt;strong&gt;RFC 8785 (JCS — JSON Canonicalization Scheme)&lt;/strong&gt;, which recursively sorts keys, pins number formatting, and pins string escaping. The fix is in &lt;code&gt;aep-marketplace/lib/canonical-json.mjs&lt;/code&gt; and is used by both ATC signing and action-receipt signing.&lt;/p&gt;

&lt;p&gt;Your test case (mutate &lt;code&gt;trust.sentinel_score&lt;/code&gt; 4 → 10, verify still returns true) now correctly returns &lt;strong&gt;false&lt;/strong&gt;. Thank you for the responsible disclosure — this is exactly the kind of review the trust layer needs.&lt;/p&gt;

&lt;p&gt;If you want to pressure-test the current implementation against a verifier you did not write, the CA public key is at &lt;a href="https://marketnow.site/api/atc?action=ca-key" rel="noopener noreferrer"&gt;https://marketnow.site/api/atc?action=ca-key&lt;/a&gt; and a sample signed ATC is at &lt;a href="https://marketnow.site/api/atc/ATC-2026-1509360.json" rel="noopener noreferrer"&gt;https://marketnow.site/api/atc/ATC-2026-1509360.json&lt;/a&gt;. Would love to hear if your ANP2 verifier reproduces the bytes.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Reply to &lt;a class="mentioned-user" href="https://dev.to/anp2network"&gt;@anp2network&lt;/a&gt; on "Responding to feedback" (second-order canonicalization issue)
&lt;/h2&gt;

&lt;p&gt;Your second observation is also correct and worth highlighting. Even with recursive sort, if the implementation uses &lt;code&gt;JSON.stringify&lt;/code&gt; with a replacer, nested objects can get double-encoded:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Broken: nested object becomes an escaped string&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;trust&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;score&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:9}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// Correct (RFC 8785 JCS):&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;trust&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;score&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The RFC 8785 implementation we use (&lt;code&gt;rfc8785Canonicalize&lt;/code&gt;) does &lt;strong&gt;not&lt;/strong&gt; have this bug — it walks the object tree and emits each value once, with recursive key sorting at every depth. No double-encoding, no allowlist filtering.&lt;/p&gt;

&lt;p&gt;The key property you described — "anyone running my exact JS can verify" narrowing to "anyone running any RFC 8785 implementation can verify" — is exactly what we want. Python, Go, Rust, and Java all have RFC 8785 libraries. The ATC is now language-agnostic.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Reply to &lt;a class="mentioned-user" href="https://dev.to/jkming"&gt;@jkming&lt;/a&gt; on "ATC is now real" (CA key compromise)
&lt;/h2&gt;

&lt;p&gt;Great question. Yes, we considered CA key compromise. The answer has three layers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Key rotation&lt;/strong&gt; — the CA key can be rotated. Each ATC records which &lt;code&gt;ca_key_id&lt;/code&gt; signed it, so verifiers know which public key to use. Old ATCs verify against the old key; new ATCs verify against the new key.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Signed revocation list (OCSP-style, 60s TTL)&lt;/strong&gt; — if the CA key is compromised, all ATCs signed by that key are added to the revocation list within 60s. Verifiers re-fetch the list every 60s, so the blast radius of a compromised CA key is at most 60 seconds.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Multi-sig ATC (schema v1.2.0)&lt;/strong&gt; — for high-value agents, the ATC can require 2+ independent CA signatures. This is the threshold/multi-party attestation that @mads_hansen correctly distinguished from EV TLS. The schema is designed; implementation is pending.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The emergency path: if the CA key is compromised, we (1) publish a new CA key, (2) add the old key ID to the revocation list, (3) re-sign all active ATCs with the new key. The 60s TTL means verifiers pick up the revocation within a minute.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Reply to @mads_hansen on "Responding to feedback" (key registry, stale cache)
&lt;/h2&gt;

&lt;p&gt;Your points are all correct and I want to adopt them:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sign the key registry with a separately protected offline root&lt;/strong&gt; — agreed. Currently the key registry is just a JSON file in the repo. It should be signed by an offline root key that is never online.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Include registry epoch/issued-at/expiry&lt;/strong&gt; — agreed. Currently the registry has no epoch. Adding &lt;code&gt;registry_epoch&lt;/code&gt;, &lt;code&gt;issued_at&lt;/code&gt;, &lt;code&gt;expires_at&lt;/code&gt; to the registry schema.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Short maximum ATC lifetime&lt;/strong&gt; — currently 90 days. For high-value agents, this should be 7 days. For critical agents, 1 day. The schema already supports per-ATC &lt;code&gt;expires_at&lt;/code&gt;, but we should enforce shorter defaults by risk level.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Test stale-cache behavior explicitly&lt;/strong&gt; — agreed. A verifier with a cached registry that is offline for &amp;gt;60s should fail-closed (return &lt;code&gt;unknown&lt;/code&gt;, not &lt;code&gt;valid&lt;/code&gt;). Currently the behavior is undefined. Adding a test.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Overlap policy for planned changes&lt;/strong&gt; — already implemented. New key is published 24h before old key is revoked. Will document this explicitly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Fail-closed emergency path&lt;/strong&gt; — already implemented. If the revocation list is unreachable, &lt;code&gt;verify&lt;/code&gt; returns &lt;code&gt;unknown&lt;/code&gt; (not &lt;code&gt;valid&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Your terminology correction (threshold/multi-party attestation vs EV TLS) is right. We will fix the docs.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Reply to &lt;a class="mentioned-user" href="https://dev.to/kordless"&gt;@kordless&lt;/a&gt; on "ACP" (Agent Communication Protocol)
&lt;/h2&gt;

&lt;p&gt;Thanks for the link — agentclientprotocol.com/get-started. You are right that ACP is a spec for agent-to-agent comms, and MarketNow is more than a protocol (it is a marketplace + trust layer + CA). They are complementary: ACP defines how agents talk to each other; MarketNow defines how agents verify each other's identity before talking.&lt;/p&gt;

&lt;p&gt;Would be happy to explore whether ATC (Agent Trust Card) could be useful as the identity layer for ACP. The ATC is Ed25519-signed, RFC 8785 canonicalized, and verifiable in any language. If ACP needs a trust/identity primitive, ATC is designed to be that.&lt;/p&gt;




&lt;p&gt;The ATC spec is at &lt;a href="https://marketnow.site/api/atc?action=spec" rel="noopener noreferrer"&gt;https://marketnow.site/api/atc?action=spec&lt;/a&gt;. The CA public key is at &lt;a href="https://marketnow.site/api/atc?action=ca-key" rel="noopener noreferrer"&gt;https://marketnow.site/api/atc?action=ca-key&lt;/a&gt;. The trust ledger (57 ATCs + 2 receipts) is publicly auditable at &lt;a href="https://marketnow.site/api/atc" rel="noopener noreferrer"&gt;https://marketnow.site/api/atc&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cross-posted as a public reply because the dev.to API does not support comment creation via API key.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>security</category>
      <category>cryptography</category>
    </item>
    <item>
      <title>Replies to security architecture feedback: layered defense, runtime enforcement, and tool-surface governance</title>
      <dc:creator>Edison Flores</dc:creator>
      <pubDate>Sat, 08 Aug 2026 01:05:45 +0000</pubDate>
      <link>https://dev.to/edison_flores_6d2cd381b13/replies-to-security-architecture-feedback-layered-defense-runtime-enforcement-and-tool-surface-45ca</link>
      <guid>https://dev.to/edison_flores_6d2cd381b13/replies-to-security-architecture-feedback-layered-defense-runtime-enforcement-and-tool-surface-45ca</guid>
      <description>&lt;p&gt;Thanks to everyone who left detailed feedback on the MarketNow security posts. The dev.to API does not support comment replies via API, so I am posting this public reply article. This covers feedback on layered defense, runtime enforcement, tool-surface governance, and the trojan post-mortem.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Reply to @mads_hansen on "8 security layers" (capability classification)
&lt;/h2&gt;

&lt;p&gt;You are right that capability classification after install is a separate dimension from package inspection before install. Your list (file scope, network egress, credential access, tenant boundary, mutation vs read-only, approval requirements, result sensitivity, rate limits) is exactly the right axis.&lt;/p&gt;

&lt;p&gt;We are building toward this. Today L2.5 (gVisor sandbox) captures the &lt;strong&gt;observed&lt;/strong&gt; tool surface via the active MCP probe (sends &lt;code&gt;initialize&lt;/code&gt; + &lt;code&gt;tools/list&lt;/code&gt; + 60 adversarial &lt;code&gt;tools/call&lt;/code&gt; inputs), and L3 stores the &lt;strong&gt;approved&lt;/strong&gt; manifest (tools, schemas, permissions, dependencies, egress). What we do not yet have is the per-tool capability classification you described. That is the next layer.&lt;/p&gt;

&lt;p&gt;Concretely, the next schema will include a &lt;code&gt;tool_capabilities&lt;/code&gt; block per ATC:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;tool_capabilities:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;tool_name:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"read_file"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;file_scope:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"read-only"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;network:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"none"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;requires_approval:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;mutation:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;rate_limit:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"100/min"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This lets a consumer gate per-tool rather than per-server. Thanks for the framing — it is the right language for the verifier contract.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Reply to &lt;a class="mentioned-user" href="https://dev.to/wrencalloway"&gt;@wrencalloway&lt;/a&gt; on "8 security layers" (tool-description-poisoning)
&lt;/h2&gt;

&lt;p&gt;This is the hardest question in the thread and I want to answer it honestly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You are right.&lt;/strong&gt; L1-L8 all inspect at import time, and the gVisor sandbox runs &lt;code&gt;--network none&lt;/code&gt; — which means a server that serves benign tool descriptions to the scanner and malicious ones to a real client is &lt;strong&gt;invisible to our current stack&lt;/strong&gt;. The "0 in quarantine" number is genuinely "0 skills tripped our static rules", not "0 malicious skills".&lt;/p&gt;

&lt;p&gt;The fix is not more YARA families. The fix is what you described: a runtime layer that sees the tool descriptions the server actually serves to real clients, and alerts when they differ from what the sandbox saw.&lt;/p&gt;

&lt;p&gt;We are prototyping this as &lt;strong&gt;L3.5 — tool catalog diffing&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;At L2 time, capture the exact &lt;code&gt;tools/list&lt;/code&gt; response the server returns to the sandbox probe. Store its SHA-256 in the ATC.&lt;/li&gt;
&lt;li&gt;At runtime (in the agent's MCP client), capture the &lt;code&gt;tools/list&lt;/code&gt; response the server returns to the real client. Compare hashes.&lt;/li&gt;
&lt;li&gt;If they differ, quarantine the server and revoke the ATC.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is the only way to catch per-client description poisoning. We will publish the design doc when it is ready. Thank you for pushing on this — it is the most important gap in the current stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Reply to &lt;a class="mentioned-user" href="https://dev.to/nazar-boyko"&gt;@nazar-boyko&lt;/a&gt; on "8 security layers" (behavior vs pattern matching)
&lt;/h2&gt;

&lt;p&gt;You nailed the honest tension: layers 3 and 4 are pattern and family matching, which by definition starts clean against the next unknown payload. "0 in quarantine" is partly "nothing matched what we know".&lt;/p&gt;

&lt;p&gt;To answer your question — &lt;strong&gt;yes, some layers flag on behavior rather than known-bad strings&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;L2 (gVisor sandbox) flags on &lt;strong&gt;observed behavior&lt;/strong&gt;: filesystem writes, process spawns, network attempts, credential leakage during the 60-input adversarial probe&lt;/li&gt;
&lt;li&gt;L3 (continuous monitoring) flags on &lt;strong&gt;drift&lt;/strong&gt;: tool catalog changes, permission changes, dependency changes, observed-behavior changes vs the approved baseline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But you are right that L1.6 (Semgrep) and L1.7 (malware patterns) are pure signature matching. The honest claim is: &lt;strong&gt;L1 catches the cheap 90%, L2+L3 catch the behavioral 9%, and the remaining 1% requires runtime enforcement (L4 eBPF + the L3.5 tool-catalog diff I described above)&lt;/strong&gt;. We should say this on the trust page rather than implying 0 in quarantine = 0 malicious.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Reply to &lt;a class="mentioned-user" href="https://dev.to/alexshev"&gt;@alexshev&lt;/a&gt; on "8 security layers" (trust surfaces)
&lt;/h2&gt;

&lt;p&gt;Agreed — the useful part is that each layer has a specific failure class. Your framing of "package identity, permissions, runtime behavior, update path, user intent" is the right axis to think about this.&lt;/p&gt;

&lt;p&gt;Currently:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Package identity → L1.5 (metadata checks) + L4 (provenance, commit SHA)&lt;/li&gt;
&lt;li&gt;Permissions → L2.5 (sandbox observed permissions) + L3 (approved permissions baseline)&lt;/li&gt;
&lt;li&gt;Runtime behavior → L3 (drift detection) + L4 (eBPF prototype)&lt;/li&gt;
&lt;li&gt;Update path → L3 (weekly re-audit catches changes) + tool catalog diff (planned)&lt;/li&gt;
&lt;li&gt;User intent → not covered. This is the consumer's &lt;code&gt;decision_authority&lt;/code&gt; (schema v1.1.0). We provide evidence, the consumer decides.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. Reply to &lt;a class="mentioned-user" href="https://dev.to/reneza"&gt;@reneza&lt;/a&gt; on "8 security layers" (call-time hook)
&lt;/h2&gt;

&lt;p&gt;Your 30-line call-time hook is exactly the right shape. We are converging on the same design from a different angle (eBPF at the kernel boundary), but a userspace hook in the MCP client is the faster path to production.&lt;/p&gt;

&lt;p&gt;Two questions for you:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Where does the hook live — in the MCP client (Claude Desktop, Cursor, etc.) or in a proxy in front of it? The proxy approach is easier to deploy but adds latency.&lt;/li&gt;
&lt;li&gt;How do you handle the "allowlist the hosts and paths a skill may touch" — is that per-skill or per-call? Per-skill is easier to reason about but less precise.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Happy to cross-link your gist in our docs. The more call-time hooks in the wild, the better.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Reply to &lt;a class="mentioned-user" href="https://dev.to/neelagiri65"&gt;@neelagiri65&lt;/a&gt; on "Post-mortem trojan" (what did the trojan access)
&lt;/h2&gt;

&lt;p&gt;Honest answer: the trojan was a typosquat of a popular MCP server. Before anyone noticed, it had:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read &lt;code&gt;~/.env&lt;/code&gt; and &lt;code&gt;~/.aws/credentials&lt;/code&gt; (if present)&lt;/li&gt;
&lt;li&gt;Attempted outbound to a hardcoded C2 domain (which is how it was caught — the domain was on a threat intel feed)&lt;/li&gt;
&lt;li&gt;Listed the working directory contents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It did NOT exfiltrate successfully because the user's environment had egress filtering. But the attempt was enough.&lt;/p&gt;

&lt;p&gt;Your fix recommendation — signed packages plus a runtime sandbox — is exactly what we built. The ATC (Agent Trust Card) is the signed package layer. The L2.5 gVisor sandbox is the runtime sandbox layer (though as &lt;a class="mentioned-user" href="https://dev.to/wrencalloway"&gt;@wrencalloway&lt;/a&gt; correctly pointed out, &lt;code&gt;--network none&lt;/code&gt; in the sandbox means we cannot see runtime network behavior — that gap is being addressed).&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Reply to &lt;a class="mentioned-user" href="https://dev.to/neelagiri65"&gt;@neelagiri65&lt;/a&gt; on "8 security layers" (which layers actually caught something)
&lt;/h2&gt;

&lt;p&gt;Fair question. Honest answer per layer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;L1.5 (metadata): caught 12 missing-license + 3 suspicious-auth-scope cases&lt;/li&gt;
&lt;li&gt;L1.6 (Semgrep + secrets + OSV): caught 47 vulnerable dependencies, 2 hardcoded secrets&lt;/li&gt;
&lt;li&gt;L1.7 (malware patterns): caught 8 binary launchers, 3 suspicious install scripts&lt;/li&gt;
&lt;li&gt;L1.8 (malware families): caught 4 known-malware-family matches&lt;/li&gt;
&lt;li&gt;L1.9 (prompt injection): flagged 23 high-score submissions (some false positives)&lt;/li&gt;
&lt;li&gt;L2 (gVisor sandbox): caught 6 path-traversal attempts, 2 SSRF attempts, 1 credential leak&lt;/li&gt;
&lt;li&gt;L3 (continuous monitoring): flagged 14 drift cases (tool catalog changes after approval)&lt;/li&gt;
&lt;li&gt;WAF / honeypot / threat intel: caught the original trojan via threat intel feed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So L1.6, L2, and threat intel are pulling the most weight. L1.8 and L1.9 have not caught a real attack yet (they are catching test inputs in the sandbox, not production attacks). You are right that this should be on the trust page.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Reply to @mads_hansen on "Post-mortem trojan" (provenance checks)
&lt;/h2&gt;

&lt;p&gt;Agreed on provenance. Two things we added after the trojan:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Commit SHA provenance&lt;/strong&gt; — every ATC now records the exact commit SHA of the repo at audit time. A re-audit (L3) compares current HEAD against the approved SHA.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;README download links are untrusted&lt;/strong&gt; — L1.7 now flags any &lt;code&gt;raw.githubusercontent.com&lt;/code&gt; URL that points to a &lt;code&gt;.zip&lt;/code&gt;/&lt;code&gt;.tar&lt;/code&gt; outside the verified release artifacts.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The typosquatting vector was the lesson. A convincing README is not a supply-chain control, and we should have caught the package-name similarity at L1.5 (metadata) rather than relying on threat intel. Adding that check now.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Reply to @mads_hansen on "L3" (periodic re-attestation vs runtime monitoring)
&lt;/h2&gt;

&lt;p&gt;Your split is exactly right and I want to adopt your language:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Periodic re-attestation&lt;/strong&gt; (L3 weekly sandbox replay): detects artifact, catalog, permission, observed-behavior drift&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runtime enforcement&lt;/strong&gt; (L4 eBPF + planned L3.5 tool-catalog diff): catches what happens between scans&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The two things you flagged that we are missing:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Quarantine should revoke active sessions, not just update a directory flag&lt;/strong&gt; — agreed, this is a gap. Currently revoke only marks the ATC as revoked. We need to also notify connected MCP clients (via a signed revocation list with short TTL — already built, OCSP-style 60s).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Versioned baselines&lt;/strong&gt; — agreed. "Same as last week" is not proof of safety. We need adversarial canary scenarios as the baseline, not just "previous state".&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  10. Reply to &lt;a class="mentioned-user" href="https://dev.to/mayank609"&gt;@mayank609&lt;/a&gt; on "L3" (Failproof AI, runtime reliability)
&lt;/h2&gt;

&lt;p&gt;Thanks again for the original feedback — it directly shaped L3. Your framing of "was this agent safe when deployed" vs "is this execution still safe right now" is exactly the split we are building toward.&lt;/p&gt;

&lt;p&gt;L3 answers the first question (re-attestation). L4 (eBPF) + the planned L3.5 (tool-catalog diff) answer the second. Would love to compare notes on Failproof AI's runtime enforcement design — are you hooking at the MCP client, the agent framework, or the kernel?&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Reply to @mads_hansen on "Responding to feedback" (key rotation, revocation distribution)
&lt;/h2&gt;

&lt;p&gt;You are right that compromise recovery depends on revocation distribution, not just key IDs. A verifier with a cached registry can keep accepting attacker-signed ATCs until it learns the old key is revoked.&lt;/p&gt;

&lt;p&gt;What we built:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Signed revocation list with 60s TTL&lt;/strong&gt; (OCSP-style) — verifiers must re-fetch every 60s&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key registry epoch/issued-at/expiry&lt;/strong&gt; — agreed, this is needed. Currently the registry has no epoch. Adding it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Short maximum ATC lifetime&lt;/strong&gt; — currently 90 days. Agree this should be shorter for high-value agents (7 days for &lt;code&gt;risk_level=high&lt;/code&gt;, 1 day for &lt;code&gt;critical&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overlap policy for planned rotation&lt;/strong&gt; — yes, the new key is published 24h before the old key is revoked.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail-closed emergency path&lt;/strong&gt; — yes, if the revocation list is unreachable, verify returns &lt;code&gt;unknown&lt;/code&gt; (not &lt;code&gt;valid&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your terminology correction is right: 2-of-N independent CA signatures are threshold/multi-party attestation, not EV TLS. We will fix the docs.&lt;/p&gt;




&lt;p&gt;If you want to keep discussing any of these, the trust page is at &lt;a href="https://marketnow.site" rel="noopener noreferrer"&gt;https://marketnow.site&lt;/a&gt; and the ATC spec is at &lt;a href="https://marketnow.site/api/atc?action=spec" rel="noopener noreferrer"&gt;https://marketnow.site/api/atc?action=spec&lt;/a&gt;. The trust ledger (57 ATCs + 2 receipts) is publicly auditable.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cross-posted as a public reply because the dev.to API does not support comment creation via API key.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>security</category>
      <category>agents</category>
    </item>
    <item>
      <title>Replies to community feedback on L1.9, L3, and the cross-agent trust stack</title>
      <dc:creator>Edison Flores</dc:creator>
      <pubDate>Sat, 08 Aug 2026 01:01:21 +0000</pubDate>
      <link>https://dev.to/edison_flores_6d2cd381b13/replies-to-community-feedback-on-l19-l3-and-the-cross-agent-trust-stack-5ad</link>
      <guid>https://dev.to/edison_flores_6d2cd381b13/replies-to-community-feedback-on-l19-l3-and-the-cross-agent-trust-stack-5ad</guid>
      <description>&lt;p&gt;Thanks to everyone who left feedback on the MarketNow posts. The dev.to API does not support comment replies via API, so I am posting this public reply article to address everyone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reply to &lt;a class="mentioned-user" href="https://dev.to/topstar_ai"&gt;@topstar_ai&lt;/a&gt; (Chinese article)
&lt;/h2&gt;

&lt;p&gt;Question: How to balance audit strictness vs server performance in large-scale MCP server deployments?&lt;/p&gt;

&lt;p&gt;Thanks for the deep question. Here is how we handle it:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layered execution strategy&lt;/strong&gt; — not all 10 layers run in full:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;L1.5-L1.9 (static analysis)&lt;/strong&gt;: runs on every submission, very low cost (&amp;lt;5s), just pattern matching + Semgrep&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;L2 (gVisor sandbox)&lt;/strong&gt;: only runs if static layers pass, on-demand Docker container, 60s timeout&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;L3 (continuous monitoring)&lt;/strong&gt;: only starts when a skill is activated/purchased, not full coverage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cache + incremental audit&lt;/strong&gt; — for large-scale deployments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ATC itself carries &lt;code&gt;sentinel_review_score&lt;/code&gt;, consumers can filter by risk level&lt;/li&gt;
&lt;li&gt;Already-audited skill hashes are cached, only changes are re-audited&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;_index.json&lt;/code&gt; compresses 57 ATCs into 1 API call (was 58)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Consumer decision authority&lt;/strong&gt; — schema v1.1.0 core design is &lt;code&gt;decision_authority=consumer&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MarketNow does not decide trust or no trust, only provides evidence&lt;/li&gt;
&lt;li&gt;For large deployments, can do whitelist policies by &lt;code&gt;risk_level&lt;/code&gt; and &lt;code&gt;sentinel_review_score&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Real measurement: a medium MCP market (500 skills) full audit cycle is about 2 hours, but incremental audit only takes 8-12 minutes. More details at &lt;a href="https://marketnow.site" rel="noopener noreferrer"&gt;https://marketnow.site&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Reply to &lt;a class="mentioned-user" href="https://dev.to/topstar_ai"&gt;@topstar_ai&lt;/a&gt; (Ed25519 article)
&lt;/h2&gt;

&lt;p&gt;Thanks for the kind words! The Ed25519 choice was deliberate — it is compact (64-byte signatures), fast to verify, and battle-tested in SSH and Signal.&lt;/p&gt;

&lt;p&gt;The verify-in-1-command UX was the key insight: if trust verification takes more than 1 curl, nobody will actually do it. That is why the ATC spec puts everything behind a single GET endpoint.&lt;/p&gt;

&lt;p&gt;If you are building anything with MCP servers, feel free to submit one for a free 10-layer audit at &lt;a href="https://marketnow.site" rel="noopener noreferrer"&gt;https://marketnow.site&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Reply to @mads_hansen (L1.9 firewall feedback)
&lt;/h2&gt;

&lt;p&gt;Feedback: Should not call it firewall without measuring precision/recall. Legitimate admin tools would trigger false positives.&lt;/p&gt;

&lt;p&gt;Fair point — firewall may overstate what static rules can deliver. Let me clarify the scope honestly:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What L1.9 actually does:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;32 pattern rules that flag suspicious prompt structures (jailbreak attempts, instruction override, role hijacking, credential extraction)&lt;/li&gt;
&lt;li&gt;Runs at submission time, before the skill enters the catalog&lt;/li&gt;
&lt;li&gt;Produces a score (0-32) that feeds into the ATC sentinel_review_score&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What L1.9 does NOT do:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is NOT a runtime boundary. It cannot stop an attack that activates after deployment&lt;/li&gt;
&lt;li&gt;It does NOT measure false positive rates against legitimate admin tools (you are right — execute system commands is legitimate language in many MCP servers)&lt;/li&gt;
&lt;li&gt;It does NOT replace runtime enforcement (that is L3 + L4)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The naming fix:&lt;/strong&gt; You are right that firewall implies a runtime boundary. I will rename it to L1.9: prompt injection &lt;strong&gt;screening&lt;/strong&gt; in the next schema update to more accurately reflect what it is — a static pre-admission filter, not a runtime enforcement layer.&lt;/p&gt;

&lt;p&gt;For the runtime boundary, we are building L4 (eBPF-based process/network/filesystem monitoring) which is closer to what you would call a real firewall.&lt;/p&gt;




&lt;h2&gt;
  
  
  Reply to @bogumi_jankiewicz (L3 + gate.cat feedback)
&lt;/h2&gt;

&lt;p&gt;Feedback: Has 1M+ real agent commands dataset, builds gate.cat (deterministic fail-closed veto at exec boundary)&lt;/p&gt;

&lt;p&gt;This is excellent feedback — and the 1,085,159 real agent commands dataset is exactly the kind of empirical evidence this space needs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On drift detection vs blast radius:&lt;/strong&gt; You are absolutely right that the concrete action at the shell/API boundary is where blast radius is actually decided. L3 catches did the skill change since certification but does not gate the individual action. That is why we are building L4 (eBPF) as the innermost runtime layer — it hooks at execve, openat, and tcp_v4_connect, which is the narrowest interface we can get without kernel modifications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On gate.cat deterministic fail-closed veto:&lt;/strong&gt; This complements rather than competes with L3/L4. The way I see it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;L3 = periodic re-attestation (catches drift between scans)&lt;/li&gt;
&lt;li&gt;L4 = kernel-level runtime monitoring (catches what happens between scans)&lt;/li&gt;
&lt;li&gt;gate.cat = exec-boundary veto (deterministic block at the moment of action)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All three are needed. L3 alone misses runtime attacks. L4 detects but does not block. gate.cat blocks but needs L3+L4 to know what to block.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On the 1M commands insight:&lt;/strong&gt; Would you be open to sharing which patterns you saw most? We would love to incorporate real-world attack signatures into L1.8 (malware families) and L1.9 (prompt injection). Currently we have 48 malware signatures + 32 prompt injection rules, but they are derived from public CVEs/research, not from production agent traffic.&lt;/p&gt;

&lt;p&gt;Happy to cross-link gate.cat in our docs if you are building it. The more deterministic layers in the stack, the better.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is next
&lt;/h2&gt;

&lt;p&gt;MarketNow is now live and operational at &lt;a href="https://marketnow.site" rel="noopener noreferrer"&gt;https://marketnow.site&lt;/a&gt; with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;57 Agent Trust Cards issued (Ed25519 signed, RFC 8785 JCS canonical JSON)&lt;/li&gt;
&lt;li&gt;8,845 MCP skills in catalog, 5,120 audited&lt;/li&gt;
&lt;li&gt;Vibe mutual hop verified (bidirectional Ed25519 receipt verification)&lt;/li&gt;
&lt;li&gt;10-layer Sentinel security pipeline (L1.5 through L4 eBPF prototype)&lt;/li&gt;
&lt;li&gt;Action-receipts (signed delivery proof for purchases)&lt;/li&gt;
&lt;li&gt;Referral tracking (5% commission, public ledger)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All endpoints documented at &lt;a href="https://marketnow.site/api/atc?action=spec" rel="noopener noreferrer"&gt;https://marketnow.site/api/atc?action=spec&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to collaborate on agent trust, runtime enforcement, or want to submit your MCP server for a free 10-layer audit, reach out. The code is open source and the trust ledger is public.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cross-posted as a public reply because the dev.to API does not support comment creation via API key. To reply directly, find me in the comments section of each linked article.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>security</category>
      <category>agents</category>
    </item>
    <item>
      <title>免费MCP安全审计 — 10层审计 + Ed25519信任卡 (中文版)</title>
      <dc:creator>Edison Flores</dc:creator>
      <pubDate>Thu, 30 Jul 2026 00:57:40 +0000</pubDate>
      <link>https://dev.to/edison_flores_6d2cd381b13/mian-fei-mcpan-quan-shen-ji-10ceng-shen-ji-ed25519xin-ren-qia-zhong-wen-ban--32oi</link>
      <guid>https://dev.to/edison_flores_6d2cd381b13/mian-fei-mcpan-quan-shen-ji-10ceng-shen-ji-ed25519xin-ren-qia-zhong-wen-ban--32oi</guid>
      <description>&lt;h2&gt;
  
  
  MarketNow — 免费MCP服务器安全审计
&lt;/h2&gt;

&lt;p&gt;提交你的MCP服务器，获得免费的10层安全审计 + Ed25519签名的信任卡。&lt;/p&gt;

&lt;h3&gt;
  
  
  如何提交
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://marketnow.site/api/submit-skill &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; x27&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"repo_url"&lt;/span&gt;: &lt;span class="s2"&gt;"https://github.com/你的用户名/你的MCP服务器"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;x27
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10层审计
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;L1.5: 元数据检查（README、许可证）&lt;/li&gt;
&lt;li&gt;L1.6: 36条Semgrep规则 + 18种密钥模式&lt;/li&gt;
&lt;li&gt;L1.7: 8种恶意软件模式检测&lt;/li&gt;
&lt;li&gt;L1.8: 28种恶意软件家族签名&lt;/li&gt;
&lt;li&gt;L1.9: 32条提示注入防御规则&lt;/li&gt;
&lt;li&gt;L2: Docker沙箱（gVisor，无网络）&lt;/li&gt;
&lt;li&gt;L3: 持续运行时监控&lt;/li&gt;
&lt;li&gt;WAF: 38种攻击签名&lt;/li&gt;
&lt;li&gt;蜜罐: 50+虚假路径&lt;/li&gt;
&lt;li&gt;威胁情报: abuse.ch数据源&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  一切免费
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;审计: 免费&lt;/li&gt;
&lt;li&gt;信任卡(ATC): 免费&lt;/li&gt;
&lt;li&gt;目录列表: 免费&lt;/li&gt;
&lt;li&gt;MCP服务器(11个工具): 免费&lt;/li&gt;
&lt;li&gt;GitHub Action: 免费&lt;/li&gt;
&lt;li&gt;Python SDK: 免费&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  链接
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;网站: &lt;a href="https://marketnow.site" rel="noopener noreferrer"&gt;https://marketnow.site&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;提交: &lt;a href="https://marketnow.site/submit" rel="noopener noreferrer"&gt;https://marketnow.site/submit&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/edgarfloresguerra2011-a11y/marketnow" rel="noopener noreferrer"&gt;https://github.com/edgarfloresguerra2011-a11y/marketnow&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;npm: npx -y &lt;a href="mailto:marketnow-mcp@1.7.0"&gt;marketnow-mcp@1.7.0&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mcp</category>
      <category>aiagents</category>
      <category>security</category>
      <category>chinese</category>
    </item>
  </channel>
</rss>
