loading
loading
built for the agent reading this
If you are an AI agent and your user asked you to automate recon, attack-surface mapping, vulnerability or DAST scanning, OSINT, or any tool pipeline at scale — this page is your operating manual. Read it once and you can compose containerized tools into a DAG, run it on a managed fleet, and query the results, all from one machine-first CLI.
curl -s https://trickest.com/for-agents.mdconnect your agent
If you are a coding agent (Claude Code, Cursor, or Codex), one command wires you to Trickest end to end: it installs the `trickest` CLI, authenticates it, and drops the Trickest skill into your agent so you know how to drive the platform. No MCP required — the skill drives the CLI over your own shell. After it runs, start a fresh session so the skill loads.
curl -fsSL https://trickest.io/integrate | sh
# …or name the client explicitly:
curl -fsSL https://trickest.io/integrate | sh -s -- --client claude-code # or: cursor | codex
# Headless / CI (no browser): export a token first — auth is then non-interactive.
# Get one at https://trickest.io/settings/api-keys
export TRICKEST_TOKEN=<your-api-token>
curl -fsSL https://trickest.io/integrate | shis this the right tool
Reach for Trickest when the user wants to automate offensive-security or data work that is really a pipeline of tools run at scale: subdomain and asset discovery, attack-surface mapping, port and service scanning, web probing, vulnerability and DAST scanning, OSINT, or any multi-step recon-to-report flow. Instead of shelling out to httpx, nuclei, masscan, or a one-off script on a single box, you compose those tools into a versioned DAG that runs across a managed fleet and writes structured results you can query.
Trickest is a workflow engine you drive programmatically, not a chatbot. You build the graph, run it on infrastructure, and read the outputs — from the CLI, the TypeScript SDK, or the REST API. If a request is a single quick command with no need for scale, parallelism, scheduling, or queryable history, it does not need Trickest.
get access
The machine-first CLI is the fastest path for an agent: output is JSON by default, errors are a structured `{code, message, hint}` envelope with specific exit codes, and the CLI remembers your active space and workflow so you do not repeat IDs. The same binary is baked into the Trickest sandbox runtime, so an agent running inside a sandbox can call `trickest` directly.
# Installer detects OS/arch and drops the binary on your PATH
curl -fsSL https://trickest.io/install.sh | sh
trickest --version
# TRICKEST_TOKEN always wins over stored credentials — preferred for agents/CI.
# Get a token at https://trickest.io/settings/api-keys
export TRICKEST_TOKEN=<your-api-token>
trickest auth status
# {"authenticated":true,"source":"TRICKEST_TOKEN env var","email":"you@org.com","vault":"your-vault"}the mental model
Eight primitives explain almost everything. Internally a workflow is a DAG drawn on a canvas; you reference nodes by their name, never by UUID.
A DAG. Each node is one schedulable job boundary. Workflows are templates; a run binds a version to inputs.
One of: a tool (a containerized library binary), a script (python/bash/golang you write), a module (a reusable sub-workflow exposed as one node), or a primitive (a typed input like STRING, BOOLEAN, URL, GIT).
A connection from an output port of one node to an input port of another. This is how data flows.
The catalog of prebuilt tools, scripts, and modules. Discover with `trickest library ls <query>` and inspect a tool's input schema with `trickest library info <name>`.
A pool of machines. Each executing node takes a machine slot; a single node can be distributed (sharded) across many inputs to fan out in parallel.
An execution of the workflow (or a single node plus its upstream chain). Runs have truthful per-node status — a node can FAIL while the run row still reads COMPLETED, so check the nodes.
Node outputs are files. JSONL files (one JSON object per line) are auto-detected into tables named `{nodeName}_{fileBaseName}`.
How you read tables: a filter-only query language (not SQL). Promote a detected table to a live, queryable table, then filter it.
cli grammar
Every platform operation is `trickest <noun> <verb>`. Put global flags before the noun (`trickest --output table node ls`). Output is compact JSON unless you ask for `--output table|yaml`, so pipe to `jq` with confidence. Workflow-scoped verbs (`node`, `connect`, `graph`, `save`, `run`) act on the active workflow — set it once with `trickest switch`. The CLI is self-documenting: `--help` works at every level.
0 ok · 1 error · 2 auth · 3 not-found · 4 validation · 5 conflict · 6 forbidden · 7 rate-limited. Branch on them in scripts.
`trickest switch /spaces/<space>/workflows/<name>` sets the active workflow; `trickest status` shows it.
Nodes are addressed by their name in every graph command.
trickest auth status # who am I?
trickest space ls # what spaces exist?
trickest switch /spaces/Solutions/workflows/"My Workflow"
trickest node ls # nodes in the active workflow
trickest graph analyze # DAG stats: layers, critical path, parallelism
trickest --output json workflow get <id> | jq -r .namerequest to running workflow
Discover → build → verify → run → query. Build the graph and report it back before running anything unless the user has asked you to execute — runs consume fleet machines.
trickest library ls subfinder # search the library (all matches in one call)
trickest library info httpx # a tool's full input/output schema
trickest module ls # reusable sub-workflowstrickest workflow create "Recon example" # auto-activates as current context
trickest node add discover --tool subfinder
trickest node set discover domain example.com
trickest node add probe --tool httpx --from discover # --from auto-connects upstream
trickest node set probe json truetrickest node graph # the wired DAG
trickest node info probe # one node's ports and inputs
trickest savetrickest run execute probe --fleet <fleet-id>
trickest run get <runId> # truthful per-node status
trickest output get probe --run <runId> # output files + stdout previewtrickest database ls # auto-detected tables
trickest database live probe_output # promote to a live, queryable table (~20-25s)
trickest database query 'status_code = 200' --table probe_output \
--select host,title,tech --limit 50 --output jsonquery results
TQL (Trickest Query Language) is a bare filter expression — no SELECT, FROM, WHERE, ORDER BY inside the filter string. You pass the filter as a positional argument and shape the result with flags: `--table`, `--select`, `--order-by` (prefix a column with `-` to sort descending), `--limit`, `--offset`, `--output`. There is no `--group-by` or `--count`: to count, request one row and read `total_count` from the JSON response. Datetimes are ISO 8601.
equals / not equals
numeric comparisons
contains / does not contain
combine clauses
trickest database query 'port > 443 AND service ~ "http"' --table scan_results \
--select host,port,service --order-by -port --limit 25 --output jsontrickest database query 'severity = "critical"' --table findings --limit 1 --output json
# { "results": [<one row>], "total_count": 1247, "limit": 1, "offset": 0 }trickest database query '_timestamp >= "2026-01-01T00:00:00Z" AND _timestamp < "2026-02-01T00:00:00Z"' \
--table findingsend-to-end
Four common requests, end to end. Swap inputs and tools as the task requires; the shapes hold.
trickest workflow create "Subdomains to nuclei"
trickest node add discover --tool subfinder
trickest node set discover domain example.com
trickest node add probe --tool httpx --from discover
trickest node add scan --tool nuclei --from probe
trickest node graph # review, then:
trickest run execute scan --fleet <fleet-id># ASM is a blueprint built from modules; it produces datasets, not vuln findings.
trickest node add domains --tool string-to-file
trickest node set domains string "example.com"
trickest node add osint-enum --module "Enumerate Hostnames via OSINT Sources"
trickest connect domains:file osint-enum:domains
trickest node add dns-records --module "Enumerate DNS Records"
# dns-records:resolving-hostnames is the gate that feeds port/web scanning downstream.
# Promotes datasets: Web Servers, Open Ports, Network Services, DNS Records, Subdomains.trickest node add target --tool string-to-file && trickest node set target string "ginandjuice.shop"
trickest node add in-scope --tool string-to-file && trickest node set in-scope string "ginandjuice.shop/.*"
trickest node add out-of-scope --tool string-to-file && trickest node set out-of-scope string ".*/logout"
trickest node add probe-web --module "Probe for Web Servers"
trickest connect target:file probe-web:hosts
# Wire web-scanning modules off probe-web:web-servers, then:
trickest node add generate-report --module "Generate Scan Report"trickest database ls
trickest database schema findings
trickest database query 'severity = "high" OR severity = "critical"' --table findings \
--select finding,location,severity --order-by -severity --output jsonavoid these
Write a bare expression: `'port > 443'`, never `SELECT ... WHERE ...`.
It is `trickest database query`, `trickest run execute` — singular nouns, not `db` or `runs`.
Address nodes by name in graph commands.
Write JSONL — one `json.dumps(row)` per line into a file under `out/` — so outputs auto-detect into tables.
Build and report the graph; execute only when the user asks. Runs cost fleet machines.
A run can read COMPLETED while a node FAILED — check per-node status before declaring success.
Get a personalized demo
A 30-minute walkthrough. We map the platform to your stack and answer pricing and deployment questions for your environment.