Updated: 2026-07-20 | Commit: 1722c9b | Branch: main
astgrep (a.k.a. "CR") — Rust workspace for multi-language static analysis. Pattern matching + taint tracking + data flow over tree-sitter ASTs. Targets security vulnerability detection (SQLi, XSS, etc.) across Java/JS/Python/SQL/Bash/XML.
.
├── src/main.rs # Binary entry → delegates to astgrep_cli::run()
│ Also intercepts `mcp` subcommand before CLI parser
│ (to avoid circular dep between astgrep-cli and astgrep-mcp)
├── src/lib.rs # Re-exports all workspace crates
├── crates/
│ ├── astgrep-core/ # Language enum, AstNode trait, Error types, config
│ ├── astgrep-ast/ # UniversalNode, visitor, builder
│ ├── astgrep-parser/ # Tree-sitter adapters per language + registry [→ AGENTS.md]
│ ├── astgrep-matcher/ # Pattern matching, metavariables, conditions
│ ├── astgrep-dataflow/ # Taint/flow/call-graph/constant analysis [→ AGENTS.md]
│ ├── astgrep-rules/ # YAML rule parsing, validation, execution [→ AGENTS.md]
│ ├── astgrep-cli/ # CLI commands (analyze/validate/info/...) + output formats
│ ├── astgrep-mcp/ # MCP (Model Context Protocol) stdio server for AI assistants
│ │ Exposes 4 tools: analyze_code / validate_rules / list_rules / list_languages
│ ├── astgrep-web/ # Axum REST API server (handlers/{analyze,rules,auth,...})
│ ├── astgrep-gui/ # egui desktop playground
│ └── test-utils/ # MockAstNode, MockParser, MockRules
├── tests/categories/ # 43 test categories (patterns/rules/parsing/tainting/...)
├── newtest/ # New test infrastructure (testcases/{lang}/pattern-matching/)
├── docs/ # Design docs (v1..v1.3), API/User/Refactoring guides
└── scripts/ # build-uos.sh, compare_with_semgrep.py
| Task | Location | Notes |
|---|---|---|
| Add new language | crates/astgrep-core/src/types.rs Language enum + crates/astgrep-parser/src/{lang}.rs |
Also update Language::extensions() and registry |
| Add/modify rules | crates/astgrep-rules/src/parser/ + tests/categories/rules/ |
YAML format with patterns/metavariables/dataflow |
| Pattern matching | crates/astgrep-matcher/src/matcher.rs → advanced_matcher.rs |
PreciseExpressionMatcher for exact matching |
| Taint analysis | crates/astgrep-dataflow/src/taint.rs → enhanced_taint.rs |
Source→Sink flow with sanitizer support |
| CLI commands | crates/astgrep-cli/src/commands/*.rs |
14 commands including migrate, validate_enhanced |
| Output formats | crates/astgrep-cli/src/output/analysis/{sarif,json,text,html,markdown,semgrep}.rs |
6 output formats |
| MCP tools | crates/astgrep-mcp/src/tools/{analyze,validate,query}.rs |
4 tools over stdio; calls analyze_collect / validate_collect |
| MCP server | crates/astgrep-mcp/src/server.rs |
AstgrepServer with rmcp 0.2 SDK, stdio transport |
| SQL parsing | crates/astgrep-parser/src/sql.rs |
Uses tree-sitter-sequel, NOT tree-sitter-sql |
| SQL dialects | crates/astgrep-parser/src/dialect/ |
SqlDialect enum + dispatcher; GaussDB→ogsql-parser, PolarDB→sqlparser-rs |
| SQL dialect adapters | crates/astgrep-parser/src/adapter/{ogsql,sqlparser}/ |
Convert parser-specific AST → UniversalNode |
| SQL dialect rules | tests/categories/rules/sql_dialects/{gaussdb,polardb_mysql}/ |
Dialect-specific YAML rules |
| Error types | crates/astgrep-core/src/error.rs |
AnalysisError enum with thiserror |
| Config | crates/astgrep-core/src/config.rs |
AnalysisConfig, SQL statement boundary toggle |
| Test cases | tests/categories/{category}/cases/{concern}/ |
@rule/@expect/@desc annotations; see tests/CONVENTIONS.md. Legacy semgrep-core tests in patterns/ use // MATCH: format |
cargo build # Build all workspace crates
cargo build --release # LTO + codegen-units=1 + panic=abort
cargo test # All tests
cargo test -p astgrep-core # Single crate
cargo test -p astgrep-parser # Parser crate
cargo test -p astgrep-rules # Rules crate
cargo test test_name -- --nocapture # Single test with output
RUST_LOG=debug cargo run -- analyze # Debug logging
cargo run -- analyze # Analyze current dir
cargo run -- validate rules/*.yml # Validate rule YAML files
cargo run -- info --extensions # List supported languages + extensions
cargo run -- analyze --format sarif -o results.sarif # SARIF output
cargo run -- mcp # Start MCP server over stdio (for AI assistants)
cargo run -- mcp --rules-dir tests/categories/rules/ # MCP server with custom rules dir- Language enum (
astgrep_core::Language) has 6 variants: Java, JavaScript, Python, Sql, Bash, Xml — but parser crate has modules for C/C#/Kotlin/Ruby/Swift/PHP too (tree-sitter adapters without full Language enum support yet) - Workspace deps defined in root
Cargo.toml [workspace.dependencies], referenced viaworkspace = true - Re-exports at crate root:
pub use module::*pattern used heavily — checklib.rsbefore importing from submodules - Tree-sitter version: 0.25 for most grammars, 0.23.5 for Java, 0.3.11 for sequel (SQL)
- Release profile: LTO=true, codegen-units=1, panic=abort — benchmark before merging perf-sensitive changes
- Test infrastructure: Rule-driven categories follow self-describing pattern in
tests/CONVENTIONS.md(@rule/@expect/@descannotations +rules/+cases/layout). Validate withpython3 tests/scripts/validate_annotations.py. Legacy semgrep-core tests inpatterns/,semgrep-core/use// MATCH:/// ERROR:format — seetests/README.md. - SQL statement boundary: Configurable via CLI
--sql-statement-boundaryflag or YAMLoptions.sql_statement_boundary - Pre-commit hooks: Run
lefthook installafter cloning. Hooks enforce fmt + clippy on commit, full test + audit on push. - Release workflow: Tags (vX.Y.Z) must be on the
mainbranch. The release workflow aborts if the tag is on a feature branch. - MCP tools implement
analyze_collect/validate_collect: These are core reusable functions extracted fromastgrep-clicommands. When adding new MCP capabilities, call them rather than duplicating CLI logic. - MCP circular dependency:
astgrep-mcpdepends onastgrep-cli(forEnhancedAnalysisConfig,analyze_collect, etc.). To avoid a cycle, themcpsubcommand is intercepted insrc/main.rsbeforeastgrep_cli::run(). TheCommands::Mcpvariant exists in the CLI enum for--helpdocumentation but hitsunreachable!()if reached.
anyhow::Resultfor application error propagationthiserrorfor typed errors inastgrep-core::error::AnalysisError- Use
.context("...")when wrapping; use?operator throughout - Never use
unwrap()in production code;expect("reason")acceptable in tests only
- Do NOT use
tree-sitter-sql— usetree-sitter-sequelfor SQL parsing - Do NOT add dependencies directly to crate Cargo.toml — add to workspace deps first, then
workspace = true - EXCEPTION: non-crates.io external deps (git sources like
ogsql-parser) MUST be declared explicitly in the consuming crate, NOT viaworkspace = true— otherwise the crate cannot be consumed as a path dependency from another workspace (see issue #21) - Do NOT modify
Languageenum without also updating parser registry +Language::extensions()+Language::from_str() - Do NOT write tests without annotations — use
@rule/@expect/@descfor rule-driven tests (seetests/CONVENTIONS.md), or// MATCH:/// ERROR:for semgrep-core legacy tests - Do NOT use
as any,unwrap()in non-test code - Do NOT suppress warnings with
#[allow(...)]without a comment explaining why - Do NOT add a direct dependency from
astgrep-clitoastgrep-mcp— this creates a circular dep. Handle MCP routing atsrc/main.rslevel.
- Root
src/lib.rsre-exports all workspace crates with aliases —astgrep_coreavailable ascrates::core crates/astgrep-cli/src/commands/has both_enhancedand base versions of analyze/validate — enhanced versions are the newer APInewtest/directory contains an alternative test infrastructure alongsidetests/categories/- Various stray files at root (test_*.rs, *.sh, *.py) are ad-hoc scripts, not part of the build
crates/astgrep-guiandcrates/astgrep-webare secondary interfaces — CLI is primarycrates/astgrep-mcpis a third interface that exposes analysis via MCP protocol for AI assistants (Claude Desktop, Copilot, etc.)- MCP server uses
rmcp0.2 SDK with#[tool]/#[tool_router]macros. New tools are added as methods onAstgrepServer.