
Servidor MCP para orquestração de remediação de CVE/configuração: inventário SSH, consultas OSV/NVD, sugestões de playbooks Ansible mapeados para CIS/DISA STIG.
Consulte OVERVIEW.md para uma descrição de alto nível do
propósito, componentes e escopo do repositório antes de fazer alterações
comportamentais.
Um orquestrador de remediação, exposto como um servidor MCP. Conecte um cliente MCP (Claude Desktop, Claude Code ou similar) e envie uma solicitação em linguagem natural, por exemplo:
Faça login no host a.b.c, verifique os pacotes instalados, encontre CVEs e sugira uma correção - Ansible se possível, e me diga a quais controles de conformidade ela é mapeada.
O prescryb fornece as primitivas (inventário SSH, correspondência de CVE, consultas
de avisos em tempo real, mapeamento de tópicos de conformidade, renderização de playbooks Ansible). O
modelo conectado faz o raciocínio: quais descobertas importam, quais CVEs
investigar, qual playbook gerar. O prescryb nunca aplica nada no
host de destino - toda ferramenta é somente leitura em relação a ele, ou pura geração
de texto/dados.
| Ferramenta | O que ela faz |
|---|---|
inventory_host(host, user="", port=22, hostname="", identity_file="", trust_unknown_host=False) | Conecta via SSH, detecta a distro, lista os pacotes instalados com versões. |
check_cves(system, packages) | Faz correspondência em lote das versões dos pacotes com o OSV.dev usando sua comparação de versões ciente do ecossistema (não apenas por nome). Cada correspondência é enriquecida com uma pontuação de probabilidade de exploração EPSS. |
fetch_advisory(cve_id) | Busca o registro atual do NVD para uma CVE - descrição, CVSS, CWE, referências - em tempo real, não a partir de dados de treinamento. |
fetch_epss(cve_ids) | Busca em lote as pontuações de probabilidade de exploração EPSS para IDs de CVE ainda não cobertos por check_cves (por exemplo, de fetch_advisory ou de uma busca na web). |
map_compliance(area) | Mapeia um tópico em texto livre ("ssh", "sudo", "kernel modules", ...) para áreas temáticas CIS/DISA STIG e, se presente no repositório GitHub konstruktoid.hardening, o role correspondente - além das técnicas e mitigações MITRE ATT&CK que essa área aborda. |
lookup_cce(target, keyword, cce_id) | Consulta entradas do NIST CCE (Common Configuration Enumeration) para uma plataforma (por exemplo, "rhel8"), obtidas da conversão JSON da comunidade em konstruktoid/cce-web. |
list_cce_targets() | Lista todas as plataformas que lookup_cce pode consultar. |
list_local_docs() | Lista documentos (Markdown/texto/PDF) encontrados no diretório local LOCAL_DOCS_DIR, ignorado pelo git. |
search_local_docs(query, top_k=5) | Busca semântica no estilo RAG sobre esses documentos locais, com embeddings gerados inteiramente na máquina. |
generate_playbook(system, cve_matches, compliance_areas, hosts_alias) | Renderiza um playbook Ansible apenas de sugestão: correções de CVE tornam-se tarefas de atualização de pacotes, áreas de conformidade tornam-se referências em roles:. |
Fluxo típico: inventory_host, depois check_cves nos pacotes retornados,
depois opcionalmente fetch_advisory nas CVEs interessantes, depois map_compliance
(e lookup_cce) para quaisquer áreas de configuração insegura notadas, depois opcionalmente
search_local_docs para contexto interno relevante de runbook/política, e então
generate_playbook para produzir algo a ser revisado.
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
Apenas as caixas de ferramentas são prescryb: inventory_host, check_cves,
fetch_advisory, map_compliance/lookup_cce, search_local_docs e
generate_playbook - cada uma uma consulta somente leitura ou uma chamada de
geração pura de texto/dados. O operador e o modelo conectado não fazem parte do
prescryb, e nada nesta cadeia toca o host de destino além da sessão SSH
somente leitura do inventory_host - aplicar o playbook gerado é um passo
deliberado e separado que o operador executa fora do 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 nunca aceita um argumento de senha. Os argumentos de chamada de ferramenta MCP podem ser registrados pelos clientes e são visíveis para o modelo conectado, portanto as credenciais nunca devem passar por eles. A autenticação funciona exatamente como executar ssh host você mesmo:
~/.ssh/config.hostname/identity_file de inventory_host substituem diretamente o endereço/caminho de chave resolvido, para hosts que você não deseja adicionar a ~/.ssh/config (apenas um caminho é passado, nunca o conteúdo da chave).trust_unknown_host=True
ssh host manualmente uma vez para fixar a chave.qemu/vm.sh inicializa uma imagem de nuvem (almalinux10, trixie, resolute) sob QEMU com um seed de cloud-init e um encaminhamento de porta SSH em 127.0.0.1 (2201, 2202, 2203). Ele precisa de qemu-system-x86_64, qemu-img, cloud-localds (cloud-image-utils), curl e ssh; o KVM é usado quando /dev/kvm é gravável. As imagens são verificadas por checksum e armazenadas em cache em 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
Para um host já acessível via ssh (resolvido através de ~/.ssh/config,
de uma chave de agente ou do arquivo de identidade padrão), especifique o hostname
diretamente; nenhuma configuração de porta ou de arquivo de identidade é necessária:
Inventarie o prod-web-01, verifique os pacotes instalados, encontre CVEs e sugira uma correção - Ansible se possível, e me diga a quais controles de conformidade isso está mapeado.
Se o host ainda não estiver em ~/.ssh/config, adicione um bloco Host ou passe
user/port/hostname/identity_file diretamente para inventory_host para uma
conexão pontual - o mesmo que o exemplo de molecule abaixo.
molecule converge -s default