Skip to content
OpenSmartRoute
Skillv1.0.0

cti-expert

Cyber threat intelligence and OSINT analysis toolkit. Runs structured investigations and delivers analyst-grade intelligence products with sourced, trust-scored findings. Use for OSINT and CTI cases,

by 7onez(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from 7onez/cti-expert (SKILL.md). Install upstream with npx skills add 7onez/cti-expert. Copyright stays with the author.

CTI Expert

Cyber threat intelligence and open-source intelligence skill. Turns Claude into a trained CTI/OSINT analyst. Generates precision search queries, interprets public data, builds case timelines, and delivers structured intelligence products — no API keys, no paid subscriptions.

Runs anywhere. Works in Claude Code (Desktop & CLI) and in OpenAI Codex / ChatGPT and other AGENTS.md-aware agents — see AGENTS.md for the cross-agent runtime contract. Throughout this file, $SKILL_DIR = the directory containing this SKILL.md (Claude Code: ~/.claude/skills/cti-expert; Codex/manual clone: the repo you are working in). Resolve it by locating SKILL.md — never hard-assume ~/.claude. Detect the OS once (Windows/macOS/Linux) and prefer uv for all Python — see §13 Tool Auto-Install Policy.

Collection method: agent-browser when available (JavaScript-heavy sites, infinite-scroll, screenshot evidence), with automatic fallback to web search / web fetch / direct URL fetch. Tool limitations are logged as collection gaps — never as case blockers.


1. Quick Start

# Full autonomous case — runs every applicable technique
/case target.com

# Guided flow for first-time investigators
/flow person

# Summary of what's been found so far
/brief

Append --yolo to any command to skip all interactive prompts and confirmations. The analyst makes every decision autonomously.


2. AEAD Case Lifecycle

Every investigation follows four phases:

Phase What Happens
Acquire Collect raw data — /sweep, /query, /username, /phone, /email-deep, /breach-deep, /subdomain, /webpivot + /icp (domain/URL targets), /dork-sweep · /docleak · /github-osint//secrets, /cn-corp · /iban · /hash-id on discovery
Enrich Recursive pivot loop — the pivot orchestration engine treats every discovered identifier as a new seed and expands the graph hop-by-hop (/branch, /crossref, /link-subjects, /signatures) automatically until the frontier is exhausted, no approval prompts (autonomy=auto). Each discovered identifier auto-fires its leak/breach/OSINT/dork legs — email→/breach-deep+/intelx (breach dumps·infostealer logs·pastes·darknet), username→/username+socials, name→/dork-sweep+/docleak, apex→/intelx --phonebook+/secrets+/github-osint — see §"Leak / breach / infostealer auto-fire" + the Dork/GitHub auto-fire matrices. Acquire↔Enrich iterate, not run once.
Assess Score and verify — /exposure, /threat-model, /validate, /coverage, /verify-finding. Judgments carry likelihood terms, coverage gets the 5W1H pass, attributions get an ACH matrix (handbook/analytic-standards.md). If the case has not converged (frontier still open after the pivot loop + deterministic pipeline) and posture is active, /case auto-escalates to the /harness deepening loop — keyless-first (the CLI's own model), egress hard-gated on hostile infra; --no-harness opts out
Deliver Package output — /report, /brief, /render, /workspace savefirst ASKS whether to import more evidence from manual investigation (merged into the report JSON before anything is built), always auto-saves the base data bundle (.md + .json + .csv + IOC bundle: .stix.json/.txt/.csv/.jsonl), then ASKS which presentation report to render — (a) PDF · (b) DOCX · (c) HTML · (d) all (both prompts skipped under --yolo/guided-auto, which default to HTML). When CHONGLUADAO_API_KEY is set, the IOC bundle also attaches CLD's STIX + MISP indicator feed as companion artifacts (cld_api.py feed stix2|misp --raw → loadable bundle, not merged into the case graph). Deep-layer persist (automatic, ZERO extra egress): when /backend is live, /case reuses the pivots it already collected — never re-fetches — to persist the versioned case at $SKILL_DIR/intel_engine/cases/<CASE-ID>/ and correlate it cross-case; see the auto-chain note below. See connectors/chongluadao-api.md

Run /progress at any point to see which phase you're in and what's pending.

/case and web-infra pivoting. For a domain or URL target, /case includes web-infrastructure pivoting (/webpivot) in the Acquire phase. It runs keyless by default (crt.sh + passive DNS + anonymous urlscan) and upgrades automatically when premium keys are set via /apikeys (Shodan/Censys/FOFA/Hunter.how/DNSLytics/SecurityTrails/urlscan-PRO/WhoisXML). With keys the pipeline also: reads the urlscan Pro hostname lifecycle (pre-registration NS/A eras on the timeline, verdict rows in Appendix B), runs the MO-neighbour pivot on the estate's non-CDN origin (co-tenants WHOIS-verified; only a registrant join-key ever seeds, same-MO personas render as a rung-10 Related personas table — --mask-personas to aggregate), measures entitlement (meta.capability.plans, per-case capability_plans.json; Censys' search is its own probe), and fires SecurityTrails DNS-history + DSL reverse-WHOIS, DNSLytics reverse-IP (co-tenancy-filtered), a once-per-case Censys cert search, Shodan cert/JARM search and IntelX (loop: --full only). Every metered leg is --free-only/no_spend-gated; IntelX selectors, WhoisXML/SecurityTrails reverse-WHOIS terms, MO-neighbour origins, DNSLytics reverse-IP and the Censys cert search are bought once per CASE (on-disk memo), while per-host legs (urlscan lifecycle, SecurityTrails subdomains/history, Shodan search) stay per host under per-case caps. Because /webpivot can fetch the target directly, for hostile infrastructure it prefers passive capture (urlscan/Wayback) — see techniques/web-pivot.md. It is not run for username/phone/person targets.

⭐ ChongLuaDao is the first-party premium upgrade. With CHONGLUADAO_API_KEY set (/apikeys set chongluadao <KEY>), Acquire/Enrich fold CLD's own datasets into /scam-check, /threat-check, /phone, /breach-deep, /email-deep, /vuln-check and /impersonate, and /cld <target> is the direct entry point. Your client connects only to ChongLuaDao, never to the target (provable from scripts/cld/cld_api.py); for URL/AI/IP checks CLD does any target fetch server-side — the safe first-touch verdict on a live scam funnel before a direct pivot. Full catalog + AEAD placement: connectors/chongluadao-api.md.

Archive IOC harvest runs by default too. For domain/URL targets the Acquire phase also runs wayback_harvest.py <domain> --indicators (add --urlscan when URLSCAN_API_KEY is set), harvesting emails, phones, crypto wallets, tracking/verification IDs, SaaS-operator IDs, and socials from the entire Wayback history — not just the live page — with first-seen/last-seen per selector. It writes case-schema indicators[] to <case>/raw/harvest.indicators.json, which merge into the case and flow into the auto-saved IOC bundle at Deliver. This is the step that recovers selectors a network later scrubbed — across the whole snapshot corpus, not just the live page. Passive by construction — only web.archive.org (+ urlscan.io if keyed), never the target.

The five v2.6 commands are in the pipeline too — no flags. /icp runs for every domain/URL/org target (and an IP's resolved hostname); /cn-corp, /iban and /hash-id fire the moment a company name/USCC, payment detail, or hash appears — and all three feed their yields back into the recursive pivot loop as new seeds, so an ICP licence serial or a reused bank account expands the graph like any other node. /redact is the exception: it is opt-in (--redact), because a redacted report is a weaker artifact and that should always be a deliberate choice. Full trigger table: §Technique Activation Matrix. Narrow with --no-cn.

Two layers, one skill: broad collector → deep pipeline. cti-expert is the broad collector — the wide net of Acquire/Enrich commands (/webpivot, /sweep, /subdomain, /icp, /username, /email-deep, /breach-deep, …) that pull artifacts from anywhere. The intel_engine engine is now vendored in-repo under intel_engine/ (intel_engine/harness/, intel_engine/tools/, intel_engine/WebPivot/, intel_engine/IntelGraph|IntelReport|BinaryPivot|IntelAnalysis/) and supplies the pipeline chains + deeper pivoting logic: a persistent knowledge base (intel_engine/knowledge/), versioned cases (cases/), cross-case correlation, calibrated assessment, and rendering.

The chain (automatic for /case, and it NEVER re-fetches): broad collection (cti-expert) already ran pivot_extract per host during Acquire. When /backend resolves to Tier 1/2 and the run produced ≥1 host seed (domain/URL/IP), /case hands what it already collected to the deterministic pipeline in reuse mode (--no-collect) — one command, a complete case dir, and nothing touches the target again:

  1. Write each host's already-collected pivot JSON to $SKILL_DIR/intel_engine/cases/<CASE-ID>/raw/<host>.json and the host list to an absolute <CASE-ID>-seeds.txt, both anchored at the engine root (ROOT=$SKILL_DIR/intel_engine) — never a CWD-relative path.
  2. intel.py pipeline open <CASE-ID> <abs-seeds.txt> --no-collect--no-collect skips the live fetch and runs the rest of the existing pipeline over the raw you just wrote: ingest → prior-overlap (/recall) → risk (/risk) → shared cluster seeds → clusters.jsoncase_graph.json → ICD-203 assessment.md. Every step is a KB/local read: zero egress, zero metered calls.

The persisted case lands at $SKILL_DIR/intel_engine/cases/<CASE-ID>/raw/, shared.txt, clusters.json, case_graph.json, assessment.md — NOT the current working directory, and it is a COMPLETE case that intel.py pipeline status <CASE-ID> accepts (not the partial dir a hand-rolled op sequence would leave). <CASE-ID> is the same id as the report filenames (mint CASE-YYYYMMDD-NN when none is given). Its cluster/risk/assessment fold back into the auto-saved report. Tier 3 (stateless), or a person/username/phone target with no host seeds → the handoff is skipped silently and the tier noted; broad collection + report are unaffected.

Collecting pipeline open (no --no-collect) stays MANUAL — /case never runs it. intel.py pipeline open without the flag re-fetches every seed directly (collect_many on https://<host>; the egress gate at collect_core.py:169 only fires when hostile is set, which the open path never sets), so a blind auto-open would be a second live round against infra /case may have just classified hostile/no-touch — which is why the automatic handoff uses --no-collect. Run collecting mode by hand only for a fresh case with no prior collection, after setting the egress posture (/scope, /cti-proxy, or --passive).

/harness deepening AUTO-ESCALATES on non-convergence (--no-harness opts out). After the --no-collect pipeline, if the case has not convergedintel.py convergence <case> reports status ≠ converged (cold = no free leads left = exhausted), or intel.py frontier <case> still lists open leads and posture is active (not --passive, infra not classified hostile/no-touch) — /case runs the harness Collect→Correlate→Assess loop to close the gap. Egress stays safe by construction: the harness's own audit.py PreToolUse gate turns hostile=True into a hard denial of outbound collection (harness/README.md), so an escalation can never re-touch no-touch infra — on hostile infra it deepens correlation/assessment only. Model — the CLI's own agent: run interactively in Claude Code, the IntelHarness skill front-end drives the same pipeline on your subscription with no separate LLM key; it falls back to HARNESS_BACKEND=local (Ollama/vLLM/LM Studio, keyless) or an API key only for unattended SDK runs. No reasoning backend reachable and non-interactive → the escalation is skipped and noted as a collection gap, never a blocker. A converged case, --passive, or hostile-only infra → no escalation and the deterministic result stands.

Self-contained & self-resolving. /backend resolves to SELF (in-repo) — no external setup. The bundled installer (scripts/install.{sh,ps1}) provisions the deep layer; or by hand: uv venv && uv pip install -r requirements.txt (harness SDK/MCP + IntelGraph renderers; the collector + KB + deterministic pipeline are stdlib and need none). An explicit $INTEL_HOME still overrides for a shared external KB. Full architecture, the op map, and the evidence-envelope schema: connectors/intel-backend.md.


2.5. Pivot Priority & False-Positive Control (CRITICAL)

Two failure modes ruin a cluster: asserting a link that isn't there, and missing one that is. This section governs both. Apply it in Enrich, before anything reaches a report.

Pivot priority ladder

Work down this ladder. Never assert same-operator on a lower rung when a higher rung is available or contradicts it. Tag every asserted link in the report with the rung it rests on.

Rung Indicator Strength
1 Registrant email / phone / org — including historic WHOIS decisive
2 One domain carrying two identities across its own WHOIS history decisive — proves an alias
3 Site-verification token (Google Search Console, etc.) decisive — proves account control
4 Shared TLS certificate / SAN cross-cover strong
5 Nameserver delegation to a host the operator runs themselves strong — proves zone control
6 APK signing certificate strong
7 Distinctive favicon / analytics / tracker / backend tenant ID moderate — verify below
8 Co-tenancy on a dedicated host (few tenants) moderate
9 Site template / framework / kit weak — kit-level, never operator-level
10 Co-tenancy on shared/reseller hosting; managed-provider nameservers information, not a link

Reverse-WHOIS is the highest-yield pivot here. Always mode=preview first — the count is free. A term returning hundreds is shared boilerplate; do not purchase it.

Mandatory false-positive control

Before any indicator becomes a cluster edge, run /reference check <value>. If it returns UNKNOWN, decide and record it with /reference add so the next case inherits the judgement.

Six traps, all of which have produced real false clusters:

Trap Why it fools you Test
Commodity site kit A template sold to hundreds of unrelated fraud operators Search the template path in urlscan/FOFA — a large population means kit-level
Privacy-proxy contacts The registrar's boilerplate phone/email, shared by every customer of that service Reverse-WHOIS it; a spread of unrelated domains means noise
Shared/reseller hosting IP A 20+-tenant cPanel box links nothing Count tenants before clustering
Managed-provider nameservers Cloudflare/GoDaddy/Gandi/Wix NS are shared by millions Self-hosted NS is rung 5; provider NS is rung 10
Org-name collision A registrant org string that also matches a real, unrelated company Reverse-WHOIS the org; inspect what comes back before attributing
Shared analytics / tag container Often one web developer reusing a container across unrelated clients Check domain creation dates — a decade-old business sharing a tag with a new fraud domain is a third party

Never put an unvalidated indicator into a report that recommends abuse reporting. Naming an uninvolved business is the most damaging error this skill can produce. When a cluster rests on a single rung-7-or-below indicator, label it candidate, single-indicator — not a cluster member.

Never submit the case's own sample to a public sandbox (CRITICAL)

/anyrun is lookup-only: it reads detonations that already happened (anyrun_lookup). The engine does carry a detonation path — anyrun_submit (T1) / bp_anyrun.py submit — but it is gated four ways, and every gate is code, not convention:

  1. Per-submission analyst confirmation. anyrun_submit without confirm=true returns the risk briefing and sends nothing; bp_anyrun.submit() refuses unless confirm=True is passed (a function parameter — references/anyrun.json can only make the policy stricter). Show the briefing, ask, and only on an explicit yes to this submission call again with confirm=true. Consent to "analyze this sample" is not consent to detonate it.
  2. Private by default, public refused. Privacy defaults to owner; public is refused even with confirm unless allow_public is separately authorised — per call, or as the analyst's standing ANYRUN_ALLOW_PUBLIC=1 in the gitignored .env. With that set, a plan that cannot go private (gate 3 denied) is downgraded to a public task explicitly — the result carries public_task, downgraded_from, public_authorized_by — never silently, and never when the plan can go private. Auto-delete defaults to a week.
  3. Free plan fails closed. Pre-flight, before any POST, the engine checks the key's own account record: /userlimits.private (observed live; 0 in any window = denied, and the analyst attestation below cannot override that positive evidence; -1/positive = entitled), else a prior non-public task in the account's history. Neither → refused + plan_evidence, unless the analyst explicitly attests to a paid plan (allow_unverified_plan=true / --i-have-a-paid-plan) — never set it on your own.
  4. Post-submit read-back. The task record carries no privacy while the sandbox is running (observed live: a status: "in progress" stub for ~2 min), so after the POST the engine polls the report — bounded to sandbox timeout + 60 s, max 240 s — and, once finished, reads the privacy ANY.RUN actually applied. A forbidden mode is withdrawn (task deleted) and the result says exposed: true. If the task outlives the wait, the result says privacy_verified: null with a verify_command; run itbp_anyrun.py verify-privacy <uuid> / anyrun_submit with verify_task=true, target=<uuid> — to finish the check and the withdrawal. Either way this is detected, not prevented: deletion does not un-publish what the feed already showed, so treat the infrastructure as tipped.

The harness adds a fifth: audit.gate() denies anyrun_submit outright unless the run was launched with HARNESS_ALLOW_SUBMIT=1. tests/test_no_sample_submission.py asserts the gate is both marked and enforced and that no upload machinery exists outside it; intel_engine/tools/eval/test_intelx_anyrun.py §7b–7c exercises every refusal, the plan proof, the attestation path and the read-back.

Do not work around any of it. Uploading the case's own APK / installer / archive to ANY.RUN — or VirusTotal, or any public sandbox — is an outbound, irreversible act:

  • A public task is world-readable: the file, its hash, screenshots and full network log.
  • Operators watch for their own samples. The standard response is to rotate the backend, revoke the signing key and re-skin the front — destroying the infrastructure the case is built on, often days before a takedown or referral can land.
  • It cannot be recalled. Deleting a task does not un-publish what was already seen.
  • A URL detonation fetches the live target from published sandbox egress: the operator learns it was sandboxed, and a "clean" verdict may be the decoy served to datacenter IPs.

Try first, and say what you tried: static analyze_artifact, then an existing detonation of the hash (anyrun_lookup, VirusTotal, MalwareBazaar, Triage, Koodous). Prefer the downloaded FILE over the live URL. Never put a case ID or an analyst/client name in tags or the filename. Never on standing permission inferred from an earlier approval, never as a side effect of a pivot. The same reasoning governs --submit (urlscan/Wayback): a public urlscan scan of a live scam funnel is visible to the operator too.

A permuted email is a hypothesis, never a finding (CRITICAL)

When a case yields a real person's name or a username, and you already hold a domain that matters to the case, run /email-permute. An operator's mailbox is almost never published, but it is usually derivable — mail hosts use a small set of local-part conventions, and the operator's own domain is the highest-yield thing to permute against.

That value comes with a matching hazard, so this rule is absolute:

  • Permute against the case's own domains. Name × the operator's domain is a narrow, high-prior question. Name × gmail.com is volume with no prior behind it — --free exists, is capped, and should be a deliberate choice, not a reflex.
  • Never ingest a candidate into the KB, cite one in a report, or contact one. A fabricated address that reaches kb_ingest becomes a shared indicator, and a shared indicator merges two operator clusters. A permutator wired straight into correlation does not enrich a case — it silently names an innocent party. This is the same failure RULE 5 exists to prevent.
  • Candidates are not seeds. They never enter the spider-map frontier. Only an address in the tool's promote list — corroborated by independent evidence (Gravatar registration, breach corpus, a GitHub commit, a page/DOM hit, a dork) — may be treated as a real email seed, and that promotion is an analyst decision.
  • Never validate over SMTP. RCPT TO probing connects to the target's mail server, which the egress posture exists to prevent on a hostile case; and a catch-all domain answers 250 for every address ever tried, so it manufactures confidence instead of measuring it. Use --verify, which gates on MX (RFC 7505 null MX included) and checks Gravatar — both keyless, neither touching the target.

State the status in the turn. "12 candidates, 0 corroborated" is an honest result; presenting those 12 as discovered addresses is not.

Dead seed? Do not stop

Zero pivots, a parked page, or NXDOMAIN is not an answer. Run /fallback <domain> — crt.sh, the full Wayback timeline, archive.today, and the local KB. A parked apex frequently has live subdomains: enumerate CT and the Wayback CDX host histogram before writing a seed off. Report an empty result as empty; a collector that returned nothing is a finding, not something to omit.

Egress control — proxy / rotation

On a hostile case your egress IP is a selector too — a direct fetch of scam infrastructure exposes your real address to the operator, and repeated lookups from one IP get you rate-limited or fingerprinted. The /cti-proxy layer routes every HTTP(S) request the collectors make (keyless crt.sh, Wayback/CDX, urlscan, the CLD connector, WHOIS, analytics reverses, /apikeys test) through a configured proxy — or a rotation pool with automatic failover — so collection egresses from an IP you choose, and successive calls can egress from different ones. It also tunnels the collector's raw-socket TLS cert probe (/cert-pivot leaf fingerprint) via CONNECT, failing closed rather than dialling direct.

Raw-socket TLS probes are handled too — nothing dials the target directly behind a proxy. The cert-SHA probes (wp_pssl.py, wp_recon.py) and JARM (jarm.py) all take their socket from cti_proxy.proxied_connection: under an HTTP pool it is CONNECT-tunnelled and fails closed (never a direct dial); under a SOCKS pool the in-process socket hook carries it (installed at import via wp_common, and jarm.py's own bootstrap) when PySocks is present in that interpreter — if it is not (e.g. the intel.py pipeline runs tools under $INTEL_PY), the hook is absent and these probes fail closed instead of leaking, so install pysocks there; with no proxy it dials direct. As a policy choice the /webpivot analyze path additionally skips JARM under an HTTP pool (ten tunnelled handshakes are slow) and runs it under SOCKS / no proxy — that gate honors the env/pool proxy, not just an explicit --proxy.

uv run scripts/proxy/proxy.py add http://user:pass@host:3128 --label res-1
uv run scripts/proxy/proxy.py add 1.2.3.4:8080        # bare host:port -> http://
uv run scripts/proxy/proxy.py rotation round-robin    # | random | sticky | off
uv run scripts/proxy/proxy.py test                    # confirm each proxy's egress IP
uv run scripts/proxy/proxy.py status                  # pool + policy + toggles
uv run scripts/proxy/proxy.py disable                 # back to the real IP
  • It is opt-in and additive — with no proxy configured the skill runs exactly as before, from your real IP. A pool, once added, is enabled by default.
  • No-leak default: with a pool set, a failed pool is not silently retried direct — turn that on deliberately with allow-direct on.
  • Precedence: env CTI_PROXY / CTI_PROXIES (and standard HTTPS_PROXY) override the stored pool for a one-off session; the store lives in scripts/proxy/proxies.json (gitignored, chmod-600 — it may hold credentials).
  • Coverage: the broad collectors (scripts/…) get full in-process rotation + failover; the deep pipeline (/backend, /pipeline, /harness) inherits the egress for every tool it spawns (one proxy per run). For an ad-hoc tool call or the MCP server, export first: eval "$(python3 scripts/proxy/proxy.py use)".
  • Formats: add accepts a full URL, a bare host:port, a provider host:port:user:pass export, a user:pass@host:port authority, or a pasted http_proxy="…" line. HTTP/HTTPS get the full rotation + failover + no_proxy behavior; socks5:///socks5h:// auto-install PySocks on add but rotate only per run — no in-process failover, and no_proxy is not enforced (the global socket hook routes everything).
  • Full reference: /cti-proxy (commands/cti-proxy.md).

3. Command Reference

How to read this table — check the marker before you announce a command.

Marker Meaning What you may say
T2: / T1: shown Backed by a real CLI op and/or MCP tool. Call it, then report what it returned.
[model] No code behind it, and none is needed — it names a way for you to work (a summary style, a checklist, a KB read-back). Do the thing. Never claim a tool ran.
[unimplemented] The tradecraft is documented but nothing executes it yet. Say so, then follow the linked technique by hand. Do NOT narrate it as a tool call.

A command with no marker and no T2:/T1: line has not been triaged yet — treat it as [unimplemented]. Announcing a tool call that cannot happen is the failure this table exists to prevent: the output looks identical to real collection and is not.

3.0 Entry point & registered commands

/cti <target> is the single entry to this skill. It routes any target type — domain, IP, email, username, phone, wallet, hash, APK — through recall → collect → cluster → assess. Plain English works identically ("analyze example.com and pivot the infrastructure"); the command form just removes ambiguity.

/case <target> is an alias of /cti <target> — the same full pipeline run; /cti is the canonical entry (and the only form that works from a cold prompt). Prefer /cti.

Nine commands are registered with Claude Code by bash scripts/register.sh and work from a cold prompt in any project:

Command Does Equivalent T2 op Equivalent T1 tool
/cti <target> entry point — routes by target type (whole chain) (whole chain)
/cti-recall <seed> seen before? run first, always recall domain_verdict, which_cases
/cti-case <ID> <seeds> full deterministic pipeline pipeline open (none — CLI only)
/cti-pivot <url|ip> collect one target pivot-extract pivot_extract
/cti-cluster <domain> correlate & expand kb, cert-overlap kb_cluster, cert_overlap
/cti-check <indicator> false-positive control reference check reference_check, reference_add
/cti-report <ID> render graph + PDF/DOCX graph, report render_diagram, render_report
/cti-status backend / MCP / credits health backend.py status api_usage
/cti-proxy [op] egress proxy / rotation pool for all outbound calls (none — CLI only) (none — CLI only)

Every other /command in §3 is a convention read from this file, not a registered command. Once the skill is loaded they are unambiguous instructions; typed at a cold prompt they do nothing. When in doubt use /cti and describe the goal.

Three layers, one operation. The same capability is reachable three ways and the names differ by layer — T0 uses kebab-case after a slash, T2 uses kebab-case ops, T1 uses snake_case tools. The table above is the canonical mapping; when you add a capability, add a row here in the same commit or the layers drift apart again.

Capabilities that are not registered commands still carry their layer mapping inline in the §3 tables. The engine's WebPivot/BinaryPivot collectors add these: /capabilities (T2 capabilities, T1 capability_check), /impersonate (T2 impersonate, T1 impersonation_hunt), /search-pivot (T2 search-pivot, T1 search_pivot), /censys (T2 censys, T1 censys), /intelx (T2 intelx, T1 intelx_search) and /anyrun (T2 anyrun, T1 anyrun_lookup).


Commands grouped by AEAD phase.

Acquire

Command What It Does Example
/case [target] Full pipeline — runs every applicable technique (alias of /cti) T2: intel.py case <seed> (= pipeline) /case example.com
/sweep [target] Multi-vector recon on any target type T2: intel.py sweep <target> (= pipeline) /sweep @username
/query [subject] Builds 12–15 advanced search operator queries T2: intel.py query <indicator> /query example.com
/username [handle] Enumerate handle across 3000+ platforms T2: intel.py username <handle>. T1: username_enum — HYPOTHESES, not findings /username johndoe
/phone [number] Carrier, line type, reputation, public associations, infostealer exposure (Hudson Rock); VN scam-phone reports (ChongLuaDao) when keyed T2: intel.py phone +<E164>. T1: phone_osint — carrier/line-type NOT determined /phone +84901234567
/email-deep [email] Accounts, breach history, infrastructure; breach/exposure records (ChongLuaDao data-leaks) when keyed T2: intel.py email-deep <email>. T1: deep_profile — metered steps planned, not fired /email-deep u@domain.com
/subdomain [domain] CT logs, brute-force, passive enumeration; flags admin/sensitive subdomains (admin,adm,kef,ador,panel…) per handbook/admin-endpoint-indicators.md T2: intel.py subdomain <domain> (keyless certspotter + hackertarget + crt.sh; names any source that was down) · intel.py subenum <apex> (subfinder auto-keyed from .env, amass, assetfinder, findomain → cases/<id>/subenum/<apex>.json). T1: subdomain_enum — the case-persisting form; live names are queued for the next collection round by case_frontier /subdomain example.com
/breach-deep [email] Multi-source breach lookup with context — Hudson Rock, IntelX, ChongLuaDao data-leaks/exposure when keyed T2: intel.py breach-deep <email>. T1: deep_profile (mode=breach) /breach-deep u@domain.com
/traffic [domain] Traffic estimation, ranking, audience data T2: intel.py traffic <domain>. T1: traffic_rank — Tranco only; no paid-panel estimates /traffic example.com
/visitors [domain] Full visitor intelligence: tech, geo, sources, analytics T2: intel.py visitors <url>. T1: pivot_extract (trackers) /visitors example.com
/techstack [domain] Technology fingerprint (CMS, analytics, CDN, server) T2: intel.py techstack <url>. T1: pivot_extract (tech_fingerprint) /techstack example.com
/competitors [domain] Competitor & related site discovery [unimplemented] /competitors example.com
/secrets [target] Exposed credentials in repos and paste sites T2: intel.py secrets <target>. T1: github_osint (secrets=true) — code search needs auth, so queries are EMITTED /secrets github.com/org
/github-osint [target] GitHub user/org/repo recon: profiles, repos, code search, commits, forks. Deterministic committer-identity harvest built in — `wp_github.py <login org
/cld [target] ChongLuaDao first-party premium connector (scripts/cld/cld_api.py, needs CHONGLUADAO_API_KEY). Now also wired into the deterministic pipeline open: wp_cld.py runs per collected domain host in enrich_live — the denylist checkurl verdict + IoC-URL analyzer land in live_results["cld"] and ingest as reputation FACTS (cld_verdict/cld_denylisted/cld_reputation_score, never a cluster edge; an empty-evidence label is flagged, not adopted), and for .vn hosts CLD WHOIS is the PRIMARY source (WhoisXML has no .vn coverage; RDAP/port-43 fall back) so the Domain Summary registrar/registrant/dates fill in. Metered → gated by --free-only/no_spend; CLD fetches the target server-side (posture-safe). Auto-routes any indicator (url/domain/ip/hash/email/phone/asn/CVE/.onion; non-indicators are skipped, never a blind metered call) to CLD's own datasets: URL verdict vs a ~20M denylist, deep AI URL analysis (risk 1–10 + findings), IoC verdict+evidence, denylist/brand-lookalike search, data-leak/breach exposure + full data-leak module (machines, stolen/exposed creds, cookies, leaked-accounts, devices, full-export — async start→poll), CVE/KEV + actor feeds, STIX/MISP export. Your client connects only to CLD, never to the target; CLD fetches server-side. 30-min timeout ceiling (--timeout); 403/404 → skip, not fail. Subcmds: route|checkurl|analyze|denylist|checkphone|whois|burner|ioc|exposure|leaks|breaches|machines|stolen-credentials|exposed-credentials|cookies|leaked-accounts|devices|device-detail|device-credentials|full-export|brand-domains|vulns|actors|onion|feed. See connectors/chongluadao-api.md /cld https://scam-site.top
/threat-check [target] IP/domain/URL/hash threat intelligence — ChongLuaDao IoC verdict + evidence (registration, reputation, threat feeds/reports) when keyed T2: intel.py threat-check <indicator>. T1: threat_check /threat-check 185.1.1.1
/scam-check [domain] Phishing/scam/malicious domain check — upgraded by ChongLuaDao checkurl (20M-URL denylist verdict) + analyze (deep AI, risk 1–10); client talks only to CLD, which fetches the target server-side T2: intel.py scam-check <domain>. T1: threat_check (mode=scam) /scam-check susp-site.xyz
/webpivot [url] Web-infra pivoting — extract favicon mmh3 / GA-GTM-AdSense / wallet / SaaS-operator artifacts from a page's DOM → ranked pivot queries (Shodan/PublicWWW/urlscan/FOFA). Flags: --render, --crawl, --history (Wayback GA), --fetch (pull archived page content — WebFetch can't reach Wayback), --harvest (full-IOC harvest across whole archive history → emails/phones/wallets/IDs/socials), --whois, --graph (cluster), --rank (score same-operator relations), --cert (cert-fingerprint pivot), --suggest, --wallets, --paths. See techniques/web-pivot.md (reverse-lookup engines per artifact → handbook/pivot-services.md) T2: intel.py webpivot <url>. T1: pivot_extract /webpivot https://scam-site.top
(automatic — no flag) Four layers now run on every collection and need no command. Asset layer: fetches the page's own JS bundles and re-runs every extractor over the source — the fix for SPA/white-label kits where the shell HTML is empty; yields off-apex api_endpoint/websocket_endpoint (the backend survives a front-end re-skin), build_env:<KEY> tenant tokens, js_bundle_sha256, and via sourceMappingURL the operator's own dev_username/dev_project. SPA route table: reads the app's router literals — spa_route:admin, spa_route:funnel, and a spa_route_signature that survives a re-skin. Zero extra requests, routes are leads only and are never fetched. Well-known/policy files: a fixed standards list (never a wordlist, no path brute-forcing) → adstxt_publisher, apple_team_id, security_contact. JARM: TLS-stack fingerprint of the server. Suppress with --no-assets / --no-well-known; cap fetches with --assets-max N (runs inside /cti-pivot)
/capabilities Run this first, and again before reporting any "nothing found". Which optional API keys are configured, and for each absent one the evidence class that went unqueried plus the free path that substitutes. A keyless run extracts every artifact but cannot reverse most of them — so "no sibling domains" with no FOFA/urlscan key is a fact about the credentials, not about the operator. Every collection also records this in meta.capability; carry the limitation statement into the assessment and cap confidence accordingly. T2: capabilities · T1: capability_check /capabilities
/impersonate [domain] Hunt lookalike / typosquat domains of a seed — typosquat permutations (omission, insertion, adjacent-key, transposition, homoglyph, hyphenation, combosquat) + a curated scam-heavy TLD sweep + a crt.sh keyword hunt, then existence-checked by live DNS. Output separates confirmed registered lookalikes (each an impersonation:candidate — run /cti-pivot on it and compare) from an unregistered monitoring watchlist. FREE (crt.sh + DNS); --fofa / --urlscan add the metered sweeps. Never live-fetches the lookalike infra. Tune the TLDs/affixes per campaign in intel_engine/WebPivot/references/impersonation.json. T2: impersonate · T1: impersonation_hunt /impersonate example.com
/search-pivot [indicator] Multi-engine search-engine pivot — the general-web complement to FOFA/PublicWWW, which only see served HTML. Takes any indicator (domain, slogan, tracking ID, wallet, Telegram/Zalo handle) and emits ready-to-open, URL-encoded dork queries across Google/Yandex/DuckDuckGo/Bing/Brave. It does not scrape: fire the queries with WebSearch, or WebFetch the DuckDuckGo html URL, then feed new hosts back into /cti-pivot. FREE, no keys. T2: search-pivot · T1: search_pivot /search-pivot "distinctive slogan"
/censys [mode] [value] Censys Platform — the server-side view FOFA/urlscan don't give. cert <sha256> returns every hostname on that exact leaf certificate (near-decisive cross-brand same-operator evidence, and it works on a free plan); host <ip>, webproperty <host> also free-plan. query <kind> <value> builds the CenQL offline and keyless; budget reports the balance. ⚠️ 100 credits/MONTH per account, no rollover — a lookup is 1, a search 5, and running the emitted CenQL in the web UI costs the same 5. Prefer handing the analyst the query over spending a search. Needs CENSYS_PAT. T2: censys · T1: censys /censys cert 1a2b3c…
/intelx [selector] Intelligence X — search ONE strong selector across a corpus nothing else here indexes: breach dumps, infostealer logs, pastes, darknet mirrors, historical WHOIS. Takes an email / domain (*.apex wildcard ok) / URL / IP / phone / wallet / IBAN — never a brand or person name (soft terms are refused and still cost a unit; classify_selector() blocks them locally). --phonebook <domain> inventories every email, subdomain and URL under an apex — the highest-value call, PAID-only. Grading is not optional: a hit in a breach dump or stealer log is EXPOSURE, flagged NOT clusterable — two addresses in one combolist share victims, not an operator. Only whois / pastes / darknet hits may carry a same-operator edge. Keyless ≈ 50%: it still types the selector and hands you the intelx.io URL. T2: intelx · T1: intelx_search /intelx registrant@example.com
/anyrun [indicator] ANY.RUN TI Lookup — READ-ONLY. What samples carrying this indicator did when other people detonated them: contacted domains/IPs/URLs/ports, family label, Suricata context, public task links. Run it after /binary on the sample's sha256, backend host or ip:port. It is the only way to recover a packed sample's real endpoints — those exist only at runtime, so a thin string sweep plus a binary:protection finding is exactly the cue. A shared family is same-KIT, never attribution on its own. Keyless ≈ 50%: composes the query + UI link. ⚠️ This tool never submits a sample — see the box below. T2: anyrun · T1: anyrun_lookup /anyrun <sha256>
/cert-pivot [domain] Cert-fingerprint pivot — other hosts serving the same TLS cert + SAN siblings (keyless; Shodan/Censys with keys). T2: intel.py cert-pivot <domain>. T1: cert_pivot /cert-pivot scam-site.top
/sensitive-paths [list] Classify a Wayback/URL list for exposed paths (.git/.env/backups/configs) — severity + per-year timeline. Pure matching, no request reaches the target. T2: intel.py sensitive-paths --file <list>. T1: sensitive_paths /sensitive-paths waymore_index.txt
/email-hygiene [email] Grade an email domain 0–100 + A–F (disposable / MX / free / role). An RFC 7505 null MX (0 .) scores as undeliverable, not valid. T2: intel.py email-hygiene <email>. T1: email_hygiene /email-hygiene admin@site.top
/vuln-check [query] CVE/vulnerability lookup (CIRCL + NVD; ChongLuaDao CVE/KEV threat-feed when keyed) T2: `intel.py vuln-check CVE-… --product . **T1:** vuln_check`
/ransomware-check [org] Check if org is a ransomware victim T2: intel.py ransomware-check <domain>. T1: threat_check (mode=scam) /ransomware-check "Acme Corp"
/stealer-log [folder] Triage an infostealer-log folder — stealer-family attribution, victim-vs-operator profiling, cross-log actor correlation, IOC extraction (raw passwords/cookies/autofill/history shown) /stealer-log ./logs
/gdoc [url] Extract metadata/owner from Google document T2: intel.py gdoc <url>. T1: doc_metadata /gdoc https://docs.google.com/...
/msftrecon [domain] M365/Azure tenant recon — tenant ID, federation, MDI, SharePoint T2: intel.py msftrecon <domain>. T1: msft_recon /msftrecon example.com
/icp [domain|serial] ICP filing (工信部备案) → registered PRC entity + licence number; reverse the licence serial to sibling domains under the same filing (same-operator, HIGH). See techniques/china-recon.md T2: intel.py icp <domain>. T1: cn_recon — MIIT is CAPTCHA-walled; gates are named /icp scam-site.top
/cn-corp [name|USCC] PRC corporate registry chain — GSXT (ground truth) → TianYanCha/QCC/Aiqicha → 信用中国 blacklist → UBO; officers, shareholders, subsidiaries, revoked-status flags T2: intel.py cn-corp --company "<name>". T1: cn_recon — GSXT/TianYanCha gated /cn-corp 深圳市某某科技有限公司
/iban [value] Validate + decompose a bank account as a selector — mod-97 checksum, country, BBAN split, bank code, jurisdiction-mismatch signals. See techniques/fiat-payment-osint.md T2: intel.py iban <IBAN> /iban GB29NWBK60161331926819
/hash-id [hash] Identify a hash's algorithm before lookup — separates file hashes from credential material (32 hex = MD5 or NTLM) so it routes to the right service T2: `intel.py hash-id [--context file credential]. **T1:** hash_id**T2:**intel.py hash-id [--context file
/appliance-scan [domain|ip] Fingerprint internet-facing edge/VPN appliances (Citrix/F5/Cisco/Ivanti/Forti/PAN/Exchange) + exposed services → CISA KEV/CVE mapping. Passive-first (Shodan InternetDB/Censys); feeds /vuln-check + /threat-model. See techniques/fx-edge-appliance-recon.md [unimplemented] /appliance-scan vpn.example.com
/saas-map [domain] Map SaaS tenancy + identity fabric — DNS-TXT tenancy tokens, non-Microsoft IdP fingerprint (Okta/Auth0/OneLogin/Ping/Keycloak/ADFS), unauth API/GraphQL/spec discovery. See techniques/fx-saas-identity-recon.md T2: intel.py saas-map <url>. T1: pivot_extract (saas_ids) /saas-map example.com
/sharelink [url] Extract sharer identity from share link T2: intel.py sharelink <url>. T1: sharelink_resolve — contacts the final host /sharelink https://vm.tiktok.com/ABC
/binary [file|url] Built-in. Static IOC extraction from a scam/fraud binary (sideloaded APK, desktop trading .exe/.dmg, bundled .jar) via the in-repo BinaryPivot/ — signing-cert SHA-256, package name/permissions, embedded C2/backend hosts, Firebase/S3 tenants, wallets, Telegram/WhatsApp handles. Output is WebPivot-shaped → clusters the app with web infra in the shared KB. See connectors/intel-backend.md §7 /binary ./trader.apk

| /dork-sweep [target] [--telegram\|--docs\|--filetype\|--all] [--after DATE] [--clean] | Zero-auth dork sweep: Telegram ecosystem, 18 doc-hosts, filetype families; 4-tier fallback cascade T2: intel.py dork-sweep <target> | /dork-sweep example.com --filetype | | /docleak [target] [--platform list] [--severity high] | 18-platform document leak hunt with severity classification (CRITICAL/HIGH/MEDIUM/LOW) T2: intel.py docleak "<target>". T1: dork_builder — emits queries, never runs them | /docleak "Acme Corp" |

| /dns-history [domain] | Historical DNS record changes (A, NS, MX) via passive DNS T2: intel.py dns-history <domain>. T1: wayback_ga | /dns-history example.com | | /cert-history [domain] | SSL/TLS certificate timeline from CT logs (crt.sh) T2: intel.py cert-history <domain>. T1: passive_ssl | /cert-history example.com | | /proton-check [email] | Proton Mail account creation date via PGP key [unimplemented] | /proton-check user@proton.me | | /pgp-lookup [email] | PGP key search — creation date, UIDs, signatures [unimplemented] | /pgp-lookup dev@example.com | | /wifi [ssid] | WiFi SSID geolocation via Wigle.net T2: intel.py wifi "<ssid>". T1: wifi_ssid — needs a WiGLE account; discloses the gap | /wifi "HomeNetwork" | | /wifi --bssid [mac] | Exact AP lookup by MAC address | /wifi --bssid AA:BB:CC:DD:EE:FF | | /register [name] | Add a subject to the case workspace | /register JohnDoe | | /snapshots [url] | List/fetch archived Wayback snapshots. WebFetch is blocked from web.archive.org (robots.txt) — this reads the archive instead, so the request never reaches the target. T2: intel.py wayback-fetch <url> [--near latest\|earliest\|YYYY] [--list]. T1: wayback_fetch. See analysis/archive-explorer.md | /snapshots example.com | | /archive-harvest [domain] | Sweep a domain's whole Wayback history for indicators an operator has since scrubbed — the GA ID that clusters the estate is often only in an old capture. T2: intel.py wayback-harvest <domain> --indicators [--from YYYY --to YYYY]. T1: wayback_harvest | /archive-harvest site-a.example | | /fallback [domain] | Dead-seed recovery (§2.5) — crt.sh + full Wayback timeline + archive.today + local KB when a seed returns zero pivots / parked / NXDOMAIN; enumerates CT + Wayback host history before a seed is written off. T2: fallback · T1: fallback_probe | /fallback scam-site.top |

Enrich

Command What It Does Example
/branch [data] Expand a discovered identifier laterally [model] /branch john@mail.com
/pivot-suggest Rank "what to pivot on next" from findings — leet/variant/reuse/temporal/domain clusters. T2: intel.py pivot-suggest <findings.json>. T1: pivot_suggest /pivot-suggest
/email-permute [name|handle] Derive email candidates from a person name or username against case domains. VN/CN/KR family-name-first aware; folds diacritics Unicode won't. --verify = MX gate + Gravatar. Output is hypotheses — see the rule below /email-permute "Nguyen Van A" --domain example.com --verify
/rank-relations Score + rank same-operator relations across analyzed pages (noise-filtered). Mechanizes one artifact = lead, two = cluster — run it before asserting a cluster. T2: intel.py rank-relations cases/<CASE>/raw/*.json. T1: rank_relations /rank-relations
/crypto-balance [addr] On-chain balance + lifetime flow for a wallet, valued at spot. T2: intel.py crypto-balance <addr>. T1: crypto_balance /crypto-balance 1ExampleBitcoinAddressDoNotUse
/timeline [subject] Assemble dated event sequence /timeline Company Inc
/crossref Detect shared identifiers across subjects T2: intel.py crossref [--case <id>]. T1: kb_crossref /crossref
/link-subjects [A] [B] Define a connection between two subjects [model] /link-subjects John Jane
/show-connections Display all logged connections [model] /show-connections
/show-trail [subject] Show the evidence chain for a subject [model] /show-trail JohnDoe
/watch [subject] Add subject to active tracking list [model] /watch example.com
/record-finding Log a finding with source and confidence [model] Paste data after command
/show-findings List all recorded findings [model] /show-findings
/graph Full ASCII subject relationship map /graph
/pathfind [A] [B] Discover connection path between subjects [model] /pathfind A B
/diff [url] Diff archived versions of a URL [model] /diff example.com/page

Assess

Command What It Does Example
/exposure [target] Composite exposure score (0–100) T2: intel.py exposure --set k=v. T1: exposure_score /exposure domain.com
/threat-model Build threat model from findings; every attribution claim carries an ACH matrix (competing hypotheses scored by inconsistency, runner-up named) per handbook/analytic-standards.md §3. Backend hook (Assess): if /backend is up, calibrate confidence on your own priors first — intel.py operators list + intel.py risk --case <id> + read knowledge/{calibration.jsonl,analyst_profile.md} — instead of scoring from scratch. See connectors/intel-backend.md §6 [model] /threat-model
/signatures Surface recurring behavioral patterns T2: intel.py signatures --set k=v. T1: signature_scan — evaluates, does not observe /signatures
/validate Quality audit — score 0–100 [model] /validate
/coverage Coverage matrix with identified gaps — technique matrix plus the 5W1H substantive pass (Why/How unanswered blocks Deliver-ready) [model] /coverage
/verify-finding [id] Re-check a specific finding's sources [model] /verify-finding 12
/subject [name] View or create subject record [model] /subject JohnDoe
/lookup [name] Retrieve a registered subject [model] /lookup JohnDoe
/modify [name] Update a subject record [model] /modify JohnDoe
/archive-subject [name] Remove subject from active tracking [model] /archive-subject JohnDoe
/find [query] Search across all subjects [model] /find domain:example.com
/blind-spots Prioritized investigation gap analysis [model] /blind-spots
/source-check Batch source URL accessibility check [model] /source-check
/drift [subject] Temporal risk score tracking T2: intel.py drift <case> [--snapshot]. T1: case_drift /drift example.com
/clarify [finding] Plain-language finding explanation [model] /clarify fnd-003

Deliver

Command What It Does Example
/report Full report — always saves the base data bundle (.md + .json + .csv + IOC .stix.json/.txt/.csv/.jsonl), then asks which presentation to render: (a) PDF · (b) DOCX · (c) HTML · (d) all /report
/report html Interactive self-contained HTML report (primary deliverable) /report html
/report brief Single-page executive brief /report brief
/report json Raw data as JSON /report json
/report csv Spreadsheet-compatible export /report csv
/report docx Word document in the PDF house style (slate/steel palette, serif body + sans headings, cover/TOC, rich charts + Diagram Design editorial diagrams + cloud figure) — on request /report docx
/report legal Evidence-formatted for legal proceedings (adds DOCX/PDF) /report legal
/report journalist Source-citation-heavy format /report journalist
/brief Plain-language summary (non-technical) [model] /brief
/render entities ASCII subject relationship diagram [model] /render entities
/render timeline Chronological event chart /render timeline
/render risk Exposure heatmap /render risk
/render network Network topology of connections /render network
/stats Counts and coverage statistics T2: intel.py stats /stats
/workspace save [name] Persist case state [model] /workspace save mycase
/workspace open [name] Resume a saved case /workspace open mycase
/workspace list Show saved cases /workspace list
/workspace diff [a] [b] Diff two saved workspaces /workspace diff case1 case2
/render threat-path ASCII attack path flow diagram /render threat-path
/render attack-surface ASCII attack surface exposure map /render attack-surface
/report ioc Export IOCs as STIX 2.1 or flat list /report ioc --format stix
/redact [file] Shareable variant of a report — stable numbered placeholders ([EMAIL_1]) + reversible JSON map; .md/.json/.csv. Opt-in — the base data bundle stays unredacted; request with /redact or --redact /redact REPORT.md

UX & Navigation

Command What It Does Example
/flow [type] Guided step-by-step case workflow [model] /flow person
/template list Browse pre-built case templates [model] /template list
/template run [name] Run a pre-built template /template run security-audit
/novice Toggle simplified, low-jargon mode [model] /novice
/terms OSINT term glossary [model] /terms
/progress Current case phase and coverage [model] /progress
/opsec OPSEC checklist for current task [model] /opsec
/onboard Interactive first-time onboarding guide [model] /onboard
/quality Investigation quality composite score [model] /quality

Configure

Command What It Does Example
/apikeys Manage premium/pro API keys (ChongLuaDao ⭐ first-party, Shodan, Censys, FOFA, SecurityTrails, DNSLytics, urlscan-PRO, WhoisXML, Hudson Rock, IntelX, GitHub, SerpAPI…) — status/set/unset/test/unlocks. Keys upgrade existing techniques (especially /cld + /webpivot); keyless/free stays the default. Stored chmod-600 in $SKILL_DIR/.env (gitignored), env-var override. See handbook/api-keys.md /apikeys set chongluadao <KEY>
/backend Detect/report the optional persistent-intelligence backend and pick the tier — Tier 1 typed MCP (intel-harness) → Tier 2 CLI → Tier 3 stateless. Runs scripts/backend/backend.py to resolve $INTEL_HOME (env → .mcp.json → sibling dir → symlink) and print the tier line. All the backend commands below dispatch through scripts/backend/intel.py <op> at Tier 2 (or the typed MCP tool at Tier 1). intel.py list maps all 73 engine ops (full CLI parity — CDN ranges, graph-build, hypothesize, calibration, evidence-report, case-store, cost, deterministic pipeline, …); intel.py mcp prints/writes the .mcp.json that enables Tier 1 ("the server"). See connectors/intel-backend.md /backend · /backend check
/kb [query] Built-in. Query the shared knowledge base. T2: intel.py kb --stats/--entity <v>/--cluster <domain>/--shared --min N; intel.py operators list. T1: kb_entity/kb_cluster/kb_query_shared /kb --entity example.com
/recall [seed] Built-in. "Have I seen this before?" — check a seed against every prior case before collecting. T1: which_cases/domain_verdict (typed MCP). T2: intel.py recall <seed> (query.py --entity; which_cases/domain_verdict are MCP-only). Surfaces known operators up front /recall scam-site.top
/risk [case] Built-in. Score a case's hosts for NRD / bulletproof-hosting / money-trail red flags. T2: intel.py risk --case <id> (or --file <pivot.json>). T1: risk_signals /risk CASE-0001
/reverse-whois [email|name] Built-in. Reverse-WHOIS a registrant identity → only high-value pivots; refuses privacy/registrar terms, flags bulk resellers as noise. T2: `intel.py reverse-whois --reverse-email --search-type

Truncated - read the full file at https://github.com/7onez/cti-expert/blob/d0a4f079065e41b745e1d657ab794f73036f8983/SKILL.md.

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/7onez-cti-expert-cti-expert/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

7onez-cti-expert-cti-expert.ocm.jsonjson
{
  "ocm": "1",
  "id": "7onez-cti-expert-cti-expert",
  "kind": "skill",
  "name": "cti-expert",
  "description": "Cyber threat intelligence and OSINT analysis toolkit. Runs structured investigations and delivers analyst-grade intelligence products with sourced, trust-scored findings. Use for OSINT and CTI cases, digital-footprint and exposure review, domain/subdomain/DNS/certificate recon, web-infrastructure pivoting (favicon hashes, tracker IDs, TLS certs, phishing-kit fingerprinting, campaign clustering), username/email/phone enumeration, breach and infostealer-log triage, image forensics, geolocation, crypto-wallet and IBAN/bank-account tracing, darknet search, M365/Azure and SaaS tenant recon, China/Sinophone recon (ICP filings, PRC corporate registries, Baidu/FOFA/Quake/ZoomEye), vulnerability and ransomware lookup, threat modeling, PII redaction, and structured reporting. Commands include /case, /sweep, /query, /webpivot, /username, /phone, /email-deep, /breach-deep, /icp, /cn-corp, /iban, /stealer-log, /exposure, /threat-model, /report, /brief, /redact, /apikeys.",
  "publisher": "7onez",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "data_analysis",
      "marketing"
    ],
    "tags": [
      "skill-md",
      "github"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "Cyber threat intelligence and OSINT analysis toolkit. Runs structured investigations and delivers analyst-grade intelligence products with sourced, trust-scored findings. Use for OSINT and CTI cases, digital-footprint and exposure review, domain/subdomain/DNS/certificate recon, web-infrastructure pivoting (favicon hashes, tracker IDs, TLS certs, phishing-kit fingerprinting, campaign clustering), username/email/phone enumeration, breach and infostealer-log triage, image forensics, geolocation, crypto-wallet and IBAN/bank-account tracing, darknet search, M365/Azure and SaaS tenant recon, China/Sinophone recon (ICP filings, PRC corporate registries, Baidu/FOFA/Quake/ZoomEye), vulnerability and ransomware lookup, threat modeling, PII redaction, and structured reporting. Commands include /case, /sweep, /query, /webpivot, /username, /phone, /email-deep, /breach-deep, /icp, /cn-corp, /iban, /stealer-log, /exposure, /threat-model, /report, /brief, /redact, /apikeys."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "github",
      "repository": "https://github.com/7onez/cti-expert",
      "path": "SKILL.md",
      "ref": "d0a4f079065e41b745e1d657ab794f73036f8983",
      "url": "https://github.com/7onez/cti-expert/blob/d0a4f079065e41b745e1d657ab794f73036f8983/SKILL.md",
      "key": "7onez/cti-expert/SKILL.md"
    }
  },
  "instructions": "# CTI Expert\n\nCyber threat intelligence and open-source intelligence skill. Turns Claude into a trained CTI/OSINT analyst. Generates precision search queries, interprets public data, builds case timelines, and delivers structured intelligence products — no API keys, no paid subscriptions.\n\n> **Runs anywhere.** Works in **Claude Code** (Desktop & CLI) and in **OpenAI Codex / ChatGPT** and other `AGENTS.md`-aware agents — see [`AGENTS.md`](AGENTS.md) for the cross-agent runtime contract. Throughout this file, **`$SKILL_DIR`** = the directory containing this `SKILL.md` (Claude Code: `~/.claude/sk",
  "cost": {
    "context_tokens": 40578
  }
}

Fetch it by URL: GET /api/v1/registry/7onez-cti-expert-cti-expert/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.