Skip to content

Integrations

0sec ships several integration surfaces for embedding into toolchains, CI pipelines, and discovery workflows. This page documents the shipped surfaces.

The MCP server (0sec mcp-server) exposes 0sec’s live-attack tools through the Model Context Protocol over stdio — any MCP client (Claude Desktop, Cline, Continue, etc.) can drive a 0sec target session.

Source: packages/cli/src/commands/mcp-server.ts

Terminal window
0sec mcp-server \
--target https://target.example.com \
--scan-id my-scan-001 \
[options]
OptionDescription
--target <url>Target URL for this MCP session (required)
--scan-id <id>Scan ID to associate findings and target updates with (required)
OptionDefaultDescription
--db-path <path>Path to SQLite database for persistence
--timeout <ms>30000Per-tool timeout in milliseconds (minimum 1000)
--scope <path>Path to a 0sec scope JSON file. Out-of-scope URLs are refused by every tool
--tools <names>all toolsComma-separated subset of MCP tools to expose
--rate-limit <spec>5 rpsPer-host request rate limit. An active --engagement-profile caps this
--allow-scannersfalseDisable generic-scanner suppression for scoped engagements
--engagement-profile <name>standardHardening posture: standard (default behaviour) or conservative (1 rps/host ceiling, full jitter, no WAF evasion)
--no-waf-evasionenabledDisable the adaptive WAF-evasion ladder (encoding/casing/whitespace mutation on block)

The MCP server exposes these 11 live-attack tools by default (use --tools to select a subset):

ToolPurpose
http_requestSend an HTTP request to the target
crawlCrawl the target application for endpoints
submit_formSubmit a form on the target
send_promptSend an LLM prompt to the target
save_findingPersist a discovered finding
update_targetUpdate the target definition mid-session
query_findingsQuery persisted findings
update_findingUpdate an existing finding’s status/metadata
doneSignal session completion
payload_lookupLook up a known payload
wp_fingerprintFingerprint WordPress instances
mongo_objectidGenerate/extract MongoDB ObjectIds

Target authentication is provided via the 0SEC_MCP_AUTH_JSON environment variable. Set it to a JSON object with one of these shapes:

// Bearer token
{"type":"bearer","token":"eyj..."}
// Cookie
{"type":"cookie","value":"session=abc123"}
// Basic auth
{"type":"basic","username":"admin","password":"pass"}
// Custom header
{"type":"header","name":"X-API-Key","value":"sk-..."}

See Configuration for the full --auth flag details used by 0sec scan and 0sec review.

The MCP server supports the same engagement hardening as the scan path. When --engagement-profile conservative is active:

  • WAF-evasion ladder is disabled (regardless of --no-waf-evasion)
  • Per-host rate is capped at 1 rps (config override can only lower it further)
  • Full request jitter is applied to all rate-limit buckets

An explicit --rate-limit value is clamped to the posture’s ceiling. The posture can only make the session quieter than the flag.

The server records an engagement_posture_applied event on the scan for auditability.

MCP supports attribution headers for authorized engagements:

  • 0SEC_MCP_ATTRIBUTION_HEADERS_JSON — JSON array of "Header-Name: value" strings
  • 0SEC_MCP_ATTRIBUTION_UA_TOKEN — free-form User-Agent token appended to the default UA string

Claude Desktop — add to claude_desktop_config.json:

{
"mcpServers": {
"0sec": {
"command": "0sec",
"args": [
"mcp-server",
"--target", "https://target.example.com",
"--scan-id", "claude-session"
],
"env": {
"ANTHROPIC_API_KEY": "sk-ant-..."
}
}
}
}

Cline / Continue — add to the MCP tools configuration:

{
"command": "0sec",
"args": ["mcp-server", "--target", "https://target.example.com", "--scan-id", "cli-session"],
"env": { "ANTHROPIC_API_KEY": "sk-ant-..." }
}

The MCP transport is stdio-only. The host MCP client manages the server process lifetime.

0sec h1 provides read-only access to the HackerOne hacker API for program discovery and scope enumeration.

Source: packages/cli/src/commands/h1.ts

SubcommandDescription
0sec h1 authVerify H1 credentials against the API
0sec h1 programs listPaginate/filter the program list
0sec h1 programs show <handle>Program detail + scope summary
0sec h1 scope dump <handle>Export structured scopes as scope JSON

Credentials are loaded from a h1.env file (see Configuration for the expected path). The H1 API uses Basic auth with a username + API token generated on the HackerOne site. Unlike cloud auth, there is no login flow — the loader reads what you put in h1.env.

CodeMeaning
0Success
1User/data error (bad input, parse failure, missing handle)
2Auth failure (missing creds or HTTP 401/403 from H1)
3Rate-limit or network error
Terminal window
# Verify credentials
0sec h1 auth
# List programs
0sec h1 programs list --limit 20
# Show program detail
0sec h1 programs show my-program-handle
# Export scope for use as a 0sec scope file
0sec h1 scope dump my-program-handle --out my-scope.json

0sec auth manages 0sec-cloud credentials via a browser-based OAuth flow.

Source: packages/cli/src/commands/auth.ts

SubcommandDescription
0sec auth loginOpen browser at the cloud host’s /cli-auth page, poll for a scoped token
0sec auth login --token <value>Manual credential path — persist a token directly
0sec auth login --host <url>Point at a self-hosted cloud host
0sec auth logoutDelete ~/.0sec/cloud.env and ~/.0cloud/credentials.json
0sec auth statusVerify cloud credentials against GET /health

Credentials persist to ~/.0sec/cloud.env (mode 0600) with the format:

# 0sec-cloud credentials. Managed by `0sec auth`.
# DO NOT commit this file or share its contents.
0SEC_CLOUD_HOST=https://cloud.0.security
0SEC_CLOUD_TOKEN=scoped-token-here

On logout both ~/.0sec/cloud.env and ~/.0cloud/credentials.json are removed. Cloud auth uses Bearer tokens, not Basic auth.

For self-hosted or recovery use, pass a token directly:

Terminal window
0sec auth login --token "your-token" --host "https://your-host.example.com"

This skips the browser flow entirely and persists the token immediately.

0sec can emit results in several machine-readable and human-readable formats. scan, review, and audit accept --format; available formats and short aliases are command-specific. Their default is terminal output, not JSON.

Source: packages/cli/src/formatters/

FormatFlagDescription
JSON--format jsonStructured JSON with findings, summary, and metadata
SARIF--format sarifStatic Analysis Results Interchange Format — upload to GitHub Code Scanning or other SARIF consumers
HTML--format htmlSelf-contained HTML report with severity bars, finding cards, collapsed evidence
PDF--format pdfPDF report via pdfkit (US Letter). Tables, severity bars, finding details
Markdown--format markdownMarkdown report
Terminal--format terminalTerminal-formatted output with ANSI colors

The SARIF output is compatible with github/codeql-action/upload-sarif@v4. See GitHub CI for a full workflow example.

Terminal window
0sec review . --format sarif > results.sarif
Terminal window
0sec scan --target http://127.0.0.1:8080 --scope ./scope.json --format pdf

The PDF formatter lazily loads pdfkit so the bun-compiled binary never bundles it. Output is US Letter format with severity-colored sections.

Terminal window
0sec scan --target http://127.0.0.1:8080 --scope ./scope.json --format html

The HTML formatter produces a standalone page with severity bars, finding cards, collapsed request/response evidence, and meta tags.

The 0sec engine is published as a multi-architecture Docker image on GitHub Container Registry:

ghcr.io/0sec-labs/0sec:latest
ghcr.io/0sec-labs/0sec:<sha>
ghcr.io/0sec-labs/0sec:main

Source: Dockerfile

The runtime image (based on ubuntu:24.04) includes:

CategoryTools
Node.js runtimeNode 24 (copied from builder stage), npm, npx
Static analysisFoxGuard (pre-provisioned, checksum-pinned)
Web pentestingsqlmap, nmap, nikto, gobuster, hydra, ffuf, wfuzz, whatweb, wafw00f, dirb
Active Directoryimpacket (0.13.1), certipy-ad (5.1.0), bloodhound-ce (1.9.1), ldap-utils, krb5-user
Cloud identityAzureHound (v3.0.0, checksum-pinned)
Source analysisripgrep (for fast source-tree searches in audit/scan), jq, git
Container analysisskopeo
Scriptingpython3, python3-requests, python3-bs4
OptionalSecLists wordlists (INSTALL_SECLISTS=1 build arg, ~1GB extra)
Terminal window
docker run --rm \
-e ANTHROPIC_API_KEY=$KEY \
-v "$PWD:/work" -w /work \
ghcr.io/0sec-labs/0sec:latest review .
# Scan a web target
docker run --rm \
-e OPENAI_API_KEY=$KEY \
ghcr.io/0sec-labs/0sec:latest scan \
--target https://example.com \
--scope /work/scope.json

The container runs as the ubuntu user (uid 1000). Mount your working directory at /work if you need the container to read source code or write reports.

  • The image drops privileges to the ubuntu user before executing commands
  • Build args INSTALL_SECLISTS (off by default) and AZUREHOUND_VERSION control optional inclusions
  • Third-party tools are installed via apt with known-good versions from ubuntu:24.04 or pinned PyPI/Go release checksums
  • The AD tools venv is deliberately not on PATH to avoid shadowing system Python packages
Terminal window
docker build -t 0sec:local .
docker build --build-arg INSTALL_SECLISTS=1 -t 0sec:full .

0sec supports two plugin mechanisms:

  • Model-authored executable plugins — TypeScript code submitted by the model at runtime, executed in isolated Docker containers or smolvm microVMs. These are the primary self-extension path, enabled by default for non-verifier agents (operator can opt out via allowModelSelfExtension: false).
  • Third-party operator plugins — CLI-managed plugins from the operator marketplace. Scaffolded; no marketplace ships.

Model-authored executable plugins (self-extension)

Section titled “Model-authored executable plugins (self-extension)”

The model can submit TypeScript source files as an executable plugin during a session. Each plugin declares a manifest with tool names, descriptions, JSON parameter property schemas, and capabilities that gate broker access:

CapabilityDescription
computeGuest-local computation, including scratch files; no host filesystem or provider access
model-callMay call the configured model provider through a controller-owned broker
networkRequests to authorized host network tools, subject to the parent’s scope
filesystem-read / filesystem-writeRequests to authorized host filesystem tools, subject to local scope
process-exec / findings-writeApplicable host execution or finding-publication gates; explicitly denied broker tools remain unavailable

A plugin’s entry source file exports an async run(toolName, args, sdk) function. The sdk object provides three broker methods:

  • sdk.callTool(name, args) — calls another registered executable tool or an available host tool through the parent’s authorization gates. Returns output or throws.
  • sdk.callSkill(name, args) — calls another registered executable skill by name. Throws if not found.
  • sdk.callModel({system?, messages?, tools?}) — delegates a model request through the controller’s authorized provider front door. Requires the model-call capability.

Guest code runs in an isolated guest (Docker backend by default) with no network, read-only root, and bounded resources. The guest SDK cannot invoke host execution tools (bash, run_command, python_exec), delegation tools (spawn_agent, spawn_agents), or control tools (self_extend, apply_patch, write_file). Nested invocations share a single broker call budget and are limited to depth 4.

Manifest parameters is a properties bag, for example {"value":{"type":"number"}}, with required declared beside it—not a complete {"type":"object","properties":...} schema. Source uses Node 24’s native TypeScript stripping; use erasable TypeScript syntax and provision dependencies in the toolbox rather than assuming a full TypeScript compiler runs on admission.

  1. Submitsubmit({manifest, files, entry, kind?}, context) saves an immutable versioned snapshot, validates the source in a guest container (admission), and activates it.
  2. Executeexecute(toolName, args, context) runs the active version’s entry function with the supplied arguments. Failed executions increment the version’s failureCount and record lastError.
  3. Replace — submitting the same plugin id creates a new active version. Prior versions are retained for rollback (up to 32 per plugin).
  4. Listlist() returns every retained version with its evidenceStatus (structural for direct submits, measured for evolved versions), active flag, failureCount, and lastError.
  5. Rollbackrollback(pluginId, versionId, context) reactivates a prior version. Retains the rolled-back version for further rollback.
  6. Evolveevolve(pluginId, profile, deps, context) runs the improvement loop over the active version’s snapshot, producing a new measured version on promotion.
  7. Close — releases the manager and aborts pending operations.

For the model-facing lifecycle, use self_extend with action set to submit, list, evolve, or rollback. Point 0SEC_PLUGIN_EVOLUTION_CONFIG at an operator-owned source-evolution config to expose the default evaluation profile. It must use the same backend and pinned image as the executable. Without a profile, creation and replacement work, but measured evolution is unavailable rather than silently approved.

YOLO removes per-action prompts within the configured scope; it does not let generated code replace its evaluator, inherit provider credentials, or expand host authorization. Direct submissions remain structurally admitted—not evidence of improved security performance.

Versions are stored in registry.json under the configured root. Each version records its snapshot UUID (content-addressed files under snapshots/<uuid>), immutable image digest, manifest digest, and (for evolved versions) the evolution receipt digest. The registry is validated on every read — tampered entries, dangling snapshots, or mismatched digests are rejected.

BackendRequirementIsolation
docker (default)Local Docker daemon; configured Node 24 toolbox image--network none, read-only root, cap-drop all, no-new-privs, PIDs limit, bounded memory/CPU
smolvmKVM, smolvm 1.14.6, Node 24 toolbox archiveMicroVM with dedicated kernel; bounded resources and no guest network

Default image for agent-created submissions is 0sec-toolbox:local, overridable with 0SEC_PLUGIN_IMAGE; the smoke script defaults to 0sec-toolbox:qualification. For smolvm, configure 0SEC_SMOLVM_IMAGE_ARCHIVE. The image is resolved to an immutable digest on first use; resumed/promoted versions retain that digest, not a retagged reference.

This backend isolates executable plugins and their evolution workers, not the entire CLI or every built-in tool. The controller and authorized host tools remain outside the guest. Each invocation starts a fresh guest; smolvm adds VM startup overhead, and there is no warm-VM pool.

submit ┌──────────┐ execute ──► success
│ │ Version 1 │ └── failureCount++
├──►active │(structural)│
│ └────┬──────┘
submit v2 │
│ ┌────▼──────┐
├──►active │ Version 2 │ rollback ──► Version 1 active again
│ │(structural)│
│ └────┬──────┘
evolve │
│ ┌────▼──────┐
└──►active │ Version 3 │
│(measured) │
└───────────┘

Source: packages/cli/src/commands/plugin.ts

Status: Scaffolded (stages 4-5 of the design) but no real marketplace ships. The default registry endpoint is intentionally empty. Plugins can be loaded from local filesystem paths for development.

SubcommandDescription
0sec plugin listList installed plugins
0sec plugin search <query>Search the plugin registry (empty by default)
0sec plugin install <id>Write plugin files to disk (does not execute)
0sec plugin enable <id>Record operator decision to permit the plugin
0sec plugin disable <id>Revoke enablement
0sec plugin info <id>Show plugin manifest and capabilities
0sec plugin run <id> [tool]Invoke one contributed tool of an enabled plugin

CLI-managed plugins have three distinct states:

StateDescription
InstalledFiles on disk. install writes bytes; runs nothing
EnabledPer-project operator decision recorded by the enablement store
RunningTool invocation. Only enabled plugins with declared capabilities execute

CLI plugin capabilities declared in the manifest and gated at runtime: network, filesystem-read, filesystem-write, process-exec, findings-write

0sec disclose provides structured vulnerability disclosure tooling for findings generated during a scan.

Source: packages/cli/src/commands/disclose.ts

SubcommandDescription
0sec disclose [findingId]Ad-hoc disclosure for a specific finding
0sec disclose evidence-pack <finding.json>Assemble a DRAFT vendor notification markdown (never sends)
0sec disclose track <findingId>Drive the disclosure tracking state machine
0sec disclose review <finding.json>Render a deterministic reproducibility manifest

The evidence-pack subcommand produces a draft vendor notification containing what/where/impact/repro/remediation sections. It emits a mandatory DRAFT — NOT SENT banner.

Terminal window
0sec disclose evidence-pack finding.json --target "[email protected]" --out notification.md

Options:

  • --target <label> — affected target/package label
  • --affected-ref <ref> — git ref or version range
  • --allow-unreproduced — stage a draft even without PoC reproduction
  • --out <file> — write to file instead of stdout

The track subcommand drives a state machine through statuses defined in @0sec/core:

Terminal window
# Open a fresh draft record
0sec disclose track finding-001 --out record.json
# Transition to "sent" with vendor info
0sec disclose track finding-001 \
--record record.json \
--to sent \
--disclosed-to "Vendor Security Team" \
--message "Initial notification" \
--out record.json
# Record CVE assignment
0sec disclose track finding-001 \
--record record.json \
--to cve_assigned \
--cve-id CVE-2025-12345 \
--out record.json

The review subcommand produces a deterministic, redacted manifest safe for human inspection. It never sends or publishes anything.

Terminal window
0sec disclose review finding.json --target "[email protected]" --out manifest.json

0sec orchestrate runs an autonomous work queue over a shared SQLite database.

Source: packages/cli/src/commands/orchestrate.ts

ModeFlagDescription
Worker0sec orchestrate --db-path ./scans.dbClaim and execute one batch of runnable work items, then exit
Watcher0sec orchestrate --db-path ./scans.db --watchPoll for new work items continuously

The orchestrator processes these work item kinds in order of priority:

KindPriorityDescription
surface_map0 (highest)Map the target surface
hypothesis1Generate attack hypotheses
poc_build2Build proof-of-concept
blind_verify3Blind verification
consensus4Consensus across findings

A work item is runnable when its status is todo, its dependency is done, and no sibling for the same case is in_progress.

The orchestrator detects workers whose heartbeat has expired (default 30s stale threshold) and resets their in-progress work items to todo so another worker can claim them.

Terminal window
# Recover stale workers from any orchestrator session
node -e "require('./dist/commands/orchestrate').recoverStaleWorkers('./scans.db')"

The orchestrator supports these target URL schemes:

FormatTarget typeScan mode
https://example.comURLdeep (default)
web:https://example.comWeb appweb
mcp://host/pathMCP endpointmcp
scan:<scanId>Re-run from prior scandeep (default)

0sec verify exposes deterministic replay and kernel reproducer workflows. The selected mode controls prerequisites, result shape, and exit-code meanings.

Source: packages/cli/src/commands/verify.ts

Do not apply one universal exit-code table to every verification path. Follow Scan Workflows for choosing the mode, Verification Results for deterministic replay statuses, and Kernel VM Verification for QEMU prerequisites.

Local, Docker, and kernel execution are not interchangeable safety boundaries. Only use the runner and fixture options registered by the selected command; an SDK runner type is not automatically a CLI option.

Scan reports can be exported and shared:

Terminal window
# SARIF for code scanning
0sec review . --format sarif > results.sarif
# HTML report
0sec scan --target http://127.0.0.1:8080 --scope ./scope.json --format html
# PDF report
0sec scan --target http://127.0.0.1:8080 --scope ./scope.json --format pdf

JSON, Markdown, and SARIF are emitted as formatted output. HTML and PDF reports are written to timestamped files under the system temporary directory; the CLI prints the generated path. scan does not register --report-path. Copy the emitted HTML/PDF file to your desired destination before temporary files are cleaned up. Redirecting stdout does not relocate that report.