Skip to main content

mcpscore

CI Coverage PyPI Python License

Lighthouse for MCP. Audit any MCP (Model Context Protocol) server and get a scored, actionable report in seconds.

MCP servers that break the spec fail in the worst place: silently, inside someone else's agent. A missing tool description, a stale protocol version, or an unencrypted endpoint never crashes your server. It makes agents pick the wrong tool, drop you from their registry, or leak traffic. mcpscore finds that before your users do. Deterministic, no API key, no sign-up.

pip install mcpscore
mcpscore https://mcp.deepwiki.com/mcp
Welcome to mcpscore!
Successfully connected to MCP server via Streamable HTTP: https://mcp.deepwiki.com/mcp
Transport: streamable-http
Starting the audit...
✅ Protocol version '2025-11-25' is one of the allowed versions
❌ Not using the latest protocol version: negotiated '2025-11-25', latest is '2026-07-28', and no stateless-lifecycle support was observed
✅ Server name is present: 'DeepWiki'
❌ Server title is not present in server info
✅ Declares the tools capability and serves 3 via tools/list
✅ Server uses HTTPS with valid TLS (TLSv1.3)
...
Audit finished. Final score: 78/91
Spec: 2025-11-25 negotiated (latest: 2026-07-28) · era: legacy
Readiness for MCP 2026-07-28: 3/13 (informative — not part of the main score; 4 of 21 checks assessed)

Every ❌ is one thing to fix, and every result cites the spec section or best practice it enforces. Full docs: docs.mcpscore.dev.

Audit any server, in any language

# A local Python or Node server — the transport is detected automatically
mcpscore path/to/server.py
mcpscore path/to/server.js

# Any other language: --stdio runs a command and consumes the rest of the line,
# so put every mcpscore option before it
mcpscore --stdio ./my-go-server
mcpscore --stdio java -jar server.jar

# Pass config to the server with --env; for secrets use the value-less form,
# which copies from your environment and keeps the value out of the report
API_KEY=... mcpscore --env API_KEY --stdio ./my-go-server

# A remote server (Streamable HTTP or SSE, detected automatically)
mcpscore https://your-server.example/mcp

# Behind OAuth or an API key: bring a token, or let --oauth open the browser
mcpscore https://your-server.example/mcp --token "$TOKEN"
mcpscore https://your-server.example/mcp --oauth

With uv installed: uvx mcpscore <target>. Node users can run npx @mcp-box/mcpscore <target> with uv or pipx also on PATH; the npm package launches the Python engine. See the npm setup guide. Guides: authenticated servers, CLI reference.

Use it in CI

# Machine-readable report on stdout; logs go to stderr
mcpscore https://your-server.example/mcp --json > report.json

# Failed rules as SARIF, for GitHub code scanning (upload with github/codeql-action/upload-sarif)
mcpscore https://your-server.example/mcp --sarif mcpscore.sarif

# Fail the build when the score drops below 80%
mcpscore https://your-server.example/mcp --fail-under 80

# After the audit, actually call your own server's tools and check they behave
mcpscore path/to/server.py --smoke

Rules that don't apply to your server, or matter more to you, go in a mcpscore.toml next to your code: off turns a rule off, a severity name re-ranks it, and [gate] fail_on = "high" fails the build on any failed rule counted in the main score at or above it. It changes the score in your CI only, never the badge. Details: configure rules.

Exit code Meaning
0 Audit completed and every gate passed
1 Audit never ran: usage error or a failed --oauth flow
2 Could not connect to the server
3 --fail-under or --fail-under-readiness threshold not met
4 A --smoke check failed (3 wins when both fail)

The GitHub Action wraps this into one step that gates the pull request and posts the report as a comment. Smoke mode explains what --smoke calls and why it never changes the score.

What the score measures

Each rule has a severity and a weight. Passing rules add their weight, and the score is reported as earned/maximum. Rules that cannot apply to your server are skipped and excluded from the maximum, never failed.

Severity Weight Example
CRITICAL 5 Protocol version, server name, TLS
HIGH 3 Server version, valid tool schemas
MEDIUM 2 Titles, descriptions, error hygiene
LOW 1 Capability extras, transport recommendations

105 rules run today, in four categories:

  • Protocol (17 rules): protocol version, server name, title and version, advertised capabilities, transport. SSE-only servers get migration advice.
  • Primitives (50 rules): tools, prompts, resources, and resource templates. Names, titles, descriptions, JSON Schema validity, URIs, MIME types, annotations, and pagination behavior. These decide whether an agent picks the right tool and calls it correctly.
  • Security & Auth (11 rules): TLS version and certificate, error responses that leak data, and for auth-gated servers the OAuth posture: the WWW-Authenticate challenge, RFC 9728 resource metadata, the RFC 8414 authorization-server chain, and PKCE enforcement.
  • Readiness (21 rules): how ready the server is for the 2026-07-28 spec revision, on its own axis. Servers already on the new stateless lifecycle get these points counted in the main score. Legacy servers see them as guidance.

Six separate Packaging rules score a published npm or PyPI listing with --package npm:name or --package pypi:name. The package is read from the registry and never downloaded or run, and its score has its own denominator.

How it all fits together: scoring methodology. Every rule with its weight and the spec revisions it applies to: rules reference.

JSON report

--json writes one JSON document to stdout. rule_id values are stable across releases and are the key to build tooling on. Names and messages can be reworded.

{
  "schema_version": 1,
  "mcpscore_version": "1.11.0",
  "target": "https://mcp.deepwiki.com/mcp",
  "transport": "streamable-http",
  "score": 78,
  "max_score": 91,
  "partial": false,
  "spec": { "negotiated_version": "2025-11-25", "latest_version": "2026-07-28", "era": "legacy" },
  "results": [
    {
      "rule_id": "protocol_version_allowed",
      "severity": "CRITICAL",
      "severity_value": 5,
      "passed": true,
      "message": "✅ Protocol version '2025-11-25' is one of the allowed versions",
      "details": {
        "basis": "MCP 2025-11-25 Lifecycle §Version Negotiation (server MUST respond with a version it supports)"
      }
    }
  ]
}

What is stable and what moves between releases: stability contract.

Score badge

Every server audited on mcpscore.dev gets a badge URL keyed by the server URL, and a report link keyed the same way. Embed it once and it shows the latest score forever.

[![mcpscore score](https://mcpscore.dev/api/v1/servers/badge.svg?url=https%3A%2F%2Fyour-server.example%2Fmcp)](https://mcpscore.dev/s?url=https%3A%2F%2Fyour-server.example%2Fmcp)

The report page on mcpscore.dev has this snippet prefilled for your server. Details: score badge.

When it fails

Error connecting to the MCP server: https://... (exit 2)

  • Cause: the URL answered, but not as an MCP endpoint. The log above it shows the legacy handshake failing and the modern-only probe finding nothing.
  • Fix: point at the MCP endpoint itself, usually ending in /mcp.

Server script not found: ./server.py (exit 2)

  • Cause: the path does not exist relative to where you ran the command.
  • Fix: check the path. For non-Python, non-Node servers use --stdio <command>.

A local server starts and then the audit hangs or exits 2

  • Cause: the server's runtime is not on PATH, or it needs an environment variable it did not get.
  • Fix: run the command yourself first. Pass config with --env NAME=VALUE, secrets with --env NAME.

PARTIAL score: 24/27 from 10 of 78 checks

  • Cause: the server answered 401 and you passed no credential, so only the auth, TLS, and transport surface was scored.
  • Fix: pass --token, --header, or --oauth. See authenticated servers.

A rule flags a protocol version mcpscore does not recognize

  • Cause: your server is newer than the installed mcpscore.
  • Fix: upgrade, and if it persists, open an issue with the version.

Requirements

  • Python 3.11 or newer.
  • For local servers, the server's own runtime on PATH: Node.js for .js targets, Python for .py targets, and whatever --stdio names for the rest.

Use as a library

The package is fully typed (py.typed). MCPClient connects and collects, MCPAuditor runs the rules and builds the same report the CLI prints.

Contributing

CONTRIBUTING.md covers the development setup and how to add a rule. MISSION.md says why the project exists. SECURITY.md is for security reports. CHANGELOG.md lists every release. Bugs and ideas go to GitHub issues.

License

MIT. See LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcpscore-1.14.2.tar.gz (328.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcpscore-1.14.2-py3-none-any.whl (186.3 kB view details)

Uploaded Python 3

File details

Details for the file mcpscore-1.14.2.tar.gz.

File metadata

  • Download URL: mcpscore-1.14.2.tar.gz
  • Upload date:
  • Size: 328.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for mcpscore-1.14.2.tar.gz
Algorithm Hash digest
SHA256 bca81212cdc24c8a0ab1612efa990e444ebdfd935366e04d94e4ebe2555f2795
MD5 6fedebb7ba8ededd97aa8e0fb641c2d0
BLAKE2b-256 f3cb3f48d077a44a48aa24d5ce587bed3a69b6433100414bc4ef42f5e87343af

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcpscore-1.14.2.tar.gz:

Publisher: publish.yml on mcp-box/mcpscore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mcpscore-1.14.2-py3-none-any.whl.

File metadata

  • Download URL: mcpscore-1.14.2-py3-none-any.whl
  • Upload date:
  • Size: 186.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for mcpscore-1.14.2-py3-none-any.whl
Algorithm Hash digest
SHA256 1b613dbc2a1c7e19dc44b8839e50f126eed3518624ba5d6876aa55e77ad2536d
MD5 1ccc6a334a744d86a1e79b48160cf56c
BLAKE2b-256 e3efe86abe3fa6245dfd39eec4951bc8701714238e809c5443695da0013555f9

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcpscore-1.14.2-py3-none-any.whl:

Publisher: publish.yml on mcp-box/mcpscore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

1.18.0

2 files

1.17.0

2 files

1.16.0

2 files

1.15.0

2 files

This release

1.14.2 This release

2 files

1.14.1

2 files

1.14.0

2 files

1.13.0

2 files

1.12.1

2 files

1.12.0

2 files

1.11.2

2 files

1.11.1

2 files

1.11.0

2 files

1.10.0

2 files

1.9.0

2 files

1.8.0

2 files

1.7.0

2 files

1.6.0

2 files

1.5.0

2 files

1.4.0

2 files

1.3.0

2 files

1.2.0

2 files

1.1.1

2 files

1.1.0

2 files

0.9.0

2 files

0.8.0

2 files

0.7.0

2 files

0.6.0

2 files

0.5.1

2 files

0.5.0

2 files

0.4.0

2 files

0.3.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page