
Server MCP per l'orchestrazione della remediation di CVE/configurazioni: inventario SSH, ricerche OSV/NVD, suggerimenti di playbook Ansible mappati CIS/DISA STIG.
Consulta OVERVIEW.md per una descrizione ad alto livello dello
scopo, dei componenti e dell'ambito del repository prima di apportare modifiche
comportamentali.
Un orchestratore di remediation, esposto come server MCP. Connetti un client MCP (Claude Desktop, Claude Code o simili) e invia una richiesta in linguaggio naturale, ad esempio:
Accedi all'host a.b.c, controlla i pacchetti installati, trova le CVE e suggerisci una correzione - Ansible se possibile, e dimmi a quali controlli di compliance corrisponde.
prescryb fornisce le primitive (inventario SSH, matching delle CVE, lookup di
advisory in tempo reale, mappatura degli argomenti di compliance, rendering dei
playbook Ansible). Il modello connesso esegue il ragionamento: quali risultati
sono rilevanti, quali CVE approfondire, quale playbook generare. prescryb non
applica mai nulla all'host di destinazione - ogni strumento è in sola lettura
nei suoi confronti, oppure è pura generazione di testo/dati.
| Strumento | Cosa fa |
|---|---|
inventory_host(host, user="", port=22, hostname="", identity_file="", trust_unknown_host=False) | Si connette via SSH, rileva la distribuzione, elenca i pacchetti installati con le versioni. |
check_cves(system, packages) | Confronta in batch le versioni dei pacchetti con OSV.dev usando il suo confronto di versioni consapevole dell'ecosistema (non un matching basato solo sul nome). Ogni corrispondenza è arricchita con un punteggio EPSS di probabilità di sfruttamento. |
fetch_advisory(cve_id) | Recupera il record NVD corrente per una CVE - descrizione, CVSS, CWE, riferimenti - in tempo reale, non dai dati di addestramento. |
fetch_epss(cve_ids) | Recupera in batch i punteggi EPSS di probabilità di sfruttamento per gli ID CVE non già coperti da check_cves (ad es. da fetch_advisory o da una ricerca web). |
map_compliance(area) | Mappa un argomento in testo libero ("ssh", "sudo", "kernel modules", ...) alle aree tematiche CIS/DISA STIG e, se presente nel repository GitHub konstruktoid.hardening, al ruolo corrispondente - oltre alle tecniche e mitigazioni MITRE ATT&CK affrontate da quell'area. |
lookup_cce(target, keyword, cce_id) | Cerca le voci NIST CCE (Common Configuration Enumeration) per una piattaforma (ad es. "rhel8"), provenienti dalla conversione JSON della community su konstruktoid/cce-web. |
list_cce_targets() | Elenca ogni piattaforma interrogabile da lookup_cce. |
list_local_docs() | Elenca i documenti (Markdown/testo/PDF) trovati nella directory locale LOCAL_DOCS_DIR, esclusa da git. |
search_local_docs(query, top_k=5) | Ricerca semantica in stile RAG su quei documenti locali, con embedding eseguito interamente sulla macchina. |
generate_playbook(system, cve_matches, compliance_areas, hosts_alias) | Genera un playbook Ansible di solo suggerimento: le correzioni delle CVE diventano attività di aggiornamento dei pacchetti, le aree di compliance diventano riferimenti in roles:. |
Flusso tipico: inventory_host, poi check_cves sui pacchetti restituiti,
poi facoltativamente fetch_advisory sulle CVE interessanti, poi map_compliance
(e lookup_cce) per eventuali aree di configurazione non sicura notate, poi
facoltativamente search_local_docs per il contesto interno rilevante di
runbook/policy, infine generate_playbook per produrre qualcosa da revisionare.
flowchart TD
U["Operator: natural-language request"] --> M["Connected model\n(Claude Desktop / Claude Code)"]
M --> A["inventory_host\nSSH in, list packages"]
A --> B["check_cves\nOSV.dev match + EPSS score"]
B --> C{"Interesting\nCVE?"}
C -->|yes| D["fetch_advisory\nNVD detail for one CVE"]
C -->|no| E
D --> E["map_compliance / lookup_cce\nCIS/DISA STIG + ATT&CK mapping"]
E --> F["search_local_docs\ninternal runbooks (optional)"]
F --> G["generate_playbook\nsuggest-only Ansible playbook"]
G --> H["Model reasons over the results\nand presents findings + playbook"]
H --> R["Operator reviews\n(ansible-playbook --check --diff)\nand applies manually"]
style R fill:#f9f,stroke:#333,stroke-width:1px
Solo i box degli strumenti sono prescryb: inventory_host, check_cves,
fetch_advisory, map_compliance/lookup_cce, search_local_docs e
generate_playbook - ciascuno una chiamata di sola lettura o di pura generazione
di testo/dati. L'operatore e il modello connesso non fanno parte di prescryb, e
nulla in questa catena tocca l'host di destinazione al di là della sessione SSH
in sola lettura di inventory_host - l'applicazione del playbook generato è un passo
deliberato e separato che l'operatore compie al di fuori di prescryb.
uv sync
Claude Code:
claude mcp add prescryb -- uv --directory /path/to/prescryb run prescryb
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"prescryb": {
"command": "uv",
"args": ["--directory", "/path/to/prescryb", "run", "prescryb"]
}
}
}
inventory_host non accetta mai un argomento password. Gli argomenti delle chiamate ai tool MCP possono essere registrati dai client e sono visibili al modello connesso, quindi le credenziali non devono mai transitare attraverso di essi. L'autenticazione funziona esattamente come eseguire ssh host manualmente:
~/.ssh/config.hostname/identity_file di inventory_host sovrascrivono direttamente l'indirizzo/percorso della chiave risolti, per gli host che non vuoi aggiungere a ~/.ssh/config (viene passato solo un percorso, mai il contenuto della chiave).trust_unknown_host=True
ssh host manualmente una volta per fissare la chiave.qemu/vm.sh avvia un'immagine cloud (almalinux10, trixie, resolute) sotto
QEMU con un seed cloud-init e un port forward SSH su 127.0.0.1
(2201, 2202, 2203). Richiede qemu-system-x86_64, qemu-img, cloud-localds
(cloud-image-utils), curl e ssh; KVM viene utilizzato quando /dev/kvm è scrivibile.
Le immagini sono verificate tramite checksum e memorizzate nella cache in qemu/.state/.
qemu/vm.sh up trixie
qemu/vm.sh ssh trixie true # retry until the guest answers
claude 'inventory 127.0.0.1 port 2202 user prescryb with identity file
qemu/.state/id_ed25519 (trust_unknown_host is fine, it is a throwaway VM),
check any vulnerabilities and suggest a fix, include compliance mapping if
possible, write the playbook suggestion to /tmp/ and print the file location'
qemu/vm.sh destroy trixie
Per un host già raggiungibile tramite ssh (risolto attraverso ~/.ssh/config,
una chiave dell'agent o il file di identità predefinito), specificare direttamente
il nome host; non è necessaria alcuna configurazione di porta o file di identità:
Inventario prod-web-01, verifica i pacchetti installati, trova le CVE e suggerisci una correzione - Ansible se possibile, e dimmi a quali controlli di conformità è associato.
Se l'host non è ancora presente in ~/.ssh/config, aggiungere un blocco Host oppure passare
user/port/hostname/identity_file direttamente a inventory_host per una
connessione una tantum - come nell'esempio molecule riportato di seguito.