<?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: Tanvith Reddy</title>
    <description>The latest articles on DEV Community by Tanvith Reddy (@safemcp).</description>
    <link>https://dev.to/safemcp</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3949797%2F8924b8a8-e87f-4ce5-bc40-f0672bdf6a1b.png</url>
      <title>DEV Community: Tanvith Reddy</title>
      <link>https://dev.to/safemcp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/safemcp"/>
    <language>en</language>
    <item>
      <title>How I built a directory of 28,577 MCP servers</title>
      <dc:creator>Tanvith Reddy</dc:creator>
      <pubDate>Mon, 25 May 2026 02:39:44 +0000</pubDate>
      <link>https://dev.to/safemcp/how-i-built-a-directory-of-28577-mcp-servers-32m8</link>
      <guid>https://dev.to/safemcp/how-i-built-a-directory-of-28577-mcp-servers-32m8</guid>
      <description>&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;mcp server discovery is a mess. you find a server on some github awesome-list, open the repo, realize it hasnt been touched in 8 months. the aggregator sites show a fraction of whats actually out there and most of them filter their listings down to whatever they can hand-curate. and there's no way to browse by what a server actually does, so you end up with 12 tabs open trying to figure out which postgres-mcp-wrapper actually works.&lt;/p&gt;

&lt;p&gt;i wanted a flat searchable index of every MCP server that exists publicly, sorted by what they do. so i built one.&lt;/p&gt;

&lt;h2&gt;
  
  
  The scanner
&lt;/h2&gt;

&lt;p&gt;scanner pulls candidates from github code search + the github api, plus a few aggregator sites that publish their listings. dedupes by owner/name. each candidate gets run through a classifier that confirms the repo actually implements MCP and isnt just mentioning it in the readme, then assigns a category and pulls a description.&lt;/p&gt;

&lt;p&gt;went with gemini via openrouter for the classifier. tried claude and gpt for spot checks, agreement rate was high enough that flash was fine for the bulk pass and way cheaper at this volume. total classifier spend ended up around $8 for the full 30k+ candidate pool.&lt;/p&gt;

&lt;p&gt;scanner reruns continuously so newly released servers show up in the index within a few days.&lt;/p&gt;

&lt;h2&gt;
  
  
  The frontend choice
&lt;/h2&gt;

&lt;p&gt;three options here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;pure static&lt;/strong&gt;: prerender all 28k server pages at build time. dead on arrival because cloudflare workers free tier has a 20,000 static asset limit. id be over the cap before i even shipped.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pure SSR&lt;/strong&gt;: every page hit goes through the worker. fine for small sites but every visit pays a worker invocation, and i wanted infra cost to stay at $0.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;hybrid (what i picked)&lt;/strong&gt;: prerender the ~100 pages that matter (home, browse, search, about, 95 category pages) into static html. the 28k per-server pages are dynamic, query cloudflare D1 (free SQLite at the edge) on first request, then cloudflare's CDN caches the rendered html for 24h. after the first hit, popular server pages are as fast as static.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;astro hybrid mode + @astrojs/cloudflare adapter handles this cleanly. one template, one route file, scales to as many servers as D1 can hold.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two gotchas that bit me
&lt;/h2&gt;

&lt;h3&gt;
  
  
  D1's 100KB statement limit
&lt;/h3&gt;

&lt;p&gt;initial export script batched INSERTs at 500 rows per statement. wrangler immediately threw SQLITE_TOOBIG. turns out D1 caps a single statement at 100KB. dropped the batch size to 50 rows per INSERT and the generated sql file grew to ~570 statements. fine, just have to know the limit exists, its not in the obvious place in their docs.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;.assetsignore&lt;/code&gt; for &lt;code&gt;_worker.js&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;astro's cloudflare adapter outputs both &lt;code&gt;_worker.js&lt;/code&gt; (the SSR entrypoint) and your prerendered html into the same &lt;code&gt;dist/&lt;/code&gt; directory. wrangler then tries to upload &lt;code&gt;_worker.js&lt;/code&gt; as a static asset, which (a) eats one of your 20k asset slots and (b) usually fails the size check. fix is a single &lt;code&gt;.assetsignore&lt;/code&gt; file in &lt;code&gt;public/&lt;/code&gt; listing &lt;code&gt;_worker.js&lt;/code&gt; and &lt;code&gt;_routes.json&lt;/code&gt;. took an hour to find because the error messages dont point at it.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;28,577 verified MCP servers indexed&lt;/li&gt;
&lt;li&gt;95 categories&lt;/li&gt;
&lt;li&gt;30k+ views on the launch post, #1 in r/mcp on day 1&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's not great
&lt;/h2&gt;

&lt;p&gt;about 20% of servers land in an "other" bucket. MCP itself is new enough that a lot of servers are too niche to slot into the 95 categories i defined, and too different from each other to spin up their own category. i show that openly on the home page instead of hiding it.&lt;/p&gt;

&lt;p&gt;the 0-100 score on each server is metadata based (popularity + description quality + multi-source presence). its a discovery signal, not a security audit, so review code before connecting anything that touches your data.&lt;/p&gt;

&lt;p&gt;solo project, no SLA. if it breaks i fix it when i see the email.&lt;/p&gt;

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

&lt;p&gt;site is at safemcp.info. free, no signup, no rate limit. if you've published an MCP server and its categorized weird or theres one i missed, email &lt;a href="mailto:hello@safemcp.info"&gt;hello@safemcp.info&lt;/a&gt;, i read everything.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>automation</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
