Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault

No arguments

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": true
}
logging
{}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}

Tools

Functions exposed to the LLM to take actions

NameDescription
cordon_load_scopeB

Load and validate an engagement scope file, creating the workspace. Must succeed before any target-taking tool will run.

cordon_statusA

Current engagement: scope summary, assets, findings, budget, rate limits, approvals.

cordon_finishA

Close the engagement: flush findings and assets to disk and seal the audit log.

scope_checkA

Ask whether targets are in scope WITHOUT touching them. Use this before planning work against a newly discovered host.

approval_pendingB

List aggressive actions parked awaiting human approval.

approval_respondA

Relay a HUMAN decision on a parked approval. Do not call this on your own initiative — only when a person has told you their decision.

job_listC

List background scans and their states.

job_fetchA

Fetch a finished job's result. Prefer fetch_slice for large result sets — this returns everything and is capped.

job_cancelB

Stop a running scan. Kills the whole process tree.

fetch_sliceA

Pull one window of a job's result instead of the whole set. path=dotted path into the result, where=regex filter, fields=keys to keep. Use this rather than job_fetch whenever a scan produced many rows.

taskgraph_nextA

What to do next: pending tasks whose dependencies are met, highest priority first. Each carries the discovery that created it. Call this after every phase rather than re-deriving the plan from scratch.

taskgraph_updateA

Mark a task done, failed, blocked, or skipped after acting on it.

taskgraph_viewA

Render the task graph as Mermaid, showing how discoveries drove the work.

memory_recallA

Retrieve proof-of-concept techniques that worked on previous engagements for this vulnerability class. Check this before designing a PoC from scratch — the store holds methods only, never credentials or target data.

graph_recallA

What this engagement already knows about a host, URL, or asset, and how it connects to everything else. Ask this before re-running recon — the answer is free and a re-scan costs the target requests.

brain_recallA

What the neuron brain has LEARNED about testing this kind of target: which validators/techniques actually paid off on this vulnerability class with this observed technology stack and WAF, ranked by cross-engagement experience. Consult before choosing validators or designing a test plan — the brain remembers outcomes the static index cannot. Empty results mean no prior experience on this shape; proceed from the technique index.

brain_learnA

Teach the neuron brain an observed outcome: a validator HIT, a CLEAN pass, or a FALSE_POSITIVE (the scanner fired and was wrong). The brain uses these to rank future plans and to suppress known-FP tools on similar targets. Use after a validator run, or when triage drops a finding — teaching it the false positive is what stops the same noise being re-filed next engagement. Stores methods and outcomes only.

brain_stateA

What the neuron brain senses right now: the phase and tool currently running, the most recent tool calls, and the memory store's stats. The brain senses every tool call through the audit log, so this is a live pulse of the whole engagement, not a report.

brain_historyB

The brain's episodic memory: what happened before, in order — every sensed tool call across engagements, filterable by phase, tool, or outcome. This is the 'what failed, what succeeded, what was a false positive, what was a true finding' record the synapse weights cannot express on their own.

dashboard_stateA

The live engagement dashboard blob: which phase is running, each phase's outcome, the findings ledger with severity/status, discovered assets, and the brain's recent sensed activity. One JSON snapshot of the whole run — use it to answer 'where is the scan, what has it found' without reading workspace files directly. The CLI mirrors this as cordon dashboard.

rules_listA

List loaded detection rules and plugins, plus anything rejected at load time. A rejected rule is a detection you do not have — check this when a scan finds less than expected.

rules_reloadA

Re-scan the rule directories. Use after editing or adding a rule file.

rule_testA

Dry-run the loaded rule-packs against a sample observation (url/status/headers/body) without touching any host. Use this to check a rule before trusting it, and to understand why one did or did not fire.

cordon_capabilitiesC

List registered capabilities with their phase, mode, and origin.

audit_tailB

Recent audit records, including refusals. The engagement's evidence trail.

cloud_asset_discoveryA

[AGGRESSIVE — requires human approval] Discover public cloud storage by guessing names from a keyword.

Runs cloud_enum and S3Scanner. Every discovered bucket is checked against the engagement scope and against ownership evidence before it counts — name similarity is not ownership.

cloud_attack_pathsA

[AGGRESSIVE — requires human approval] Build attack paths from cloud configuration (Prowler + Cartography graph).

Turns a list of misconfigurations into reachability: which public entry points lead to which privileged roles, and in how many hops. That chain is what makes a cloud finding worth a severity rating.

cloud_auditA

[AGGRESSIVE — requires human approval] Audit cloud posture with Prowler and ingest failed checks as findings.

cloud_permissionsC

[AGGRESSIVE — requires human approval] Map principals, permissions, and privilege-escalation paths with CloudFox.

Requires credentials the program gave you. Read-only enumeration.

k8s_postureA

[AGGRESSIVE — requires human approval] Assess Kubernetes posture with Kubescape.

Kubescape ships its own MCP server. If you are doing significant Kubernetes work, connect that directly alongside Cordon rather than routing everything through this wrapper — but vet it first, like any third-party MCP server.

contract_static_scanB

Run Slither over a Solidity project and normalize the detector output.

repo is a path inside the engagement workspace. Analysis is local: no network request is made and no contract is executed, which is why this is passive and costs no budget.

Every result is a CANDIDATE. Slither's high-impact detectors fire on safe code often enough that a finding without a runnable PoC is not submittable on any platform that pays for smart-contract bugs.

contract_toolchainA

Report which smart-contract tools are present and correctly identified.

Absence is reported per tool rather than as an overall failure, so a missing fuzzer never reads as "the contract is fine".

cdn_checkA

Identify which hosts sit behind a CDN, WAF, or cloud provider.

Worth running before any port scan: scanning a CDN edge tells you about the CDN, wastes the program's rate limit, and occasionally violates the CDN's own terms rather than the target's.

dns_permuteA

[AGGRESSIVE — requires human approval] Generate subdomain permutations with alterx and resolve them with dnsx.

Finds hosts that no passive source knows about. Requires approval: this is a brute-force pattern, just against DNS rather than HTTP.

dns_resolveA

Resolve hosts and return A/AAAA/CNAME/MX/NS/TXT records.

Flags hosts whose CNAME resolves but which have no address record — the shape of a dangling delegation. Those are candidates for takeover_verify, never findings on their own.

content_discoveryA

[AGGRESSIVE — requires human approval] Brute-force paths with ffuf, at the engagement's rate limit.

wordlist is either a name from the vetted payload store ("admin", "juicy-paths", "api-routes" — call payload_catalog for the list) or a path to a file inside the engagement workspace.

There is no default. The size of the wordlist is the size of the impact on the target, and that should be a deliberate choice.

endpoint_discoveryA

Collect known URLs for a domain from public archives.

Sources: gau (Wayback + Common Crawl + URLScan), waybackurls, waymore. These query archives, not the target, so they cost the program nothing.

include_crawl adds a shallow katana crawl, which does touch the target — keep it off unless the archives came back thin.

fuzz_compareA

Diff responses against a baseline to find what a payload actually changed.

baseline_url is the unmodified request; case_urls are the injected variants. Each case is diffed against the baseline across status, mime, body hash, length, duration and headers, and cases are clustered by body hash so identical responses (the catch-all page) read as one cluster.

re_request adds a second fetch of every case — the cache-poisoning probe. If the second response differs from the first and matches the injected body while a fresh requester asked only for the baseline URL, the cache served the poisoned copy; that is the only honest way to move web cache poisoning from "manual" toward detectable.

Read-only: GET requests through the engagement's rate limiter, nothing is sent beyond the URLs you name.

graphql_auditA

Audit a GraphQL endpoint: introspection, suggestions, GraphiQL, CSRF, trace mode.

Passive. Every check that remains is a single well-formed query used to read what the server discloses. graphql-cop's denial-of-service family (alias overloading, batching, directive overloading, circular introspection) is excluded unconditionally — those exist to make the server burn CPU, which is out of bounds under scope.rules.no_dos.

If the URL has no path, graphql-cop tries /, /graphql, /graphiql, /playground and /console; give it the exact path to keep the request count down.

param_discoveryA

[AGGRESSIVE — requires human approval] Discover hidden request parameters on a URL with Arjun.

Guessing costs requests. Mine endpoint_discovery's archive results for parameter names first — they are free and already known to exist.

payload_catalogA

List the payload wordlists available to content and parameter discovery.

Names returned here are what content_discovery expects for its wordlist argument. Touches no target and costs no budget.

Only tier A discovery wordlists appear. Tier B injection payloads belong to the approval-gated exploitation tools, and tier C is quarantined and has no name bound to it at all — see docs/PAYLOADS.md.

websocket_probeA

Open a WebSocket handshake and report whether the server validates Origin.

Pass the https:// (or bare host) form of the endpoint, not wss://: the scope engine cannot parse a ws/wss URL and fails closed on one, so a wss:// target is refused before this ever runs. The upgrade to wss:// happens here, after the scope check has had its say.

Passive: one upgrade request, no frames sent, connection closed immediately. -u inhibits the send direction and -1 stops after a single message, so nothing this tool does can be mistaken for traffic.

A handshake that succeeds with a foreign Origin is a candidate for cross-site WebSocket hijacking. It only becomes a finding when the socket also carries authentication that the browser would attach automatically — which this tool cannot and does not test.

authz_compareA

[EXPLOIT — requires human approval] Fetch one URL as two identities and report whether the server told them apart.

The core authorization test. If A can read A's resource and B can read it too, the server is not checking ownership — that is an IDOR. If B is refused, it is.

Restricted to GET and HEAD on purpose. Proving broken access control never requires writing: reading another user's record is the proof, and writing to it modifies data that is not yours, which every program in this space forbids outright.

Reports a CANDIDATE, never a confirmed finding. Two identical responses can also mean the resource is public, or that neither session is actually authenticated. The result says which checks would settle it.

browser_verifyA

[AGGRESSIVE — requires human approval] Verify a candidate in a real browser and capture evidence.

url is the target URL. param names a query parameter and payload is what to put in it (an XSS payload, a canary token, a URL for open redirect — passed unescaped; this tool builds the URL itself). The browser loads the page and reports:

  • reflectionraw / escaped / none (unescaped reflection of the payload is a reflected-XSS candidate),

  • executed — whether the payload ran (dialog, page error, or console message containing it) — the strongest signal,

  • redirectfinal_url host differing from the requested host (open-redirect candidate),

  • console messages and page errors,

  • screenshot / dom_excerpt — saved to the workspace evidence/ dir and referenced from the filed finding.

A finding is filed for raw reflection (MEDIUM), execution (HIGH), or a host-changing redirect (LOW) — all needs_manual_review with the screenshot as evidence.

burp_sendA

[AGGRESSIVE — requires human approval] Send one HTTP request per target through the operator's Burp proxy.

target is one or more comma-separated URLs (at most BURP_HANDOFF_MAX_TARGETS); every one is scope-checked before anything is sent. method is one of GET/POST/PUT/PATCH/DELETE/HEAD/OPTIONS. headers overrides the default tagged User-Agent; body is the request body for POST/PUT/PATCH.

Each request goes through the local Burp proxy (tools.burp.proxy_url in config.yaml), lands in Burp's history, and the responses are returned so the caller can attach them to leads. If Burp is not listening the call fails with burp_not_running — start Burp and retry.

This is a human-handoff primitive, not a scanner: one request per target, nothing automated, and the classes it serves (IDOR, business logic, race conditions, cache poisoning) are exactly the ones that end in a human reading a request.

cmdi_probeB

[EXPLOIT — requires human approval] Detect OS command injection with commix. Detection only, never a shell.

parameter restricts testing to one parameter; leave it unset to let commix test every parameter it finds in the URL. level (1-2) widens the payload set.

The techniques available here are classic, eval-based and time-based — the three that answer "does this execute" by observing output or delay. File-based is excluded: it proves the same thing by writing a file into the target's web root, which is a change to the target, not evidence.

Read the tool-availability note if this returns UNTESTED. PyPI's commix package is not commixproject/commix; it is an unrelated 2019 package that only knows how to print a banner. This spec carries an identity marker so the impostor is refused rather than run — a refusal here means the real tool is missing, and the surface is untested.

exploit_chainA

[EXPLOIT — requires human approval] Run the exploit validators across discovered injection points.

target is the comma/newline-joined list of URLs the earlier phases found (the pipeline passes the asset store's URLs). Each URL's query parameters are extracted and tested one at a time, capped at limit injection points. include_heavy adds sqlmap and dalfox on top of the native probes. Every result is a CANDIDATE; the validators store their own findings.

Returns tested (injection points actually probed) for the pipeline's "did it do anything" gate, plus a per-point summary.

exploit_promptA

The prompt pack for one vulnerability class.

bug_class is one of: sqli, nosqli, xss, ssti, ssrf, cmdi, lfi, redirect, auth, authz, business_logic, cache_poisoning, race_condition, takeover, deserialization, file_upload, graphql, injection.

The pack names the role, objective, scope (including what is not allowed), the success criteria a candidate must meet before it may be called a finding, and the evidence fields a reproducible PoC must fill. Use it before driving a live test or writing up a candidate: a finding that cannot fill the evidence fields is a lead, not a finding.

fingerprint_wafA

Identify the WAF vendor from response headers, body, and status code.

headers is a dict of response headers ({"server": "...", "cf-ray": ...}). Pass the block page as body when you have one — the markers there are often the only signal. Returns matches sorted by confidence; an empty list means no signature reached threshold (no WAF, an unknown one, or a transparent one that never modifies responses).

forbidden_chainA

[AGGRESSIVE — requires human approval] Auto-chain 403 bypass across a list of URLs.

Pre-checks up to max_candidates URLs with one HEAD each, keeps the real 403s, then runs forbidden_bypass (unKover's 12 techniques) on up to max_bypass of them. Every bypass files its own finding; a clean pass is recorded as coverage evidence that the access decision held.

Give it the estate's live URLs (the pipeline passes the asset store, which arrives as a comma/newline-joined string). The chain is what makes a 403 a tested access decision instead of a dead end an operator has to revisit by hand.

guided_validateA

[AGGRESSIVE — requires human approval] Run the validators the research playbook names for a class, on an asset.

vuln_class (fuzzy names work) and asset (a URL in scope) are the same inputs research_guidance takes; this tool goes one step further and executes the validators the coverage matrix wires to the class, capped at limit tools. Classes whose validation row is manual/none return the evidence checklist instead of dispatching anything — the honest answer is "no scanner owns this", and the checklist is what a report needs.

Every dispatched validator goes through the control plane again (scope, rate, budget, approval) — guidance never becomes an unapproved action. Returns the playbook plus a per-validator outcome summary; validators that prove something file their own findings.

nosqli_probeA

[EXPLOIT — requires human approval] Detect NoSQL injection (MongoDB operator injection) with nosqli.

data supplies one name=value body parameter, and it should be a valid value (username=alice): the tool mutates what you give it, and a body rejected before it reaches the query tests nothing.

One pair, not a body, because & is hard-denied for every argument in this project and nosqli's --data takes a single string. A login form needing both a username and a password cannot be expressed here — test that by hand, or with a proxy-driven request. Saying so is the point: the alternative is a probe that silently tests half the form.

Authentication bypass is the usual impact: {"password": {"$ne": ""}} matching every document. This probe stops at detection, and enumerating a collection to show severity is exactly what "do not exfiltrate" means.

oob_listenerB

[AGGRESSIVE — requires human approval] Start an interactsh listener and return the callback URL for blind classes.

Inject the returned URL into the suspected sink, wait, then check the polled interactions. A DNS or HTTP hit from the target's infrastructure is the proof.

poc_recordB

Record a proof-of-concept a human reproduced, and confirm the finding.

For the classes no tool should prove on its own — IDOR, auth bypass, RCE, blind SSRF — this is how a finding becomes confirmed: a person reproduced it and wrote down exactly what they did and what happened.

All three of reproduction, expected_result, and observed_result are required. A PoC missing the observed result is a hypothesis.

prompt_classesA

List the vulnerability classes that have an exploit/validation prompt pack.

smuggling_canary_probeA

[AGGRESSIVE — requires human approval] Test for HTTP request smuggling, proving hits by canary reflection.

repeat is how many times each payload is retried; the framework scores confidence statistically ("17/20 poisoned"), which is the right model for a bug class that is inherently probabilistic. Capped at 10 by the argument policy — every increment multiplies the whole payload set.

Returns coverage alongside findings: payloads sent, detectors run, and detectors skipped. A smuggling scan that could not find an echo gadget, or could not confirm queue poisoning, has not tested those things — and this result says so rather than letting zero findings imply a clean front-end.

smuggling_probeA

[EXPLOIT — requires human approval] Detect HTTP request smuggling (CL.TE / TE.CL desync) with smuggler.

Unlike everything else in this module, a hit here has collateral: a desync poisons the connection for whoever uses it next. --exit_early is always passed so the scan stops on the first finding instead of confirming it a dozen more times, and the timeout is held low.

The probe is timing-based — smuggler measures whether the back-end waits for a body the front-end already terminated. Treat a hit as a strong lead and re-test manually against a target you control, or with the program's explicit agreement, before writing it up.

sqli_validateC

[EXPLOIT — requires human approval] Detect SQL injection with sqlmap. Detection only, never data extraction.

There is no payload_list here on purpose: sqlmap takes no payload file, and --tamper — the flag that comes closest — loads executable Python and is denied for this tool. Its own boolean/time inference is what proves SQLi.

bypass_vendor names a WAF vendor whose sqli bypass set is looked up from the knowledge base; its first payload is split into a boundary that sqlmap applies via --prefix/--suffix. A WAF that flags the raw OR 1=1 keyword often lets the same condition through wrapped in the vendor's evasive boundary. The exploit chain uses it to re-test a point whose base pass came back clean.

ssrf_probeA

[EXPLOIT — requires human approval] Test one URL parameter for server-side request forgery with SSRFmap.

parameter names the query parameter suspected of taking a URL. The probe asks the target to connect back to its own loopback interface across a port list; a port that answers differently from the baseline means the target performed the fetch, which is the SSRF.

This is deliberately the narrowest of SSRFmap's 24 modules. The ones that make SSRF interesting — reading IMDS credentials, writing a Redis key, proxying through the victim — are the ones a bug bounty program means when it says do not exfiltrate and do not pivot, and they are not on the allowlist. Confirm reachability here, then prove impact by hand with poc_record().

ssti_probeA

[EXPLOIT — requires human approval] Detect server-side template injection with SSTImap.

injection_points selects where to inject: Q(uery), B(ody), H(eaders), C(ookies) — query only by default, because headers and cookies multiply the request count and are usually not the reported sink. engine optionally narrows to one template engine once http_probe has told you the stack (jinja2, twig, freemarker, velocity, smarty, …).

A hit here is arithmetic evaluated in a template — {{7*7}} returning 49 — and nothing else. SSTImap's shell, eval and file-transfer flags are denied, so the tool cannot be talked into demonstrating RCE. Establishing that a template engine evaluates attacker input is the finding; proving code execution beyond that is a decision a human makes, in writing.

strix_deepA

[EXPLOIT — requires human approval] Delegate deep application exploitation to Strix, then ingest its results.

Disabled by default. Requires exploitation to be permitted by the engagement and explicit human approval per call.

validate_findingsA

[EXPLOIT — requires human approval] Prove candidate findings with minimal PoCs. Validators run in parallel.

Only a finding whose validator produced a reproducible PoC becomes 'confirmed'. Everything else is downgraded to 'needs manual review' with the reason recorded. This is the only automatic route to a confirmed finding.

waf_bypassA

Ordered WAF-bypass payloads for (vendor, vuln_class), basic → advanced.

vendor is a wafw00f display name ("Cloudflare", "Amazon Web Services (AWS) WAF") or a canonical key ("cloudflare", "aws_waf", "modsecurity"). vuln_class is one of xss, sqli, cmdi, ssti, ssrf, path_traversal. level filters to basic / intermediate / advanced / all.

Read-only: returns text payloads tagged with technique + level, nothing is sent. Payloads are the data the exploit chain feeds its validators when a base pass was clean; calling this tool does not fire anything at a target.

waf_vendorsA

List supported WAF vendors with the classes each has bypass payloads for.

web_injection_probeA

[EXPLOIT — requires human approval] Detect open redirect, CRLF, LFI, XXE or HPP in one parameter.

target is the full URL carrying the parameter to test (one parameter — & is refused project-wide). parameter names it. bug_class is one of open-redirect, crlf, lfi, xxe, hpp.

regex_bypass expands the class's payload set with generated WAF-regex bypass variants (every mode x every encoding, bounded at 500): a WAF regex that blocks the textbook ../ or <script> often lets the same byte through when written as %2e%2e/ or split by a metachar replacement. It multiplies the request count and is strictly a second pass — run the plain probe first and reach for this only when a parameter reflects but nothing fires.

Every result is a CANDIDATE: the class signature must appear in the injected response and not in the baseline request. Nothing is confirmed here.

xss_validateA

[EXPLOIT — requires human approval] Confirm reflected XSS on a URL with dalfox.

payload_list optionally names a tier B list from the vetted payload store to hand dalfox via --custom-payload. Leave it unset first: dalfox's built-in payloads are context-aware and prove most reflected XSS on their own. Reach for a list when a parameter reflects but nothing fires — xss-waf-bypass against a filtering target, xss-polyglots when the injection context is unclear, xss-js-frameworks for a Vue/Angular front end. Tier B is injection payloads, not discovery wordlists, and this is the only tool that can request one.

bypass_vendor names a WAF vendor whose ordered XSS bypass set is looked up from the knowledge base and handed to dalfox via --custom-payload the same way a tier B list would be. The exploit chain uses it to re-test a point whose base pass came back clean: the WAF may have eaten the textbook payloads while the vendor-specific set gets through.

cors_auditA

Check a URL's CORS policy for origin reflection and trust-boundary bugs.

Passive: a handful of GETs with different Origin headers, reading the Access-Control-Allow-* response headers. Nothing is submitted, nothing changes state.

A permissive policy is only a vulnerability when the endpoint returns data worth stealing and Allow-Credentials is true — findings are filed as candidates, never as confirmed.

http_probeA

Probe hosts for live HTTP services: status, title, tech, server, IP.

One request per host per scheme, at the engagement's rate limit. Rule-packs are evaluated against each response, so native detections surface here. Content-length and content-type are reported per host — the two scalars that separate a real application from a parked page or an error shell — and screenshots=True captures render-time evidence of the most interesting hosts (requires a headless browser where httpx runs).

recon_reviewA

Rank live hosts by how worth they are of manual testing.

Reads the asset store (probe results + scope focus URLs) and returns the top limit hosts with scores and the reasons behind each. Zero traffic. The top of the list is the hand-off for auth_surface (find the login) and auth_crawl/authz_compare (test behind it).

tls_auditA

Audit a host's TLS configuration: protocols, ciphers, certificate, headers.

Passive. Every check run here is a standard TLS handshake plus one HTTP GET — the same traffic any browser produces. testssl's vulnerability battery (-U: Heartbleed, CCS injection, Ticketbleed, ROBOT, DROWN) is not run and is denied at the sanitizer: those send malformed or exploit-shaped handshakes, and Heartbleed in particular reads server memory. Reaching them would make the "passive" label a lie. Use the exploit-phase validators, with approval, if a TLS vulnerability needs proving.

waf_detectB

Identify the WAF or protection layer in front of a host.

Knowing the WAF changes what is worth trying and what will simply be blocked. The vendor names this reports are what the exploit chain's bypass pass consumes: waf_bypass looks up the vendor's payload set and the validators re-fire with it only when a base pass came back clean — still behind the exploit gate. Identifying the vendor stays passive; sending bypass payloads is exploitation and goes through the same approvals as any other.

job_statusA

Check, wait on, or list long-running scans.

Tools that can outlast a single MCP call — nuclei_scan, bbot_scan, osmedeus_flow — hand back {"completed": false, "job_id": ...} once their internal wait (capped at 300s) elapses. This is how the result is collected afterwards. Without it a scan longer than five minutes finishes into a job nothing can read.

Omit job_id to list jobs. wait_seconds blocks for up to 300s, so a nearly-finished scan can be collected in one call instead of polled.

js_analyzeA

Fetch JavaScript bundles and extract endpoints, secrets, and libraries.

Fetches each URL once (a normal browser request), then runs native pattern matching, jsluice (grammar-based URL extraction), linkfinder (regex-based endpoint recovery over the saved files) and retire.js (known-vulnerable library detection). Either external tool being absent is reported per-tool in tools; it never turns into a quiet zero. Credential candidates are masked in the output and are never tested against a live service here.

llm_probe_catalogA

List the LLM probe families, what each tests, and how findings are graded.

Read this before running llm_redteam. Choosing probes by impact rather than running everything is the difference between a report a program acts on and a list of jailbreak transcripts.

llm_redteamA

[AGGRESSIVE — requires human approval] Probe the target's AI feature with garak, one probe family at a time.

family: indirect-injection (default), tool-abuse, context-leak, output-handling, or jailbreak. Run llm_probe_catalog first to choose.

Results are candidates. An LLM probe failing is a behaviour, not yet an impact — see the note in the result for what a report needs.

llm_scan_configA

[AGGRESSIVE — requires human approval] Run a promptfoo or deepteam suite from a config inside the workspace.

Use this when you have a target-specific test suite — application-aware probes almost always outperform generic ones, because they know what the feature is supposed to refuse.

account_registerA

[AGGRESSIVE — requires human approval] Create a test account and register the resulting session.

This is the one action in the authenticated toolchain that creates state rather than reading it, so it is refused unless the program said it may happen: rules.allow_self_registration in scope.yaml, which is transcribed from the program's published policy and defaults to false.

signup_url is the form's action (where the signup POST goes). username_field/password_field/email_field name the form fields. Credentials default to generated values; pass them to register a specific account. The session that comes back (cookies + headers) is registered under name so authz_compare can use it immediately.

The response is masked; the generated credentials are returned once so the operator can store them, and never logged.

auth_crawlA

[AGGRESSIVE — requires human approval] Crawl an application as a registered session and map what is behind the login.

session names a session from session_register; it is only sent to the host it was issued for.

Before crawling, the entry point is fetched with and without the session. If the two responses are identical the session authenticates nothing, and the crawl is refused — a list of public pages labelled "authenticated surface" would poison every conclusion drawn from it.

When a page turns out to be a single-page-app shell, its same-origin script bundles are fetched and mined for paths — API literals, request call sites, and the route table. Those become crawl seeds under the same guards as a link, and are counted separately in coverage so it is visible how much of the map a link crawler alone would have missed. max_bundles bounds the extra requests.

Returns the discovered URLs, the forms found (read-only ones submitted with empty values, state-changing ones reported and never touched), and — the useful part — the URLs carrying an object reference, which is what authz_compare must be pointed at. A URL with no identifier in it belongs to everyone and proves nothing about access control.

auth_surfaceA

Detect authentication functionality and rank hosts by account-worthiness.

target takes one host or a comma-separated list — normally the live URLs http_probe found, which is how scripts/hunt.sh chains it. Targets are scope-checked before this body runs, so the list cannot be widened here.

Every request is a GET against a conventional path. Nothing is submitted, no account is created, and no credential is sent. The output is a recommendation to a human: register on these hosts, by hand, if the program's rules permit it — then bring the sessions back with session_register and authz_compare can finally test authorization.

coverage_reportA

Report bug-class coverage: what Cordon finds, confirms, and bypasses.

The completeness check a client asks for before a test. Every row grades a bug class as auto (a validator proves it), detect-only (found but not confirmed), or manual (inherently judgement-shaped). A class is never silently absent — gaps are named, with what would close them. Touches nothing and costs no budget.

  • class_name — one class in full ("sql-injection", "xxe-injection")

  • status — everything of one grade ("auto", "detect-only", "manual")

  • gaps_only — just the non-auto classes, the watch-list

engagement_attachA

Re-attach to an existing engagement workspace by path.

Loads the workspace's scope, budget ledger, assets, findings, sessions and pipeline state so a new session continues exactly where the previous one left off — background jobs included, because they live in the server's event loop rather than in a dead shell process.

engagement_newB

Create (or re-open) an engagement and make it the active one.

This is cordon_load_scope plus the resumability an agent needs: passing an existing workspace directory re-opens it — budget, assets, findings, sessions, task graph and the phase runner state are all inherited — so a session that dropped mid-run resumes instead of starting over.

Returns the workspace path; every later tool call acts on this engagement until another engagement_new/engagement_attach switches it.

hunt_planA

Propose concrete tests based on what recon actually observed.

Sends no traffic. Reads the engagement's asset store and returns testable propositions, each citing the observation behind it.

focus optionally narrows the request ("authentication", "idor", "business logic"). Leave it unset for a general pass.

Returns proposals — things to try — and gaps, which is the more valuable half: what the model would need in order to say anything sharper. On a target where everything interesting sits behind a login, gaps will say so, and that is the honest answer rather than five generic suggestions.

pattern_scanA

Scan URLs (and optionally their response bodies) with vetted gf patterns.

Classifies each URL by its query parameters and path segments, and — when scan_bodies is true — fetches it once and scans the response for sink shapes. Results are grouped by bug class, each candidate naming the validator that would prove or kill it. Nothing here files a finding: a pattern match is a lead, and the validators exist because leads are usually wrong.

target names URLs, or "auto" to inherit the live URLs an earlier phase recorded. The pattern library lives in rules/gf/; if it failed to load, this returns UNTESTED rather than an empty scan.

pipeline_statusA

Where the pipeline is right now: per-phase state, next pending phase.

Machine-readable version of the status.jsonl trail — branch on state/next instead of tailing files.

program_scope_fetchB

Fetch a bug bounty program's published scope into a scope.yaml scaffold.

program is a HackerOne handle or policy URL (e.g. acme or https://hackerone.com/acme). The tool fetches the policy page, extracts the in-scope and out-of-scope domains/wildcards the page declares, and writes out (default scope.yaml) as a transcription scaffold.

The file is NOT a finished authorization: cordon scope validate keeps warning until you review it, rename the engagement, and confirm the entries against the policy page. Never run the pipeline on a scaffold you have not reviewed.

research_guidanceA

Research a vulnerability class and produce an actionable testing playbook.

vuln_class is a bug class ("sql-injection", "xss", "ssrf", "idor", "request-smuggling", … — fuzzy names work). asset is the URL under test, evidence any observation so far (a 403, a parameter, a scanner hit), stack the observed technologies (comma-separated) to scope the brain's memory recall. Read-only: assembles knowledge, sends no traffic. To execute the validators it names, call guided_validate instead.

run_phaseA

[AGGRESSIVE — requires human approval] Run a single phase against a target and record its state.

phase is one of the pipeline phases (probe, scan, exploit, …). target defaults to the engagement's first seed. extra_json is an optional JSON object of extra kwargs for the phase's tool (e.g. {"include_heavy": true} for the exploit phase).

The phase result is persisted to pipeline-state.json and the audit log, so run_pipeline/pipeline_status and later sessions see it.

run_pipelineA

[AGGRESSIVE — requires human approval] Run the engagement pipeline, gated, resumable, in-process.

phases restricts to a comma list ("probe,scan"); from_phase starts at a named phase; exploit adds the exploit phase (still refused unless the scope authorizes exploitation).

Each phase runs through its registered MCP tool — the full control-plane chain applies per phase — and results land in pipeline-state.json + the audit log. Finished phases are skipped on re-entry, so a dropped session resumes where it stopped.

session_listA

List registered sessions. Values are masked.

session_registerC

Register an authenticated session for later phases to use.

cookies takes sid=abc; csrf=def. headers takes Authorization: Bearer xyz (semicolon or newline separated).

host is mandatory and is enforced: a session is only ever attached to that host or its subdomains. Sending an operator's cookie to a host it was not issued for is a credential leak, and guessing is how that happens.

role is free text — "admin", "user-a", "user-b". Register two accounts of differing privilege and authz_compare can test authorization properly; one account only tests that the application works.

Nothing here creates an account. Self-registration is a policy question: some programs invite it, others are silent, and silence is not permission. Read the program's rules, register by hand, then bring the session here.

Values are masked in every result, log and audit entry. The store lives in the engagement workspace, which is gitignored, mode 0600.

technique_lookupA

Query the PayloadsAllTheThings technique index for how to test a bug class.

The counterpart to wstg_lookup: WSTG says what to check, this says how. Each record names the Cordon tools that test the class, the vetted payload lists, and the gf pattern packs that correspond to it. Retrieval, not automation — nothing here fires anything, and it costs no budget.

Five ways in, most specific first:

  • class_name — one technique in full ("sql-injection", "open-redirect")

  • tool — every technique a given Cordon tool covers ("sqli_validate")

  • technologies— comma-separated stack from http_probe ("Rails,MongoDB,GraphQL")

  • query — free text ("jwt forgery", "deserialization")

  • phase — everything in a phase (input_validation, authentication …)

upload_surfaceA

Detect file-upload surfaces (multipart forms, file inputs, upload paths).

Fetches the discovered pages read-only and reports which URLs carry a file input, a multipart form, or an upload-shaped action/parameter. Nothing is uploaded — this is detection only, and every entry is a lead for a human or an approved validator, not a finding.

wstg_lookupA

Query the OWASP Web Security Testing Guide for what to test next.

Four ways in, most specific first:

  • test_id — one test in full ("WSTG-INPV-05")

  • technologies — comma-separated stack from http_probe ("Java,Tomcat,OAuth")

  • query — free text ("session fixation", "file upload")

  • phase — everything in a phase (recon, authentication, input_validation …)

Retrieval, not automation. A WSTG test says what to check and why; whether it applies to this target is a judgement no detector makes for you. Touches nothing and costs no budget.

port_scanA

[AGGRESSIVE — requires human approval] Discover open TCP ports with naabu.

ports: "top-100", "top-1000", or an explicit list like "80,443,8080-8090". CDN ranges are excluded automatically.

service_scanA

[AGGRESSIVE — requires human approval] Fingerprint services on specific ports with nmap -sV plus safe NSE scripts.

scripts is restricted to default/discovery/version/banner. Exploit, dos, brute, malware, intrusive, and safe-as-a-category are refused: the safe category pulls broadcast-* scripts (which crash nmap with the nse_nsock.cc:342 assertion and probe the LAN instead of the target) and http-slowloris-check (which holds connections open and stalls the whole scan at the engagement's rate limit). default is the curated category that fingerprints without either failure mode.

ports defaults to what port_scan already discovered for the requested hosts (the open_port assets in the store) and falls back to the web ports 80,443 only when nothing was discovered. target may name several hosts — the service phase feeds it every host that has an open_port asset, so one nmap pass fingerprints the whole estate instead of the single focus host. The old design scanned one host's 80,443 and silently reported "no services" on every estate that runs on 3000/8080/ 8443 — exactly the ports port_scan exists to find. The chain is ports -> services; services must consume what ports produced.

asn_lookupA

Look up ASN and netblocks for a domain or organization.

Netblocks are returned for context only — an ASN belonging to the target does not put its ranges in scope. Check anything you find with scope_check before touching it.

bbot_scanA

Map attack surface with BBOT. The primary recon entrypoint.

Presets: subdomain-enum (default), cloud-enum, code-enum, email-enum, web-basic, baddns, fast. Aggressive presets (web-thorough, spider, paramminer, web-screenshots, baddns-thorough, kitchen-sink) are routed through bbot_scan_active instead, which requires approval.

Returns inline if the scan finishes within wait_seconds; otherwise returns a job_id — poll it with job_status and read results with fetch_slice.

bbot_scan_activeA

[AGGRESSIVE — requires human approval] Actively probe with BBOT (web-thorough, spider, paramminer, screenshots).

Requires human approval. Prefer bbot_scan first: active probing on an unmapped surface wastes the program's rate limit on hosts you have not yet established are interesting.

osmedeus_flowB

[AGGRESSIVE — requires human approval] Run a named Osmedeus flow from the reviewed flows directory.

Only flows present in engines.osmedeus.flows_dir may be run — arbitrary flow paths are refused because an Osmedeus flow can execute shell commands.

security_txtC

Fetch /.well-known/security.txt and report the declared security contact.

subdomain_enumA

Enumerate subdomains from every installed passive source and merge them.

Runs whichever of subfinder / assetfinder / findomain / amass / theHarvester are present, in parallel, and returns the deduplicated union filtered through the engagement scope. Installing more sources widens coverage with no code change — the tool set is discovered, not hardcoded.

include_amass defaults off. On a real engagement amass ran the full 15 minutes and returned zero subdomains — its productive sources want API keys — while subfinder and assetfinder found 322 and 301. It also spawns an amass engine child that calls setsid itself, so it escapes the process-group kill on timeout and keeps running, unthrottled, after the engagement believes the tool stopped. Turn it on when amass is configured with datasource credentials; leave it off otherwise.

thorough adds slower sources (theHarvester, amass with more providers). Prefer bbot_scan when BBOT is available: it covers more sources than all of these combined.

tls_infoA

Read TLS certificates and pull subject-alternative names.

SANs frequently reveal internal hostnames and sibling domains. They are scope-filtered before being stored, since one certificate often covers hosts belonging to several organizations.

tlsx opens TLS connections to the target, so its concurrency and inter- connection delay are pinned to the engagement. Its default concurrency is 300.

whois_lookupA

WHOIS registration data for a domain: registrar, org, dates, nameservers.

Useful for confirming an asset actually belongs to the program before you spend requests on it.

finding_detailA

Full record for one finding, including evidence and PoC.

finding_noteC

Attach an analyst note to a finding. Notes appear in the report.

findings_listA

List findings, optionally filtered by status and severity.

Returns a compact table by default. Set detail=True for full records — prefer the compact form while planning; it costs a fraction of the tokens.

report_generateA

Write Report.md, Report.csv, findings.json, and the task graph to reports/.

Confirmed findings (those with a reproducible PoC) are reported separately from unproven leads. Pass partial_reason when a run stopped early so the report says so on its first page.

forbidden_bypassA

[AGGRESSIVE — requires human approval] Test a URL that returned 403 against twelve access-bypass techniques.

url must be a URL that actually returned 403 (run forbidden_candidates or check the probe result first — unKover refuses anything else). prefix optionally adds an API version prefix (/v2) that the server may not protect. Returns the first working technique with a curl PoC, or a clean report when nothing bypasses.

forbidden_candidatesA

Pre-check a list of URLs and return the ones that actually return 403.

forbidden_bypass refuses anything that is not 403, so this is the pre-filter: one cheap HEAD per URL, returns the 403s. Give it URLs from http_probe or content discovery that looked interesting; it tells you which are worth the bypass pass. Read-only.

jwt_inspectA

Decode a JWT and report its algorithm, claims, and timestamps.

Fully offline: not one request leaves this machine, which is why it is passive and costs zero requests. target is the in-scope asset the token came from — it exists so the call is still scope-checked and the finding has an owner, not because jwt_tool contacts it.

Every jwt_tool mode that forges a token (-T/-I/-S/-X), cracks a key (-C), or replays one at a live host (-t/-M) is denied by the argument policy. Proving a JWT flaw is an exploit-phase action with its own approval gate, not something this tool can be talked into.

secret_scanA

Scan files in the engagement workspace for credentials. No validation.

Runs Kingfisher (primary), Nosey Parker (git history + ML denoising), and gitleaks where installed. Sends no traffic anywhere — every hit is a candidate until secret_validate says otherwise.

path is workspace-relative; paths outside the workspace are refused.

secret_validateA

[AGGRESSIVE — requires human approval] Validate candidate credentials with Kingfisher and map their blast radius.

This is what makes a secrets report actionable: a live credential is critical, an unvalidated match is noise. It is gated because validation is use — the request goes to AWS/GitHub/Stripe authenticated as whoever owns the key.

Validation traffic is paced at the engagement's max_rps. That ceiling was written for the target, and these requests go to third parties instead — but it is the only rate this engagement has consented to, and issuing hundreds of authenticated requests per second at anyone is not something a scan should decide on its own.

source_fetchA

Clone a public repository into the workspace so it can be scanned.

Cloning is separated from scanning so the audit log always answers "what code did Cordon read". Only github/gitlab/bitbucket HTTPS URLs are accepted.

Confirm the repository actually belongs to the program before scanning it — an organization name matching the target is not proof of ownership.

takeover_confirmA

[EXPLOIT — requires human approval] Verify a human-executed takeover PoC is live and attach it to the finding.

Fetches the proof URL, checks the proof content is actually served from the target host, and only then promotes the finding to confirmed. This is the single place a takeover can become 'confirmed'.

takeover_detectA

[AGGRESSIVE — requires human approval] Screen hosts for takeover candidates with subzy and dnsReaper.

Output is a candidate list, never findings. Run takeover_verify on each hit before treating any of them as real.

takeover_poc_planA

Produce the minimal, responsible PoC steps for a verified takeover.

Cordon does not register resources at third-party providers on your behalf. This returns the exact steps, including a unique proof path tied to your researcher handle, so the proof is unambiguous and the impact stops at 'I could have'.

takeover_verifyA

Verify a takeover candidate: CNAME chain + live response + fingerprint.

All three must agree before the host is recorded as a verified candidate. A verified candidate is filed as 'needs manual review' — confirming it requires actually claiming the resource, which is takeover_poc_plan followed by takeover_confirm.

NS and MX delegations are graded higher: those hand over the zone or the mail.

triage_canary_previewA

Show the fabricated canary findings triage would mix into a batch.

Useful for confirming the decoys look plausible enough to be a real test. They always live on a .invalid host, which by RFC 2606 can never resolve.

triage_findingsA

Run AI triage over candidate findings to cut false positives.

Fabricated canary findings are mixed into the batch; a pass that "confirms" one has its verdicts weighted down, and the measurement is reported.

Triage never confirms anything. Escalated findings go to validate_findings.

triage_taskflowsA

List available triage taskflows and their steps.

code_auditA

Run the white-box code audit over source in the engagement workspace.

Scans path (relative to the workspace, default source — the directory source_fetch clones into) with Semgrep's parsing rules and gitleaks, then writes a merged deliverable:

  • code-audit.json — structured, redacted records from both tools.

  • code-audit.md — human-readable audit with attack-surface implications.

Semgrep hits are filed as CANDIDATE findings (reachability is a later question — static analysis finds sinks, not exploits). Gitleaks hits are redacted and kept in the deliverable only: unvalidated regex matches are not findings, and the secret-scanning phase owns that class.

With no source in the workspace the phase reports count: 0 — run source_fetch(repo_url=...) first and confirm the repository belongs to the program.

jaeles_scanA

[AGGRESSIVE — requires human approval] Run Jaeles YAML signatures (plugin class C) against in-scope targets.

selector picks signatures by name or glob, e.g. 'cordon/' or 'cve/'. Signatures are loaded from rules/jaeles/ only.

Returns inline if it finishes within wait_seconds, otherwise a job_id.

nikto_scanA

[AGGRESSIVE — requires human approval] Scan a web server with nikto for dangerous files and misconfiguration.

Aggressive, and gated: nikto walks a database of several thousand paths, so it is loud, obvious in logs, and will trip a WAF. That is a decision for a human, not a default.

Two bounds apply and neither is negotiable. -maxtime stops nikto from the inside so its report still gets written, and the process timeout sits above it as a backstop. max_minutes is clamped to MAX_SCAN_MINUTES (30).

Pacing comes from scope.rules.max_rps via -Pause; there is no rate argument. The Denial of Service test group is excluded by a sanitizer pattern that every -Tuning value must satisfy.

nuclei_scanA

[AGGRESSIVE — requires human approval] Scan in-scope targets with Nuclei templates or a workflow.

templates: template files/dirs/ids to run. Custom rules under rules/nuclei/ are always included. workflow: a workflow file for conditional chaining. tags: comma-separated template tags (dos/fuzz/intrusive are refused).

Returns inline if it finishes within wait_seconds, otherwise a job_id.

semgrep_scanB

Run Semgrep (plugin class D) over source in the engagement workspace.

Passive: reads files already fetched into the workspace and sends nothing to the target. Rules in rules/semgrep/ always participate; config may add a registry pack ('p/security-audit') or another workspace path.

Use source_fetch first to bring a repository into the workspace.

wapiti_scanA

[AGGRESSIVE — requires human approval] Crawl and attack a web application with wapiti.

Aggressive, and gated. Even profile='safe' crawls the whole application; profile='injection' submits SQLi, XSS, command-injection, SSRF, CRLF and XXE payloads to every parameter found. Nothing about that is observational.

Bounds, all enforced server-side: --max-scan-time caps the run, --max-attack-time caps each module, crawl depth and links-per-page are capped, and the process timeout sits above all of them. max_minutes is clamped to MAX_SCAN_MINUTES (30).

wapiti exposes no requests-per-second control — the closest it offers is --scan-force, which is set from scope.rules.max_rps here. That is an approximation and it is reported as one: a program with a strict published rate limit is a reason to prefer nuclei with -rl.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

B3.4/5.0

Scored across 127 tools

Disambiguation3/5

Most tools are crisply differentiated, but several pairs genuinely overlap: code_audit and semgrep_scan both run Semgrep over workspace source, brain_recall / memory_recall / graph_recall are three near-synonymous 'recall knowledge' tools, and cordon_status vs dashboard_state both report engagement state. An agent would plausibly misselect among these. The pipeline families (takeover_detect/verify/confirm/poc_plan, forbidden_candidates/bypass, secret_scan/validate) are otherwise well-structured.

Naming Consistency4/5

The dominant convention is snake_case verb_noun (subdomain_enum, whois_lookup, content_discovery, secret_scan) with a consistent toolname_scan sub-family (nikto_scan, nuclei_scan, wapiti_scan, semgrep_scan). Deviations exist — the cordon_* brand prefix, cmdi_probe's abbreviation, security_txt's nominal form, and fuzz_compare's verb_verb — but they are minor against the overall pattern.

Tool Count1/5

With roughly 70 tools listed (127 claimed), this is an extreme count — an order of magnitude beyond the 3-15 well-scoped range and far past the 25+ threshold. Even granting the platform's broad domain (web, cloud, k8s, smart contracts, memory, reporting), no agent can navigate this surface efficiently, and the presentation overwhelms rather than assists.

Completeness5/5

The surface covers the entire offensive-security lifecycle: scope loading and checking, passive and active recon, web/cloud/k8s/smart-contract scanning, approval-gated exploitation, secrets, SAST, findings management, reporting, job control, rules management, knowledge lookup, memory, task-graph planning, audit, triage, and approvals. References to port_scan/http_probe/job_status suggest tools outside this list, but within the provided set there are no obvious dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues