Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

Remote MCP endpoint scoring rubric

A remote server is a hosted endpoint you connect to but don’t run, so we score the connection, the operator, and the quality of what it exposes, verified where possible against a live MCP handshake.

Half the score is about the endpoint itself: endpoint security 40% and transport and reachability 10%. The other half is the shared core, scored the same way here as on a packaged server: schema quality and AI usability 18%, stability and change management 14%, tool coverage 8%, tool safety 6% and capabilities 4%. A clean, fully readable endpoint can reach 100.

Transport & reachability (10%)

Can we actually reach and speak MCP to the declared endpoint, and over which transport?

This is its own category. Until July 2026 transport modernity was scored inside capabilities, which made that category impossible to apply to a packaged server: a package always runs over stdio, and that says nothing about the package. Transport is a fact about how an endpoint is reached, so it now sits with endpoint security on the remote-only side, and capabilities became part of the shared core.

PassingNeeds a fix
A live MCP handshake completes over the declared transportWe couldn’t connect; the TLS certificate failed verification; the endpoint redirected instead of answering directly; it answered but didn’t complete an MCP handshake; it returned an HTTP error; no usable transport is declared; or only stdio is declared, which can’t run as a live remote endpoint → transport

An endpoint that requires authentication we don’t hold can’t have its transport verified; it scores 0 and counts against the score. Claim the server and verify ownership to lift it: a fixable gap, not a permanent fail.

Endpoint security (40%)

The transport and operator-accountability signals, checked against the relevant standards: TLS 1.2 or higher, HSTS (RFC 6797), and OAuth protected-resource metadata (RFC 9728).

AreaPassingNeeds a fix
TLSThe certificate is valid, in date, and uses a strong keyA weak key (partial credit), a protocol below TLS 1.2, an expired certificate, a hostname mismatch, an untrusted chain, or MCP served over plain HTTP → TLS
HTTPSHTTPS is enforced, with no plaintext access pathThe endpoint is reachable over plaintext HTTP → HTTPS
HSTSThe Strict-Transport-Security header is presentThe header is absent → HSTS
AuthorizationAuthorisation is enforced and advertised via RFC 9728 metadata, whether on connect or on tool callsA challenge with no discoverable route to a token, open access to a tool marked destructive, open access with only non-destructive tools (partial credit), or open access with tools that never declare whether they’re destructive → authentication
DNSSECThe domain’s records validate against the full chain to the rootDNSSEC is absent, or signatures are present but fail validation → DNSSEC

Capabilities (4%)

Does the server speak a current slice of the protocol? This category was rebuilt, then narrowed again when transport moved out of it: it now scores protocol-version recency and a UI-hint bonus, and nothing else. Both are read straight from the handshake, which is why this category applies unchanged to packaged servers too.

SignalPassingNeeds a fix
Spec versionA current or still-supported MCP spec version. We read it from server/discover where the server offers it, and fall back to the initialize handshake for pre-2026-07-28 serversAn outdated spec version, or one newer than any we recognise (unverifiable) → protocol version
UI hintUI / widget rendering support is advertised-

The UI hint is a pure bonus and not a trust or security signal, just a “cared-for” nicety: present raises the score, absent emits no signal at all, so a headless server is never docked for it. Signals that used to live here (transport modernity, primitive coverage, sampling/roots, structured output, auth support) are no longer scored here: transport moved to its own category above, and the rest were removed, because a declared primitive is a claim not a capability, sampling and roots are client capabilities a server shouldn’t advertise, and auth and structured output are each scored once elsewhere (endpoint security and tool coverage) rather than double-counted.

Schema quality & AI usability (18%)

How well an agent can actually understand and use the tools.

SignalPassingNeeds a fix
DescriptionsA high share of prompts and resources carry a non-trivial descriptionLow coverage → schema quality
ExamplesTools include usage examplesNo tool includes an example → schema quality
Clarity & footprintClear, AI-judged instruction quality, and lean tool/resource definitionsDefinitions over the context-window budget → schema quality

The description measurement here covers prompts and resources only. Tool and parameter descriptions are scored in Tool coverage, not counted twice. The second half of the clarity row guards the schema’s context-window budget: every tool and resource definition is loaded into the model’s context on each request, so we estimate the tokens those definitions use against a per-item budget. At or under budget scores full marks, and only genuine overspend decays the score.

An empty schema (no tools, prompts, or resources, so nothing to assess) scores as a fail, not inconclusive: a content-free server never gets credit for a “leanest possible” schema it never actually wrote. When we couldn’t read the schema at all, by contrast (the endpoint was unreachable, or it requires authentication we don’t hold), the checks are genuinely inconclusive: nothing could be assessed either way.

Tool coverage (8%)

Deterministic checks on the tool definitions themselves, computed directly from the captured schema (no AI judgement, unlike the clarity check in schema quality).

SignalPassingNeeds a fix
DescriptionsA high share of tools carry a non-trivial descriptionLow coverage → tool coverage
Parameter docsA high share of tool parameters carry a descriptionUndocumented params → tool coverage
Output schemaStructured output schemas are declared (credit-only)-

Tool and parameter descriptions are scored here and only here (schema quality covers prompts and resources), so no measurement is charged to two categories. The old naming-consistency signal was removed. Output schema is credit-only: declaring one raises the score and not declaring one never lowers it (outputSchema is optional). Parameter docs and output schema are each omitted rather than counted against a server that has no parameters or no output schema, so a small or output-less server is never penalised for a gap that isn’t a defect. When we couldn’t read the tools at all (the endpoint was unreachable, or it requires authentication we don’t hold) the category is inconclusive and scores 0 until we can.

Tool safety (6%)

Tool coverage asks whether your tool text is there. Tool safety asks what that text tells a host model to do. An agent never meets your server, it meets your server instructions, your tool names and titles, and the descriptions of your tools and their parameters, so every one of those strings is an instruction channel whether you meant it to be one or not.

SignalPassingNeeds a fix
Injection markersNo marker phrases or hidden characters in the captured textAn instruction override, an instruction to conceal the call, an instruction to read or send credentials, or hidden non-rendering content → tool safety
Destructive annotationsEvery tool whose name or description implies an irreversible operation declares destructiveHint and is not marked readOnlyHint: trueA destructive tool declaring nothing, or declaring readOnlyHint: truetool safety
Judged manipulationAn AI judge reads every captured unit of tool text and finds none written to manipulate the model reading itText addressed to the reader rather than describing the tool → tool safety

Half the category’s weight sits on the marker scan, a quarter on the annotation gap and a quarter on the judged reading. The marker scan is a fixed list of phrases and characters, not a classifier: it has no opinion about intent, so a phrase quoted inside your own text does not count, and a security server that documents the attacks it detects is describing one rather than performing one. The annotation gap is graded, not pass or fail, and scores the share of implied-destructive tools that declare themselves. The MCP spec treats an absent destructiveHint as true, so declaring it either way is the fix. The judged reading reuses the same per-tool judgement that schema quality already runs, so it costs no extra reading of your server.

Tool safety never caps a score: a finding here costs a few points and names the tool and field it found, rather than condemning the whole server. When we couldn’t read the tool text at all (the endpoint was unreachable, or it requires authentication we don’t hold) the category is inconclusive and scores 0 until we can.

Each signal can also be inconclusive on its own, and an inconclusive signal keeps its weight rather than being skipped. If we captured no inspectable text the marker scan reports that; if we captured no tools the annotation gap does; and if a component’s tool text has not been read by the judge, or has only partly been read, the judged signal reports unjudged rather than assuming it is clean. That last one is the common case on a component we have only just met, and it resolves by itself once the judgement lands. We would rather charge ourselves for a gap than certify text no model has read.

Stability & change management (14%)

Does the surface stay stable so agents don’t break?

This category is also scored on packaged servers, where it compares the versions we have captured rather than a live schema. See the package rubric for how that differs.

PassingNeeds a fix
No destabilising schema changes in the last 30 daysSchema churn: tool removals, breaking changes, or a dropped auth requirement → stability

Churn covers tool removals, breaking input/output changes, and a dropped authorization requirement between snapshots (a server that stops enforcing auth is a breaking security regression). Adding auth is an improvement and is never penalised. Credit ramps linearly over the observed window rather than waiting for a full 30 days: score = clamp(observedDays / 30 − penalty) × 100, so a clean young server earns partial credit from its first observed day and full marks once 30 days of steady history accrue. Destabilising changes subtract from whatever credit has accrued, which means a young server can never outscore its observation window. A server with no scan history at all still can’t be verified and scores 0 until its first snapshots land.

Written by Stuart Blackler · Last reviewed 29 August 2026.