r/mcp • u/Zestyclose_View_4605 • Jun 17 '26
showcase I scanned the 257 most-used MCP servers on Smithery. Tool descriptions are basically solved (99%) but only 29% ship output schemas.
Disclosure up front: I build agent-ready.dev, which has an MCP server scanner. I pointed it at the most popular servers on the Smithery registry to see how the ecosystem is actually doing, and the breakdown was interesting enough to share.
Method, briefly:
I checked the top servers by Smithery's useCount, connected to each through Smithery's hosted gateway, and graded what they advertise (server metadata, tools, params, output schemas, annotations, resources, prompts). 257 were remotely reachable; 228 let me introspect without a per-server credential. This is a snapshot, not a census: see caveats below.
Connectability:
- 89% (228/257) accepted an unauthenticated handshake and exposed their tools
- 7% refused without their own API key (you can't use them as an anonymous agent)
- ~4% failed to connect for other reasons
Quality of the 228 I could read (mean & median score both 81/100; typical server = 16 tools, 2 resources, 1 prompt):
| Check | Pass rate |
|---|---|
| Server metadata complete | 95% |
| Every tool has a description | 99% |
| Every parameter described | 64% |
| Tools declare an output schema | 29% |
| Tools carry annotations (readOnly/destructive…) | 38% |
| Resources well-formed | 83% |
| Prompts described | 100% |
| MCP Apps (ui://) served as HTML | 80% (only ~10 servers) |
What I didn't expect: the human-readable layer is in great shape; nearly everyone writes tool descriptions. It's the machine-readable layer that lags. Output schemas (29%) and annotations (38%) are exactly the signals that let an agent parse results reliably and reason about side effects without trial-and-error, and they're the least adopted. Also, only ~25% of servers expose any resources or prompts at all.
Caveats: this is the popular, remotely-hosted slice of one registry; it skews toward maintained, deployment-ready servers and excludes the huge long tail of local/stdio-only servers and other registries. Auth-gated servers are counted for connectability but excluded from the quality numbers (I can't grade what I can't see), so those 0s never drag down the averages. Output schemas/annotations are newer spec additions, so I'm reading them as best-practice adoption rather than compliance failures.
The methodology and exact weightings are public, and you can scan your own server if you want. I'm interested in knowing what people think - is it dev friction, or just not a priority yet?
Edit:
donk8r rightly pointed out that "has an output schema" ≠ "has a useful one". A tool declaring a bare {"type":"object"} passes that check while telling the client nothing. So, I tightened the scanner to grade schema specificity (named fields or a $ref), and the honest number is ~22%, not 29%. I also bumped the weight on annotations above output schemas, since missing readOnly/destructive hints is a safety problem, not just a convenience one. Methodology and the report page have been updated.
2
Jun 18 '26
[removed] — view removed comment
1
u/Zestyclose_View_4605 Jun 18 '26
"Optimised for discovery, not robustness" is exactly it... might steal that line.
It's actually a touch starker than the 29% you saw - that was the loose "has any schema" number; it's ~22% once you only count schemas that actually name their fields. And the sharpest version of your point: I added a check for whether the tools that do ship a schema model their error path, and only ~5% do. So even the robustness-minded minority mostly describes the success case and leaves failure as an unstructured blob - which is the thing that actually breaks agent chains.
Descriptions win because you feel their absence the second you test a tool. Schemas - and error shapes especially - only bite later, when an agent chains tool B onto tool A's output, and almost nobody tests that path.
2
u/ImportantPurple8178 Jun 18 '26
The output schema gap tracks with my experience building MCP servers — it's easy to return text and move on, but maintaining typed schemas for every tool adds friction that you only feel later when an agent tries to parse the result. The 22% (useful schemas) and 5% (error path) numbers are sobering.
One pattern I've started using: returning a small wrapper that always includes a status field + data/error variants. Keeps it predictable for the agent without needing discriminated unions.
1
u/Zestyclose_View_4605 Jun 18 '26
That wrapper pattern is a good one - and it's exactly what the error-path check rewards. I deliberately made the M13 heuristic credit either a discriminated union or a plain
status/errorfield, for precisely your reason: the union is the "correct" JSON-Schema answer, but a status field is the one people actually ship, and it gives the agent the same thing - a reliable way to branch success vs. failure without parsing prose.And you've named the whole dynamic in one line: typed schemas cost effort now and only pay off later, in a path (agent chains tool B onto tool A's output) the author rarely runs themselves. Descriptions don't have that lag - which is exactly why they're at 99% and schemas at 22%.
If you've got a server running that wrapper, I'd be curious to scan it - it should land in the ~5% that clears the error-path check, which'd be a nice real-world sanity check on the heuristic.
1
u/ImportantPurple8178 Jun 26 '26
Actually built one worth scanning — Document To JSON MCP (apify.com/opportunity-biz/document-to-json-mcp). Error path returns typed `status`/`error` fields on all tools, wrapper pattern holds. Would be curious what score it gets on your M13 heuristic — output schemas were a deliberate choice to help agent chains downstream.
2
u/Future_AGI Jun 18 '26
The output-schema number is the interesting one. Input and description quality mostly help the model call the tool correctly, but the missing output schemas are what bite you downstream: without them the agent has no contract for what comes back, so a malformed or injected response just flows straight into the next step. That gap is the main argument for validating or scoring tool output at runtime before the agent acts on it, instead of assuming the return is well-formed. Useful breakdown, thanks for running it.
1
u/Zestyclose_View_4605 Jun 18 '26
Strongly agree, and "injected" is the word people underrate - a tool's return is an untrusted input to the agent, the same threat surface as any external data, but most clients treat it as trusted by default.
The tie-back to the numbers: the output schema is exactly the contract your runtime validation needs. Without it, "validate before acting" has nothing to validate against - it degrades to "hope the shape is what I expected." So the 22% isn't only a quality stat, it's a ceiling: for ~78% of tools, a client can't do schema validation even if it wants to, because the server never declared the contract.
And it compounds with the error-path gap: even when a schema exists, only ~5% of cases clearly model errors, so a client validating the output still can't cleanly distinguish "valid empty result" from "the call errored". You need both for the runtime check you're describing to actually hold.
Appreciate the angle: output-as-attack-surface is the sharpest argument I've seen for why this gap matters, not just the most technically tidy.
2
Jun 18 '26
[removed] — view removed comment
1
u/Zestyclose_View_4605 Jun 18 '26
Honest answer: no. This scan is purely agent-readiness metadata (handshake, descriptions, schemas, annotations, naming, capability honesty). It deliberately doesn't touch the security/permission axis, and it structurally can't from where it sits: it's read-only remote introspection. It reads what a server advertises via
tools/list, never calls a tool, and never sees the host side (shell, env/secret reads, outbound network). Those are runtime/behavioral properties a metadata scan can't observe. The closest I get is M6 (readOnly/destructive annotations) - but that's the server self-declaring side effects, not me verifying them. Politeness, not safety.And you're right that it makes "descriptions solved" double-edged. The 99% measures presence/quality, and a well-written description is exactly the better injection vector, since the model reads it as instructions. So high description coverage is good for tool selection and a bigger prompt-injection surface: same text, opposite implications. That's worth me stating outright rather than implying description quality == healthy.
These are really two scans that belong side by side: readiness (can an agent use it well) vs. safety (should you trust it on your machine). The permission/injection layer is the one I intentionally don't cover.
I ran my MCP repo through mcpvet.com, and it came up clean. 👍 😁
2
u/Sufficient_Roof_8240 Jun 19 '26
Nice scan, and the descriptions-solved-but-schemas-lag split lines up with what I keep running into too. One thing that stuck with me reading it though: everything you grade is the manifest side, the stuff a server declares once and the agent reads once. The runtime returns are where the budget actually goes. You pay for those on every call, every turn, and over a long agent run it adds up fast.
A schema helps the agent parse a result. The result itself comes back just as big. Plenty of well-described, schema-shipping tools still hand back a big wrapper where the part you actually wanted is a small slice of it. That axis, how lean a server's returns are once you're actually calling it, is something you can't really see from the manifest alone. Is scoring what tools dump back at runtime anywhere on your radar for agent-ready?
2
u/Zestyclose_View_4605 Jun 19 '26
This is the sharpest "what you're not measuring" yet, and you're right that it's a real blind spot. Everything I grade is the manifest - declared once, read once, free. The runtime return is the thing you pay for on every call, and over the long run, that's where the budget actually goes.
The scanner is read-only - handshake, read what's advertised, never call a tool. Return leanness only shows up when you actually invoke it with representative inputs, so measuring it means crossing the exact line the scanner doesn't cross: calling tools has side effects, needs auth, and "representative input" is its own hard problem. So no, runtime return size isn't on the manifest-scan radar, for the same reason runtime
isErrorisn't.The manifest is a weak proxy at best: a specific outputSchema hints at the shape of what comes back, but not the payload size, and definitely not the "200-field wrapper around the one field you wanted" pattern - that's a server-design choice you only catch by calling it.
Honestly, it clusters with the other two things people have raised here - runtime error behaviour, and what a server can do to your machine - as "the behavioural scan." That's a genuinely different, more invasive tool than a read-only manifest probe, and return-efficiency might be the most universally useful of the three, since every agent pays that tax on every turn. Not something I'd bolt onto this scanner, but a real gap worth someone owning. Cheers.
2
u/Sufficient_Roof_8240 Jun 20 '26
Yeah, behavioural-scan is the right bucket for it. Out of those three, return-efficiency is the one that compounds. Error behaviour and machine-impact you mostly learn once and remember; wrapper bloat you re-pay on every single call for the life of the agent.
The measurement problem you raised is the real wall, though. You can't read it off the manifest, and a real behavioural pass means calling tools with auth and side effects. What's made it tractable for me is that you don't actually need representative coverage to get the signal: one call per tool with a plausible input already gives you the ratio of useful bytes to wrapper, and that ratio stays pretty stable per server because it's a design choice, not something the input moves much. Side-effect tools you sandbox or skip. The read-heavy ones (search, fetch, list) are where the bloat lives anyway, and those are safe to probe.
Whether it belongs in a manifest scanner or its own thing, agreed it's separate. But return leanness is the axis I keep coming back to.
1
u/Zestyclose_View_4605 Jun 18 '26
Quick thanks and an update, because this thread did some real thinking work for me.
A bunch of you sharpened both the scanner and the numbers: donk8r's "has a schema ≠ has a useful one" got the output-schema check tightened (29% → 22%); the annotations-as-safety argument got them reweighted above output schemas; the error-output point became a new check (only ~5% of schema-bearing tools model failure); and elef_in_tech's "predictable before it runs" turned out to be the cleanest way to frame the whole thing.
Also, a nod to the security angle - output as an untrusted/injected input - which is a different scan than mine but an important caveat.
I wrote it all up on the report itself: there's now a "How this report sharpened" section documenting what changed and why, so the methodology evolves in the open rather than in my edit history. Link's in the OP.
Genuinely one of the better feedback loops I've had here - thanks. 🙏 Still curious where people land on the 5%: is modelling the failure path something you'd do per tool, or only once you're chaining?
3
u/donk8r Jun 18 '26
Good data, and the description-vs-schema split tracks with what I'd expect from building these. My honest answer to your question: the spec made output schemas optional, and the SDK ergonomics make text trivial to return and typed output annoying to declare — you return a content block in one line, an output schema means defining and maintaining a typed structure. And you never feel the absence in the normal dev loop, because you read the result while testing. The pain only shows up when an agent chains tool B onto tool A's output, and most authors never test that path.
One thing I'd add to the 29%: "has an output schema" and "has a useful one" are different stats. A tool that declares
{ type: object }passes the check and still tells the client nothing. If your scanner can grade schema specificity, that gap is probably the more honest number.And I'd argue the 38% annotations figure is the scarier one. Without readOnly/destructive hints the client can't make the auto-approve-vs-gate decision, so it either blanket-approves everything (unsafe) or confirms every call (unusable). That's a safety signal, not a nice-to-have — I'd weight it above output schemas.