<?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: Teng</title>
    <description>The latest articles on DEV Community by Teng (@tengbyte).</description>
    <link>https://dev.to/tengbyte</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%2F4034846%2F02e3dd95-564f-416e-ac40-e80271f27cbb.jpg</url>
      <title>DEV Community: Teng</title>
      <link>https://dev.to/tengbyte</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tengbyte"/>
    <language>en</language>
    <item>
      <title>I lint-scanned 36 popular MCP servers. A third of them are failing your agent.</title>
      <dc:creator>Teng</dc:creator>
      <pubDate>Wed, 22 Jul 2026 06:22:03 +0000</pubDate>
      <link>https://dev.to/tengbyte/i-lint-scanned-36-popular-mcp-servers-a-third-of-them-are-failing-your-agent-102d</link>
      <guid>https://dev.to/tengbyte/i-lint-scanned-36-popular-mcp-servers-a-third-of-them-are-failing-your-agent-102d</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://tengli.dev/posts/mcp-servers-failing-agents.html" rel="noopener noreferrer"&gt;tengli.dev&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Your MCP server can be 100% spec-compliant and still be unusable by an agent.&lt;/p&gt;

&lt;p&gt;The Model Context Protocol spec tells you how to &lt;em&gt;transport&lt;/em&gt; tools: JSON-RPC framing, capability negotiation, schema shapes. It says nothing about whether a model can actually &lt;em&gt;use&lt;/em&gt; what you serve — whether it picks the right tool out of your catalog, fills the arguments correctly, or burns 8k tokens parsing your schemas on every single request.&lt;/p&gt;

&lt;p&gt;I integrate first- and third-party MCP connectors into a production AI agent for a living, and I kept seeing the same failure: servers that pass every compliance check, yet the model calls the wrong tool, hallucinates arguments, or ignores the tool entirely. The problems were never in the protocol layer. They were in the parts no one lints: descriptions, naming, schema design.&lt;/p&gt;

&lt;p&gt;So I wrote &lt;a href="https://github.com/TengByte/mcpgrade" rel="noopener noreferrer"&gt;mcpgrade&lt;/a&gt; — a Lighthouse-style scorecard for MCP servers. One command, no API key, report in seconds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx mcpgrade &lt;span class="nt"&gt;--stdio&lt;/span&gt; &lt;span class="s2"&gt;"npx -y your-mcp-server"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I pointed it at 36 popular servers. It did not go great.&lt;/p&gt;

&lt;h2&gt;
  
  
  The results
&lt;/h2&gt;

&lt;p&gt;Full sortable table: &lt;a href="https://tengli.dev/mcp-leaderboard.html" rel="noopener noreferrer"&gt;https://tengli.dev/mcp-leaderboard.html&lt;/a&gt;. The short version (static analysis, point-in-time snapshot; servers marked &lt;em&gt;(archived)&lt;/em&gt; are unmaintained reference implementations, included because they're still widely installed and copied):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Top of the class (A):&lt;/strong&gt; brave-search &lt;em&gt;(archived)&lt;/em&gt;, exa, google-maps &lt;em&gt;(archived)&lt;/em&gt;, slack &lt;em&gt;(archived)&lt;/em&gt;, perplexity-ask, @shopify/dev-mcp, @apify/actors-mcp-server, airbnb, figma-developer-mcp, tavily, gitlab &lt;em&gt;(archived)&lt;/em&gt;, elastic, shrimp-task-manager, and more — 15 of 36.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bottom of the class (D/F), 11 of 36 — and it's not hobby projects:&lt;/strong&gt; MongoDB's official server (66, with 66 errors), Notion's official server (62), Airtable (69, 66 errors), todoist-mcp-server (67, &lt;strong&gt;110 errors&lt;/strong&gt;), GitHub's archived reference server (67, 44 errors), and firecrawl-mcp at the very bottom (57, &lt;strong&gt;134 errors&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;Two more servers (Stripe, Supabase) couldn't be scanned with dummy credentials and were excluded rather than graded.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding 1: the ecosystem has an undocumented-parameter epidemic
&lt;/h2&gt;

&lt;p&gt;Almost every D/F server has a &lt;strong&gt;descriptions score of zero&lt;/strong&gt; while its schema, naming, and token scores are fine. One rule dominates: &lt;code&gt;D004 — parameter has no description&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;firecrawl: 132 of its 134 errors are undocumented parameters. &lt;code&gt;url&lt;/code&gt;, &lt;code&gt;formats&lt;/code&gt;, &lt;code&gt;jsonOptions&lt;/code&gt; — the model gets a name and a type, nothing else. todoist: 110. MongoDB and Airtable: 66 each.&lt;/p&gt;

&lt;p&gt;The root cause is visible in the source of nearly all of them: &lt;strong&gt;schemas are generated from zod or OpenAPI definitions, and nobody adds &lt;code&gt;.describe()&lt;/code&gt;&lt;/strong&gt;. The type system knows &lt;code&gt;url: string&lt;/code&gt;. The model needs to know &lt;em&gt;which&lt;/em&gt; URL, in what format, with what constraints. Your schema generator is quietly stripping the single most important signal your tools have.&lt;/p&gt;

&lt;p&gt;If you take one thing from this post: open your server, count the parameters without a &lt;code&gt;description&lt;/code&gt;, and fix them. It's the highest-leverage hour you can spend on agent reliability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding 2: it's documentation discipline, not catalog size — but size makes discipline harder
&lt;/h2&gt;

&lt;p&gt;My first pass at this data suggested "small catalogs win": most 95+ scorers have few tools, and the 24–26 tool servers cluster at D/F. Then shrimp-task-manager scored &lt;strong&gt;A/96 with 15 tools&lt;/strong&gt; — carefully documented, tightly named, every description distinct.&lt;/p&gt;

&lt;p&gt;So the honest version: &lt;strong&gt;well-documented big catalogs are possible; they're just rare.&lt;/strong&gt; Every tool you add is another description to write, another name that can collide, another schema to keep tight. Discipline doesn't scale by default. (Size still taxes you either way: the full catalog is serialized into every request.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding 3: compliance and usability are different axes
&lt;/h2&gt;

&lt;p&gt;The most-updated servers aren't the most usable ones. The &lt;em&gt;archived&lt;/em&gt; Slack reference server — code nobody maintains — scores A/97, because someone once documented every tool and every parameter by hand. Meanwhile several actively-developed commercial servers ship parameters with no descriptions at all.&lt;/p&gt;

&lt;p&gt;Agent usability is a &lt;em&gt;writing&lt;/em&gt; problem more than an engineering problem. Compliance checkers can't measure it. That's the gap mcpgrade fills.&lt;/p&gt;

&lt;p&gt;(One hopeful counterpoint: while writing this, context7 shipped a new version that fixed all its missing parameter descriptions — jumping from C to a perfect static score. The ecosystem can move fast when the gap is visible.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding 4: I checked the static scores against a real model. The scary number is refusal.
&lt;/h2&gt;

&lt;p&gt;Static lint is a proxy, so I built &lt;code&gt;--eval&lt;/code&gt;: it synthesizes realistic single-step tasks (each embedding concrete values for every required parameter), shows a model the full catalog, and measures whether it picks the right tool and fills valid arguments. Calibration details and methodology: &lt;a href="https://github.com/TengByte/mcpgrade/blob/main/docs/eval-calibration.md" rel="noopener noreferrer"&gt;docs/eval-calibration.md&lt;/a&gt;. Cost: pennies per server on a small model.&lt;/p&gt;

&lt;p&gt;Two results worth your attention:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Static findings predict live confusion.&lt;/strong&gt; On well-documented servers, tool-selection accuracy was 100%. On firecrawl it dropped to 84% — and the misses land &lt;em&gt;exactly&lt;/em&gt; on the naming collisions static rules flag: &lt;code&gt;extract&lt;/code&gt;↔&lt;code&gt;scrape&lt;/code&gt;, &lt;code&gt;agent_status&lt;/code&gt;↔&lt;code&gt;check_crawl_status&lt;/code&gt;, &lt;code&gt;feedback&lt;/code&gt;↔&lt;code&gt;search_feedback&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Big fuzzy catalogs break refusal.&lt;/strong&gt; Given deliberately out-of-scope tasks, the model correctly declined 100% of the time on small, well-documented catalogs — but only &lt;strong&gt;50% of the time&lt;/strong&gt; on firecrawl's 26 fuzzy tools. Half the time it "found" a plausible tool and called it. In production, that's an agent doing &lt;em&gt;something&lt;/em&gt; when it should do &lt;em&gt;nothing&lt;/em&gt; — arguably the most dangerous failure mode there is.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "good" looks like
&lt;/h2&gt;

&lt;p&gt;From the top scorers, a checklist:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every tool description answers three questions: what it does, when to use it, what it returns.&lt;/li&gt;
&lt;li&gt;Every parameter has a description with format and one example value.&lt;/li&gt;
&lt;li&gt;Fixed value sets live in &lt;code&gt;enum&lt;/code&gt;, not in prose.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;required&lt;/code&gt; is declared explicitly — even when it's empty.&lt;/li&gt;
&lt;li&gt;One naming convention, verb_object style, no generic verbs, no near-twin names.&lt;/li&gt;
&lt;li&gt;Errors name the missing/invalid parameter so the model can self-correct in one turn.
## Try it on your server
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx mcpgrade &lt;span class="nt"&gt;--stdio&lt;/span&gt; &lt;span class="s2"&gt;"node ./my-server.js"&lt;/span&gt;   &lt;span class="c"&gt;# local stdio&lt;/span&gt;
npx mcpgrade https://my-server.example/mcp    &lt;span class="c"&gt;# streamable HTTP&lt;/span&gt;
npx mcpgrade &amp;lt;target&amp;gt; &lt;span class="nt"&gt;--fail-on&lt;/span&gt; error         &lt;span class="c"&gt;# CI gate&lt;/span&gt;
npx mcpgrade &amp;lt;target&amp;gt; &lt;span class="nt"&gt;--eval&lt;/span&gt;                  &lt;span class="c"&gt;# live model test (BYO key; any OpenAI-compatible endpoint works)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;24 rules, each with a concrete fix and a rationale you're welcome to dispute in the issues — the ruleset is opinionated by design, and I'd rather have the argument in public. (How this differs from mcp-lint and other MCP QA tools — with side-by-side outputs: &lt;a href="https://github.com/TengByte/mcpgrade/blob/main/docs/comparison.md" rel="noopener noreferrer"&gt;docs/comparison.md&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;If you maintain one of the servers above and fix your score, open a &lt;code&gt;rescan&lt;/code&gt; issue — I'll happily re-run and update the table. PRs to your own servers beat arguments with my ruleset.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I build production AI agent integrations at a large tech company; mcpgrade is a personal project and reflects scars from integrating dozens of MCP connectors. No affiliation with any server ranked above.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>mcp</category>
      <category>devtools</category>
    </item>
  </channel>
</rss>
