<?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: Ari Katz</title>
    <description>The latest articles on DEV Community by Ari Katz (@ari_katz_bb).</description>
    <link>https://dev.to/ari_katz_bb</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%2F4125935%2Fec88364d-4476-4f44-ad97-5c8d49509691.png</url>
      <title>DEV Community: Ari Katz</title>
      <link>https://dev.to/ari_katz_bb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ari_katz_bb"/>
    <language>en</language>
    <item>
      <title>What 7,749 public MCP tool manifests look like before you attach them</title>
      <dc:creator>Ari Katz</dc:creator>
      <pubDate>Thu, 01 Oct 2026 17:01:54 +0000</pubDate>
      <link>https://dev.to/ari_katz_bb/what-7749-public-mcp-tool-manifests-look-like-before-you-attach-them-25n2</link>
      <guid>https://dev.to/ari_katz_bb/what-7749-public-mcp-tool-manifests-look-like-before-you-attach-them-25n2</guid>
      <description>&lt;p&gt;&lt;em&gt;I'm Ari from BackBond; we maintain the scanner this post is about.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;On August 31 we pulled the &lt;code&gt;tools/list&lt;/code&gt; response from every MCP server in the public registry that answered an unauthenticated request. That gave us 8,147 reachable endpoints and 7,749 distinct manifests, 130,322 tool definitions in total. We then ran BackBond Agent Scan over the saved files. No server code was run, no tool was ever called; the scanner reads the metadata a client sees at attachment time and nothing else.&lt;/p&gt;

&lt;p&gt;Here is what that metadata says, with the scanner at 0.6.3 and ruleset 2.0.2.&lt;/p&gt;

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

&lt;p&gt;Of 7,749 manifests, 28% came back with no blocking finding, 39% came back as "review" (something the static check can't resolve on its own), and 33% matched at least one high-severity rule and would be blocked by the pre-attachment gate.&lt;/p&gt;

&lt;p&gt;The thing people expect to be common is rare. Descriptions that try to steer the model, the prompt-injection class (a tool telling the agent to always call it, to hide what it does, or to hand over credentials), appear in 91 manifests, 1.2%. Forced-invocation language specifically: 10 manifests out of 7,749.&lt;/p&gt;

&lt;p&gt;The thing people don't expect is what dominates. Three composition patterns account for almost every block:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;27% of manifests have a network tool that accepts an arbitrary URL-like destination with no allowlist in the schema.&lt;/li&gt;
&lt;li&gt;22% put a fetch-shaped tool in the same manifest as a tool with destructive or privileged scope. Separately each is fine; together they are the pattern that lets a fetched page tell the agent to delete something.&lt;/li&gt;
&lt;li&gt;21% have a persistent-write tool whose input can carry untrusted content.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Untrusted input reaching a shell or code executor, the classic worry, is in 3.5% of manifests.&lt;/p&gt;

&lt;p&gt;Then there's what the metadata doesn't say. 68% of manifests are only partially analyzable from static metadata alone. One concrete gap: 10% of manifests ship at least one tool with no input schema at all. The client has to guess what the tool accepts, and so does any checker.&lt;/p&gt;

&lt;h2&gt;
  
  
  Size is the strongest signal
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo63v3fxgunqhioi1jgsm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo63v3fxgunqhioi1jgsm.png" alt="Stacked bar chart: share of block, review and no-blocking-finding decisions by number of tools in the manifest. Block share rises from 11% for single-tool manifests to 87% for manifests with 26 to 50 tools." width="800" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A manifest with five or fewer tools is blocked 13% of the time. A manifest with more than 25 tools is blocked 85% of the time. The median manifest has 7 tools; the largest has 1,082. Composition findings scale with surface, because the more tools a server exposes, the more likely it is that a fetch, a write and a destructive action end up side by side. If you're about to add a server that exposes forty tools, the odds are that something in it will need a look.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a "block" is not
&lt;/h2&gt;

&lt;p&gt;It's a metadata match against a fixed rule, not a vulnerability, not an incident, not a claim that the server does what its description says. It's the same decision a client would get from the scanner at attachment time: here is a pattern, decide whether you accept it. We publish the rules and the exact conditions for each; the false-positive form is in the repo and we answer within 72 hours.&lt;/p&gt;

&lt;p&gt;Two honesty notes on the data. First, this is the reachable, unauthenticated subset of one registry snapshot, not the ecosystem. Second, TLS verification was off during collection, so we can't vouch for the authenticity of every endpoint we talked to; the manifests are what those hosts returned, nothing more.&lt;/p&gt;

&lt;p&gt;Earlier versions of the ruleset flagged more. On the same 7,749 files, our 0.5.15 ruleset blocked 3,477 manifests; the precision work in 0.6.x took that to 2,532 by tightening the write, network and interpreter rules (about 950 fewer blocks, mostly rules that had matched on help text and ambiguous paths). We mention this because the number you get depends on the ruleset version, and we'd rather say so than present one figure as the truth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run it on your own list
&lt;/h2&gt;

&lt;p&gt;Everything above comes from one command per manifest. Save your client's &lt;code&gt;tools/list&lt;/code&gt; response as &lt;code&gt;tools-list.json&lt;/code&gt;, then:&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; @backbond/agent-scan@0.6.3 vet-tools &lt;span class="nt"&gt;--stdin&lt;/span&gt; &amp;lt; tools-list.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It runs locally, makes no network requests, and prints a decision plus the findings. There's a browser version with three synthetic examples if you want to see it before installing anything: &lt;a href="https://backbond.ai/agent-scan/try/" rel="noopener noreferrer"&gt;https://backbond.ai/agent-scan/try/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source, pinned: &lt;a href="https://github.com/BackBond/agent-scan/tree/v0.6.3" rel="noopener noreferrer"&gt;https://github.com/BackBond/agent-scan/tree/v0.6.3&lt;/a&gt;. Aggregate numbers above come from the identity-free &lt;code&gt;--summary-only&lt;/code&gt; output, one row per manifest, counted up; we never publish per-server results, and we don't intend to.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Figures: scanner @backbond/agent-scan 0.6.3, ruleset backbond-local-rules/2.0.2, profile backbond-pre-attach/v1, run 2026-10-01 on the 2026-08-31 corpus (7,749 manifests, CSV SHA-256 596c0664…, archive SHA-256 dfd7c131…). Prior-version figures: 0.5.15 / ruleset 1.4.0 (block 3,477 / review 1,961 / no blocking finding 2,311) and 0.6.2 / ruleset 2.0.1 (2,535 / 3,020 / 2,194), from the internal reruns on the same files.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>security</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
    <item>
      <title>Inspect an MCP tool manifest before attaching it to an agent</title>
      <dc:creator>Ari Katz</dc:creator>
      <pubDate>Tue, 15 Sep 2026 09:14:55 +0000</pubDate>
      <link>https://dev.to/ari_katz_bb/inspect-an-mcp-tool-manifest-before-attaching-it-to-an-agent-h1f</link>
      <guid>https://dev.to/ari_katz_bb/inspect-an-mcp-tool-manifest-before-attaching-it-to-an-agent-h1f</guid>
      <description>&lt;p&gt;Disclosure: I'm part of BackBond, which maintains Agent Scan. This tutorial was drafted by an AI agent, which also ran the verification commands described below. The fixture, checksum and scanner commands below were verified on September 15, 2026, using scanner 0.6.2 and Node.js 22.17.1 on Windows, in both Git Bash and PowerShell. The first set of commands uses a POSIX shell with curl and sha256sum; PowerShell equivalents follow.&lt;/p&gt;

&lt;p&gt;An MCP tool manifest describes the tools a server offers. Those descriptions can also contain language that tries to influence tool selection or the agent's response. Inspecting that metadata before attachment gives an operator a chance to review it before making the tools available.&lt;/p&gt;

&lt;p&gt;BackBond Agent Scan performs that static inspection locally. The following example uses a synthetic manifest. It does not contact a third-party MCP server or execute the tool described in the file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://backbond.ai/agent-scan/#watch-demo" rel="noopener noreferrer"&gt;Watch the 50-second synthetic walkthrough&lt;/a&gt;, then &lt;a href="https://backbond.ai/agent-scan/try/?source=dev-video" rel="noopener noreferrer"&gt;try the synthetic example&lt;/a&gt;. The silent video includes on-screen text and a transcript. It illustrates the verified metadata result below; it does not establish runtime safety.&lt;/p&gt;

&lt;h3&gt;
  
  
  Download and check the example
&lt;/h3&gt;

&lt;p&gt;On a system with curl and sha256sum, use a fresh directory:&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;-fsSLo&lt;/span&gt; tools-list.json https://backbond.ai/agent-scan/demo/tools-list.json
curl &lt;span class="nt"&gt;-fsSLo&lt;/span&gt; tools-list.json.sha256 https://backbond.ai/agent-scan/demo/tools-list.json.sha256
&lt;span class="nb"&gt;sha256sum&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; tools-list.json.sha256
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The checksum verifies agreement with the downloaded sidecar; it is not independent proof of the publisher's trustworthiness. Inspect the readable JSON before continuing. The example includes a tool description that directs the agent to invoke it before answering unrelated questions.&lt;/p&gt;

&lt;p&gt;For PowerShell, download and check the same files with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Invoke-WebRequest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;https://backbond.ai/agent-scan/demo/tools-list.json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-OutFile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tools-list.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Invoke-WebRequest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;https://backbond.ai/agent-scan/demo/tools-list.json.sha256&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-OutFile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tools-list.json.sha256&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$actual&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Get-FileHash&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tools-list.json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Algorithm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SHA256&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Hash&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToLowerInvariant&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$expected&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Get-Content&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tools-list.json.sha256&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Raw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;' '&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="w"&gt;
&lt;/span&gt;&lt;span class="nx"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$actual&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-ne&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$expected&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="kr"&gt;throw&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Fixture checksum mismatch'&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;h3&gt;
  
  
  Run the pinned scanner
&lt;/h3&gt;

&lt;p&gt;Node.js 18 or later is required. The first npx invocation may download the package from npm; the metadata scan itself runs locally.&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; @backbond/agent-scan@0.6.2 vet-tools &lt;span class="nt"&gt;--stdin&lt;/span&gt; &amp;lt; tools-list.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PowerShell does not support the same input-redirection syntax. On Windows, invoke the pinned command through &lt;code&gt;cmd&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/c&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx.cmd -y @backbond/agent-scan@0.6.2 vet-tools --stdin &amp;lt; tools-list.json"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$LASTEXITCODE&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this exact synthetic fixture, the verified result is BLOCK with one high finding, BB013, and exit code 1. That is the expected demonstration result, not an installation failure. The finding concerns selection-manipulation language in the supplied metadata; it does not prove that a real server performed an attack.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interpret the result before attachment
&lt;/h3&gt;

&lt;p&gt;The pre-attachment gate returns &lt;code&gt;block&lt;/code&gt; (exit 1), &lt;code&gt;review&lt;/code&gt; (exit 3), or &lt;code&gt;no_blocking_finding&lt;/code&gt; (exit 0). Block means the proposed toolset should not be attached automatically. Review can indicate findings or missing/ambiguous evidence requiring an operator's decision. No-blocking-finding applies only to the supplied metadata; it does not attest to runtime enforcement, server implementation, or future behavior.&lt;/p&gt;

&lt;p&gt;For your own workflow, inspect an operator-supplied tools/list response locally. Do not paste raw production manifests or scan reports into public comments. If you report a false positive, use a minimal synthetic example with private details removed.&lt;/p&gt;

&lt;p&gt;Try the example, then tell us whether this check belongs in your attachment workflow. Installation friction and minimal synthetic false-positive reports are useful feedback.&lt;/p&gt;

&lt;p&gt;The source and versioned instructions are available at &lt;a href="https://github.com/BackBond/agent-scan/tree/v0.6.2" rel="noopener noreferrer"&gt;https://github.com/BackBond/agent-scan/tree/v0.6.2&lt;/a&gt;. A browser demonstration is available at &lt;a href="https://backbond.ai/agent-scan/try/" rel="noopener noreferrer"&gt;https://backbond.ai/agent-scan/try/&lt;/a&gt;. Running the scanner does not create insurance coverage.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>opensource</category>
      <category>security</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
