If you're running security reviews with an AI coding agent, you've probably noticed that different agents produce wildly different output for the exact same task. Ask Claude Code to do a SAST pass and you get one shape of report. Ask Gemini CLI or Codex the same question and you get another, different headings, different severity language, sometimes a different idea of what counts as a "finding" at all.
Most agentic security tools deal with this by picking one agent and building around it. We built SecFoo to work with whatever you've already got instead: Claude Code, Cursor, Gemini CLI, Codex, GitHub Copilot CLI, Antigravity, Factory Droid, or Devin. Same 9 security skills (SAST, secret scanning, threat modeling, SCA reachability, security architecture review, and a few others), your choice of agent, comparable output every time.
The part that was actually hard
Writing a good security review prompt isn't the hard part. The hard part is getting nine wildly different agents to produce results you can parse, compare, and track over time, without hardcoding around any single one of them.
SecFoo handles this with an adapter layer. Every agent integration subclasses a common AgentAdapter base class that owns the boring-but-critical stuff: binary detection, timeouts, process-tree kill on timeout (important: some agents spawn grandchildren that outlive a naive kill()), and result capture. Each adapter's actual job is small: build the right command line for that agent, and parse its usage/cost figures if it reports them.
On top of that, every skill has a fixed output contract: a required "Overall risk rating:" line, and "### [SEVERITY] ID: title" headings for every finding. It doesn't matter if Claude Code phrases a finding one way and Codex phrases the same category of bug completely differently, SecFoo can still parse severity, CWE, and location out of either, because the contract is enforced at the skill level, not left to whatever the agent feels like producing that day.
What a run actually does
For anyone curious about the mechanics, here's the pipeline for a single --skill run (skills run concurrently when you pass more than one):
- Resolve the target - a local path as-is, or a shallow clone of a GitHub URL, cleaned up afterward.
- Detect the stack - languages from file extensions, frameworks from manifests (package.json, requirements.txt, pom.xml, go.mod). Never inferred from the model's own prose, so it's consistent across runs and across agents.
- Render the prompt - a read-only safety preamble, the skill's instructions, depth guidance, scope exclusions, and the skill's output contract.
- Run the agent - the adapter launches the agent CLI as a subprocess (or calls a model API directly for the api agent), with a timeout and process-tree kill.
- Capture - report, prompt, and logs get written locally, plus token/cost figures where the agent reports them.
- Parse - severity counts and structured findings get pulled out of the report using the fixed contract, and CVSS scores get computed by SecFoo itself rather than trusted from the agent's own text.
Steps 3 through 6 are where the adapter pattern earns its keep: everything downstream of "run the agent" is agent-agnostic.
Where this is still rough
Not every agent gets equal treatment yet. MCP tooling (used for things like Confluence context) is wired up automatically for Claude Code, and available via a one-time secfoo mcp sync for Cursor and Gemini CLI, but Codex, Copilot, Droid, and Devin don't have it wired yet. Antigravity's CLI doesn't expose an MCP mechanism at all, so it's a dead end there for now. The api agent (plain model API via LiteLLM, no CLI) has no tool loop, so it just gets the target's source pasted into the prompt, fine for small to medium repos, not great for anything large.
None of that is hidden. It's the honest state of an open source project that's still adding adapters.
Try it
SecFoo is MIT licensed: https://github.com/secfoo-com/secfoo
If you're already running Claude Code, Cursor, Gemini, Codex, Copilot CLI, or any of the others for day to day work, this points the same agent at your repo for a security pass instead of needing a separate, agent-specific tool. Built at RakFort (https://www.linkedin.com/company/rakfort). Curious what agent CLIs people are actually standardizing on, and whether consistency across agents is a problem anyone else has run into outside of security review specifically.
Top comments (0)