Architecture
This document describes the internal architecture of mcp-scanner.
Module Overview
src/
├── main.rs # Entry point and CLI
├── cli.rs # Command definitions
├── error.rs # Error types
├── discovery/ # MCP server discovery
│ ├── clients/ # Per-client parsers
│ └── config.rs # Server configuration
├── scanner/ # Security scanning
│ ├── threats/ # Threat detectors
│ ├── snapshot.rs # Description drift tracking
│ └── report.rs # Scan results
├── proxy/ # STDIO proxy
│ ├── interceptor.rs
│ └── rules.rs
├── protocol/ # MCP protocol
│ ├── jsonrpc.rs # JSON-RPC 2.0
│ ├── mcp.rs # MCP types
│ └── transport/ # Transport implementations
├── db/ # SQLite storage
│ ├── audit.rs # Audit logging
│ └── migrations.rs
└── web/ # Web dashboard
├── api.rs # REST API
└── ui.rs # htmx UI
Discovery
The discovery module finds MCP servers across AI clients:
McpClientParsertrait defines how to parse client configs- Each client has a parser in
discovery/clients/ all_clients()returns all available parsersdiscover_all()finds and parses all configs
Scanning
The scanner connects to MCP servers and analyzes them:
Scannermanages the scanning processThreatDetectortrait defines threat detection- Each detector in
scanner/threats/checks for specific issues - Results are collected into
ScanResult
Proxy
The proxy intercepts tool calls:
- Client connects to mcp-scanner via STDIO
- mcp-scanner spawns the real server
- JSON-RPC messages are intercepted
- Rules are applied to tool calls
- Audit log entries are created
Protocol
MCP communication uses JSON-RPC 2.0:
Messageenum represents requests/responses/notificationsStdioTransporthandles STDIO communication- MCP-specific types in
mcp.rs
Database
SQLite stores persistent data:
r2d2connection pool- Migrations run on startup
AuditLogfor tool call history- Snapshots stored as JSON files (not in DB)
Web Dashboard
htmx-powered web interface:
- Axum web server
- REST API for data access
- Server-rendered HTML with htmx for interactivity