Version 1.0.0. Markdown ยท Check IDs
Knot Verified methodology v1.0.0
Knot Verified publishes what a probe measured about an MCP server. Anyone can re-run the probe and get the same facts.
What a listing shows
- A verdict: alive, degraded, dead or unverifiable.
- The checked-at time and the server version that was checked.
- Every check result, with the raw response, for the last 30 days.
- Latency, uptime and security facts. These are numbers and facts, not part of the verdict.
What Verified does not measure
- Popularity, stars or downloads. They appear beside a listing and never change it.
- Reviews or ratings.
- Source code quality.
- Usefulness.
- Anything judged by an LLM.
- Anything bought. Money, sponsorship and Knot's commercial programs never change a verdict, rank or badge.
Verdicts
A verdict follows mechanically from the check results below. No human edits it.
| Verdict | Rule |
|---|---|
| Alive | L0 passes. Every L1 check passes. Every L2 check that ran passes. |
| Degraded | L0 passes and at least one L1 check or one L2 check that ran fails. |
| Dead | L0 fails on three attempts in one run, 60 seconds apart, while the probe's own control check passes. |
| Unverifiable | The probe cannot check past L0, or cannot check at all, for a reason that is not the server's fault. See below. |
Unverifiable is a different status from a failure. An unverifiable server never gets a low or negative mark.
A server is unverifiable when any of these is true:
- It answers but requires credentials or OAuth. The listing shows that it is alive and which auth it asks for.
- It is a stdio server that cannot start without credentials or services the sandbox does not have.
- The probe's control check failed in the same run, so the probe cannot trust its own network.
Check layers
Each check is a yes or no. Each has a stable ID that appears in the raw results.
L0 Liveness
It tells you the server exists and speaks MCP, and nothing more.
| ID | Passes when |
|---|---|
L0.reachable | DNS resolves and the connection opens (remote), or the process starts (stdio). |
L0.tls | The TLS handshake succeeds with a valid certificate (remote only). |
L0.initialize | initialize returns a result within 10 seconds. |
L0.protocol_version | The result names a protocol version published in the MCP spec. |
L0.capabilities | The result includes a capabilities object. |
L1 Contract
It catches servers that handshake and then return garbage.
| ID | Passes when |
|---|---|
L1.server_info | serverInfo has a non-empty name and version. |
L1.envelope | Every response is valid JSON-RPC 2.0 with a matching id. |
L1.tools_list | tools/list returns, if the server declares tools. |
L1.tool_schemas | Every tool has a name and an inputSchema that is valid JSON Schema. |
L1.resources_list | resources/list returns valid entries, if the server declares resources. |
L1.prompts_list | prompts/list returns valid entries, if the server declares prompts. |
L1.unknown_method | An unknown method returns a JSON-RPC error with code -32601. |
L2 Behavior
It checks that the server does the right thing, using only safe calls.
| ID | Passes when |
|---|---|
L2.call_ok | A safe call returns a well-formed tool result. A result flagged as an error, or a -32602 refusal, still passes, because a harmless sandbox value can be rightly refused. A crash, a malformed reply or any other protocol error fails, unless the call used a made-up value such as a file path or an id. A server refusing a made-up value says nothing about it, so that call counts as untested. |
L2.output_schema | If the tool declares an outputSchema, the structured result validates against it. |
L2.bad_input | Arguments that break the tool's own schema return a clean error, not a crash or a success. |
L2.timeout | A call that does not finish within 30 seconds ends with a clean error or a closed request, not a hung connection. |
A tool with no safe call is marked behavior untested. It is never guessed at, and it does not fail the server.
L3 Reliability over time
L3 is published as numbers and is not part of the verdict in v1.
- Uptime: the share of checks where L0 passed, over 24 hours, 7 days and 30 days.
- Latency: p50 and p95 of
initializeand of safe calls, in milliseconds. - Flakiness: how often consecutive checks disagree.
- Version drift: the server's tools or schemas changed without a version change.
Verdict thresholds for L3 will be set from the distribution measured in the first sweep. They will be published with a methodology version bump before they affect any verdict.
L4 Security posture
L4 states facts and is never part of the verdict. A server that needs write access is not worse than one that does not.
- Transport: stdio, streamable HTTP or SSE.
- TLS version and certificate expiry (remote only).
- Auth model: none, bearer header, or OAuth with published discovery metadata.
- What the server declares: capabilities and the count of tools marked read-only, destructive or unmarked.
- Whether credentials are requested in the URL query.
Which calls are safe
The probe calls a tool only when all of these are true:
- The tool is annotated
readOnlyHint: trueand notdestructiveHint: true, or it is on the public reviewed allowlist. - Its name does not contain a word from the public mutation list (create, delete, update, write, send, post, execute, run, deploy and similar), and its description does not open with one.
- Every required argument can be built from the tool's own schema: a default, an enum value, a constant or a minimal example. Free-text arguments get a fixed harmless value.
At most five tools are called per run, in alphabetical order. Tools that fail any rule, or fall past the limit, are never called. The allowlist, the mutation list and the argument rules are public and versioned with the methodology.
Freshness
- Every verdict carries a checked-at time. It is shown next to the verdict and inside the badge.
- Full checks (L0 to L2) run every 24 hours. L0 runs every 6 hours.
- A verdict older than 48 hours is labeled stale. Older than 7 days, the verdict is hidden and the last known result is shown as history.
- A verdict belongs to one server version. A new version is checked again and the old version keeps its result as history.
Records and disputes
- Every check is stored with its timestamp, methodology version, probe version and raw results.
- A new check supersedes the old one. Old checks stay visible as history.
- Nothing is edited by hand. A dispute is settled by re-running the probe.
- To dispute a result, open the server's page and use Request a re-run. Give your email, the check you think is wrong and a short reason.
- A request never edits a result. A person reads the queue and the probe runs again. Whatever the new run measures is published, including the same result.
- Raw results of the latest check and of the last 30 days are public, so anyone can compare them to their own run.
- Older history, bulk export and the API are paid access. Paid access never changes a verdict, rank or badge.
Reproducing a check
- The probe is a standalone program. Its source, its version and the list of probed servers are public.
- It identifies itself in its User-Agent and probes each host at a limited rate.
- It runs from a datacenter address in one region. Results can differ from other regions.
- Stdio servers run in a container with no network secrets and no access to the host. Their package versions are pinned in the raw results.
Same rules for everyone
The same methodology checks every listing, including Knot's own server.
Changes to this methodology
- Versions follow major.minor.patch. The version is stored on every check.
- Changes never rewrite past checks.
- A change that can alter verdicts is a minor or major version, and it is announced here before it takes effect.
Known limits
- Servers behind OAuth are checked only as far as L0.
- The probe sees one region and one account-less client.
- A server that blocks datacenter addresses can look dead. The control check reduces this and cannot remove it.