A Rust command centre for autonomous security operations.
Most "agentic" tooling is a confidence trick performed with logs. Serpantoxide takes the less glamorous view that orchestration should be explicit, typed, inspectable, and difficult to romanticise. It is a Rust runtime for running a crew of security workers with a proper operator surface, shared state, browser control, topology intelligence, and just enough suspicion about its own abstractions to remain useful.
In plain English: this is a working offensive-security console. It plans, delegates, watches, revises, records, and reports. It has a production TUI, an experimental macOS GPUI shell, and very little interest in pretending that "AI" is a substitute for instrumentation.
Because the usual arrangement is intolerable.
- Python prototypes become accidental constitutions.
- Agent frameworks multiply concepts the way damp basements multiply fungus.
- Tool calls vanish into stringly typed fog.
- Interfaces soothe the operator precisely when they ought to confess uncertainty.
Serpantoxide is the opposite design instinct: fewer illusions, harder edges, better visibility.
- A live terminal UI with telemetry, worker logs, topology views, inspection panes, and report generation.
- An experimental native macOS shell built on the same runtime.
- A mission-aware crew orchestrator that can infer intent, publish a checklist, spawn, monitor, and synthesise multiple workers.
- Worker agents that operate as iterative tool-calling loops rather than decorative one-shot prompts.
- Native tools for
terminal,browser,web_search,notes,nmap,sqlmap,osint,hosting,image_gen, andevm_chain. - Persistent findings in
loot/notes.json, filtered by active target when a scope is set. - Prompt history, multiline completion lists, target-aware autocomplete, shared operator note storage, pause-and-correct control, and persisted mission/config state.
- A lightweight graph model that turns findings into something closer to intelligence.
- Deterministic mock mode when provider keys are absent, because pretending otherwise would be vulgar.
Serpantoxide is arranged around four deliberate layers:
main.rsboots the selected frontend.runtime.rsandautomation.rsprovide the shared command, event, snapshot, and operator-control model.orchestrator.rsthinks in campaigns.worker_agent.rsdoes the grubby work and returns with evidence.
That separation matters. The orchestrator is there to think at a level above a shell command. The workers are there to prevent those thoughts from floating away into rhetoric.
- Rust toolchain with
cargo - Chromium or a compatible browser runtime for
chromiumoxide - Optional native binaries:
nmapsqlmapholehesherlocktheHarvester
- Optional environment variables:
OPENROUTER_API_KEYDEEPSEEK_API_KEYTAVILY_API_KEYGOOGLE_API_KEYETHERSCAN_API_KEYEVM_RPC_URLLLM_MODEL
cargo runIf startup goes sideways before the UI appears, inspect:
tail -n 80 /tmp/serpantoxide-startup.log# Default TUI
cargo run
# Experimental macOS shell
cargo run -- --gpui
# Force the TUI explicitly
cargo run -- --tuiscripts/package_macos_app.sh
scripts/package_macos_app.sh --target x86_64-apple-darwin --zip/agent <task> Run a focused autonomous assessment
/crew <task> Run multi-agent crew mode
/preset [name] Show or select a mission preset
/presets List mission presets
/target <host> Set the active target
/tools Show worker capabilities
/notes [category] Show stored findings
/store <cat> <text> Store an operator note in shared knowledge
/config Show runtime config
/config set ... Update runtime config
/pause [all|crew|agent-id]
/resume [all|crew|agent-id] [instruction]
/memory Show graph-derived intelligence
/topology Open the interactive topology explorer
/prompt Show the crew prompt
/report Generate a markdown report
/models Open the model picker
/keys Open the provider key editor
/clear Clear telemetry
/help Show help
/modes Show mode and prefix help
/quit Exit
The TUI prompt also supports:
- freeform non-slash input as an implicit crew mission
- multiline paste
UpandDownprompt history navigation when no completion list is open- current-line completion inside multiline drafts with a scrollable suggestion list
UpandDownsuggestion navigation plusTabaccept for completions- target-aware LLM ghost-text completion for single-line prompts
- runtime lane enforcement that blocks off-scope tool calls and forces a replan
Escto pause all active automation, inject corrective instructions, and resumePto pause the selected worker and inject a worker-specific correction
Workers can call:
terminalbrowserweb_searchnotesnmapsqlmaposinthostingimage_genevm_chain
And if subtlety is getting in the way, forced intent prefixes are available:
NMAP: <host>
SQLMAP: <url>
BROWSER: <url>
SEARCH: <query>
TERMINAL: <command>
OSINT: <tool and target>
HOSTING: <action and path>
IMAGE: <prompt>
EVM: <action and address/query>
Serpantoxide stores local runtime state in .serpantoxide_config. If OPENROUTER_API_KEY or DEEPSEEK_API_KEY is present, it loads those provider catalogs into /model. If both are absent, the runtime drops into deterministic mock behaviour. This is not a scam. It is simply the difference between a live provider and a rehearsal.
Current persisted fields:
{
"selected_model": "openai/gpt-4o",
"selected_preset": "auto",
"last_target": "example.org",
"max_iterations": 16
}You can inspect and update the runtime config from inside the app:
/config
/config set max_iterations 24
Typical configuration:
OPENROUTER_API_KEY=...
DEEPSEEK_API_KEY=...
TAVILY_API_KEY=...
GOOGLE_API_KEY=...
ETHERSCAN_API_KEY=...
EVM_RPC_URL=...
LLM_MODEL=openai/gpt-4osrc/
main.rs
automation.rs
runtime.rs
startup_trace.rs
tui.rs
gpui_app.rs
orchestrator.rs
pool.rs
worker_agent.rs
mission.rs
llm.rs
browser.rs
notes.rs
graph.rs
terminal.rs
nmap.rs
sqlmap.rs
osint.rs
hosting.rs
image_gen.rs
evm_chain.rs
prompts.rs
events.rs
config.rs
- docs/OPERATOR_RUNTIME_SPEC.md
- docs/OPERATIONS.md
- docs/TOOL_REFERENCE.md
- docs/DEVELOPMENT.md
- docs/GIT_SPLIT.md
cargo fmt
cargo check
cargo testUse this only against systems you are authorised to assess. Good tooling does not suspend ethics. It merely removes the excuse of incompetence.