Reads the files. Does not run them.

TraceLamp scans a repository for what AI agents and MCP servers can touch: tools, data stores, credentials, and cloud spend.

A scan is static, no-execute, and meant for CI. It never spawns a process and never opens a network connection.

01 Scanner

What a scan actually does

You pass a path. TraceLamp reads files under that path and applies in-process rules. MCP config files are parsed as text. The scanner does not start those servers to ask them for a tool list.

Tree-sitter covers Python, JavaScript, TypeScript, Go, and Rust for functions, API endpoints, and the difference between a shell call and a database call. Other languages use a regex fallback. exec.Command is shell. db.Exec is not.

Hidden paths such as .cursor/mcp.json are still scanned. Default skips include .git, node_modules, target, vendor, dist, build, __pycache__, .venv, and .go. The walk also honors .gitignore, .tracelampignore, and .reconignore. Binary files and files larger than 1 MiB are skipped.

02 Install

Build from source

No release archives are published, and the crate is not on crates.io. There is no install command to download a binary. Build the tagged source you cloned.

git clone https://github.com/cdobratz/TraceLamp.git
cd TraceLamp
cargo build --locked --release

That produces two binaries:

  • target/release/tracelamp
  • target/release/recon, the same CLI under the old command name

On Windows the file names end in .exe. HTTP uses rustls, so the build does not need OpenSSL.

When a git tag vX.Y.Z matches the version in Cargo.toml, GitHub Actions builds archives for Linux x86_64, Linux aarch64, macOS Intel, macOS Apple Silicon, and Windows x86_64. Until that tag exists, those files are not on the release page. Do not expect a download URL to resolve.

Checks used in this repo: cargo test --locked (the static-scan tests need strace) and cargo clippy --locked --all-targets -- -D warnings.

03 Use

Commands

The binary name is tracelamp. Global flags are --config <file> and -v, repeated for more log detail. RUST_LOG overrides that filter.

tracelamp scan <path>
tracelamp scan <path> --format json
tracelamp scan <path> --format sarif
tracelamp scan <path> --format mermaid
tracelamp scan <path> --format cyclonedx
tracelamp scan <path> --only agents,mcp
tracelamp scan <path> --write-baseline tracelamp-baseline.json
tracelamp scan <path> --baseline tracelamp-baseline.json
tracelamp analyze <path>
tracelamp analyze <path> --llm --provider openai --max-cost 0.25
tracelamp report <path> --format sarif --output report.sarif
tracelamp skill add ./todo.toml
tracelamp skill list
tracelamp skill run todo --target <path>
tracelamp skill remove todo
tracelamp agent add ./reviewer.toml
tracelamp agent list
tracelamp agent run reviewer --target <path>
tracelamp agent run reviewer --target <path> --llm
tracelamp config init
tracelamp config show

scan writes the terminal by default. Formats are terminal, json, sarif, mermaid, and cyclonedx. --only and --ignore take comma-separated lists. --ignore uses gitignore syntax.

--baseline prints findings whose fingerprint is not already in the file and exits 1 when any remain. --write-baseline records the current findings and does not fail the run. A fingerprint is the SHA-256 of the rule id, the path relative to the scan root, and the snippet with whitespace collapsed. Line numbers are not part of it.

analyze scores the static findings. Add --llm to also send those findings and short snippets to a model. The default provider is local Ollama (llama3.2 at http://localhost:11434, or OLLAMA_HOST). --provider openai reads OPENAI_API_KEY. --provider anthropic reads ANTHROPIC_API_KEY. The run stops when the estimated cost would pass llm.max_cost_usd (0.25 by default). Ollama is priced at zero.

A skill is a TOML file of regex search patterns. An agent runs the static scan, then its skills, then the rule scores. --llm or use_llm = true in the agent file is what turns the model on.

04 Local MCP

Keep the server on your machine

TraceLamp can speak MCP. That server is part of the CLI you run locally. This website does not scan repositories, and there is no hosted TraceLamp API.

Stdio is the default. A client config can point at the binary:

{
  "mcpServers": {
    "tracelamp": {
      "command": "tracelamp",
      "args": ["mcp", "serve"]
    }
  }
}

The server name is tracelamp. Log lines go to stderr so they stay off the protocol stream. Tools:

  • scan_repo reads a repository path on that machine.
  • list_findings reads the same kind of path and can filter by severity.
  • explain_finding explains one rule id.
  • agent_inventory returns the agent, MCP server, tool, data store, and credential inventory.

HTTP is optional and still local:

tracelamp mcp serve --transport http --port 3000
tracelamp mcp connect "tracelamp mcp serve"
tracelamp mcp connect http://127.0.0.1:3000/mcp

The HTTP process listens on 0.0.0.0:<port> and serves /mcp. The accepted hosts are localhost, 127.0.0.1, ::1, and 0.0.0.0. There is no login and no tenant boundary. scan_repo reads whatever path the caller passes on that machine. Do not publish this port.

tracelamp scan does not start the MCP server. tracelamp mcp connect either spawns a stdio command or opens an http:// or https:// endpoint.

05 Reports

JSON, SARIF, Mermaid, CycloneDX

JSON includes inventory (agent, MCP server or tool, data store, credential) and inventory_mermaid. --format mermaid prints only the diagram. --format cyclonedx prints a CycloneDX 1.6 document of that inventory. The export does not fetch a schema and does not contact a registry.

SARIF output is 2.1.0. The tool driver name is tracelamp. informationUri is https://tracelamp.dev. Each built-in rule is listed under tool.driver.rules with help text and its OWASP Agentic ASI tags. Result ruleId values keep the recon/ prefix so existing baselines and suppressions stay valid.

Suppress a finding with tracelamp:ignore <rule-id> on the same line or the previous line. recon:ignore <rule-id> still works. //, #, and /* */ comments all work. Several rule ids can be separated by spaces or commas.

06 Limits

What it will not do

  • scan, report, and analyze without --llm only read files. They do not spawn npx, uvx, a shell, or any other process, and they do not connect to MCP URLs, package registries, or LLM APIs.
  • --llm is off unless you set it. It sends findings and short snippets, not whole files.
  • The MCP HTTP listener is a local process with a host allowlist and no authentication. It is not a multi-user scan backend.
  • Config, skills, and baseline files live on the local disk. There is no database.
  • TraceLamp defines no RECON_ environment variables. Provider variables stay OPENAI_API_KEY, ANTHROPIC_API_KEY, and OLLAMA_HOST.

07 Docs

Rules, config, aliases

Rule ids are stable. They are the strings stored in baselines, SARIF, and inline suppressions.

RuleASIWhat it flags
recon/shell-execution ASI05 Real process spawns (exec.Command, subprocess, os.system, child_process). Not db.Exec.
recon/mcp-unpinned-package ASI04 npx or uvx package with no exact version. pkg@1.2.3 and pkg==1.2.3 do not match.
recon/mcp-remote-cve-2025-6514 ASI05 mcp-remote versions 0.0.5 through 0.1.15 (CVE-2025-6514).
recon/mcp-secret-in-env ASI03 Literal secret in an MCP env value. ${VAR} references do not match.
recon/mcp-filesystem-root ASI02 Filesystem root set to / or ~.
recon/mcp-shell-without-approval ASI02, ASI05 Shell or exec tool with no approval flag.
recon/agent-cloud-spend ASI02 Agent or MCP server with cloud credentials, a cloud CLI or IaC apply, or a cloud write tool.

Configs read for the inventory: mcp.json, .mcp.json, .cursor/mcp.json, .vscode/mcp.json, claude_desktop_config.json, and LangChain tool lists.

Config file

tracelamp config init creates ~/.config/tracelamp/config.toml when neither config file exists. If only ~/.config/recon/config.toml exists, init and config set keep using that file. When both exist, the TraceLamp file wins.

config set and config get accept llm.provider, llm.model, llm.api_key, llm.base_url, llm.max_cost_usd, llm.max_findings, llm.max_snippet_chars, report.default_format, and report.min_severity. The default provider is ollama. The default serve transport in the sample config is stdio on port 3000. The running command uses its own --transport and --port flags.

Names that still work

CurrentStill accepted
tracelamprecon command, installed as a second binary
~/.config/tracelamp/config.toml~/.config/recon/config.toml when the TraceLamp file is absent
.tracelampignore.reconignore
tracelamp:ignorerecon:ignore

Skills are copied into the directory in skills.directory, which defaults to skills relative to the working directory.