Quality score
Trust answers “can I believe this listing”. Quality answers “is this a good MCP server to connect an agent to”. Both are transparent: the descriptor lists every check, its status and the evidence that decided it.
Checks run on what our credential-free, read-only probes observe. Tools are never called and no code audit is performed.
Categories and weights
Section titled “Categories and weights”| category | weight | what it looks at |
|---|---|---|
| protocol | 25 | 2026-07-28 support, stateless answers, legacy-only transports, cacheable tool lists (ttlMs) |
| auth | 15 | for OAuth servers: Protected Resource Metadata, authorization server metadata, CIMD versus the deprecated DCR; for every server: no secret in the URL |
| hygiene | 30 | tool descriptions present and concise, object input schemas, readOnlyHint or destructiveHint annotations, all four directory hints (readOnlyHint, destructiveHint, idempotentHint, openWorldHint; the Claude and OpenAI directories each require some of them) on every tool, the token cost of loading every tool, “an API mapped one endpoint per tool” |
| stability | 15 | tool changes in the last 30 days, and any tool that kept its name but changed most of its description |
| dependencies | 15 | for servers with an npm or PyPI package: known advisories in the resolved dependency graph (failing on a high or critical one that has a fix), the official MCP SDK’s own advisories, and whether the graph resolved completely |
Each check is pass (1 point), warn (half), fail (0) or na.
A category’s value is the average of its applicable checks; the score is the weighted average of the categories that apply.
Checks that do not apply leave the denominator, and a server with fewer than three applicable checks outside dependencies gets no score (null) rather than a flattering one: dependencies never score a server on their own, so a local-only package shows its dependency report without a score.
Stability only counts after a week of recorded tool history: not having seen a change yet is not evidence of stability.
Servers behind OAuth or an API key usually have no public tool list, so their hygiene and stability checks are na and the report says so.
Labels
Section titled “Labels”Next to the number, every server gets a plain-language label. Labels describe the signals above; none of them says a server is safe, and no audit is implied.
| label | when |
|---|---|
strong |
quality 90 or more and trust 75 or more |
good |
quality 75 or more |
needs work |
quality 40 to 74 |
poor |
quality under 40 |
new |
the server appeared in the registry less than 7 days ago |
not scored |
fewer than three checks apply (usually a local package or a remote nobody could probe) |
blocked |
the listing is on the blocklist |
The label is in the descriptor (_meta["dev.protogrid/quality"].label), in /quality, and in every search result as quality_label next to quality_score.
Colors on the portal and the badge use the same thresholds: green from 75, amber from 40, red below.
Where to find it
Section titled “Where to find it”- The descriptor’s
_meta["dev.protogrid/quality"]:score,components,checks(id, category, status, detail),drivers(-idfor failures,~idfor warnings),tool_count,token_estimate,tools_hash,tools_changed_at. GET /v1/servers/{name}/qualityadds the daily score for the last 90 days;GET /v1/servers/{name}/changeslists the tool-definition history (see the REST API).- Every server page on the portal has a Quality section with each check and its evidence, the token cost of the tool list and the latest tool-definition changes, with the description before and after.
tools_hashchanges whenever any tool’s name, description, schemas or annotations change: pin it to notice a change before your agent trusts the new definitions.
Every server has a public SVG badge with its current quality score, at https://protogrid.dev/badge/{name}.svg.
It follows the score within about five minutes and says not scored when too few checks apply.
When the server’s owner has claimed it, the badge adds an owner verified segment; add ?owner=0 to the image URL for the compact version.
Paste it into a README, linking to the server page:
[](https://protogrid.dev/servers/io.github.acme/acme-mcp)The server page has the snippet ready to copy under “Badge for your README”.
Dependencies
Section titled “Dependencies”For servers published as an npm or PyPI package, protogrid reads the dependency graph of the published version as a clean install would resolve it, and matches every package in it against known advisories. Nothing is downloaded, installed or run. Advisories are matched against every graph daily, so a newly published advisory shows up without the server changing. A new release is read right away; otherwise graphs are refreshed monthly, and daily for servers their owners claimed and monitor.
deps.known_vulnsfails when a package in the graph has a high or critical advisory (or is a known malicious package) and a fixed version exists, and warns on any other advisory; the evidence names the advisory, the package and whether it is a direct or indirect dependency.deps.mcp_sdk_versionlooks at the official MCP SDK (@modelcontextprotocol/sdkand its v2 packages on npm,mcpon PyPI) the same way and says which version to update to; its advisories are not counted again indeps.known_vulns.deps.resolvablewarns when the graph resolved with errors, because advisories may then be missing, and isnawhen the package version is not known to the resolver.
Remote-only servers have no package, so their dependency checks are na.
Data sources: dependency graphs from deps.dev and advisories from OSV.dev, including the GitHub Advisory Database and the PyPI Advisory Database, all under CC BY 4.0.