<?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: Ismail Khouya</title>
    <description>The latest articles on DEV Community by Ismail Khouya (@ismail_khouya_4643b00c238).</description>
    <link>https://dev.to/ismail_khouya_4643b00c238</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%2F4048182%2Fcd7280bf-68e9-4b89-9bb7-4d83f986ebf8.png</url>
      <title>DEV Community: Ismail Khouya</title>
      <link>https://dev.to/ismail_khouya_4643b00c238</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ismail_khouya_4643b00c238"/>
    <language>en</language>
    <item>
      <title>I Built a Security Scorer for 213 MCP Servers — Here's What Made the Difference</title>
      <dc:creator>Ismail Khouya</dc:creator>
      <pubDate>Sun, 26 Jul 2026 16:52:35 +0000</pubDate>
      <link>https://dev.to/ismail_khouya_4643b00c238/i-built-a-security-scorer-for-213-mcp-servers-heres-what-made-the-difference-2hi4</link>
      <guid>https://dev.to/ismail_khouya_4643b00c238/i-built-a-security-scorer-for-213-mcp-servers-heres-what-made-the-difference-2hi4</guid>
      <description>&lt;p&gt;Every time I wanted to add an MCP server to Claude Desktop or Cursor, I ended up&lt;br&gt;
with a dozen browser tabs open, trying to answer one question the README never&lt;br&gt;
answers: &lt;strong&gt;is this actually safe to give tool-call access to my machine?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;MCP (Model Context Protocol) directories exist, but most of them just mirror&lt;br&gt;
GitHub — stars, a README excerpt, a copy-paste config. None of them score&lt;br&gt;
&lt;em&gt;risk&lt;/em&gt;. So I built &lt;a href="https://repoai.io" rel="noopener noreferrer"&gt;RepoAI&lt;/a&gt;, and I want to share the exact&lt;br&gt;
methodology, because I think it's more interesting than the product pitch.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with "just check the stars"
&lt;/h2&gt;

&lt;p&gt;Stars measure popularity, not safety. A server with 5,000 stars can still:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;have no read-only mode (every tool call can write/delete)&lt;/li&gt;
&lt;li&gt;ship with no auth method at all&lt;/li&gt;
&lt;li&gt;be an unmaintained fork nobody's patched in a year&lt;/li&gt;
&lt;li&gt;be archived — meaning whatever's wrong with it stays wrong, forever&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of that shows up in a star count.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 15 signals
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;computeSecurityScore()&lt;/code&gt; runs 15 checks against each server, sums signed point&lt;br&gt;
values, and clamps the result to 0–100. Two categories:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repo health&lt;/strong&gt; (max +101):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Points&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Official maintainer&lt;/td&gt;
&lt;td&gt;+18 / 0&lt;/td&gt;
&lt;td&gt;Vendor-published &amp;gt; random fork&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Editorially verified&lt;/td&gt;
&lt;td&gt;+5 / 0&lt;/td&gt;
&lt;td&gt;A human actually reviewed it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Actively maintained&lt;/td&gt;
&lt;td&gt;+12 / +6 / 0&lt;/td&gt;
&lt;td&gt;Last commit ≤90d / ≤365d / older&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Established contributor base&lt;/td&gt;
&lt;td&gt;+10 / +5 / 0&lt;/td&gt;
&lt;td&gt;Bus factor: ≥5 / ≥2 / 1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Community adoption&lt;/td&gt;
&lt;td&gt;+10 / +5 / 0&lt;/td&gt;
&lt;td&gt;Stars: ≥1000 / ≥100 / fewer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Has license&lt;/td&gt;
&lt;td&gt;+8 / 0&lt;/td&gt;
&lt;td&gt;Unlicensed = unclear usage terms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reasonable dependency footprint&lt;/td&gt;
&lt;td&gt;+5 / +2 / 0&lt;/td&gt;
&lt;td&gt;Smaller supply-chain surface&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Has homepage/docs&lt;/td&gt;
&lt;td&gt;+3 / 0&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Substantial README&lt;/td&gt;
&lt;td&gt;+5 / 0&lt;/td&gt;
&lt;td&gt;≥500 chars&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Archived&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0 / &lt;strong&gt;−40&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;No future fixes. Ever.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;MCP-specific:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Points&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Read-only mode available&lt;/td&gt;
&lt;td&gt;+15 / 0&lt;/td&gt;
&lt;td&gt;A safer way to run it should exist&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supports OAuth&lt;/td&gt;
&lt;td&gt;+10 / 0&lt;/td&gt;
&lt;td&gt;Stronger than static tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dangerous tools present&lt;/td&gt;
&lt;td&gt;0 / −10 / −25&lt;/td&gt;
&lt;td&gt;Share of tools flagged execute/delete/write&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dangerous tools, no safe mode&lt;/td&gt;
&lt;td&gt;0 / &lt;strong&gt;−20&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;The double penalty — risky &lt;em&gt;and&lt;/em&gt; no escape hatch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Weak or missing auth&lt;/td&gt;
&lt;td&gt;0 / −15&lt;/td&gt;
&lt;td&gt;Anyone with the config file can use it&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Scores land in three bands: 80–100 &lt;code&gt;safe&lt;/code&gt;, 60–79 &lt;code&gt;medium&lt;/code&gt;, 0–59 &lt;code&gt;high&lt;/code&gt; risk.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part I almost got wrong
&lt;/h2&gt;

&lt;p&gt;My first instinct was to let an LLM write the verdict &lt;em&gt;and&lt;/em&gt; set the score.&lt;br&gt;
That's a mistake — an AI can be convinced by good marketing copy in a README&lt;br&gt;
just as easily as a human can. So the pipeline splits it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;score&lt;/strong&gt; comes only from verifiable facts: GitHub metadata, license,
commit history, tool risk classification. No AI in that loop at all.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;verdict&lt;/strong&gt; (the human-readable "should you use this" paragraph) starts
as an AI draft grounded strictly in those same facts — then a human reads
it before it ever goes live. Nothing gets published on the strength of an
AI's opinion alone.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What it looks like end to end
&lt;/h2&gt;

&lt;p&gt;For a server like &lt;code&gt;qdrant/mcp-server-qdrant&lt;/code&gt;, the pipeline:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Scrapes the repo (README, package.json, releases, commit history)&lt;/li&gt;
&lt;li&gt;Runs the 15 checks → a score (58, in this case — &lt;code&gt;medium&lt;/code&gt; risk, mostly
held back by no OAuth support and a moderate dependency footprint)&lt;/li&gt;
&lt;li&gt;Generates a ready-to-paste config for Claude Desktop / Cursor / VS Code / Windsurf&lt;/li&gt;
&lt;li&gt;Extracts its actual tool list and FAQs from the README&lt;/li&gt;
&lt;li&gt;Waits for a human to confirm the AI's draft summary before anything ships&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Where it stands today
&lt;/h2&gt;

&lt;p&gt;213 servers, 36 categories, all re-scraped and re-scored on a rolling basis&lt;br&gt;
so a score reflects last week's commit activity, not last year's.&lt;/p&gt;

&lt;p&gt;It's &lt;a href="https://repoai.io" rel="noopener noreferrer"&gt;open at repoai.io&lt;/a&gt; — MCP is the first layer, Claude&lt;br&gt;
Skills and the rest of the AI-tool ecosystem are next, same trust model.&lt;/p&gt;

&lt;p&gt;Curious what other people would want a security scorer to check for —&lt;br&gt;
what's bitten you when installing an MCP server?&lt;/p&gt;




</description>
      <category>ai</category>
      <category>webdev</category>
      <category>security</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
