# xgrep

A fast, Semgrep-compatible code scanner written in Go.

xgrep scans codebases using Semgrep YAML rule syntax and tree-sitter for language-aware pattern matching.

## Design Goals

xgrep optimizes for **accuracy**: when it reports a vulnerability, it should be real
and exploitable. False positives are what kill SAST tools — once a scanner cries wolf,
people stop reading its output and real bugs slip through. Every rule and engine change
is judged against these goals:

1. **Report exploitable issues, not imperfect code.** The bar for a security finding is
   "exploitable," not "technically imperfect." A technically-true-but-harmless match is
   treated as noise.
2. **Earn precision through dataflow/reachability, not by weakening detection.** Prefer
   firing when untrusted input actually reaches a dangerous sink over matching code shape
   alone. Relaxing *what counts as a bug* to cut noise also loses real bugs — add context,
   don't loosen the pattern.
3. **Separate correctness from security.** A code smell (e.g. an unescaped `.` in a
   hostname regex) is a low-severity correctness note; an exploitable bug is a security
   finding. Smells must never drown out confirmed vulnerabilities.
4. **Calibrate severity and confidence to exploitability.** HIGH/CRITICAL only when impact
   is demonstrable; uncertain findings are low-confidence "review" items, clearly distinct
   from confirmed ones.
5. **Prefer AST and semantic analysis over regex.** Tree-sitter ASTs and taint dataflow are
   more precise than text patterns, and are the default.
6. **Never suppress a true positive to lower a count.** If xgrep finds a real bug — even a
   minor one — the fix belongs in the code, not in muting the rule.

## Installation

```bash
go install go.mondoo.com/xgrep/cmd/xgrep@latest
```

Or build from source:

```bash
git clone https://github.com/mondoohq/xgrep.git
cd xgrep
go build -o xgrep ./cmd/xgrep
```

## Quick Start

```bash
# Scan a directory with a rule file
xgrep -f rules.yaml src/

# Scan with a directory of rules
xgrep -f rules/ src/

# Use --config/-c as an alias for -f/--rules
xgrep --config rules.yaml src/
```

## Usage

```
xgrep [flags] -f <rules> <targets...>

Flags:
  -f, --rules string      path to rule file or directory
  -c, --config string     path to rule file or directory (alias for --rules)
      --json              output results as JSON
      --sarif             output results as SARIF
  -j, --jobs int          number of parallel workers (default: NumCPU)
      --severity string   minimum severity to report (INFO, WARNING, ERROR)
      --include string    include only files matching glob pattern
      --exclude string    exclude files matching glob pattern
      --max-target-bytes  skip files larger than N bytes
  -o, --output string     write output to file instead of stdout
      --rule-id string    only run rules with matching IDs (comma-separated)
      --skip-rule string  skip rules with matching IDs (comma-separated)
      --autofix           apply fixes to source files in place
      --dry-run           show fixes without applying (use with --autofix)
      --verbose           enable debug output

Subcommands:
  scan              scan targets (default when -f is provided)
  inspect           code intelligence: search symbols, navigate definitions, assess impact
  graph             build and query the code graph
  mcp               run as an MCP server over stdio (for AI agents)
  test <path>       run tests on rule files in a directory
  validate <path>   validate rule files without scanning
  lsp               start an LSP server over stdio
  version           print version and exit
```

## Code Intelligence

`xgrep inspect` provides fast code navigation for both humans and AI agents:

```bash
# Understand a codebase
xgrep inspect overview .

# Search for symbols by name
xgrep inspect symbol "Handler" --kind function

# Fast text search (trigram-indexed via Zoekt)
xgrep inspect search "TODO|FIXME" --regex --lang go

# Go to definition
xgrep inspect definition --file src/server.go --line 42

# Find all callers and callees
xgrep inspect references "ProcessRequest"

# File outline (all symbols)
xgrep inspect outline src/server.go

# Assess blast radius before changing a function
xgrep inspect impact "ProcessRequest"

# Show call dependencies (upstream + downstream)
xgrep inspect deps "ProcessRequest"
```

All commands support `--json` for structured output. The code graph and search index are
cached in `.xgrep/` and rebuild incrementally.

See [docs/CODE_INTELLIGENCE.md](docs/CODE_INTELLIGENCE.md) for full documentation.

## Code Graph

```bash
# Build the code graph (auto-cached to .xgrep/graph.json)
xgrep graph build .

# Find callers / callees
xgrep graph callers --json <function-name>
xgrep graph callees --json <function-name>

# Find call paths between two functions
xgrep graph paths --json <source> <dest>

# Show N-hop neighborhood with inlined source code
xgrep graph context <function-name> --depth 2
```

## MCP Server

Run xgrep as an [MCP](https://modelcontextprotocol.io) server for AI agent integration:

```bash
xgrep mcp
```

Exposes all scan, graph, and inspect capabilities as MCP tools over stdio.

## Supported Languages

### Tree-sitter languages (full AST matching)

| Language   | Extensions                          |
|------------|-------------------------------------|
| Python     | `.py`, `.pyi`                       |
| Go         | `.go`                               |
| Java       | `.java`                             |
| JavaScript | `.js`, `.jsx`, `.mjs`, `.cjs`       |
| TypeScript | `.ts`                               |
| TSX        | `.tsx`                              |
| Ruby       | `.rb`                               |
| PHP        | `.php`                              |
| C          | `.c`, `.h`                          |
| C++        | `.cc`, `.cpp`, `.cxx`, `.hpp`       |
| C#         | `.cs`                               |
| Rust       | `.rs`                               |
| Kotlin     | `.kt`, `.kts`                       |
| Scala      | `.scala`, `.sc`                     |
| Bash       | `.sh`, `.bash`, `.zsh`              |
| Lua        | `.lua`                              |
| Julia      | `.jl`                               |
| OCaml      | `.ml`, `.mli`                       |
| HTML       | `.html`, `.htm`, `.vue`             |
| JSON       | `.json`                             |
| YAML       | `.yaml`, `.yml`                     |
| XML        | `.xml`                              |
| HCL        | `.tf`, `.hcl`                       |

### Regex-only languages

Dockerfile, Solidity, Swift, Dart, R, Clojure, Elixir, Erlang, Scheme, Lisp, and generic/text files are matched using regex patterns.

## Rule Format

xgrep supports the Semgrep YAML rule format:

```yaml
rules:
  - id: my-rule
    pattern: eval(...)
    message: Avoid using eval()
    severity: WARNING
    languages: [python]
```

Supported rule features include:
- `pattern`, `patterns`, `pattern-either`, `pattern-not`, `pattern-inside`, `pattern-not-inside`
- `pattern-regex`, `pattern-not-regex`
- Metavariables (`$VAR`, `$...ARGS`)
- `metavariable-pattern`, `metavariable-regex`, `metavariable-comparison`
- `focus-metavariable`
- `fix` (autofix support)
- Taint analysis (`mode: taint` with `pattern-sources`, `pattern-sinks`, `pattern-sanitizers`, `pattern-propagators`)
- Supply chain rules (`r2c-internal-project-depends-on`)
- `options` including `interfile: true` for cross-file analysis
- `min-version` / `max-version` for engine version constraints

See the [Semgrep rule syntax documentation](https://semgrep.dev/docs/writing-rules/rule-syntax) for details.

## Testing Rules

Use `xgrep test` to validate rules against annotated test files:

```bash
xgrep test rules/
```

Test files use comment annotations to mark expected matches:

```python
# ruleid: my-rule
eval(user_input)

# ok: my-rule
safe_function(data)

# todoruleid: my-rule
not_yet_supported()
```

## Output Formats

### Text (default)

```
src/app.py:10:my-rule: Avoid using eval()
```

### JSON

```bash
xgrep -f rules.yaml --json src/
```

### SARIF

```bash
xgrep -f rules.yaml --sarif src/
```

## LSP Support

xgrep includes a Language Server Protocol server for editor integration:

```bash
xgrep -f rules.yaml lsp
```

The LSP server communicates over stdio and provides real-time diagnostics as you edit code.
