Methodology

What MCPCheckup actually checks, how each finding turns into a penalty, and how the per-axis scores combine into the final grade.

← back to the scanner

The core idea

An MCP server's tool descriptions, parameter descriptions, and connection-time instructionsaren't passive documentation — they're text injected directly into an LLM's context, read and acted on before a human ever sees it. MCPCheckup treats "quality" accordingly: alongside conventional checks (does it connect, is TLS valid, is there a license), it specifically looks for content engineered to manipulate the model reading it, and for shapes that make an agent's job harder (bloated context, missing safety hints, dishonest capability claims).

Scoring axes

Every check belongs to exactly one of four axes. Each axis is scored independently from 0–100, then the overall score is a weighted average of the four axis scores.

Security

45%

Whether the server, and the context it injects into an LLM, can be trusted. This axis carries the most weight because a malicious or compromised MCP server can manipulate any agent connected to it, regardless of how well it behaves on every other axis.

Reliability

25%

Whether the server does what its handshake claims: it connects, negotiates a protocol version, and honestly reports the capabilities it lists in `initialize`.

Agent Ergonomics

20%

Whether the server's tools, resources, and prompts are well-shaped for an LLM to consume: not too costly in context tokens, with metadata that helps an agent reason about what's safe to call.

Governance

10%

Whether basic operational/legal information about the server is published.

How penalties work

Each axis starts at 100. For every check in that axis, MCPCheckup subtracts a penalty for the check's overall status, plus a penalty for every individual finding it raised, based on severity. The result is clamped to 0–100.

To avoid over-penalizing servers with many tools, the combined penalty from a single check's minorfindings (info / low / medium) is capped at 20 per check — flagging the same small issue across ten tools can't drain an axis on its own. High and criticalfindings are never capped: those are the ones meant to be able to tank a score. Informational findings carry no penalty at all — they're surfaced for review, not scored.

Check statusPenalty
error-15
warning-5
ok-0
skipped-0
Finding severityPenalty
critical-35
high-20
medium-10
low-4
info0

Grades: A ≥ 90, B ≥ 75, C ≥ 60, D ≥ 40, F below 40 — applied to the final weighted score.

Every check

Connectivity & Handshake

Reliability

Can MCPCheckup establish an MCP connection at all, and how fast?

  • · Attempts an MCP handshake over Streamable HTTP, falling back to SSE.
  • · Records the transport used, handshake latency, server info, declared capabilities, and any server instructions.
  • · If the connection fails outright, every other check downstream is skipped or marked accordingly — a server that can't be reached can't be scored on anything else.

Protocol Version

Reliability

Which version of the MCP spec did the server negotiate?

  • · Compares the negotiated protocol version against the latest version known to the SDK.
  • · Flags servers that fail to negotiate any version.
  • · Surfaces an informational note about upcoming spec changes so server operators know what's coming.

Tools, Resources & Prompts

Reliability

What does the server expose, and does it match what it claimed to support?

  • · Lists tools, resources, resource templates, and prompts.
  • · "Capability honesty": if the server's `initialize` response declares a capability (e.g. "tools") but the corresponding list call (`tools/list`) fails, that's flagged as a finding — the server is lying about what it supports. Simply not declaring a capability is not penalized.

Security Heuristics

Security

Is the model-facing text trying to manipulate the LLM reading it, and is the transport secure?

  • · Tool descriptions are model-facing context, not documentation for a human — an LLM reads them before it ever decides which tool to call. This check scans tool descriptions, individual parameter descriptions, and the server's connection-time `instructions` for prompt-injection phrasing (e.g. "ignore previous instructions", "do not tell the user", fake `<system>` tags).
  • · Scans the same text for hidden/invisible Unicode characters (zero-width spaces, bidirectional overrides) that can hide instructions from a human reviewer while remaining fully readable to the model.
  • · Flags tool names/descriptions that suggest a sensitive capability (code execution, filesystem writes, arbitrary network requests, privilege escalation) so reviewers know to check the actual access scope. This is informational only — having a capability isn't a flaw, so it carries no score penalty.
  • · Flags tools with little or no description, since an unreviewable tool is a smaller version of the same problem.
  • · Flags plain HTTP transport (no TLS), since traffic — including any auth tokens — travels unencrypted.

Network & TLS

Security

Is the transport layer itself sound?

  • · Checks the TLS certificate's validity window, flagging expired or soon-to-expire certificates.
  • · Checks for common HTTP security headers (HSTS, X-Content-Type-Options, X-Frame-Options, CSP).
  • · Flags a wide-open CORS policy (`Access-Control-Allow-Origin: *`), which lets any website call the server from a browser context.

Change History

Security

Has anything changed since the last time MCPCheckup scanned this exact server?

  • · This is the only check that compares a scan against the past, and it exists specifically to catch "rug pulls": a tool an agent already trusts by name silently starts doing something different.
  • · Each scan is stored (when a database is configured). On the next scan of the same target, the current tool list is diffed against the most recent prior scan.
  • · A tool whose description or input schema changed since the last scan is flagged at high severity — nothing about a live MCP connection otherwise signals that change to an agent that already trusts the tool.
  • · Added tools, removed tools, and significant score drops since the last scan are also reported, at lower severity.
  • · Shows as "skipped" on the first scan of a target (nothing to compare against yet), or if no database is configured for this deployment.

Context Footprint

Agent Ergonomics

How many tokens of context does this server's manifest cost on every single turn?

  • · Every tool, resource, resource template, and prompt the server declares gets serialized into the model's context before the conversation even starts — on every turn, whether or not any of it gets used.
  • · Counts tokens (via a GPT tokenizer) for the combined manifest and flags large totals at two thresholds (warning, then error).
  • · Separately flags individual tools whose own description/schema are unusually verbose, since trimming those pays off regardless of overall manifest size.

Annotations & Schema Quality

Agent Ergonomics

Can an agent reason about whether a tool call is safe, and is the input schema even valid?

  • · Tool annotations (`readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint`) are hints an agent's planner uses to decide whether a call needs confirmation or can be retried safely. A tool with none of these declared gives the agent nothing to reason about.
  • · Cross-checks a tool's name/description against its annotations: a tool that looks destructive ("delete", "wipe", "purge"...) but explicitly declares `destructiveHint: false` is actively misleading, which is worse than declaring nothing.
  • · Flags self-contradictory annotation combinations (e.g. `readOnlyHint: true` and `destructiveHint: true` at once).
  • · Validates that each tool's `inputSchema` is actually a well-formed JSON Schema (via Ajv) — an invalid schema means clients that validate arguments before calling the tool may reject every call, or skip validation entirely.

Usage Terms & Licensing

Governance

Are the usage terms for this server published anywhere?

  • · A remote MCP server is a hosted service, not a GitHub repo, so a LICENSE file at the domain root (a source-repo convention) is rarely the right signal. This check treats a LICENSE file, a Terms of Service page, and a Privacy Policy page as equally valid evidence that usage terms exist, probing common paths for each (`/LICENSE`, `/terms`, `/privacy`, etc.).
  • · Also checks whether the server's connection-time instructions mention a license, terms of service, or privacy policy.
  • · Separately checks for a `/.well-known/security.txt` vulnerability disclosure policy, which gives security researchers a clear way to report issues responsibly.
  • · Both findings are informational: missing usage terms or a missing security.txt don't heavily penalize the score, but are flagged as unclear/missing governance signals.

Monetization Signals (x402)

Governance

Does the server document a pay-per-call model (e.g. the x402 protocol)?

  • · MCPCheckup never invokes a server's tools, so it can never observe an actual HTTP 402 response. This check instead looks for the server documenting a pay-per-call model in text an agent would already read: tool names/descriptions and connection-time instructions.
  • · Looks for mentions of the x402 protocol, stablecoin/USDC payment language, "pay-per-call" pricing, or explicit HTTP 402 references.
  • · Purely informational and never penalizes the score: a paid tool is not inherently riskier than a free one, but it's useful for an agent operator to know a call may cost real money before it's made.
← back to the scanner