# cyberdata — guide d'intégration MCP

Serveur **MCP** donnant à un assistant IA (ou à un système multi-agent) un accès
direct aux sources cyber officielles : NVD (CVE + CPE), CISA KEV, EPSS, CERT-FR,
OSV.dev, MITRE CWE, MITRE ATT&CK, endoflife.date.

- **Endpoint** : `https://cyberdata.bystep.cloud/mcp`
- **Transport** : MCP Streamable HTTP
- **Auth** : `Authorization: Bearer <token>`
- **Healthcheck public** : `GET /healthz`

```json
{
  "mcpServers": {
    "cyberdata": {
      "type": "http",
      "url": "https://cyberdata.bystep.cloud/mcp",
      "headers": { "Authorization": "Bearer VOTRE_TOKEN" }
    }
  }
}
```

## La règle à connaître avant tout

> **Ne rien trouver ne veut pas dire « pas vulnérable ».**

Chaque réponse vide porte ce rappel dans `avertissements`. Le service indexe ce
qui est **publié et normalisé** ; il ne voit ni les failles non publiées, ni les
produits mal identifiés, ni ce que le chargement initial n'a pas encore ingéré
(voir `health`).

Corollaire opérationnel : le champ `statut` d'une correspondance vaut `affecte`
ou `indetermine`. Il ne vaut **jamais** « non affecté ». Quand une version n'a pas
pu être comparée de façon défendable, la correspondance est remontée, pas écartée.

## Champs communs à toute réponse

| Champ | Sens |
|---|---|
| `fiabilite` | `referentiel` · `correlation` · `probabiliste` · `taxonomie` · `aucun` |
| `usage` | ce que l'assistant a le droit de faire de cette réponse |
| `avertissements` | ce qui doit être dit à l'utilisateur, jamais avalé |
| `couverture` | volume, fraîcheur et état de chargement des sources interrogées |
| `provenance` | source, URL, identifiant, date de version — sur chaque résultat |

### Les cinq niveaux de fiabilité

- **`referentiel`** — enregistrement officiel repris tel quel (NVD, CISA, CERT-FR,
  OSV). Citable en l'état.
- **`correlation`** — rapprochement produit/version ↔ vulnérabilités via CPE ou
  plages OSV. Vérifier que le produit désigné est bien le vôtre.
- **`probabiliste`** — EPSS. Une probabilité, jamais un constat.
- **`taxonomie`** — CWE, ATT&CK. Un cadre de raisonnement ; ne dit rien de votre parc.
- **`aucun`** — rien d'exploitable. Ne rien conclure.

## Outils, par intention

### « Cette CVE, c'est quoi et est-ce urgent ? »
- `get_cve(cve_id)` — fiche complète : CVSS **et son auteur**, CWE, produits
  affectés, KEV, EPSS, avis CERT-FR, paquets OSV.
- `prioriser(cve_ids)` — classe une liste avec la **raison** de chaque rang.

### « Mon parc est-il concerné ? »
- `search_produit(requete)` — retrouve l'écriture normalisée CPE (*navigation* :
  renvoie des identifiants candidats, pas un constat).
- `cve_par_produit(produit, version, editeur)` — le cas d'usage central.
- `fin_de_support(produit)` — un produit hors support est à risque **sans CVE**.

### « Mes dépendances sont-elles saines ? »
- `vulns_paquet(ecosysteme, paquet, version)` — OSV. Indispensable : une
  bibliothèque PyPI ou npm n'a presque jamais de CPE, donc `cve_par_produit` ne
  la verra pas.

### « Quoi de neuf ? »
- `veille(depuis)` — ajouts KEV, alertes CERT-FR non closes, CVE critiques,
  **dans cet ordre de lecture**.
- `list_kev(depuis, rancongiciel_seulement)` — exploitation confirmée.
- `search_certfr(requete, type_fiche)` / `get_avis_certfr(reference)`.

### « Comment raisonner et détecter ? »
- `get_cwe(cwe_id)` / `search_cwe(requete)` — la classe de faiblesse.
- `get_technique_attack(id)` / `search_attack(requete)` — mode opératoire et
  pistes de **détection**.
- `search_cve_semantique(requete)` — recherche par le sens sur la prose indexée.

### Supervision
- `health()` — fraîcheur **et volume réel** de chaque référentiel. À appeler
  quand une réponse paraît trop rassurante.

## Deux moteurs de recherche, deux usages

- **`search_cve`** : lexical (FTS5/BM25) sur 372 000 descriptions. Exige d'abord
  **tous** les mots ; si rien ne sort, élargit à « au moins un » et le signale via
  `requete_elargie`. Précis sur le vocabulaire d'identifiants.
- **`search_certfr` / `search_attack` / `search_cwe` / `search_cve_semantique`** :
  hybride lexical + vectoriel (fusion RRF) sur la prose. Un passage trouvé par le
  seul vecteur doit reprendre au moins un mot de la question, sinon il est écarté
  et le nombre d'écartés est annoncé.

## Consigne système suggérée pour l'agent

```
Tu disposes du serveur MCP « cyberdata » (sources cyber officielles).
- Ne conclus JAMAIS qu'un produit est sûr parce qu'un outil ne renvoie rien.
  Cite explicitement ce que l'outil a répondu.
- Pour un produit installé : search_produit puis cve_par_produit.
  Pour une dépendance : vulns_paquet. Les deux ne couvrent pas le même terrain.
- Traite les résultats `statut="indetermine"` comme potentiellement affectés.
- Pour prioriser, utilise prioriser() et REPRENDS ses justifications :
  exploitation confirmée (KEV) avant probabilité (EPSS) avant gravité (CVSS).
- Reporte toujours les `avertissements` à l'utilisateur, et cite la `provenance`.
```

## Erreurs

| Cas | Réponse |
|---|---|
| Identifiant mal formé | `{"error": "identifiant_invalide", "detail": "…"}` |
| Rien trouvé | `resultats: []`, `fiabilite: "aucun"`, `pistes`, et le rappel « absence ≠ preuve » |
| Token absent ou invalide | HTTP `401 unauthorized` |
