mcplint 0.4.0

MCP Server Testing, Fuzzing, and Security Scanning Platform
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
# CLAUDE.md

This file provides guidance to Claude Code when working with code in this repository.

## Project Overview

MCPLint is a Rust-based security testing tool for Model Context Protocol (MCP) servers. It provides protocol validation, security vulnerability scanning, coverage-guided fuzzing, AI-assisted vulnerability explanation, and multi-backend caching with SARIF output for CI/CD integration.

## Build and Development

```bash
# Build
cargo build              # Debug build
cargo build --release    # Release build

# Install
cargo install --path .   # Install to ~/.cargo/bin

# Test
cargo test               # Run all tests
cargo test -- --nocapture  # Show test output

# Lint and Format
cargo clippy             # Lint
cargo fmt                # Format code
```

## Running MCPLint

After installation:

```bash
mcplint servers                  # List servers from config
mcplint validate <server>        # Validate protocol compliance
mcplint scan <server>            # Security scan
mcplint fuzz <server>            # Fuzz testing
mcplint explain <server>         # AI explanations
mcplint rules --details          # List rules
mcplint doctor                   # Environment check
mcplint cache stats              # Cache statistics
mcplint fingerprint generate <s> # Generate fingerprints
mcplint watch <server>           # Watch mode
mcplint multi-scan --all         # Multi-server scanning
```

## Architecture

```
src/
  main.rs              # CLI entry point
  lib.rs               # Library exports
  cli/
    mod.rs             # CLI configuration
    config.rs          # Configuration loading
    commands/          # Subcommand implementations
      validate.rs      # Protocol validation
      scan.rs          # Security scanning
      fuzz.rs          # Fuzzing
      explain.rs       # AI explanations
      cache.rs         # Cache management
      watch.rs         # File watching
      init.rs          # Config generation
      rules.rs         # List rules
      doctor.rs        # Environment check
      servers.rs       # List servers
      multi_scan.rs    # Multi-server scanning
  ai/                  # AI provider integration
    engine.rs          # ExplainEngine
    prompt_templates.rs # Advanced prompt engineering (few-shot, CoT)
    neo4j_kb.rs        # Neo4j knowledge graph (optional feature)
    provider/          # Provider implementations
      anthropic.rs     # Claude API
      openai.rs        # GPT API
      ollama.rs        # Local Ollama
  cache/               # Caching system
    mod.rs             # CacheManager
    memory.rs          # In-memory backend
    filesystem.rs      # Filesystem backend
    redis.rs           # Redis backend (optional)
    rug_pull.rs        # Schema change detection
  scanner/             # Security scanner
    engine.rs          # ScanEngine
    finding.rs         # Finding, Severity
    multi_server.rs    # Multi-server parallel scanning
    rules/             # Detection rules
      tool_injection.rs
      tool_shadowing.rs
      schema_poisoning.rs
      unicode_hidden.rs
      oauth_abuse.rs   # OAuth scope abuse detection
  fingerprinting/      # Tool fingerprinting
    mod.rs             # Fingerprint generation
    comparator.rs      # Fingerprint comparison
    normalizer.rs      # Schema normalization
  fuzzer/              # Fuzzing framework
    session.rs         # FuzzSession
    corpus.rs          # CorpusManager
    mutation/          # Mutation strategies
  validator/           # Protocol validator
    engine.rs          # ValidationEngine
    rules.rs           # Validation rules (56 rules)
  transport/           # Transport layer
    stdio.rs           # Stdio transport
    sse.rs             # SSE transport
    streamable_http.rs # HTTP transport
  protocol/            # Protocol types
    jsonrpc.rs         # JSON-RPC types
    mcp.rs             # MCP types
  client/              # MCP client
  baseline/            # Baseline comparison
  reporter/            # Output formatters
    sarif.rs           # SARIF output
    junit.rs           # JUnit output
    gitlab.rs          # GitLab output
```

## Key Components

### Validation Rules (validator/rules.rs)

56 rules across 7 categories:
- PROTO-001 to PROTO-015: Protocol compliance
- SCHEMA-001 to SCHEMA-005: Schema validation
- SEQ-001 to SEQ-003: Sequence validation
- TOOL-001 to TOOL-005: Tool validation
- RES-001 to RES-003: Resource validation
- SEC-001 to SEC-015: Security checks (path traversal, injection, SSRF, XXE, template injection, prompt injection, tool shadowing)
- EDGE-001 to EDGE-010: Edge cases (null bytes, deep nesting, overflow, timeouts)

### Scanner Rules (scanner/rules/)

Detection rules for:
- Tool injection (prompt injection in tool descriptions)
- Tool shadowing (impersonating standard tools)
- Schema poisoning (malicious defaults in schemas)
- Unicode hidden characters
- OAuth scope abuse

### Transport Layer

- StdioTransport: Local servers via stdin/stdout
- SseTransport: Remote servers via SSE
- StreamableHttpTransport: MCP 2025 HTTP spec

Environment variables are passed to spawned processes from the config file.

### Cache System

Multi-backend caching:
- MemoryCache: In-process
- FilesystemCache: Persistent (default)
- RedisCache: Distributed (optional feature)

Categories with different TTLs: Schema, ScanResult, Validation, Corpus, ToolHash

## Configuration

MCPLint reads server configuration from Claude Desktop config:
- Windows: %APPDATA%/Claude/claude_desktop_config.json
- macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
- Linux: ~/.config/Claude/claude_desktop_config.json

Project configuration via .mcplint.toml (generate with `mcplint init`).

## Environment Variables

```
ANTHROPIC_API_KEY     # For Claude models
OPENAI_API_KEY        # For GPT models
OLLAMA_BASE_URL       # For local Ollama (default: http://localhost:11434)
MCPLINT_CACHE_DIR     # Cache directory
MCPLINT_CACHE_BACKEND # Backend: filesystem, memory, redis

# Neo4j Knowledge Graph (optional, requires --features neo4j)
NEO4J_URI             # Neo4j connection URI (e.g., neo4j+s://xxx.databases.neo4j.io)
NEO4J_USERNAME        # Database username
NEO4J_PASSWORD        # Database password
NEO4J_DATABASE        # Database name (default: neo4j)
VOYAGE_API_KEY        # Voyage AI API key for embeddings
```

## Exit Codes

- 0: Success, no findings
- 1: Success, findings detected
- 2: Error
- 3: Partial success
- 4: Timeout

## Dependencies

Key crates:
- rmcp: MCP SDK
- clap: CLI parsing
- tokio: Async runtime
- serde/serde_json: Serialization
- reqwest: HTTP client
- tracing: Logging
- neo4rs: Neo4j graph database (optional, `--features neo4j`)

## Test Coverage

Current statistics:
- **3,068 unique tests** (2,965 unit + 103 integration)
- Integration tests use live MCP servers (filesystem, memory)
- Run time: ~80 seconds for full suite

Test breakdown:
| Suite | Tests |
|-------|-------|
| Unit tests (lib.rs) | 2,965 |
| ai_integration | 26 |
| cache_integration | 13 |
| interactive_tests | 30 |
| server_integration | 34 |

Key module coverage:
- scanner/engine.rs: 93.8%
- transport/stdio.rs: 93.5%
- validator/rules.rs: 99.5%
- validator/engine.rs: 69.4%
- scanner/multi_server.rs: 100%
- fuzzer/session.rs: comprehensive unit tests
- baseline/store.rs: comprehensive unit tests

Run tests:
```bash
cargo test                        # Run all tests
cargo test -- --test-threads=1    # Sequential execution
cargo test scanner::              # Run scanner module tests only
```

## v0.2.0 CLI Features

### Smart Context Detection
- Auto-detects TTY, CI, and plain output modes
- Respects NO_COLOR environment variable
- Unicode/ASCII fallback based on terminal capabilities

### Progress Indicators
- Real-time progress bars for scan operations
- Connection spinners with phase tracking

### Enhanced Error Handling
- Miette-based diagnostic errors with source context
- "Did you mean?" suggestions using Jaro-Winkler similarity
- Contextual help for common errors

### Shell Completions
- Dynamic completions for bash, zsh, fish, PowerShell, elvish
- Server name completion from Claude Desktop config

### Watch Mode
- Differential display showing new/fixed issues
- Debounced file watching

## Multi-Server Scanning

Scan multiple MCP servers in parallel:

```bash
mcplint multi-scan --all --profile standard
mcplint multi-scan -s server1,server2 --format sarif
mcplint multi-scan --all --fail-on critical,high
```

Features:
- Parallel execution with configurable concurrency (-j flag)
- Combined SARIF output for CI/CD
- Aggregated statistics and severity counts
- Per-server timeout configuration

## Public API Reference

MCPLint exposes a library API for programmatic use. Key public types:

### Core Engines

```rust
// Scanner - Security vulnerability detection
use mcplint::{ScanEngine, ScanConfig, ScanResults, Finding, Severity};

let engine = ScanEngine::new(config);
let results: ScanResults = engine.scan(&tools).await?;
for finding in results.findings {
    println!("{}: {}", finding.severity, finding.title);
}

// Validator - Protocol compliance checking
use mcplint::{ValidationEngine, ValidationConfig, ValidationResults};

let engine = ValidationEngine::new(config);
let results: ValidationResults = engine.validate(&client).await?;

// Fuzzer - Coverage-guided fuzzing
use mcplint::fuzzer::{FuzzEngine, FuzzSession, FuzzResults, FuzzProfile};

let session = FuzzSession::new(config).await?;
let results: FuzzResults = session.run().await?;
```

### AI Explanation

```rust
use mcplint::ai::{AiConfig, ExplainEngine, AiProvider, AudienceLevel};

let config = AiConfig {
    provider: AiProvider::Ollama,
    model: Some("llama3.2".to_string()),
    audience: AudienceLevel::Intermediate,
    ..Default::default()
};
let engine = ExplainEngine::new(config, cache).await?;
let explanation = engine.explain(&finding).await?;
```

### Advanced Prompt Engineering

```rust
use mcplint::ai::{AdvancedPromptBuilder, VulnCategory, FewShotExample};

// Build prompts with chain-of-thought reasoning and few-shot examples
let builder = AdvancedPromptBuilder::new()
    .with_finding(finding.clone())
    .with_chain_of_thought(true)
    .with_confidence_scoring(true);

let (system_prompt, user_prompt) = builder.build_prompts();

// Categories: Injection, Authentication, Cryptographic, DataExposure,
//             Deserialization, Dos, ProtocolViolation, Generic
```

### Neo4j Knowledge Graph (optional)

```rust
#[cfg(feature = "neo4j")]
use mcplint::ai::{
    Neo4jConfig, SecurityKnowledgeGraph, VoyageEmbedder, EmbeddingProvider,
    SimilarFinding, CweKnowledge,
};

// Connect to Neo4j with vector search for similar vulnerabilities
let config = Neo4jConfig::from_env()?;
let embedder = Arc::new(VoyageEmbedder::new(api_key, "voyage-code-2", 1536));
let kg = SecurityKnowledgeGraph::new(config, embedder).await?;

// Store and search findings
kg.store_finding(&finding, "my-server").await?;
let similar = kg.find_similar_vulnerabilities(&finding, 5, 0.7).await?;

// Retrieve CWE knowledge
let cwe = kg.get_cwe_knowledge("CWE-78").await?;
```

### Caching

```rust
use mcplint::cache::{CacheManager, CacheConfig, CacheBackend};

// Memory cache
let cache = CacheManager::memory();

// Filesystem cache (persistent)
let config = CacheConfig::default();
let cache = CacheManager::new(config).await?;

// Store/retrieve
cache.set_schema("server-hash", &tools).await?;
let cached: Option<Vec<Tool>> = cache.get_schema("server-hash").await?;
```

### Baseline Comparison

```rust
use mcplint::baseline::{Baseline, DiffEngine, DiffResult};

let baseline = Baseline::load("baseline.json")?;
let diff: DiffResult = DiffEngine::compare(&baseline, &current_findings);
println!("New: {}, Fixed: {}", diff.new.len(), diff.fixed.len());
```

### Fingerprinting

```rust
use mcplint::fingerprinting::{FingerprintHasher, FingerprintComparator, ToolFingerprint};

let fingerprint: ToolFingerprint = FingerprintHasher::fingerprint(&tool)?;
let diff = FingerprintComparator::compare(&old_fp, &new_fp);
if diff.is_breaking() {
    println!("Breaking change detected!");
}
```

### Transport Layer

```rust
use mcplint::transport::{Transport, TransportType, StdioTransport, detect_transport_type};

// Auto-detect transport
let transport_type = detect_transport_type("http://localhost:8080/mcp");

// Connect to server
let mut transport = StdioTransport::spawn(
    "node",
    &["server.js".to_string()],
    &env_vars,
    TransportConfig::default()
).await?;

// Send request
let response = transport.request("tools/list", None).await?;
```

### Scanner Profiles

```rust
use mcplint::scanner::ScanProfile;

// Quick: Fast checks, ~5 seconds
// Standard: Balanced (default), ~30 seconds
// Full: Comprehensive, ~2 minutes
// Enterprise: Maximum depth, ~5 minutes
let profile = ScanProfile::Standard;
```

### Finding Severities

```rust
use mcplint::scanner::Severity;

// Critical - Immediate exploitation risk
// High - Significant security impact
// Medium - Moderate risk
// Low - Minor issues
// Info - Informational findings
match finding.severity {
    Severity::Critical | Severity::High => panic!("Security issue!"),
    _ => {}
}
```

### Output Formats

```rust
use mcplint::cli::OutputFormat;
use mcplint::reporter::{SarifReporter, JunitReporter, GitlabReporter};

// Generate SARIF for GitHub Code Scanning
let sarif = SarifReporter::new().generate(&results)?;

// Generate JUnit for test runners
let junit = JunitReporter::new().generate(&results)?;
```

## Architecture Deep Dive

### Data Flow

```
User Command
┌─────────────────────────────────────────────────────────────────────┐
│  CLI Layer (src/cli/)                                               │
│  ├── commands/  - Subcommand implementations                        │
│  ├── config.rs  - Configuration loading & validation                │
│  └── interactive/ - TUI wizards for scan/fuzz/init/explain          │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│  Transport Layer (src/transport/)                                   │
│  ├── stdio.rs         - Spawn & communicate with local servers      │
│  ├── sse.rs           - SSE transport (MCP 2024-11 spec)           │
│  └── streamable_http.rs - HTTP transport (MCP 2025 spec)           │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│  Engine Layer                                                        │
│  ├── validator/  - Protocol compliance (56 rules)                   │
│  ├── scanner/    - Security vulnerability detection (20+ rules)    │
│  ├── fuzzer/     - Coverage-guided fuzzing with mutation strategies│
│  └── ai/         - AI-powered vulnerability explanations            │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│  Support Layer                                                       │
│  ├── cache/         - Multi-backend caching (memory/fs/redis)       │
│  ├── baseline/      - Diff comparison for CI/CD                     │
│  ├── fingerprinting/- Tool schema change detection                  │
│  └── reporter/      - SARIF, JUnit, GitLab, HTML output             │
└─────────────────────────────────────────────────────────────────────┘
```

### Module Responsibilities

| Module | Purpose | Key Types |
|--------|---------|-----------|
| `validator` | MCP protocol compliance checking | `ValidationEngine`, `ValidationResults` |
| `scanner` | Security vulnerability detection | `ScanEngine`, `Finding`, `Severity` |
| `fuzzer` | Coverage-guided fuzzing | `FuzzSession`, `FuzzResults`, `FuzzCrash` |
| `ai` | AI-powered explanations | `ExplainEngine`, `ExplanationResponse` |
| `ai::prompt_templates` | Advanced prompt engineering | `AdvancedPromptBuilder`, `VulnCategory`, `FewShotExample` |
| `ai::neo4j_kb` | Neo4j knowledge graph (optional) | `SecurityKnowledgeGraph`, `VoyageEmbedder` |
| `cache` | Multi-backend caching | `CacheManager`, `CacheConfig` |
| `baseline` | Diff comparison | `Baseline`, `DiffEngine`, `DiffResult` |
| `fingerprinting` | Schema change detection | `FingerprintHasher`, `ToolFingerprint` |
| `transport` | Server communication | `Transport`, `StdioTransport` |
| `reporter` | Output formatting | `SarifReporter`, `JunitReporter` |
| `protocol` | MCP/JSON-RPC types | `Tool`, `Resource`, `JsonRpcMessage` |

### Security Rule Categories

| Prefix | Category | Example Rules |
|--------|----------|---------------|
| `SEC-INJ-*` | Injection | Command injection, SQL injection, path traversal |
| `SEC-AUTH-*` | Authentication | Credential exposure, OAuth abuse |
| `SEC-TRANS-*` | Transport | TLS/SSL security |
| `SEC-PROTO-*` | Protocol | Tool poisoning, shadowing, rug pull |
| `SEC-DATA-*` | Data | Data exposure, leakage |
| `SEC-DOS-*` | Availability | Denial of service |

### Validation Rule Categories

| Prefix | Category | Count | Description |
|--------|----------|-------|-------------|
| `PROTO-*` | Protocol | 15 | JSON-RPC 2.0 and MCP protocol compliance |
| `SCHEMA-*` | Schema | 5 | JSON Schema validation |
| `SEQ-*` | Sequence | 3 | Method call ordering |
| `TOOL-*` | Tool | 5 | Tool definition and invocation |
| `RES-*` | Resource | 3 | Resource listing and access |
| `SEC-*` | Security | 15 | Security vulnerability checks |
| `EDGE-*` | Edge | 10 | Boundary conditions and edge cases |