Navi MCP Server

Servidor MCP para automatizar o gerenciamento de exposição.

Documentação

Suíte navi-mcp

Um servidor MCP para o CLI navi da Tenable (Tenable Vulnerability Management / Tenable One), além do conjunto complementar navi-claude-skills, fornecido aqui para que o servidor possa servi-los.

A superfície de ferramentas é validada contra a fonte do navi — as declarações @click.option em navi/plugins/*.py, não uma captura de --help — porque o texto de ajuda não pode mostrar uma proteção que avisa sem sair, uma flag que é silenciosamente ignorada para o seletor com o qual você a combinou, ou um prompt que causará deadlock em uma chamada de ferramenta. docs/gap-ledger.md carrega o rastro por descoberta.

Estrutura

server/      server.py — the MCP server (20 tools + resources)
server/tests/  argv-level check suites + run_all.py (no live tenant needed)
skills/      the 17 skills, in NAVI_SKILL_DIR layout — a vendored copy of
             upstream (<skill>/SKILL.md, plus references/ on the denser ones)
tools/       navi_mcp_config.py — auto-detects paths, emits the install config
             sync_skills.py     — refresh skills/ from upstream, verify vs server
docs/        audit framework, gap ledger, verified findings, help-crawler,
             fix-xref-prompt.md (a reported bug in the navi CLI, not this repo)
INSTALL.md   step-by-step install for Claude Desktop
README.md    this file

Na raiz do repositório, pyproject.toml compila o acima em um pacote instalável (navi-mcp-suite/server/ → navi_mcp/, navi-mcp-suite/skills/ → navi_mcp/resources/skills/) sem mover arquivos, e fix-mcp.sh é um script de diagnóstico que verifica toda a cadeia de inicialização.

As 17 skills

Direcionando o servidor: navi (roteador) · navi-core · navi-mcp · navi-troubleshooting · navi-acr · navi-export · navi-scan · navi-was · navi-action · navi-mail · navi-remote-exec · navi-explore · navi-enrich

Criação de conteúdo de conformidade Nessus: navi-audit · navi-audit-syntax · navi-audit-platforms · navi-audit-catalog. Estas não usam o servidor MCP, mas o roteador direciona para elas, então elas viajam com o conjunto.

Material aprofundado (schema completo, catálogo exaustivo de seletores, exemplos longos e trabalhados) vive em references/*.md e é puxado sob demanda.

Estas são uma cópia fornecida. Elas são mantidas em packetchaos/navi-claude-skills e vivem aqui apenas para que NAVI_SKILL_DIR tenha algo para servir. Atualize-as — e verifique-as contra a superfície real de ferramentas do servidor — com:

python tools/sync_skills.py --dry-run     # what would change
python tools/sync_skills.py --verify      # sync, then cross-check vs server.py

--verify analisa cada chamada navi_*(...) escrita nas skills e sinaliza nomes de ferramentas que o servidor não registra, argumentos de palavra-chave que uma ferramenta não aceita, e ferramentas que nenhuma skill documenta. Execute-o sempre que a superfície de ferramentas mudar: é assim que navi_action_delete(kind="scan", id=…) foi detectado, onde o parâmetro real é object_id.

Executando o servidor MCP

O servidor chama o binário navi e lê o navi.db local. Ele não gerencia chaves de API — defina-as fora de banda com navi config keys primeiro (veja skills/navi-core).

Requisitos

mcp >= 1.9, < 2. O limite superior não é cautela — mcp 2.0 renomeou mcp.server.fastmcp para mcp.server.mcpserver e FastMCP para MCPServer, então 2.x falha na importação com ModuleNotFoundError: No module named 'mcp.server.fastmcp' antes que qualquer ferramenta seja registrada. No Claude Desktop isso aparece apenas como "Server disconnected". Não execute pip install --upgrade mcp — ele instala 2.x. Instalar este projeto como pacote aplica o pin para você.

Instalação

pip install navi-mcp                 # from PyPI
pip install "navi-mcp[navi]"         # also pulls navi-pro into the same environment

Para uma instalação autocontida que outros pacotes no interpretador não possam perturbar — que é o que você quer por trás do Claude Desktop — use pipx:

pipx install "navi-mcp[navi]"

Ou a partir do código-fonte:

pip install .                # from a checkout
pip install "git+https://github.com/packetchaos/navi-mcp"

Execução

navi-mcp                           # stdio (default); waits for a client
navi-mcp --http                    # streamable HTTP on :8000
python -m navi_mcp                 # equivalent entry point

A partir de um checkout, sem instalar:

python navi-mcp-suite/server/server.py            # stdio
python navi-mcp-suite/server/server.py --http     # streamable HTTP on :8000

Variáveis de ambiente

Cada uma delas é lida uma vez, na inicialização do servidor. Alterar qualquer uma significa reiniciar o servidor (e, no Claude Desktop, sair completamente do aplicativo) — nenhuma delas pode ser alterada de dentro de uma chamada de ferramenta, que é o ponto das proteções.

VarPropósitoPadrão se não definido
NAVI_WORKDIRDiretório que contém navi.db e exportações CSV. O servidor executa cada subprocesso do navi com este como cwd.~/.navi-mcp — criado na inicialização se ausente
NAVI_BINCaminho para o executável navinavi (resolvido em PATH)
NAVI_SKILL_DIRO diretório skills/, para que os recursos navi://skill/... sejam resolvidos<dir of server.py>/resources/skills. Instalado como pacote, isso resolve para as skills incluídas e a var é opcional; executando a partir de um checkout ele não existe, então os recursos de skill retornam 404 até você defini-lo
NAVI_SKILL_PATHLegado: um único SKILL.md monolítico. Definir isso coloca o servidor em modo de arquivo único e NAVI_SKILL_DIR é ignorado. Prefira NAVI_SKILL_DIR.não definido
NAVI_MCP_ALLOW_WRITES1 abre a proteção mestre de escrita (veja abaixo)não definido → somente leitura
NAVI_EMAIL1 habilita navi_action_mail. Empilha na proteção de escrita.não definido → desligado
NAVI_REMOTE_CODE_EXECUTION1 habilita navi_action_push. Empilha na proteção de escrita.não definido → desligado

Armadilha de primeira instalação. NAVI_WORKDIR tem como padrão ~/.navi-mcp, não o seu diretório atual. O CLI do navi escreve navi.db no diretório de onde você o executou, então se você deixar NAVI_WORKDIR não definido, o servidor criará silenciosamente um ~/.navi-mcp vazio, não encontrará banco de dados lá, e cada leitura retornará vazia — parecendo um tenant quebrado em vez de um caminho errado. Leia navi://workdir primeiro: ele imprime o workdir resolvido e se navi.db está realmente presente.

Aponte NAVI_SKILL_DIR para a pasta skills/ deste repositório. O servidor lê pastas de skills descompactadas, não zips empacotados de .skill/.plugin.

As proteções

Três camadas independentes. Uma ferramenta só é executada quando cada camada que se aplica a ela é satisfeita; elas são ANDed, nunca ORed.

Layer 1  NAVI_MCP_ALLOW_WRITES=1      master write gate      server env, restart
Layer 2  NAVI_EMAIL=1                 email capability       server env, restart
         NAVI_REMOTE_CODE_EXECUTION=1 remote-exec capability server env, restart
Layer 3  confirm=True                 per-call intent        in the tool call

Camada 1 — a proteção mestre de escrita. Desligada por padrão, então uma instalação nova é somente leitura e segura para apontar para produção. Abri-la habilita tudo que muda estado no seu tenant Tenable: marcação, ACR, importação de ativos, controle de scan, lançamentos WAS, exclusões, rotação de chaves, cancelamento de exportação, navi_config(kind='url'), e navi_explore_api POST/PUT. Também cobre navi_config_rebuild — essa destrói dados locais em vez de dados do tenant (veja abaixo), mas é destrutiva o suficiente para ficar atrás do mesmo interruptor.

Camada 2 — proteções de capacidade. Duas capacidades são perigosas de maneiras que gravações comuns de plataforma não são, então cada uma precisa de seu próprio opt-in separado além da camada 1. Abrir a proteção de escrita sozinha não habilita nenhuma delas:

  • NAVI_EMAIL=1 → navi_action_mail pode enviar e-mail como você. Também precisa de SMTP configurado fora de banda via navi config smtp. Harness: skills/navi-mail.
  • NAVI_REMOTE_CODE_EXECUTION=1 → navi_action_push pode executar comandos de shell em hosts remotos. Também precisa de credenciais SSH via navi config ssh. Esta é a capacidade de maior risco no navi. Harness: skills/navi-remote-exec.

Camada 3 — confirm=True. Uma flag por chamada em cada ferramenta protegida. As camadas 1 e 2 são decisões permanentes tomadas uma vez pelo operador; a camada 3 é uma decisão sobre esta chamada específica, e a convenção é que o modelo narra exatamente o que está prestes a fazer e recebe uma resposta humana antes de passá-la. Como ela vive na chamada de ferramenta em vez do ambiente, é a única camada que um modelo pode satisfazer sozinho — que é precisamente por que nunca é a única camada para qualquer coisa que toca o tenant.

O que precisa do quê

FerramentaProteção de escritaProteção de capacidadeconfirm=True
navi_enrich_tag, navi_enrich_acr, navi_enrich_add✅—✅
navi_scan (create/start/stop/pause/resume)✅—✅
navi_was (scan/start/upload)✅—✅
navi_action_delete, navi_action_rotate, navi_action_cancel✅—✅
navi_config(kind='url')✅—✅
navi_explore_api POST/PUT✅—✅
navi_config_rebuild✅—✅
navi_action_mail✅NAVI_EMAIL=1✅
navi_action_push✅NAVI_REMOTE_CODE_EXECUTION=1✅
navi_explore_query não-SELECT——✅
todo o resto (leituras, exportações, navi_explore_api GET, encrypt/decrypt)———

Duas assimetrias que valem a pena conhecer em vez de descobrir:

  • navi_explore_query não-SELECT é somente confirmação. Um DELETE/DROP através dele atinge seu navi.db local, nunca o tenant, então fica fora da proteção de escrita — mas é destrutivo, e ao contrário de navi_config_rebuild nada além de confirm=True fica na frente dele. Se você quer um banco de dados local estritamente somente leitura além de um tenant somente leitura, isso não é o que a proteção de escrita oferece hoje.
  • O confirm=True de navi_config_rebuild está fazendo trabalho literal. O próprio caminho -rebuild do navi chama click.confirm() antes de descartar a tabela. Sob MCP, stdin está fechado, então esse prompt abortaria o comando — o servidor responde em seu nome. Seu confirm=True é o "y" sendo digitado. É por isso que a ferramenta recusa sem ele em vez de tratá-lo como formalidade.

Somente leitura por padrão

Sem variáveis de ambiente definidas além de NAVI_WORKDIR e NAVI_BIN, o servidor expõe apenas leituras. Essa é a postura inicial recomendada: conecte-o, leia navi://workdir, execute uma consulta ou duas, e abra proteções deliberadamente uma vez que você confie no que ele está apontando.

Ferramentas destrutivas

Apenas duas ferramentas destroem algo, e nenhuma toca a Tenable:

  • navi_config_rebuild — DROPa uma tabela local assets ou vulns, recria-a, e rebaixa novamente. Nada no Tenable VM muda; o que você perde é o cache local e as horas que levou para construí-lo em um tenant grande. Tabelas derivadas dessas (certs, software, vuln_route, vuln_paths) ficam obsoletas no mesmo momento — o _notice da ferramenta nomeia as chamadas que atualizam cada uma. Anotado destructiveHint=True, que navi_config_update deliberadamente não é: uma atualização mescla na tabela existente e nunca descarta.
  • navi_action_delete — remove tags, usuários, scans, ativos, grupos de alvos, grupos de usuários, ou tags TONE no tenant. Protegido por escrita e confirmação.

Reconstruir ambas as tabelas de uma vez é navi config update full -rebuild no CLI; full não é exposto como ferramenta porque executa por horas independentemente.

Instalação no Claude Desktop

Passo a passo completo em INSTALL.md. A versão curta — instale o pacote, então aponte a configuração para o script de console:

pip install ".[navi]"
which navi-mcp          # absolute path for "command"
{
  "mcpServers": {
    "navi": {
      "command": "/absolute/path/to/navi-mcp",
      "env": {
        "NAVI_WORKDIR": "/absolute/path/to/folder-with-navi.db",
        "NAVI_MCP_ALLOW_WRITES": "0",
        "NAVI_EMAIL": "0",
        "NAVI_REMOTE_CODE_EXECUTION": "0"
      }
    }
  }
}

Sem args, sem NAVI_SKILL_DIR (as skills vêm no pacote), e sem NAVI_BIN quando navi está instalado junto via o extra [navi]. Use um caminho absoluto — o Claude Desktop não terá o PATH do seu shell.

Executando a partir de um checkout? Deixe o helper descobrir os caminhos, execute com o interpretador que você quer que o Claude Desktop use:

python tools/navi_mcp_config.py            # print the mcpServers JSON
python tools/navi_mcp_config.py --write    # merge into your config (backs up first)

As flags de proteção no helper mapeiam um-para-um para as variáveis de ambiente acima: --allow-writes, --allow-email, --allow-remote-code-execution. As duas últimas não têm efeito sem a primeira.

Após editar a configuração, saia completamente e reabra o Claude Desktop, então leia navi://workdir para confirmar que ele conectou.

Recursos

  • navi://schema/{table} — definições de colunas ao vivo para uma tabela navi.db
  • navi://workdir — workdir resolvido, presença/tamanho/atualização de navi.db, todos os três estados de proteção, binário navi, orçamento de chamadas, e status do diretório de skills
  • navi://skill/{name} — carrega uma skill (router/core/mcp/…); lista suas referências
  • navi://skill/{name}/{ref} — carrega uma referência incluída (ex.: navi://skill/core/schema)

Além do prompt navi_workflow, que injeta a skill do roteador.

Operações de longa duração

Exportações do navi podem rodar por dezenas de minutos em tenants grandes — além do teto de ~4 minutos por chamada de ferramenta do host MCP. O servidor aplica um orçamento de chamadas (~220s) e retorna um erro limpo nomeando o comando CLI exato para executar em vez disso, com escopo idêntico à chamada que expirou. Sincronizações fundamentais (navi config update full) permanecem intencionalmente somente CLI. A principal alavanca para encaixar uma sincronização dentro do orçamento é o escopo: days, since, severity, plugin_id, ou um par de tags category/value em navi_config_update. Veja skills/navi-core e skills/navi-troubleshooting.

Testes

python server/tests/run_all.py        # summary
python server/tests/run_all.py -v     # every check

As suítes simulam o subprocesso do navi e verificam o argv que cada ferramenta constrói, portanto não precisam de tenant, nem de chaves de API, nem de navi.db. O NAVI_WORKDIR é redirecionado para um diretório temporário e o binário real do navi nunca é invocado — seguro para executar contra uma instalação de produção. Execute-as após instalar em uma nova máquina: elas detectarão um mcp SDK quebrado, um Python antigo demais para a sintaxe de tipos, ou um checkout parcial antes de você conectar um cliente.

Instalando as skills como skills do Claude

Instale-as a partir de packetchaos/navi-claude-skills, que gera um pacote navi-skills.plugin para Claude.ai / Claude Cowork / Claude Code. Este repositório não distribui mais cópias empacotadas: um segundo canal de distribuição é uma segunda coisa para esquecer de atualizar, e é exatamente assim que as skills aqui acabaram descrevendo um servidor que evoluiu sem elas. A pasta skills/ permanece porque o servidor MCP a lê diretamente.

Status de validação

server.py compila sem erros, todas as ferramentas estão anotadas, todas as 20 registram, e as suítes em server/tests/ estão verdes. As anotações de ferramentas exigem mcp >= 1.9; mcp.types.ToolAnnotations é importado atrás de um try/except para que um SDK mais antigo degrade para ferramentas sem anotações em vez de falhar. Um SDK 2.x não degrada de forma graciosa — ele falha diretamente, e é por isso que a dependência está fixada em <2.

Ele não foi testado em tempo de execução contra um tenant Tenable ativo. As verificações confirmam o que o servidor pede ao navi para fazer; elas não podem verificar o que o navi e a API do Tenable fazem em resposta. Antes de confiar nele, valide com uma leitura ativa — navi_explore_data(subcommand="cve", cve="CVE-2021-44228") — e leia navi://workdir para confirmar que o diretório de trabalho e os estados de gate são os que você pretendia.

Consulte docs/verified-findings.md para o inventário por bug e docs/gap-ledger.md para o registro completo de auditoria.