Skip to main content

mcp-authscan logo

VATA, MCP Security Scanner

Tracked by Cyber Toolchain

Auth scanner for live MCP servers.

VATA checks the security posture of Model Context Protocol deployments. It runs in two modes.

Live endpoint assessment (active). Given an MCP server URL, mcp-authscan sends real HTTP requests to that running server and records what comes back. It discovers the OAuth surface through RFC 9728 protected-resource metadata and RFC 8414 authorization-server metadata, then runs nine authorization-server probes: issuer identity, resource binding, token endpoint Cache-Control, token endpoint CORS, JWKS key types, password grant rejection, PKCE S256, redirect URI exact match, and client authentication.

Repository scan (static). Given a GitHub repository URL, it reads the source instead of sending requests.

Want your own MCP server reviewed?

I run authorised, evidence-backed security reviews of MCP server deployments. You get a written report with every finding by severity, the request and response behind each one, and an explicit list of what was not tested.

Two ways in: a single-server review at $1,750, or a full assessment at $3,500 including one retest after you fix.

I only scan servers I hold written permission to test. Email lhmisme2011@gmail.com with the endpoint and who authorises it.

Authorized use

Every scan needs an authorization basis. The CLI refuses to start without --authorized-by and --auth-basis, and that validation runs before any network call, so an unauthorized run exits 2 having sent nothing.

Only point this at systems you own or are permitted to test.

Install

Python 3.11 or newer, including for the standalone scanner.

git clone https://github.com/LHMisme420/mcp-authscan.git
cd mcp-authscan
pip install -e ./mcp_authscan

Packaging metadata lives in mcp_authscan/pyproject.toml; the repository root is the web project. Build distributions with python -m build ./mcp_authscan --outdir ./dist.

Run

mcp-authscan api.example.com/mcp \
  --authorized-by "Your Name" \
  --auth-basis "written consent" \
  --contact "you@example.com"

What a probe reports

Every probe returns one record: status, HTTP status, the response headers captured, the body sha256, whether its prerequisite was met, and its declared limitation. A FAIL cannot be constructed without a severity and the endpoint it was observed on. EXCLUDED requires prerequisite_met: false plus a named prerequisite.

Statuses are PASS, FAIL, NOT_OBSERVED and EXCLUDED.

  • PASS: the response positively demonstrated the property.
  • FAIL: the response demonstrated the property is absent or broken.
  • NOT_OBSERVED: the request went out and the property was not demonstrated. A 404, 405, 5xx, timeout or HTML body is not a pass.
  • EXCLUDED: the probe was never sent because a prerequisite, such as a registered client, was missing.

Coverage is PASS plus FAIL over the in-scope set after exclusions. Excluded means never sent. Not observed means sent and not demonstrated.

Exit codes

  • 0 clean, no FAIL at or above --fail-on (default high)
  • 1 FAIL at or above --fail-on
  • 2 authorization validation failed, no network requests made
  • 3 target unreachable
  • 4 target is not a valid MCP server
  • 5 server not assessable, coverage incomplete or zero testable probes
  • 6 usage error

A FAIL at or above the threshold outranks incomplete coverage, so a run with both exits 1.

Validation

A negative control runs in CI as cors-scanner-tests: a deliberately bad fixture reports 1 finding, cors_origin_credentials_reflection, with four endpoints in evidence, and the good fixture reports 0.

Known limits

  • The nine probes assess the authorization server. They do not test the MCP resource endpoints themselves.
  • An endpoint prober cannot verify a three-party OAuth flow. Issuer binding is enforced client-side, so the probe checks what the metadata declares, not what a client will do.
  • PKCE S256 and redirect URI exact match need a registered client and report EXCLUDED without one.
  • No source review, no dependency CVE check, no secrets-in-history scan.
  • Absence of a finding is not proof of safety.

A version string is a claim. A response from the running server is a receipt.

Published findings

Credited reporter on GHSA-v693-3rfr-6q3q, critical DNS rebind protection bypass in microsandbox, fixed in 0.6.3. Credited reporter on GHSA-vqqp-x5qm-5qp4, client credentials redirected to an attacker-controlled authorization server in fastmcp, fixed in 4.1.2. Credited reporter on CVE-2026-60085, sandbox policy bypass in PraisonAI, rated high. Credited reporter on GHSA-q8pm-q3r2-q7cg, argument injection in mcp-shell-server.

Findings from the official MCP reference servers were reported to the maintainers in October 2026 and are awaiting publication. That analysis is pinned to modelcontextprotocol/python-sdk commit 9972c21 and package 2.2.0.

Versions

Tool version 1.1.1 and probe set 1.1.0 are versioned separately, so adding a probe never rewrites how a past report reads.

About

Independent AI security research by Leroy H. Mason, who also publishes as Elior Malak. GitHub: LHMisme420 · ORCID: 0009-0002-3115-534X Contact: lhmisme2011@gmail.com

Metadata

Release files for mcp-authscan 1.1.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mcp-authscan 1.1.5
File Size Uploaded Provenance Actions
mcp_authscan-1.1.5.tar.gz 181.7 kB Without provenance Details for mcp_authscan-1.1.5.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for mcp-authscan 1.1.5
File Interpreter ABI Platform Actions
mcp_authscan-1.1.5-py3-none-any.whl Python 3 none any Details for mcp_authscan-1.1.5-py3-none-any.whl

Total release size: 305.7 kB

Release files / mcp_authscan-1.1.5.tar.gz

Download URL mcp_authscan-1.1.5.tar.gz
Size 181.7 kB
Tags Source
SHA-256 checksum
How to use checksums
58948a4b6c5023c05bb7e11cc6f3421f9e6348f27b6a748c83f36b969972e34c
BLAKE2b-256 checksum
How to use checksums
c0c543f370e4d5ae73ea9f9d1d9ebdbb0911d158de0147a935c61c06b263d779
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Release files / mcp_authscan-1.1.5-py3-none-any.whl

Download URL mcp_authscan-1.1.5-py3-none-any.whl
Size 123.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dc23c951360529c52c99e5ac50c6c7ca78c53ef6646728c067b77bfdcd98e833
BLAKE2b-256 checksum
How to use checksums
bc69899443c6d35cc18e8feff2c3fb0d5988a92d02086256f84339be928404ff
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Security for mcp-authscan 1.1.5

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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