Security intelligence built
from data, not theory.
Nobody had actually measured what's happening across the MCP ecosystem. We built the tooling to find out - 6 crawlers, 184 detection rules, fully deterministic, no LLMs.
The problem we're solving
MCP servers are granted access to files, databases, APIs, and code execution — often in a single claude_desktop_config.json edit. There is no vetting. No audit. No trust signal.
Every AI security framework talks about prompt injection, tool poisoning, and supply-chain risk in the abstract. We run 184 concrete checks on every server we can find, store the results immutably, and publish them — so developers, enterprises, and gateway builders can make decisions from evidence, not intuition.
The data is the product. We are the security intelligence layer upstream of every gateway, registry, and deployment decision in the MCP ecosystem.
How a scan works
Four deterministic stages. Every stage is a separate package with a documented contract. No LLMs, no black boxes.
Crawls 6+ sources: npm, PyPI, GitHub, PulseMCP, Smithery, MCP Registry. Deduplicates by GitHub URL → npm package → name. Logs source, servers_found, new_unique, duplicates, errors, elapsed_time.
Wraps the official MCP SDK. Calls initialize and tools/list only - never invokes tools. Captures serverInfo.name, serverInfo.version, instructions field, auth method, transport, and response time.
Runs 184 deterministic detection rules (TypeScript, registry-based) against tool metadata, schema, source code, dependencies, connection metadata, and initialize response. Every finding includes rule_id, evidence, and remediation.
deriveVerdict() turns the findings and the coverage ledger into one of four verdicts. Risk: any critical finding, or a lethal trifecta. Caution: any high finding. Safe: no critical or high finding AND coverage sufficient to certify. Otherwise Insufficient coverage - never Safe by default.
184 detection rules across 21 categories
Every rule is a typed TypeScript implementation with a mandatory evidence chain. The engine is deterministic. Every finding requires rule_id, evidence, and remediation. Categories A-K are detailed below; the full A-U catalogue is on the taxonomy page.
Description Analysis
9 rulesRequires: Tool metadata
Unicode homoglyph attacks, zero-width character injection, base64-encoded payloads hidden from human review
Schema Analysis
7 rulesRequires: Tool metadata
Parameter-level injection surface, dangerous defaults (recursive:true, disable_ssl_verify:true), unconstrained additional properties
Code Analysis
17 rulesRequires: Source code
20+ secret token formats, prototype pollution, unsafe deserialization, JWT algorithm confusion, timing attacks on secret comparison
Dependency Analysis
7 rulesRequires: package.json / requirements.txt
50+ confirmed malicious package names including MCP ecosystem typosquats, Levenshtein distance for typosquat detection, dependency confusion (high version number trick)
Behavioral Analysis
6 rulesRequires: Connection metadata
Live connection checks - transport security, authentication presence, response time anomalies, tool count explosion - plus what the sandbox observatory witnessed a tool actually do versus what it declared
Ecosystem Context
8 rulesRequires: Tool metadata
Lethal Trifecta (private data + untrusted input + external comms = a Risk verdict), circular data loop enabling persistent injection, multi-step exfiltration chain
Adversarial AI
7 rulesRequires: Tool metadata + scan history
Attacks that only work because the target is an AI - indirect injection gateways, trust assertion injection, tool behavior drift (rug pull), DNS data exfiltration
2026 Attack Surface
3 rulesRequires: Mixed
March 2026 additions: OAuth 2.0 MCP auth flaws, injection into MCP initialize response fields (processed before tool descriptions), cross-agent propagation in multi-agent orchestration
Protocol Surface
17 rulesRequires: Protocol metadata + annotations
MCP protocol primitive attacks: annotation deception (readOnlyHint lies), sampling abuse (23-41% attack amplification), cross-config lethal trifecta, consent fatigue exploitation (84.2% success rate), credential harvesting via elicitation
2026 Threat Intelligence
9 rulesRequires: Source code + tool metadata
CVE-backed rules from real-world incidents: cross-agent config poisoning (CVE-2025-53773), git argument injection (CVE-2025-68143), full schema poisoning (CyberArk FSP), health endpoint disclosure (CVE-2026-29787), tool output poisoning (CyberArk ATPA), OpenAPI spec injection (CVE-2026-22785)
Compliance & Governance
20 rulesRequires: Source code
Framework-mapped rules closing gaps across ISO 27001, ISO 42001, EU AI Act, NIST AI RMF, CoSAI, MAESTRO - audit trail integrity, human oversight, credential lifecycle, supply chain hooks, sandbox enforcement
OWASP MCP Top 10 mapping
Every rule is mapped to the OWASP MCP Top 10. A server's OWASP posture shows whether any findings were detected in each category.
| ID | Category | Rules |
|---|---|---|
| MCP01 | Prompt Injection | A1, A5, A7, A8, A9, B5, F1, F6, G1, G2, G3, H2, I3, I6, I7, J3, J5, J6 |
| MCP02 | Tool Poisoning | A2, A4, A6, F2, F5, G5, I1, I2, J5, J6, K12, K13 |
| MCP03 | Command Injection | C1, C9, C13, C16, J2, J7 |
| MCP04 | Data Exfiltration | A3, F1, F3, F7, G7, I9, I13, K18 |
| MCP05 | Privilege Escalation | C2, C8, C10, C12, H1, I4, I12, J1, K6, K8, K14 |
| MCP06 | Excessive Permissions | A2, B3, B7, E4, F2, I11, I16, K6 |
| MCP07 | Insecure Configuration | B6, C7, C8, C11, C14, C15, D6, E1, E2, H1, I15, J4, K7, K17, K19 |
| MCP08 | Dependency Vulnerabilities | D1, D2, D3, D4, D5, D6, D7, K9, K10 |
| MCP09 | Logging & Monitoring | C6, E3, K1, K2, K3, K20 |
| MCP10 | Supply Chain | D3, D5, D7, A4, F5, G6, I5, I14, J7, K9, K10, K11 |
The verdict
How it is derived
Risk any critical finding,
or a lethal trifecta (F1 / I13)
Caution otherwise, any high finding
Safe no critical or high finding
AND coverage sufficient to certify
Insufficient no critical or high finding,
coverage but too little was checked
to call it safe
Never Safe by default.What it means
If a server reads private data AND ingests untrusted content AND has external network access — or a client config spreads those three across servers — the verdict is Risk regardless of other findings. No amount of clean code compensates for this combination.
Findings are positive evidence: a proven critical is Risk at any coverage. The absence of findings is not. A clean result is Safe only when the coverage band is high or medium and no high or critical rule was left with an unanswered input — otherwise it is Insufficient coverage. Refused, out-of-scope and not-observed are never “clean”.
Per-finding confidence, per-framework compliance percentages and the attack-graph exploitability score (0–1) are separate signals and remain. There is no composite number to fold them into.
Architecture principles
All 184 detection rules are TypeScript TypedRuleV2 implementations registered in a central registry - metadata in the registry, detection in code, no YAML. Adding a rule never requires changing engine code.
Every detection is deterministic - AST taint analysis, capability graphs, entropy, structural parsing, CVE lookup. LLM classification is deferred to v1.1.
Crawlers store all raw metadata. Analysis is a separate pass. We never discard data because we don't have a rule for it yet.
Every scan result is immutable. Verdicts and findings change over time; the history table tracks every change. Trends are first-class.
We only call initialize and tools/list. Dynamic invocation is a separate, gated capability requiring explicit server-author opt-in.
Every finding must include rule_id, evidence (what triggered it), and remediation (how to fix it). Findings without evidence are useless.