The vulntel MCP tools
vulntel is a hosted MCP server that gives an AI security agent source-grounded vulnerability intelligence: a fused corpus (NVD + CISA KEV + FIRST EPSS + OSV/GHSA + CISA SSVC) plus a mechanic layer distilled from ~14,000 disclosed, paid bug-bounty reports. This page shows what the twelve tools actually return, with real output from the live server, trimmed for length. (Two that are async or verbose, observe and assist_submission, show the response shape rather than one capture.)
Full per-argument reference: TOOLS.md on GitHub. To drive it on a real hunt: the MIT-licensed bug-bounty skill + playbook. A key is free: mcp.rozetyp.com/signup.
Recon a target
observe - live recon of a host
Fingerprints a live host: recovers the real backend from the JS bundle (even for SPAs that hide it from header-fingerprinting), crawls the endpoints, and joins the stack to the corpus as a ranked dig-order. Async: a cache miss returns status="scanning" and you poll. The ready payload carries these fields:
observe("acme.example.com") -> { "status": "scanning", "retry_after_seconds": 8 } # poll again
observe("acme.example.com") -> { "status": "ready",
"backend": "...recovered from the JS bundle...",
"endpoints": [ ...the real API surface... ],
"recurring_loci": [ ...the bug-class shapes to hunt... ],
"affected": [ ...CVE join for the resolved stack... ] }
hunt_plan - a recon'd stack to a ranked dig-order
Ranks a stack by its most-exploitable bug and names where each component historically bleeds.
hunt_plan(["craftcms 4.4", "nginx", "keycloak"])
#1 craftcms 4.4 97 CVEs, 12 high-risk recurring_loci CWE-94 code injection x7 (2 exploited in the wild)
dig here P1 KEV EPSS 99.8 CVE-2025-32432 unauthenticated RCE (CVSS 10) your 4.4 is AFFECTED, fixed in 4.14.15
#2 nginx HTTP/2 Rapid Reset CVE-2023-44487 (KEV)
#3 keycloak recurring_loci CWE-287 auth x12
check_technology - one product to version-resolved, ranked CVEs
De-dupes across NVD CPE and OSV, ranks exploitation-first, flags name ambiguity instead of a silent zero.
check_technology("Apache Struts")
P1 KEV CVE-2017-5638 Jakarta Multipart parser RCE via a crafted Content-Type
P1 KEV CVE-2013-2251 OGNL expression injection -> remote code execution
P1 KEV CVE-2020-17530 forced OGNL evaluation on tag attributes -> RCE
program_outcome_prior - what actually pays on a bug-bounty program
A minute-zero, disclosure-conditioned prior: which bug classes have historically landed, with lift over the global base rate. Descriptive, not predictive; use it to reorder attention, never to eliminate a class.
program_outcome_prior("gitlab") # n_reports: 257
broken access control 16.7% (lift 2.0x)
SSRF 7.0% (lift 3.4x)
code/command injection 7.0% (lift 1.4x)
Transfer a mechanic to your target
The corpus distills ~14,000 disclosed, paid reports into transferable mechanics. These tools find the move that worked on another product and hand it to you for yours.
find_attack_approaches - borrow a proven attack, and grow tried= to reach the non-obvious
Retrieves the disclosed mechanics closest to your situation, each with the transferable trigger to adapt. The tried= parameter is what makes it a loop and not a list: name the bug classes you have already worked and it pushes them down, surfacing the approaches you have not tried yet. Grow tried= each round.
Same query, before and after you tell it what you have already worked (real output, trimmed):
find_attack_approaches("a multi-tenant SaaS with a REST API and file uploads") # tried=[]
broken access control (public S3 bucket) zomato over-permissive bucket ACL to write objects
arbitrary file read Nextcloud trick the victim into an attacker-controlled app
broken access control (exported component) owncloud abuse an exported file-receiving activity
find_attack_approaches(..., tried=["IDOR", "access control", "broken object level auth"])
cloud storage takeover IBM take over the S3 bucket tied to the endpoint
authorization bypass (signed upload) Rails a mismatched content_length so the presigned URL does not bind it
arbitrary file write (S3 upload policy) Shopify an upload policy that constrains the key prefix, not the content
Tell it you have worked IDOR and access-control, and it surfaces the S3-bucket-takeover and the presigned-URL content-length bypass instead, adapted from real reports on other products. Each card carries the trigger to adapt, the program it paid on, and whether it is still in scope.
find_continuations - your position to the concrete next step
Give it your product-free attacker position (what you control, reach, observe, and are blocked by) and it returns the concrete payload-bearing step from real report bodies, each UNVERIFIED with the decisive check that settles it and a link to the source report.
find_continuations("I control a webhook URL the server fetches server-side; the response is blind; I want to reach cloud metadata")
move_step: point the webhook at a server that issues a 303 redirect, then read the responses of
arbitrary HTTP/HTTPS requests the app makes [UNVERIFIED] hackerone.com/reports/508459
move_step: register a DNS-rebinding host (alternating to 127.0.0.1) as the webhook so the SSRF
filter passes but the fetch lands internally [UNVERIFIED] hackerone.com/reports/1379656
move_step: a failure email arrives for http://localhost but NOT for the internal URL that worked,
so the absence of the email is your blind-SSRF oracle [UNVERIFIED] hackerone.com/reports/243277
Real disclosed moves adapted to your exact position, not a list of CVEs. The decisive_check on each says what to read on the target to confirm the precondition holds.
search_vulns - CVE search by keyword or by mechanism
One entry point, three modes: free-text (keyword + semantic fused), a seed cve_id (mechanism-siblings across products), or a time window (recent high-risk).
search_vulns(cve_id="CVE-2021-44228") "what else works like Log4Shell"
sim 0.88 CVE-2021-44832 Log4j2 JDBC Appender, JNDI LDAP RCE
sim 0.82 CVE-2022-40145 Apache Karaf, code injection via a JNDI URL # different product, same mechanism
Dig, fact-check, finish
enrich_cve - one CVE, the full dossier
enrich_cve("CVE-2024-3400") Palo Alto PAN-OS GlobalProtect
P1 KEV CVSS 10.0 unauthenticated command injection -> root RCE
SSVC exploitation=active automatable=yes technical_impact=total
Metasploit exploit/linux/http/panos_telemetry_cmd_exec (rank: excellent)
Public PoC 44 repos (h4x0r-dz 161 stars, ...)
verify_cve_claim - fact-check a claim, catch the hallucination
Per-assertion supported / refuted / unverifiable with cited evidence.
verify_cve_claim("CVE-2025-99999")
-> exists: false "No record in NVD / OSV / GHSA. Likely hallucinated or not-yet-published."
verify_cve_claim("CVE-2021-44228", product="Apache Struts", severity="medium", exploited=false)
refuted "not exploited" -> in CISA KEV (added 2021-12-10)
refuted "severity medium" -> actual CVSS 10.0 -> P1
refuted "affects Apache Struts" -> this CVE is Apache Log4j2, not Struts
search_public_code - who copied a vulnerable line
Finds public repositories containing an exact code string. Raw hits you read yourself, best for spotting an unpatched vendored copy or how a bug was fixed in the wild.
search_public_code("<an exact line from the vulnerable function>")
-> [ { "repo": "someorg/someproj", "path": "src/parser.py", "url": "https://github.com/..." }, ... ]
assist_submission - draft a submission, guarded
Pulls the closest disclosed precedent for a draft finding and returns a grounded brief with a citation guard. It surfaces prior art and what is novel; it does not decide whether to submit. Shape:
assist_submission("IDOR: GET /api/v2/invoices/{id} returns another tenant's invoice PDF")
-> { "count": <n>, "citations_grounded": <bool>,
"prior_art": [ ...closest disclosed IDOR reports, program, payout... ],
"brief": "precedent, what is novel here, how to frame the impact" }
corpus_stats - is the data fresh?
corpus_stats()
-> { "cves": 368765, "kev_entries": 1638, "epss_scores": 344957,
"latest_cve_modified": "2026-07-14", "data_age_days": 0.4, "stale": false }
Figures drift daily; call corpus_stats for the live count rather than trusting a number here.
Get a free key at mcp.rozetyp.com/signup, point your agent at mcp.rozetyp.com/mcp, and the bug-bounty skill drives all twelve on a real engagement. For the field notes behind the corpus, start here.