Aevrin

Introduction

What Aevrin scans, how it scores risk, and where to start.

Aevrin scans Model Context Protocol (MCP) servers for security risks before you trust them — as a source repository, a local path on your machine, or a live server URL. It runs a fixed set of established open-source scanners (Semgrep, Bandit, Gitleaks, TruffleHog, OSV-Scanner, Trivy, mcp-shield, and the official MCP SDK) and maps every result onto the OWASP MCP Top 10, so a finding means the same thing everywhere it appears: in the CLI, in a Claude Code hook block, and on the dashboard.

The three ways to use it

Quick start

pipx install aevrin
aevrin login
aevrin scan https://github.com/owner/mcp-server

See Getting Started for the full walkthrough, including installing on older Python versions and connecting the Claude Code hook.

What a scan actually checks

A repository or local-path scan clones (or reads) the target and runs, in order:

  1. Static analysis — Semgrep + Bandit for injection, path traversal, SSRF, and other code-level risks.
  2. Secrets — Gitleaks + TruffleHog for hardcoded credentials, with TruffleHog additionally verifying whether a matched credential is actually live.
  3. Dependencies — OSV-Scanner + Trivy for known-vulnerable packages, plus OpenSSF Scorecard if you've set a GITHUB_TOKEN.
  4. Tool description check — mcp-shield and safe, remote-only MCP SDK inspection inspect the server's declared MCP tools for hidden-instruction (tool poisoning) and prompt-injection patterns, and Aevrin's own rules check for weak/missing auth and audit logging.

A live-server URL or a pasted MCP config skips the code-level stages (nothing to clone) and only gets the tool-description check — see Concepts for why.

Honesty over false confidence

Two things Aevrin is deliberately strict about, because a security scanner that can be tricked into saying "clean" is worse than no scanner at all:

  • Incomplete scans are never reported as clean. If Docker isn't running, a scanner binary is missing, or the network is unreachable, the affected category is marked unreliable and the scan is flagged incomplete everywhere — CLI exit code, hook decision, and dashboard badge. An empty findings list from a category that never ran is not the same thing as a clean one.
  • Not everything is tested. Prompt injection via a live tool's runtime responses (MCP08) requires dynamic, adversarial testing against a running server and is out of scope for static scanning — every report says so explicitly rather than silently omitting it.

Read more in Concepts.