100% free · instant API key

MCP Security API

Scan an MCP server's tools.json manifest, a published npm / PyPI package, a GitHub repository, or a live remote MCP endpoint (OAuth-protected servers included) over a single HTTPS request — and get back an auditable A–F Trust Score with every finding and its evidence as JSON. Completely free — grab a key and start scanning in seconds.

The API runs the same deterministic engine as the open-source MCP Trust Checker CLI: no LLM in the loop, no telemetry, and the same input always produces the same score. Use it to gate CI, power a marketplace listing, or check a server before you connect it to your data.

The API is completely free

Access is free — there is nothing to buy and no card to add. Calls are authenticated with an API key, and you get one instantly: fill in the short form and your key works right away. No waiting for approval.

  • No cost
  • No credit card
  • Commercial use allowed
  • Instant — no waiting

Quick start

Every scan carries your API key — only /health is open. Get one free with the button above — it works immediately.

curl https://mcptrustchecker.com/api/v1/scan/npm/@modelcontextprotocol/server-filesystem \\ -H 'Authorization: Bearer YOUR_API_KEY'

Or scan a manifest you already have:

curl -X POST https://mcptrustchecker.com/api/v1/scan/manifest \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ --data-binary @tools.json

Endpoints

Base URL https://mcptrustchecker.com/api/v1. Every response is application/json. Two unversioned aliases are kept for older integrations — /api/health and /api/scan/manifest — but new code should use the /api/v1 paths.

POST /scan/manifest

Scans a JSON body: a tools.json manifest or a raw tools/list result. Fully offline — nothing is fetched. Best for private or self-hosted servers.

FieldTypeNotes
bodyJSON objectRequired. Max 512 KB. Arrays and scalars are rejected.
curl -X POST https://mcptrustchecker.com/api/v1/scan/manifest \ -H 'Content-Type: application/json' \ -d '{"tools":[{"name":"read_file","description":"Read a file from disk."}]}'
GET /scan/npm/{package}

Fetches the published npm artifact, verifies it against the registry-declared hash, and analyses the exact source you would install — in memory, without installing or executing anything. Scoped names and pinned versions are supported.

PathExamples
{package}left-pad · @upstash/context7-mcp · [email protected]
curl https://mcptrustchecker.com/api/v1/scan/npm/@upstash/context7-mcp
GET /scan/pypi/{package}

The same deep scan for PyPI: resolves the sdist (or wheel), verifies its SHA-256, and reads the shipped Python source.

curl https://mcptrustchecker.com/api/v1/scan/pypi/mcp-server-fetch
GET /scan/github/{owner}/{repo}

Scans a GitHub repository directly — for MCP servers not published to npm or PyPI, or when you want to grade the source on the default branch. The engine downloads the repository archive, reads its real source in memory (never executed), and returns the same A–F Trust Score. The download is size-capped and the working copy is deleted after every scan.

curl https://mcptrustchecker.com/api/v1/scan/github/upstash/context7
POST /scan/remote

Scans a live remote MCP server by URL — the growing class of servers that ship as a hosted endpoint rather than a package, so there is nothing to download. The scanner connects over Streamable-HTTP (with SSE fallback), enumerates the real tool surface and grades it. Pass accessToken for a server behind a bearer or OAuth token; it is used for that request only and never stored.

Coverage is live, not source. A remote scan reads only what the wire exposes: tool poisoning, capability blast radius and cross-tool toxic flows are all detected, but the implementation is never fetched. The grade is not directly comparable to a package scan — the report states this in coverage.

Guarded. https only, no embedded credentials, and the host must still be public after DNS resolution — a hostname that resolves to a loopback, private, link-local or cloud-metadata address is refused, and every redirect hop is re-checked.

curl -X POST https://mcptrustchecker.com/api/v1/scan/remote \\ -H 'Authorization: Bearer YOUR_KEY' \\ -H 'Content-Type: application/json' \\ -d '{"url":"https://mcp.deepwiki.com/mcp"}'
GET /badge/{registry}/{package}

Returns a shields.io endpoint payload — the grade, the score and the colour — for the package's current Trust Score. Like every other /api/v1 call it is authenticated, so shields.io cannot fetch it directly; for a README badge use the keyless registry badge at /registry/{slug}/badge.svg instead.

![MCP Trust Score](https://img.shields.io/endpoint?url=https%3A%2F%2Fmcptrustchecker.com%2Fapi%2Fv1%2Fbadge%2Fnpm%2Fleft-pad)
POST /registry/publish

Submits a package to the public MCP Trust Registry so everyone else can look it up before installing it. npm and PyPI packages only — no other ecosystem is listed yet. Scanning on its own never lists anything: this is a separate call, and it must carry explicit consent.

What you send is an application, not a verdict. The request carries the package identity and your consent — no report, no findings, nothing about your machine. mcptrustchecker.com re-scans the package with its own engine, and only that scan is ever published. A grade you computed locally may travel along as localGrade for comparison and can never become the listed grade — which is exactly what stops a key from publishing an "A" for a malicious package.

FieldTypeNotes
registrystringRequired. npm or pypi — anything else is rejected.
specstringRequired. The package name, e.g. @upstash/context7-mcp.
consentbooleanRequired, and must be exactly true. A truthy string is not consent.
categorystringOptional. A registry category slug; defaults to other.
versionstringOptional, informational.
localGradestringOptional, informational only — recorded for comparison, never listed.
curl -X POST https://mcptrustchecker.com/api/v1/registry/publish \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{"registry":"npm","spec":"@upstash/context7-mcp","consent":true}'

You get queued when the package enters the scan queue, or already-listed with its registry URL when it is already there. Re-submitting the same package never creates a duplicate — in the registry, in the queue or in the submission log.

{ "status": "queued", "registry": "npm", "spec": "@upstash/context7-mcp", "publicationId": 41, "message": "… was queued for scanning — it appears in the registry once our engine has graded it." }
POST /access/request

Issues an API key. This is what the button at the top of this page calls — use it directly if you would rather script it. The key is returned once and never stored in plaintext, so save it on the spot. No approval step: it is active immediately.

FieldTypeNotes
emailstringRequired. Where we would reach you about the key.
useCasestringRequired, up to 2000 chars. What you are building.
expectedVolumestringOptional, up to 120 chars.
turnstileTokenstringRequired only while the captcha is enabled — see /config below.
curl -X POST https://mcptrustchecker.com/api/v1/access/request \ -H 'Content-Type: application/json' \ -d '{"email":"[email protected]","useCase":"Gating MCP servers in CI"}'
{ "status": "active", "apiKey": "…", "message": "Save this key now — it is shown only once and works immediately." }

Answers 201. This endpoint is limited per IP address rather than per key, for obvious reasons: 10 requests per 10 minutes. An address that already has three requests on file gets 409 — contact support instead of minting more.

GET /config

Public runtime configuration, needed only if you build your own key-request form: whether the captcha is currently on and, if so, its site key. The secret key never leaves the server.

{ "turnstile": { "enabled": true, "siteKey": "0x4AAA…" } }

No API key required.

GET /health

Liveness, engine version and current scanner load. No API key, not rate limited — safe to poll from a monitor.

{ "status": "ok", "engine": "1.13.0", "methodology": "mcptrustchecker-1.13", "concurrency": { "active": 0, "queued": 0, "max": 12 } }
GET /registry/{slug}/badge.svg · badge.json

A badge for a server that is already listed in the registry, addressed by its registry slug rather than by package name — no scan is run, so it answers instantly and needs no API key. Note these two sit at the site root, not under the /api/v1 base above.

badge.svg returns a ready SVG image you can point an <img> at; badge.json returns the shields.io endpoint payload. Both send Access-Control-Allow-Origin: * and cache for an hour.

![MCP Trust Score](https://mcptrustchecker.com/registry/context7-mcp/badge.svg)

Use /api/v1/badge/{registry}/{package} above instead when the package is not in the registry — that one scans on demand.

The response

Every scan returns the same shape. Three independent axes answer three different questions.

Trust — A to FHow safe is this server for you to ADOPT? The threat score of its published code, adjusted down for blast radius, publisher verification and scan depth. Drives the 0–100 score.
Capability — minimal to criticalHow much damage if the model driving it is manipulated? A fact, not a verdict.
Coverage — live to emptyHow much the scan could actually inspect. A clean grade on a shallow scan is not an all-clear.
{ "tool": { "name": "mcptrustchecker", "version": "1.13.0", "methodologyVersion": "mcptrustchecker-1.13" }, "target": { "id": "@modelcontextprotocol/server-filesystem", "source": { "kind": "package" } }, "scannedAt": "2026-07-23T16:41:52.108Z", "score": { "score": 94, "grade": "A", "vector": [ … ], "categorySubtotals": { … } }, "capabilityProfile": { "level": "high", "tags": [ "sensitive-source", "file-write", "external-sink" ], "reasons": { … } }, "coverage": { "level": "source", "caveats": [ "Tools were statically extracted from the published source (14 recovered)…" ] }, "findings": [ { "ruleId": "MTC-FLOW-004", "title": "Sensitive-source and external-sink co-exist", "severity": "high", "confidence": "strong", "evidence": "sources [read_file, read_text_file, …] → sinks [write_file, move_file]", "location": { "kind": "flow", "name": "read_file → move_file" } } ], "toxicFlows": [ … ], "surfaceDigest": "a3f81c40e7b2…" }

Every point of the score is reconstructable. score.vector itemises each penalty — rule, severity, confidence multiplier and diminishing factor — so you can verify the grade rather than trust it.

Pricing, rate limits & fair use

The API is free and keys are issued instantly. A key exists so abuse can be stopped without punishing everyone else — not to upsell you.

ControlValue
PriceFree — all endpoints, including commercial use
API keyRequired — get one free, issued instantly
Rate limit120 requests/min per key (burst 120)
Request body512 KB maximum
Package scan cache15 minutes (repeat scans served instantly)
Timeout30s package scan · 10s manifest scan

Exceeding the rate limit returns 429 with a Retry-After header. When the scanner is saturated you may get 503 — retry shortly.

Not exposed by design. The hosted API will not spawn a process and will not connect to a caller-supplied URL — remote-code-execution and SSRF vectors respectively. To scan a live or private endpoint, run the open-source CLI locally: it does everything the API does, plus live stdio/HTTP scanning and OAuth sign-in, entirely on your machine.

Errors

StatusMeaning
400Invalid input — malformed JSON, not a valid registry package name, or a publish without consent: true.
401Missing or unrecognised API key.
403Key is not active.
404Unknown endpoint.
413Body larger than 512 KB.
429Rate limited. See Retry-After.
503Scanner saturated — retry shortly.
504Scan exceeded its time budget.
{ "error": { "status": 400, "message": "package must be a registry package name, not a URL" } }

Prefer to run it yourself?

The scanner is MIT-licensed and runs fully offline. Everything the API does — and more — works locally.

npx mcptrustchecker # scan every MCP server you already have installed npx mcptrustchecker scan ./tools.json # a manifest, offline npx mcptrustchecker scan <package> --online # read the real published source npx mcptrustchecker scan ./tools.json --sarif # SARIF for GitHub code scanning

Publishing from the CLI — arriving in the next release. It is its own command, not a flag on scan:

mcptrustchecker publish <package> --token YOUR_API_KEY

Scanning never publishes and never asks — not even with a key in the environment. The only way anything is submitted is by typing publish, and typing it is the consent, so there is no prompt to dismiss. Only npm and PyPI packages qualify; a missing key or a target with no registry identity fails before the package is downloaded.

Changelog

What changed on the hosted API, most recent first. The scanning engine is versioned separately — GET /health always reports the exact engine and methodology a scan ran under.

WhenWhat changed
2026-08-25
engine 1.13
Scanning engine upgraded to methodology mcptrustchecker-1.13. Verification is stricter about what it claims. A vendor tier now rests solely on ownership of the npm scope, which npm enforces at publish time — it is no longer inferred from the repository field a package declares about itself, which anyone could point at a well-known organisation. A package carrying build provenance keeps source: an attestation proves those bytes were built by a workflow, not whose. Provenance is also read for the version actually scanned rather than whatever npm tags latest, so a pinned scan no longer inherits a newer release’s attestation. No score or grade moves — the two tiers carry the same weight. Affects the verification field in every report.
2026-07-27
engine 1.12
Scanning engine upgraded to methodology mcptrustchecker-1.12 (reported by /health) — a detection and correctness release. Injection detection gained a decode ladder (a payload hidden behind base64, URL- or entity-encoding is now decoded and read), semantic shapes (MTC-INJ-SEM-1) that catch a paraphrased override no phrase pattern would match, and description ↔ schema coherence (MTC-INJ-SCHEMA-1). The scanned surface was widened to everything the model is actually handed: a payload in inputSchema.description is no longer invisible. Two scoring invariants were repaired — adding a finding can no longer raise a score, and a scan that inspected nothing no longer grades A. Grades move only where these detections fire; on a 40-package sample across every band, existing registry grades were unchanged.
2026-07-24
remote endpoints
Added POST /scan/remote — scan a live remote MCP server by URL, including servers behind OAuth (the online scanner runs the full discovery + dynamic client registration + PKCE flow and holds the token in memory for a single scan). Fetching a caller-supplied URL is the one SSRF surface in the API, so it is tightly guarded: https only, no embedded credentials, and the host must remain public after DNS resolution, re-checked on every redirect and OAuth-discovery hop. A remote scan reports coverage: live — the tool surface is read over the wire, the implementation is not.
2026-07-24
github + scanner
Added GET /scan/github/{owner}/{repo} — scan a GitHub repository directly, for MCP servers not published to npm or PyPI. The repository archive is downloaded (size-capped), read in memory and deleted after every scan; same deterministic A–F Trust Score as a package scan. Alongside it, a free online scanner now runs the same engine in the browser with no key — every result is a shareable link with a live Trust Score badge that works even before a server is listed.
2026-07-24
engine 1.9
Scanning engine upgraded to methodology mcptrustchecker-1.9 (reported by /health) — the largest accuracy improvement since the model was introduced, driven by a full-population audit of every grade across 30,000+ scanned servers. The headline: evaluating a runtime value is capability, not malice. MTC-SRC-010 (eval/new Function on a variable) moved to the capability axis, matching MTC-SRC-001 — it is what an honest code-runner, interpreter or template engine does, and scoring it charged one capability twice. Nothing was lost on the threat side: the assembled-command + eval dropper still scores, decode-then-execute droppers still score, and no weight, category cap, grade band or hard gate changed. Eight precision guards shipped alongside it — security scanners no longer flag their own detection patterns, bilingual descriptions are no longer read as homoglyphs, documented example keys and test fixtures are no longer "leaked secrets", and a server's own src/tools handlers are no longer excused as dev tooling. Every registry grade was recomputed under the new methodology.
2026-07-23
engine 1.8
Scanning engine upgraded to methodology mcptrustchecker-1.8 (reported by /health). Package scans now statically extract the tool surface from the published source, so the MCP-specific detectors — tool-poisoning, hidden-Unicode smuggling and cross-tool toxic flows — run on npm/PyPI packages, not only on a live server. Publisher verification gained a repo tier: a public, inspectable repository is the ecosystem norm and is discounted only lightly, distinct from a package whose source cannot be located. Injection precision was tightened after a per-rule false-positive audit — plain emphasis, ALL-CAPS acronyms, self-ordering prerequisites and detector/guard tools that merely quote an attack no longer raise a finding on their own. Every registry grade was recomputed under the new methodology.
2026-07-23
publishing
Added POST /registry/publish — submit a scanned npm or PyPI package to the MCP Trust Registry. A key is required and every submission carries explicit consent; the server re-scans the package itself, so a caller can never set a package's grade.
Per-key rate limit raised to 120 requests/min, request body cap raised to 512 KB, and the package-scan timeout tightened to 30s.
2026-07-22
launch
Deterministic scanning over one HTTPS request: /scan/npm, /scan/pypi and /scan/manifest, plus /badge and /health. Same engine as the open-source CLI — no LLM, and the same input always yields the same score.

Breaking changes, if any ever land, will be announced here before they ship. The endpoints above are stable; responses may gain new fields, so parse them leniently.

Frequently asked questions

Is there an API to check if an MCP server is safe?

Yes. The MCP Trust Checker API scans a Model Context Protocol server, a tools.json manifest, or an npm/PyPI package and returns an auditable A–F Trust Score as JSON, including every finding with its evidence. It is free to use; a free API key is issued on request.

How do I scan an MCP server with an API request?

POST your tools.json manifest to /api/v1/scan/manifest, or GET /api/v1/scan/npm/{package} to scan a published npm package. Both return the full JSON scan report with a Trust Score, Capability level and Coverage.

Is the MCP security API free?

Yes — the API is completely free. There is no cost and no credit card, including for commercial use. Access is authenticated with an API key, which is issued instantly from the API page: fill in a short form and it works right away. The key exists so abuse can be stopped without rate-limiting everyone else, not to charge you.

Does the MCP security API require an API key?

Yes. Requests are authenticated with a free API key. Get one from the API page — provide an email and a short description of your use case — and it works immediately, no approval wait. Send the key as "Authorization: Bearer " or "X-API-Key: ".

What does the MCP Trust Score measure?

The Trust Score is a 0–100 number with an A–F grade that answers one question: how safe is this MCP server for the user who wants to adopt it. It is computed in two deterministic, itemised stages — first a threat score from a penalty vector over threat findings (prompt injection, tool poisoning, hidden Unicode payloads, cross-tool toxic flows, supply-chain risk and rug-pull drift), then three small, subtract-only client-adoption-risk terms: the capability blast radius if the server were manipulated, how strongly the publisher is verified, and how much of the package the scan could inspect. Capability (blast radius) and Coverage are reported as their own axes.

Can the API scan a private or self-hosted MCP server?

The hosted API does not connect to caller-supplied URLs. To scan a private or self-hosted server, POST its tools.json manifest to the manifest endpoint, or run the open-source CLI locally with npx mcptrustchecker — it runs on your own machine and reaches nothing but the server you point it at.

Can I add a package to the MCP Trust Registry through the API?

Yes, for npm and PyPI packages: POST to /api/v1/registry/publish with "consent": true. Scanning alone never lists anything — publishing is a separate, explicit call. What you send is an application rather than a verdict: mcptrustchecker.com re-scans the package with its own engine and publishes that result, so a grade computed elsewhere can never become the listed one. Re-submitting the same package does not create a duplicate. The open-source CLI does the same with its own command: mcptrustchecker publish <package> --token YOUR_API_KEY. Scanning never publishes and never asks — publishing is a separate command, needs the same free key (or MCPTRUSTCHECKER_TOKEN), and ships in the next CLI release.

Request API access

Access is free and instant. Tell us what you are building, and your key is ready to use right away.