Introduction
Secfoo is a context-based security architectural assessment orchestrator. Pick one or more security activities, point them at a target, choose which coding-agent CLI runs them, and browse every assessment ever run in a local web dashboard.
What Secfoo does
- Runs any of 8 activities — architecture review, threat modeling, SAST, SCA, secret scanning, prompt review, deployment readiness, Responsible AI compliance — concurrently against the same target.
- Targets a public GitHub URL, a local directory, plus optional Confluence pages for extra context.
- Drives Claude Code, Cursor, Antigravity, or Gemini CLI as the agent that actually performs the review.
- Stores every run locally and serves it from
secfoo serve— a dashboard that never calls out to a CDN while you're reading a report.
secfoo vendor mermaid once (~3.5MB) to render it as a picture in the dashboard — without it, the diagram source still appears, just unrendered.
Installation
Pick whichever fits how you work — they're all the same tool underneath.
pip install secfoonpm install -g @rakfortltd/secfoocurl -fsSL https://raw.githubusercontent.com/secfoo-com/secfoo/main/install.sh | shirm https://raw.githubusercontent.com/secfoo-com/secfoo/main/install.ps1 | iexdocker run --rm ghcr.io/secfoo-com/secfoo --helppip install -e ".[dev]"Quickstart
# 1. Run a skill against the current directory
secfoo run --skill security-architecture-review --agent claude
# 2. List past runs
secfoo list
# 3. Launch the dashboard
secfoo serve
On a real terminal, step 1 asks for a project name and application ID before it runs — that's what makes the case file it creates findable later on the Assessments page instead of just a bare run. Skip the prompt with --project-name/--app-id flags, or leave it non-interactive (CI, scripts) and it's skipped automatically. See the CLI reference for the full flag list.
Configuration
Set a default agent, depth, timeout, exclusions, and MCP servers once in ~/.secfoo/config.toml, instead of passing flags on every secfoo run. The file is plain TOML, entirely optional — an empty or missing config is fine, secfoo just falls back to built-in defaults — and CLI flags always win over whatever it sets.
secfoo config init # writes a starter ~/.secfoo/config.toml
[defaults]
Fallbacks for secfoo run's --agent, --depth, --timeout, and --exclude flags.
| Key | Type | Default | Notes |
|---|---|---|---|
agent | string | claude | claude · agent (Cursor) · agy (Antigravity) · gemini |
depth | string | quick | quick (fast triage) or standard (full checklist) |
timeout | integer | agent's own default | Per-skill timeout, in seconds |
exclude | array of strings | [] | Additive on top of secfoo's built-ins (node_modules/, .git/, dist/, …) — never a replacement for them. --exclude on the command line adds further paths on top, for a single run. |
[[mcp_servers]]
Define MCP servers once here instead of wiring each agent CLI separately — e.g. an Atlassian/Confluence connector for --confluence context. Repeat the [[mcp_servers]] table for each server.
| Key | Required | Notes |
|---|---|---|
name | Yes | Unique identifier — secfoo mcp list and secfoo mcp sync refer to servers by this. |
command | Exactly one of command / url | stdio transport — the binary secfoo runs, e.g. npx. |
args | No | Array of arguments passed to command. |
url | Exactly one of command / url | sse/http transport — a remote MCP endpoint. |
transport | No | Default stdio. Set to sse or http alongside url. |
env | No | Key-value environment variables passed to a stdio process. |
headers | No | Key-value HTTP headers for an sse/http server, e.g. an Authorization bearer token. |
[[mcp_servers]] entry fails config loading with mcp_servers.<name>: set exactly one of command (stdio) or url (sse/http).How a configured server actually reaches an agent depends on that agent's own CLI:
secfoo run (via --mcp-config, scoped to that invocation only — your global Claude config is never touched).secfoo mcp sync --agent <agent> once to register persistently in that tool's own config. Re-run after adding new servers — already-registered ones are skipped.A complete example — one stdio server bridged through npx, one remote server reachable directly over HTTP:
[defaults]
agent = "claude"
depth = "quick"
# timeout = 1800
# exclude = ["vendor/", "third_party/", "some-cloned-repo/"]
# Atlassian (Confluence/Jira) via the official Rovo MCP server, bridged
# through the mcp-remote npm package (stdio transport: secfoo just needs
# a command + args to run).
[[mcp_servers]]
name = "Atlassian-Rovo-MCP"
command = "npx"
args = ["-y", "mcp-remote@latest", "https://mcp.atlassian.com/v1/mcp/authv2"]
# A plain remote MCP server reachable directly over HTTP/SSE (no bridge
# needed) -- use url + transport instead of command.
[[mcp_servers]]
name = "example-remote"
url = "https://example.com/mcp"
transport = "http"
headers = { Authorization = "Bearer YOUR_TOKEN" }
Check what's loaded with secfoo mcp list, then see the full mcp / config command reference →