Metadata-Version: 2.4
Name: mcpvuln
Version: 0.3.0
Summary: Vulnerability detection for Model Context Protocol codebases, with a reproducible benchmark
Home-page: https://github.com/DINAKAR-S/Agentic-MCP-Scanner/
Author: Dinakar S
Author-email: dinakars2003@gmail.com
Project-URL: Homepage, https://github.com/DINAKAR-S/Agentic-MCP-Scanner
Project-URL: Source, https://github.com/DINAKAR-S/Agentic-MCP-Scanner
Project-URL: Issues, https://github.com/DINAKAR-S/Agentic-MCP-Scanner/issues
Project-URL: Changelog, https://github.com/DINAKAR-S/Agentic-MCP-Scanner/blob/main/CHANGELOG.md
Project-URL: Benchmark, https://github.com/DINAKAR-S/Agentic-MCP-Scanner/tree/main/mcp-scan/benchmark
Project-URL: Contributing, https://github.com/DINAKAR-S/Agentic-MCP-Scanner/blob/main/CONTRIBUTING.md
Project-URL: Security Policy, https://github.com/DINAKAR-S/Agentic-MCP-Scanner/blob/main/SECURITY.md
Project-URL: Release Notes, https://github.com/DINAKAR-S/Agentic-MCP-Scanner/releases
Keywords: security,vulnerability,analysis,mcp,model-context-protocol,ai,llm,benchmark
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Software Development :: Testing
Classifier: Environment :: Console
Classifier: Natural Language :: English
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: cvss==3.6
Provides-Extra: github
Requires-Dist: gitingest==0.1.4; extra == "github"
Provides-Extra: narrative
Requires-Dist: google-generativeai==0.8.5; extra == "narrative"
Requires-Dist: python-dotenv==1.1.1; extra == "narrative"
Provides-Extra: intel
Requires-Dist: firecrawl-py==2.16.3; extra == "intel"
Requires-Dist: python-dotenv==1.1.1; extra == "intel"
Provides-Extra: dev
Requires-Dist: pytest==8.4.2; extra == "dev"
Requires-Dist: pytest-cov==6.2.1; extra == "dev"
Requires-Dist: ruff==0.13.0; extra == "dev"
Provides-Extra: all
Requires-Dist: firecrawl-py==2.16.3; extra == "all"
Requires-Dist: gitingest==0.1.4; extra == "all"
Requires-Dist: google-generativeai==0.8.5; extra == "all"
Requires-Dist: python-dotenv==1.1.1; extra == "all"
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: keywords
Dynamic: project-url
Dynamic: provides-extra
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# mcpvuln

[![PyPI](https://img.shields.io/pypi/v/mcpvuln)](https://pypi.org/project/mcpvuln/)
[![Downloads](https://img.shields.io/pypi/dm/mcpvuln)](https://pypi.org/project/mcpvuln/)
[![CI](https://github.com/DINAKAR-S/Agentic-MCP-Scanner/actions/workflows/ci.yml/badge.svg)](https://github.com/DINAKAR-S/Agentic-MCP-Scanner/actions/workflows/ci.yml)
[![License](https://img.shields.io/badge/License-MIT-yellow)](https://github.com/DINAKAR-S/Agentic-MCP-Scanner/blob/main/LICENSE)
[![Python](https://img.shields.io/badge/python-3.9%2B-blue)](https://www.python.org/)

**A vulnerability scanner for Model Context Protocol codebases that proves how often it is wrong.**

MCP lets an agent discover and call tools at runtime, from servers somebody else operates. That moves the unit of trust from a single function call to a whole protocol session, and the failures that follow have no equivalent in ordinary application security: forged agent identities, trust scores computed but never enforced, audit logs that can be rewritten, one tenant's context served to another.

There are scanners already. What none of them ships is a way to tell how much of the output is real, because they are only ever evaluated against code known to be broken. This one ships a **benign control corpus** as well, so precision is measured rather than assumed.

```bash
pip install mcpvuln
```

## Try it in thirty seconds

```bash
git clone https://github.com/DINAKAR-S/Agentic-MCP-Scanner
mcpvuln Agentic-MCP-Scanner/demo/vulnerable   # 20 findings, 12 categories, all four layers
mcpvuln Agentic-MCP-Scanner/demo/safe         # 0 findings
```

The repository ships the **same MCP server twice**, with every vulnerability in the first one fixed in the second. The second command is the one that matters: any scanner finds planted bugs, but one that also fires on the corrected version is not measuring anything.

No API key. No network. Under a second.

## Measured, not claimed

**Precision, recall and F1** against a public ground truth of 22 documented vulnerabilities ([`benchmark/score_demo.py`](https://github.com/DINAKAR-S/Agentic-MCP-Scanner/blob/main/mcp-scan/benchmark/score_demo.py)):

| | TP | FP | FN | Precision | Recall | F1 |
|---|---|---|---|---|---|---|
| **All layers** | 19 | 0 | 3 | **1.000** | **0.864** | **0.927** |
| LLM | 1 | 0 | 0 | 1.000 | 1.000 | 1.000 |
| Traditional web | 5 | 0 | 0 | 1.000 | 1.000 | 1.000 |
| MCP | 11 | 0 | 1 | 1.000 | 0.917 | 0.957 |
| Agentic AI | 2 | 0 | 2 | 1.000 | 0.500 | 0.667 |

**False positives** on 285,463 lines of clean, officially maintained MCP code, where every finding is a candidate false positive ([`benchmark/`](https://github.com/DINAKAR-S/Agentic-MCP-Scanner/tree/main/mcp-scan/benchmark)):

| Version | Findings | Per 100 LOC |
|---|---|---|
| 0.1.0 | 3,642 | 1.28 |
| 0.2.0 | 23 | 0.008 |
| **0.3.0** | **38** | **0.013** |

A 96-fold reduction from 0.1.0, with fourteen more rules than 0.2.0. CI fails the build
if that rate rises above 0.05. The 2025-2026 CVE classes are scored on a second public
corpus, `demo/vulnerable-2026` (16 instances, 16 detected, 0 false positives on the fixed
half), kept separate so the 22-instance paper corpus above stays frozen.

## Usage

```bash
mcpvuln ./my-mcp-server                    # offline, no API key needed
mcpvuln https://github.com/org/repo        # ingest from GitHub
mcpvuln ./repo --json scan.json            # emit the scan contract
mcpvuln ./repo --min-confidence 0.7        # tighten the threshold
mcpvuln ./repo --fail-on high              # exit non-zero, for CI
mcpvuln --self-check                       # validate the rule set
```

**Detection needs no credentials.** No `GOOGLE_API_KEY`, no `OPENAI_API_KEY`, no network. Only the optional `--narrative` and `--threat-intel` reach out, and both degrade to a warning without their key.

### Extras

```bash
pip install "mcpvuln[github]"      # scan a GitHub URL directly
pip install "mcpvuln[narrative]"   # model-written analyst commentary
pip install "mcpvuln[intel]"       # external advisory lookup
pip install "mcpvuln[all]"         # all of the above
```

## What it detects

44 rules across four layers, each carrying a confidence prior and CVSS v4.0 base metrics.
Fourteen of them mirror MCP vulnerabilities published as CVEs in 2025 and 2026 (SSRF from
a tool's URL argument, argument injection into `git`, DNS-rebinding protection disabled,
all-interface binds, shared HTTP transports, line jumping, tool shadowing, invisible
Unicode); the mapping is in
[docs/cve-coverage.md](https://github.com/DINAKAR-S/Agentic-MCP-Scanner/blob/main/docs/cve-coverage.md).

| Layer | Covers |
|---|---|
| **MCP** | JWT verification disabled, weak HS256 secrets, agent-card auto-verification, audit-log mutation, privileged containers and `docker.sock` mounts, pipe-to-shell installs, tool-poisoning sinks, cross-tenant context bleed, plaintext transport |
| **Agentic AI** | Trust scores computed but never enforced as an authorisation floor, unscoped cross-agent memory queries, shell and REPL tools handed to an agent, unsigned goal mutation |
| **LLM** | Untrusted input concatenated into a system prompt, model context populated from a fetched or decoded remote source |
| **Traditional web** | Command injection, SQL injection, XSS, path traversal, hardcoded secrets, weak crypto, insecure RNG, unsafe deserialisation, dynamic execution |

## How it works

```
ingest  ->  detect  ->  score  ->  report
```

- **detect** is deterministic pattern matching over whole files, with comment, docstring and prose suppression, per-pattern case sensitivity, and a confidence score. No model.
- **score** computes CVSS v4.0 base scores through the [`cvss`](https://pypi.org/project/cvss/) implementation of the FIRST specification, and evaluates the SSVC deployer decision tree. Both are reproducible; the same finding scores identically on every run.
- **report** renders Markdown with no model call, including a plain-language summary per finding.

The boundary between stages is a versioned JSON **scan contract**. Save it with `--json`, diff it across commits, score it offline.

## What is not built yet

Stated plainly, because the gap between what a security tool claims and what it does is itself a security problem.

- **Recall on unseen code is unmeasured.** A clean report is not evidence of safety.
- **No runtime or protocol-state analysis.** Vulnerabilities defined by protocol state can be localised but not reliably classified. This is the main known ceiling, and it is why the Agentic AI layer scores lowest above.
- **No taint tracking.** A rule sees a construct, not whether attacker-controlled data reaches it.
- **`--narrative` output is not reproducible.** It is a language model; the deterministic report underneath it is.
- **Python has the strongest context analysis.** Other languages get a weaker heuristic and therefore more noise.

Full detail in the [limitations table](https://github.com/DINAKAR-S/Agentic-MCP-Scanner#what-is-not-built-yet).

## Links

- **Source and issues:** <https://github.com/DINAKAR-S/Agentic-MCP-Scanner>
- **Changelog:** <https://github.com/DINAKAR-S/Agentic-MCP-Scanner/blob/main/CHANGELOG.md>
- **Contributing:** <https://github.com/DINAKAR-S/Agentic-MCP-Scanner/blob/main/CONTRIBUTING.md> — a new rule needs a true-positive test, a false-positive test, and a benchmark run showing it costs nothing
- **Security policy:** <https://github.com/DINAKAR-S/Agentic-MCP-Scanner/blob/main/SECURITY.md>

## License

MIT
