CLI Reference

Complete command-line reference for mcp-scan, covering all commands, flags, and usage examples.

General Syntax

mcp-scan <command> [subcommand] [options] [arguments]

Commands

CommandDescription
scanRun vulnerability scan on a project
surfaceExtract MCP surface without running full analysis
baseline generateCreate a baseline from current scan findings
baseline showDisplay baseline contents and statistics
baseline mergeCombine multiple baseline files
initGenerate a default .mcp-scan.yaml configuration file
versionDisplay version, commit, and build information

scan

Primary command. Scans a project directory for security vulnerabilities.

Syntax

mcp-scan scan <path> [options]

Arguments

ArgumentRequiredDescription
<path>YesPath to the project directory to scan

Options

OptionShortDefaultDescription
--mode-mfastAnalysis mode: fast or deep
--output-ojsonOutput format: json, sarif, or evidence
--fail-on-f(none)Exit with code 1 if findings meet or exceed severity: info, low, medium, high, critical
--config-c.mcp-scan.yamlPath to configuration file
--rules(all)Comma-separated rule IDs or class letters: A,B,E or MCP-A003,MCP-E001
--exclude(none)Additional glob patterns to exclude (in addition to config)
--timeout5mMaximum scan duration (e.g., 30s, 5m, 1h)
--workers-w0 (auto)Number of parallel workers. 0 auto-detects CPU count
--baseline-b(none)Path to baseline file for filtering accepted findings

Examples

# Basic scan with defaults (fast mode, JSON output)
mcp-scan scan ./my-project

# Deep analysis with SARIF output
mcp-scan scan ./my-project --mode deep --output sarif

# Only check specific vulnerability classes
mcp-scan scan ./my-project --rules A,E,G

# Only check specific rule IDs
mcp-scan scan ./my-project --rules MCP-A003,MCP-E001

# Fail CI pipeline on high or critical findings
mcp-scan scan ./my-project --fail-on high

# Use baseline to exclude accepted findings
mcp-scan scan ./my-project --baseline .mcp-scan-baseline.json

# Custom config, increased timeout, 8 workers
mcp-scan scan ./my-project --config custom-config.yaml --timeout 10m --workers 8

# Exclude additional paths
mcp-scan scan ./my-project --exclude "**/generated/**"

# Deep scan with evidence bundle output
mcp-scan scan ./my-project --mode deep --output evidence

# Combine baseline with severity gate
mcp-scan scan ./my-project \
  --baseline .mcp-scan-baseline.json \
  --fail-on high \
  --output sarif > results.sarif

Output Formats

JSON (default) – Structured results with findings, summary, MSSS score, and MCP surface:

mcp-scan scan . --output json

SARIF 2.1.0 – Standard format for static analysis, compatible with GitHub Code Scanning, Azure DevOps, VS Code SARIF Viewer, and GitLab Security Dashboard:

mcp-scan scan . --output sarif > results.sarif

Evidence Bundle – Directory-based format for security audits with individual evidence files per finding:

mcp-scan scan . --output evidence
# Creates evidence-bundle/ directory

surface

Extracts the detected MCP surface from your project without running a full vulnerability scan. Use this to inspect what tools, resources, prompts, transport, and auth signals the scanner identifies in your code.

Syntax

mcp-scan surface <path> [options]

Arguments

ArgumentRequiredDescription
<path>YesPath to the project directory

Options

OptionDefaultDescription
--config.mcp-scan.yamlPath to configuration file
--formattextOutput format: text or json

How It Relates to scan

The surface command runs only the discovery and surface extraction stages of the pipeline. The scan command runs the full pipeline, which includes surface extraction plus vulnerability analysis:

scan = [discovery] -> [parsing] -> [SURFACE] -> [analysis] -> [findings]
                                      ^
                              surface command
                           (extracts only this part)

When to Use surface

  • Debug what tools mcp-scan detects in your code
  • Quick preview before running a full scan
  • Generate an inventory of your MCP server’s exposed surface
  • Verify that expected tools are being detected correctly

Example Output (text)

MCP Surface Analysis
====================

Transport: stdio

Tools (3 detected):
  - read_file
    Description: Read contents of a file
    Handler: handle_read_file (src/tools.py:45)

  - write_file
    Description: Write contents to a file
    Handler: handle_write_file (src/tools.py:78)

  - run_command
    Description: Run a shell command
    Handler: handle_run (src/tools.py:112)

Auth Signals:
  - JWT verification detected (src/auth.py:23)

Example Output (json)

mcp-scan surface ./my-project --format json
{
  "transport": "stdio",
  "tools": [
    {
      "name": "read_file",
      "description": "Read contents of a file",
      "handler": "handle_read_file",
      "location": {
        "file": "src/tools.py",
        "line": 45
      }
    }
  ],
  "auth_signals": [
    {
      "type": "jwt",
      "location": {
        "file": "src/auth.py",
        "line": 23
      }
    }
  ]
}

baseline generate

Creates a baseline file from current scan findings. Baseline entries are excluded from future scans, allowing you to track accepted findings separately from new ones.

Syntax

mcp-scan baseline generate <path> [options]

Arguments

ArgumentRequiredDescription
<path>YesPath to the project directory to scan

Options

OptionShortDefaultDescription
--output-o.mcp-scan-baseline.jsonOutput file path for the baseline
--reason-r(none)Reason for accepting the findings
--accepted-by-a(none)Identity of the person or team accepting the findings
--config-c.mcp-scan.yamlPath to configuration file
--mode-mfastScan mode to use when generating findings

Examples

# Generate baseline with default name
mcp-scan baseline generate ./my-project

# Generate baseline with metadata
mcp-scan baseline generate ./my-project \
  --reason "Initial security review - all findings reviewed" \
  --accepted-by "[email protected]"

# Generate baseline using deep mode findings
mcp-scan baseline generate ./my-project \
  --mode deep \
  --output baselines/deep-baseline.json \
  --reason "Deep audit Q1 2026" \
  --accepted-by "[email protected]"

Baseline File Structure

{
  "version": "1.0",
  "created_at": "2026-01-23T10:00:00Z",
  "updated_at": "2026-01-23T10:00:00Z",
  "entries": [
    {
      "rule_id": "MCP-E001",
      "location_hash": "sha256:abc123...",
      "file": "src/config.py",
      "line": 47,
      "reason": "Development API key, not used in production",
      "accepted_by": "[email protected]",
      "timestamp": "2026-01-23T10:00:00Z"
    }
  ]
}

baseline show

Displays the contents and statistics of a baseline file.

Syntax

mcp-scan baseline show <baseline-file> [options]

Arguments

ArgumentRequiredDescription
<baseline-file>YesPath to the baseline JSON file

Options

OptionShortDescription
--stats-sShow only aggregate statistics, not individual entries

Examples

# Show full baseline contents
mcp-scan baseline show .mcp-scan-baseline.json

# Show statistics only
mcp-scan baseline show .mcp-scan-baseline.json --stats

Example Output

BASELINE: .mcp-scan-baseline.json
==================================

Version: 1.0
Created: 2026-01-23T10:00:00Z
Updated: 2026-01-23T15:30:00Z

Total Entries: 5

BY RULE ID:
  MCP-E001: 3 entries
    - src/config.py:47 (Development API key)
    - src/config.py:48 (Development DB password)
    - src/legacy/old.py:12 (Legacy token)

  MCP-A003: 1 entry
    - scripts/admin.py:25 (Internal admin tool, not exposed)

  MCP-N001: 1 entry
    - . (Lockfile managed externally)

baseline merge

Combines multiple baseline files into a single file, deduplicating entries.

Syntax

mcp-scan baseline merge <baseline1> <baseline2> [baseline3...] [options]

Arguments

ArgumentRequiredDescription
<baseline1> <baseline2> ...Yes (2+)Two or more baseline files to merge

Options

OptionShortDefaultDescription
--output-o(first file)Output file for the merged baseline

Merge Behavior

  1. Deduplication: Entries with the same rule_id and location_hash are merged
  2. Conflict resolution: When duplicates exist, the most recent entry is kept
  3. Metadata preservation: Reasons and accepters from all sources are preserved

Examples

# Merge two baselines
mcp-scan baseline merge team1.json team2.json --output combined.json

# Merge multiple baselines from different environments
mcp-scan baseline merge \
  baselines/dev.json \
  baselines/qa.json \
  baselines/legacy.json \
  --output .mcp-scan-baseline.json

init

Generates a default .mcp-scan.yaml configuration file in the current directory with documented defaults.

Syntax

mcp-scan init [options]

Options

OptionDefaultDescription
--output.mcp-scan.yamlOutput file path
--forcefalseOverwrite existing configuration file

Examples

# Generate default config
mcp-scan init

# Generate at custom location, overwriting existing
mcp-scan init --output config/scan.yaml --force

Generated Configuration

The generated file includes all available options with their defaults and explanatory comments. Key sections include:

  • include/exclude – File discovery patterns
  • rules – Disable rules, override severities, define custom rules
  • allowlists – Trusted hosts, URL schemes, paths
  • secrets_patterns – Additional and ignored secret patterns
  • scan settings – Mode, timeout, workers, fail-on
  • output settings – Format, snippet redaction, taint traces
  • baseline settings – Baseline file path

version

Displays version, commit hash, and build timestamp.

Syntax

mcp-scan version

Example Output

mcp-scan version 1.0.0
commit: abc1234
built: 2024-01-15T10:00:00Z

Exit Codes

All commands follow consistent exit code conventions:

CodeMeaningTypical Action
0Success. No findings above --fail-on threshold (or no threshold set)CI passes
1Findings found above the --fail-on thresholdCI fails, review findings
2Configuration or usage error (bad flags, invalid config file)Fix configuration
3Scan error (timeout, parse failure, internal error)Increase timeout, check input

Environment Variables

Configuration can be set or overridden through environment variables:

VariableDescriptionEquivalent Config/Flag
MCP_SCAN_CONFIGDefault configuration file path--config
MCP_SCAN_MODEDefault scan mode (fast or deep)--mode / mode: in YAML
MCP_SCAN_TIMEOUTDefault timeout--timeout / timeout: in YAML
MCP_SCAN_FAIL_ONDefault severity threshold--fail-on / fail_on: in YAML
MCP_SCAN_WORKERSDefault worker count--workers / workers: in YAML
NO_COLORDisable colored terminal output
MCP_SCAN_MODE=deep MCP_SCAN_FAIL_ON=high mcp-scan scan .

Configuration Precedence

When the same setting is specified in multiple places, the following precedence applies (highest to lowest):

  1. CLI flags (e.g., --mode deep)
  2. Environment variables (e.g., MCP_SCAN_MODE=deep)
  3. Configuration file (e.g., mode: deep in .mcp-scan.yaml)
  4. Built-in defaults (e.g., fast)

Shell Completion

mcp-scan supports shell completion for Bash, Zsh, and Fish:

Bash

mcp-scan completion bash > /etc/bash_completion.d/mcp-scan

Zsh

mcp-scan completion zsh > "${fpath[1]}/_mcp-scan"

Fish

mcp-scan completion fish > ~/.config/fish/completions/mcp-scan.fish