@trident-ai/cli
v0.6.0
Published
Trident CLI — sign in, wire your repo into Trident with your coding agent, pentest what you deploy, and read findings from the terminal.
Maintainers
Readme
Trident CLI
Security for the AI apps and agents you're building — from the terminal.
npm install -g @trident-ai/cli
trident login
trident setuptrident setup hands the wiring to whichever coding agent you already have
installed (Claude Code, Codex, Cursor, Copilot, Gemini, opencode). It provisions
the keys, writes a precise brief for your specific codebase, and the agent does
the edits.
One credential, once
trident login opens your browser, you sign in, and you're done. There is no
API key to copy, no token to paste, nothing to put in your shell profile.
Sign-in is handled by your Trident deployment's identity provider (WorkOS AuthKit on the hosted service), so whatever already applies to you in the dashboard — SSO, passkeys, MFA — applies here too.
$ trident login
▲ Trident 0.3.0
Sign in to continue.
┌────────────────────┐
│ W D J B - M J H T │
└────────────────────┘
1. Open https://praiseworthy-venture-75.authkit.app/device
2. Enter the code above
Opening your browser…
✓ Signed in as [email protected]
project Default projectThe credential lands in ~/.trident/credentials.json (mode 0600).
trident logout revokes it server-side and deletes it. Nothing from the
identity provider is kept — the token it issues is used once, to establish the
session, and discarded.
If your account can reach more than one project, the CLI asks which one to
scope this machine to. Pass --project <id> to skip the question (required
when there's no terminal to ask, e.g. inside a coding agent or CI).
Commands
| Command | What it does |
| ---------------------- | ----------------------------------------------------- |
| trident login | Sign in (opens your browser) |
| trident logout | Sign out and revoke this machine's session |
| trident whoami | Show the signed-in identity |
| trident setup | Wire this repo into Trident with your coding agent |
| trident connect | Find the editors you have installed and connect them |
| trident mcp | Connect one editor to Trident over MCP |
| trident scan <url> | Pentest a live app or repository |
| trident findings | List your findings inbox |
| trident finding | Show one finding in full — code, lines, suggested fix |
| trident fix <id> | Hand a finding to your coding agent to repair |
| trident report <run> | Export a scan's engineering report as Markdown |
| trident status | Connection and project health |
| trident init | Scan this machine for AI credentials worth protecting |
| trident evals | Run promptfoo evals, with a watch loop |
Every command takes --help, and --json where output is worth piping.
trident mcp rejects a flag it doesn't recognise rather than ignoring it and
answering anyway — --clint cursor exits 2 and suggests --client. The rest
of the commands are moving onto the same parser.
Your editor, over MCP
Trident runs a remote MCP server, so the agent you already work in can read findings, pull the code around them, and launch scans:
https://mcp.tridentsecurity.io/mcptrident connect # find every editor you have and wire them up
trident mcp # or print the command for one client
trident mcp --install # or let that client's own CLI do it
trident mcp --client cursor # one-click install links for Cursor, VS CodeThere's nothing to paste. The server authenticates with OAuth: your client opens a browser the first time it connects, you approve it there, and it keeps a credential of its own. An agent gets the role you already have, minus anything you don't approve, and you can revoke the grant from the dashboard without touching your own session.
Don't add an Authorization header to it. Claude Code turns its OAuth
fallback off when a header is present, so a stale token then reports a hard
connection failure instead of offering you sign-in. That's why trident mcp
prints a bare-url config and no token.
Belong to more than one organization? Pin a client to one by pointing
--server at https://mcp.tridentsecurity.io/mcp/o/<org-slug>.
The older https://app.tridentsecurity.io/api/public/mcp endpoint — the one
that takes a bearer token — still works and isn't going away.
trident mcp --legacy prints its config, for clients set up against it before
the remote server existed.
Triage and fix
The loop the CLI exists for. A finding you can't act on is just a notification,
so finding and fix carry the whole writeup — the file, the line range, the
offending snippet, and any patch the scanner already worked out:
trident findings --severity CRITICAL,HIGH # what's open, worst first
trident finding <id> # the full writeup and the code
trident finding <id> --json # the same, for an agent to consume
trident fix <id> # write a brief, launch your agenttrident fix writes TRIDENT_FIX.md and launches whichever coding agent you
have installed. If none is found — or you're in CI — the brief is still written
and copied to your clipboard, so the fallback is "paste this", never "nothing
happened".
If you are a coding agent reading this: trident finding <id> --json is the one
call you want. It returns the description, every affected file with line ranges,
the snippet, the suggested patch, and the trace that proves the finding is real.
Scanning
trident scan https://app.example.com # attack a live app
trident scan https://app.example.com --watch # …and wait for results
trident scan --repo https://github.com/me/app # whitebox source review
trident scan --list # recent runsYou can only scan a domain you own. Scope is enforced server-side against the
registrable domain of the email you logged in with — [email protected] may scan
acme.com and its subdomains, and nothing else. That check is the reason this
needs a real login rather than an API key.
A scan can also be refused for concurrency: your organization runs a limited
number of scans at the same time (three web application scans by default;
your organization's ceiling may be higher, and the error names the real
number). Over that, trident scan reports how many are already running instead
of queueing. The limit counts only your own organization's scans — trident
scan --list shows what is occupying the slots, and it clears as those finish.
That ceiling is on simultaneous scans — it consumes nothing and no counter resets on a clock, so a slot frees the moment a running scan reaches a terminal status.
There are three distinct refusals and they clear differently:
| Refusal | Clears by |
| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Per-org concurrency | a running scan finishing — often seconds |
| Daily launch quota (scan_quota_exhausted) | the daily window rolling over, at the UTC instant the refusal names. Agent/OAuth clients get 25 scan launches per project per day by default — more for an organization with a raised scan entitlement — counted per client so a fresh token does not reset it |
| Trial grants exhausted | nothing — a trial's Surface scan grants are finite and consumed |
Read the error rather than assuming: waiting out a concurrency refusal takes minutes, waiting out a daily quota takes until the window rolls over, and waiting out an exhausted trial never works.
If the interesting surface is behind a login, capture a test identity in the
dashboard first and pass it with --identity <profileId>.
Findings
trident findings --severity CRITICAL,HIGH
trident findings --status OPEN --since 7
trident findings --json | jq '.findings[] | .title'Exporting a report
The same engineering handoff the dashboard's "Export report" button produces — target, scan metadata, the executive summary, and every confirmed finding with its evidence and suggested fix — as plain Markdown:
trident report <runName> # print it
trident report <runName> > report.md # redirect it
trident report <runName> --output report.md # or write it directly
trident report <runName> --json | jq -r .markdownFind a runName with trident scan --list. Built for feeding into whatever
reads Markdown next — a ticket, a coding agent, an MCP tool call writing a CRM
record — rather than for reading in the terminal; trident finding <id> is
the one for that.
CI and headless environments
There's no browser in CI, so mint a token from a machine that has one and set it in the environment:
export TRIDENT_CLI_TOKEN="tct-…"
trident findings --jsonWith TRIDENT_CLI_TOKEN set, the credentials file is bypassed entirely and
nothing is written to disk.
Environment
| Variable | Purpose |
| -------------------- | --------------------------------------------------------- |
| TRIDENT_ENDPOINT | Dashboard URL (default https://app.tridentsecurity.io) |
| TRIDENT_MCP_URL | MCP server (default https://mcp.tridentsecurity.io/mcp) |
| TRIDENT_CLI_TOKEN | Pre-authenticated token for CI; skips login |
| TRIDENT_CONFIG_DIR | Where credentials live (default ~/.trident) |
| TRIDENT_DEBUG | Print stack traces on failure |
| NO_COLOR | Disable color |
Notes
- Node 20+. Zero runtime dependencies — installing this pulls one small tarball and nothing else.
tridentctlstill works. It's an alias fortrident; existing scripts don't need to change.trident setupwritesTRIDENT_SETUP.mdcontaining a live secret key for your project. The CLI warns you if that file isn't gitignored. Delete it once setup is done.
Links
- Dashboard — https://app.tridentsecurity.io
- Issues — https://github.com/esprit-labs/Trident/issues
MIT licensed.
