From Gold Datasets to AI Agents: VulnMCP 2.0.0, ML-Gateway 1.4.0, and VulnTrain 3.2.0

Today we are releasing an entire chain at once. VulnTrain 3.2.0 turns a hand-curated gold dataset of CVE-to-ATT&CK mappings into a published multi-label classifier — with the methodology now on arXiv. ML-Gateway 1.4.0 serves that model (and its siblings) over a local REST API, hardened against real-world inputs. And VulnMCP 2.0.0 puts the whole thing — plus the Vulnerability-Lookup API, KEV catalogs, sightings, the GCVE registry, and now the CNA partners of the CVE Program — one tool call away from any MCP-capable AI agent.

In other words: the same pipeline goes from an expert-annotated dataset, through training and evaluation, to a model your chat agent can invoke mid-conversation to tell you which MITRE ATT&CK techniques a fresh CVE is likely to enable.

How the pieces fit together

  graph LR
    subgraph sources["Data & ground truth"]
        VL[("Vulnerability-Lookup<br/>CVE, GHSA, KEV,<br/>sightings, comments")]
        CTID["MITRE CTID<br/>expert CVE→ATT&CK mappings"]
    end

    subgraph vulntrain["VulnTrain (training)"]
        DS["Dataset generation<br/>(Hugging Face datasets)"]
        TR["Trainers & validators<br/>severity / CWE / ATT&CK"]
    end

    HF[("Hugging Face<br/>CIRCL models")]

    subgraph inference["Inference"]
        MLG["ML-Gateway<br/>REST API"]
        MCP["VulnMCP<br/>MCP server"]
    end

    AGENT["AI agents, chat clients,<br/>automated workflows"]

    VL --> DS
    CTID --> DS
    DS --> TR
    TR --> HF
    HF --> MLG
    HF --> MCP
    MLG -->|"VLAI enrichment"| VL
    VL -->|"REST API"| MCP
    MCP --> AGENT

Vulnerability-Lookup feeds the training datasets; VulnTrain produces the models published under the CIRCL organization on Hugging Face; ML-Gateway serves them back to the Vulnerability-Lookup platform (that is where the VLAI severity scores on vulnerability.circl.lu come from); and VulnMCP loads the same models locally and combines them with the live APIs, for AI agents.

VulnMCP 2.0.0

When we introduced VulnMCP in March, it shipped severity classification, CWE prediction, CPE guessing, and the core Vulnerability-Lookup tools. Version 2.0.0 grows the server to 17 tools and reworks the internals to make the next seventeen cheap to add.

ATT&CK techniques in your agent’s toolbox

The headline feature: classify_attack_techniques, backed by CIRCL/vulnerability-attack-technique-classification-roberta-base, trained with VulnTrain on the curated gold dataset described below. It is a genuine multi-label classifier: every technique in the vocabulary is scored independently through a sigmoid head, and scores at or above 0.5 are the model’s positive predictions — the same threshold used for the F1 metrics during training.

This is how the tool presents itself to an MCP client such as Claude Code:

The classify_attack_techniques tool of VulnMCP shown in Claude Code, with its description and parameters

The classify_attack_techniques tool as exposed by VulnMCP, seen from Claude Code.

Asking it about Log4Shell’s description:

poetry run fastmcp call vulnmcp/server.py classify_attack_techniques \
    description="Apache Log4j2 JNDI features do not protect against attacker \
controlled LDAP and other JNDI related endpoints. An attacker who can control \
log messages or log message parameters can execute arbitrary code loaded from \
LDAP servers when message lookup substitution is enabled." top_k=5
{
  "techniques": [
    {"technique": "T1496", "name": "Resource Hijacking",                 "score": 0.8451, "predicted": true},
    {"technique": "T1190", "name": "Exploit Public-Facing Application",  "score": 0.7370, "predicted": true},
    {"technique": "T1498", "name": "Network Denial of Service",          "score": 0.6935, "predicted": true},
    {"technique": "T1133", "name": "External Remote Services",           "score": 0.6759, "predicted": true},
    {"technique": "T1071", "name": "Application Layer Protocol",         "score": 0.6717, "predicted": true}
  ],
  "model": "CIRCL/vulnerability-attack-technique-classification-roberta-base"
}

Resource Hijacking ranked first is not a glitch — it is the model remembering that the single most common thing attackers actually did with Log4Shell was deploy cryptominers.

CNA partners of the CVE Program

Using the gcve library 0.13.0, VulnMCP can now search the 539 CNA partners of the CVE Program (mirrored at gcve.eu) by name, country, program role, or organization type — and retrieve one partner’s full record. The partner short name is the same assignerShortName you see in CVE records, so an agent can go from a CVE straight to the authority behind it, its disclosure policy, and its advisory feed:

poetry run fastmcp call vulnmcp/server.py get_cna_partner short_name=CIRCL
{
  "partner": "Computer Incident Response Center Luxembourg (CIRCL)",
  "program_role": "CNA",
  "organization_type": "CERT",
  "country": "Luxembourg",
  "metadata": {
    "cna_id": "CNA-2026-0027",
    "disclosure_policy": [
      {"url": "https://www.circl.lu/pub/coordinated-vulnerability-disclosure/"}
    ],
    "security_advisories": {
      "advisories": [{"url": "https://vulnerability.circl.lu/search?assigner=CIRCL"}]
    },
    "root": {"shortName": "ENISA", "organizationName": "EU Agency for Cybersecurity (ENISA)"}
  }
}

Everything else that landed since 1.0.0

  • Russian severity classificationclassify_severity now routes English, Chinese, and Russian descriptions to the right fine-tuned model automatically, based on the script of the input text.
  • search_comments and search_bundles — community analyses and curated CVE collections from Vulnerability-Lookup, straight into the agent’s context.
  • KEV-aware searchsearch_vulnerabilities cwe=CWE-89 prioritize_kev=true enriches each result against the KEV catalogs and sorts known-exploited vulnerabilities first.

A few one-liners to give you the flavour:

# Which recent SQL-injection CVEs are actually being exploited?
poetry run fastmcp call vulnmcp/server.py search_vulnerabilities cwe=CWE-89 prioritize_kev=true

# Is this CVE in a KEV catalog, and who has seen it in the wild?
poetry run fastmcp call vulnmcp/server.py get_vulnerability vulnerability_id=CVE-2021-44228 with_sightings=true

# All CNA partners located in Luxembourg
poetry run fastmcp call vulnmcp/server.py search_cna_partners country=Luxembourg

This is not just a demo toolbox: these tools, working together, are what we use to automatically generate our monthly vulnerability reports. An AI agent follows the report prompt shipped in the VulnMCP repository and chains the tools itself — most-sighted vulnerabilities, KEV entries across the CISA, CIRCL, ENISA, and Shadowserver catalogs, contributor comments and bundles, severity classifications — into the report you read at the start of each month.

Under the hood

2.0.0 is a major version for a reason: the internals were restructured. All HTTP plumbing for Vulnerability-Lookup and cpe-guesser moved into a shared vulnmcp/lookup.py, every MCP tool is now a plain importable Python function, and the server instructions are assembled from per-skill declarations. That made the project properly testable: the release ships an offline test suite (51 tests, under a second, every network call and model pipeline faked) with CI on Python 3.10 and 3.13. transformers and torch are imported lazily, so the server starts in well under a second and only pays the model-loading cost when a classification tool is actually invoked. And a bare poetry install now pulls CPU-only torch wheels — CUDA is an explicit --extras cuda opt-in.

ML-Gateway 1.3.0 and 1.4.0

ML-Gateway is the other consumer of these models: a FastAPI-based service that loads them at startup and exposes them over REST, so that a Vulnerability-Lookup instance (or anything else on your network) can classify without touching Python or Hugging Face directly.

1.3.0 added POST /classify/attack-techniques — the same multi-label ATT&CK model, with technique names resolved from the bundled enterprise ATT&CK STIX data. This is what powers the ATT&CK tab on the CVE pages of vulnerability.circl.lu:

The ATT&CK tab on the Vulnerability-Lookup page for CVE-2021-44228, showing AI-suggested MITRE ATT&CK techniques with confidence scores, served by ML-Gateway

AI-suggested ATT&CK techniques for CVE-2021-44228 on Vulnerability-Lookup, served by ML-Gateway. Click to open the live page.

You can query the endpoint directly:

curl -s -X POST http://127.0.0.1:8000/classify/attack-techniques \
  -H "Content-Type: application/json" \
  -d '{"description": "An attacker who can control log messages can execute arbitrary code loaded from LDAP servers.", "top_k": 5}'

The endpoint handlers were also deliberately made non-async: inference is CPU-bound, and running it on the event loop would block every concurrent request. FastAPI moves synchronous handlers to a thread pool, which is exactly what you want here. Models are preloaded at startup and gunicorn --preload is supported, so workers share memory pages instead of each loading their own copy.

1.4.0 fixes a subtle production bug worth describing, because anyone serving fine-tuned models can hit it. Some fine-tuned checkpoints ship without model_max_length in their tokenizer config, and transformers then reports a huge sentinel value instead. Result: truncation silently does nothing, and the first genuinely long vulnerability description — CSAF advisories can be enormous — crashes the model with an index error deep in the embedding layer. ML-Gateway now clamps every tokenizer’s limit to the model’s actual max_position_embeddings (minus RoBERTa’s two offset slots) immediately after loading, via a shared helper with its own test coverage. Long inputs are truncated; the server no longer cares how verbose an advisory gets.

VulnTrain 3.2.0: the research behind the model

VulnTrain 3.2.0 ships the complete pipeline behind the ATT&CK classifier, and the accompanying paper is now public:

Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion — Cédric Bonhomme, Alexandre Dulaunoy.

Instead of walking the indirect CWE → CAPEC → ATT&CK chain, the classifier is trained directly on a gold dataset of 1,207 CVEs derived from the expert mappings of the MITRE Center for Threat-Informed Defense, with technique IDs normalized against the current enterprise ATT&CK STIX bundle. The 3.2.0 release includes the whole toolchain:

  • vulntrain-dataset-attack-generation — builds the CIRCL/vulnerability-attack-techniques dataset from the curated mappings.
  • vulntrain-train-attack-classification — the multi-label trainer: sigmoid head with binary cross-entropy loss, optional per-label weighting, and sub-technique collapsing.
  • vulntrain-validate-attack-classification — evaluation with recall@k and MRR; vulntrain-infer-attack-classification for single-CVE inference.
  • vulntrain-dataset-attack-llm-labeling — LLM-assisted label expansion with Ollama and Anthropic backends, structured outputs, and provenance tracking.

The headline numbers: the gold-only model reaches recall@5 of 0.673 ± 0.019. And the negative result is just as interesting as the positive one — LLM-generated labels agreed with expert annotations only about 0.39 of the time, and expanding the training set with them brought no reliable improvement while reducing coverage of rare techniques. Expert-curated data consistently helped; synthetic labels did not. The classifier is limited by label quality, not dataset size. All datasets, models, code, and training logs are public.

This work builds on the original VLAI approach — RoBERTa-based severity classification trained on more than 600,000 real-world vulnerability descriptions — described in VLAI: A RoBERTa-Based Model for Automated Vulnerability Severity Classification, the model that has been scoring vulnerabilities on vulnerability.circl.lu since 2025.

Try it

If you run an MCP-capable client — Claude Code, an IDE assistant, or your own agent framework — VulnMCP is a poetry install away, and every classification runs locally on CPU. Feedback, ideas, and new skills are very welcome.

References

Funding

EU Funding

AIPITCH (AI-Powered Innovative Toolkit for Cybersecurity Hubs) is a co-funded EU project supported by the European Cybersecurity Competence Centre (ECCC) under the DIGITAL-ECCC-2024-DEPLOY-CYBER-06-ENABLINGTECH program and CIRCL.