Navi MCP Server

Servidor MCP para automatizar la gestión de exposición.

Documentación

suite navi-mcp

Un servidor MCP para la CLI navi de Tenable (Tenable Vulnerability Management / Tenable One), junto con el conjunto navi-claude-skills, incluido aquí para que el servidor pueda servirlos.

La superficie de herramientas se valida contra el código fuente de navi — las declaraciones @click.option en navi/plugins/*.py, no una captura de --help — porque el texto de ayuda no puede mostrarte una guardia que advierte sin salir, una bandera que se ignora silenciosamente para el selector con el que la combinaste, o un prompt que bloqueará una llamada de herramienta. docs/gap-ledger.md lleva el rastro por hallazgo.

Estructura

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

En la raíz del repositorio, pyproject.toml construye lo anterior en un paquete instalable (navi-mcp-suite/server/ → navi_mcp/, navi-mcp-suite/skills/ → navi_mcp/resources/skills/) sin mover ningún archivo, y fix-mcp.sh es un script de diagnóstico que verifica toda la cadena de lanzamiento.

Las 17 habilidades

Impulsando el servidor: navi (router) · 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

Creación de contenido de cumplimiento Nessus: navi-audit · navi-audit-syntax · navi-audit-platforms · navi-audit-catalog. Estas no usan el servidor MCP, pero el router enruta hacia ellas, así que viajan con el conjunto.

Material profundo (esquema completo, catálogo exhaustivo de selectores, ejemplos largos trabajados) vive en references/*.md y se extrae bajo demanda.

Estas son una copia incluida. Se mantienen en packetchaos/navi-claude-skills y viven aquí solo para que NAVI_SKILL_DIR tenga algo que servir. Actualízalas — y verifícalas contra la superficie real de herramientas del servidor — con:

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

--verify analiza cada llamada navi_*(...) escrita en las habilidades y marca nombres de herramientas que el servidor no registra, argumentos de palabra clave que una herramienta no acepta, y herramientas que ninguna habilidad documenta. Ejecútalo siempre que cambie la superficie de herramientas: así es como se detectó navi_action_delete(kind="scan", id=…), donde el parámetro real es object_id.

Ejecutar el servidor MCP

El servidor invoca el binario navi y lee el navi.db local. No gestiona claves API — configúralas fuera de banda con navi config keys primero (ver skills/navi-core).

Requisitos

mcp >= 1.9, < 2. El límite superior no es precaución — mcp 2.0 renombró mcp.server.fastmcp a mcp.server.mcpserver y FastMCP a MCPServer, así que 2.x falla en la importación con ModuleNotFoundError: No module named 'mcp.server.fastmcp' antes de que se registre cualquier herramienta. En Claude Desktop eso aparece solo como "Server disconnected". No ejecutes pip install --upgrade mcp — instala 2.x. Instalar este proyecto como paquete aplica el pin por ti.

Instalación

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

Para una instalación autocontenida que otros paquetes en el intérprete no puedan alterar — que es lo que quieres detrás de Claude Desktop — usa pipx:

pipx install "navi-mcp[navi]"

O desde el código fuente:

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

Ejecución

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

Desde un checkout, sin instalar:

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

Variables de entorno

Cada una de estas se lee una vez, al iniciar el servidor. Cambiar cualquiera significa reiniciar el servidor (y, en Claude Desktop, salir completamente de la aplicación) — ninguna puede cambiarse desde dentro de una llamada de herramienta, que es el punto de las compuertas.

VarPropósitoValor por defecto si no está definida
NAVI_WORKDIRDirectorio que contiene navi.db y exportaciones CSV. El servidor ejecuta cada subproceso de navi con esto como su cwd.~/.navi-mcp — creado al inicio si falta
NAVI_BINRuta al ejecutable navinavi (resuelto en PATH)
NAVI_SKILL_DIREl directorio skills/, para que los recursos navi://skill/... se resuelvan<dir of server.py>/resources/skills. Instalado como paquete, esto resuelve a las habilidades incluidas y la variable es opcional; ejecutando desde un checkout no existe, así que los recursos de habilidades dan 404 hasta que la configures
NAVI_SKILL_PATHLegado: un único SKILL.md monolítico. Configurarlo pone al servidor en modo de archivo único y NAVI_SKILL_DIR se ignora. Prefiere NAVI_SKILL_DIR.sin definir
NAVI_MCP_ALLOW_WRITES1 abre la compuerta maestra de escritura (ver abajo)sin definir → solo lectura
NAVI_EMAIL1 habilita navi_action_mail. Se apila sobre la compuerta de escritura.sin definir → desactivado
NAVI_REMOTE_CODE_EXECUTION1 habilita navi_action_push. Se apila sobre la compuerta de escritura.sin definir → desactivado

Trampa de primera instalación. NAVI_WORKDIR por defecto es ~/.navi-mcp, no tu directorio actual. La CLI de navi escribe navi.db en el directorio desde el que la ejecutaste, así que si dejas NAVI_WORKDIR sin definir, el servidor creará silenciosamente un ~/.navi-mcp vacío, no encontrará base de datos allí, y cada lectura volverá vacía — pareciendo un tenant roto en lugar de una ruta incorrecta. Lee navi://workdir primero: imprime el workdir resuelto y si navi.db está realmente presente.

Apunta NAVI_SKILL_DIR a la carpeta skills/ de este repositorio. El servidor lee carpetas de habilidades desempaquetadas, no zips empaquetados de .skill/.plugin.

Las compuertas

Tres capas independientes. Una herramienta se ejecuta solo cuando cada capa que le aplica está satisfecha; están 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

Capa 1 — la compuerta maestra de escritura. Desactivada por defecto, así que una instalación nueva es de solo lectura y segura para apuntar a producción. Abrirla habilita todo lo que cambia estado en tu tenant de Tenable: etiquetado, ACR, importación de activos, control de escaneos, lanzamientos WAS, eliminaciones, rotación de claves, cancelación de exportaciones, navi_config(kind='url'), y navi_explore_api POST/PUT. También cubre navi_config_rebuild — esa destruye datos locales en lugar de datos del tenant (ver abajo), pero es lo suficientemente destructiva como para estar detrás del mismo interruptor.

Capa 2 — compuertas de capacidad. Dos capacidades son peligrosas de maneras que las escrituras ordinarias de plataforma no son, así que cada una necesita su propia aceptación separada además de la capa 1. Abrir la compuerta de escritura sola no habilita ninguna:

  • NAVI_EMAIL=1 → navi_action_mail puede enviar correo como tú. También necesita SMTP configurado fuera de banda vía navi config smtp. Arnés: skills/navi-mail.
  • NAVI_REMOTE_CODE_EXECUTION=1 → navi_action_push puede ejecutar comandos de shell en hosts remotos. También necesita credenciales SSH vía navi config ssh. Esta es la capacidad de mayor riesgo en navi. Arnés: skills/navi-remote-exec.

Capa 3 — confirm=True. Una bandera por llamada en cada herramienta con compuerta. Las capas 1 y 2 son decisiones permanentes tomadas una vez por el operador; la capa 3 es una decisión sobre esta llamada específica, y la convención es que el modelo narra exactamente lo que está a punto de hacer y obtiene una respuesta humana antes de pasarla. Como vive en la llamada de herramienta en lugar del entorno, es la única capa que un modelo puede satisfacer por sí solo — que es precisamente por qué nunca es la única capa para nada que toque el tenant.

Qué necesita qué

HerramientaCompuerta de escrituraCompuerta de capacidadconfirm=True
navi_enrich_tag, navi_enrich_acr, navi_enrich_add✅—✅
navi_scan (crear/iniciar/detener/pausar/reanudar)✅—✅
navi_was (escanear/iniciar/subir)✅—✅
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 no-SELECT——✅
todo lo demás (lecturas, exportaciones, navi_explore_api GET, cifrar/descifrar)———

Dos asimetrías que vale la pena conocer en lugar de descubrir:

  • navi_explore_query no-SELECT es solo confirmación. Un DELETE/DROP a través de ella golpea tu navi.db local, nunca el tenant, así que está fuera de la compuerta de escritura — pero es destructiva, y a diferencia de navi_config_rebuild nada más que confirm=True se interpone frente a ella. Si quieres una base de datos local estrictamente de solo lectura además de un tenant de solo lectura, eso no es lo que la compuerta de escritura te da hoy.
  • El confirm=True de navi_config_rebuild está haciendo trabajo literal. El propio camino -rebuild de navi llama a click.confirm() antes de soltar la tabla. Bajo MCP, stdin está cerrado, así que ese prompt abortaría el comando — el servidor lo responde en tu nombre. Tu confirm=True es la "y" que se está escribiendo. Por eso la herramienta se niega sin ella en lugar de tratarla como una formalidad.

Solo lectura por defecto

Sin variables de entorno configuradas más allá de NAVI_WORKDIR y NAVI_BIN, el servidor expone solo lecturas. Esa es la postura inicial recomendada: conéctalo, lee navi://workdir, ejecuta una consulta o dos, y abre compuertas deliberadamente una vez que confíes en a dónde está apuntado.

Herramientas destructivas

Solo dos herramientas destruyen algo, y ninguna toca Tenable:

  • navi_config_rebuild — HACE DROP de una tabla local assets o vulns, la re-crea, y re-descarga. Nada en Tenable VM cambia; lo que pierdes es el caché local y las horas que tomó construirlo en un tenant grande. Las tablas derivadas de esas (certs, software, vuln_route, vuln_paths) se vuelven obsoletas en el mismo momento — el _notice de la herramienta nombra las llamadas que refrescan cada una. Anotado destructiveHint=True, que navi_config_update deliberadamente no es: una actualización se fusiona en la tabla existente y nunca hace drop.
  • navi_action_delete — elimina etiquetas, usuarios, escaneos, activos, grupos objetivo, grupos de usuarios, o etiquetas TONE en el tenant. Con compuerta de escritura y confirmación.

Reconstruir ambas tablas a la vez es navi config update full -rebuild en la CLI; full no se expone como herramienta porque se ejecuta durante horas de todos modos.

Instalar en Claude Desktop

Guía completa en INSTALL.md. La versión corta — instala el paquete, luego apunta la configuración al script de consola:

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"
      }
    }
  }
}

Sin args, sin NAVI_SKILL_DIR (las habilidades viajan en el paquete), y sin NAVI_BIN cuando navi se instala junto vía el extra [navi]. Usa una ruta absoluta — Claude Desktop no tendrá el PATH de tu shell.

¿Ejecutando desde un checkout en su lugar? Deja que el helper descubra las rutas, ejecuta con el intérprete que quieras que 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)

Las banderas de compuerta en el helper mapean uno a uno a las variables de entorno de arriba: --allow-writes, --allow-email, --allow-remote-code-execution. Las últimas dos no tienen efecto sin la primera.

Después de editar la configuración, sal completamente y reabre Claude Desktop, luego lee navi://workdir para confirmar que se conectó.

Recursos

  • navi://schema/{table} — definiciones de columnas en vivo para una tabla navi.db
  • navi://workdir — workdir resuelto, presencia/tamaño/frescura de navi.db, los tres estados de compuerta, binario navi, presupuesto de llamadas, y estado del directorio de habilidades
  • navi://skill/{name} — carga una habilidad (router/core/mcp/…); lista sus referencias
  • navi://skill/{name}/{ref} — carga una referencia incluida (p. ej. navi://skill/core/schema)

Más el prompt navi_workflow, que inyecta la habilidad del router.

Operaciones de larga duración

Las exportaciones de navi pueden ejecutarse durante decenas de minutos en tenants grandes — más allá del techo de ~4 minutos de llamada de herramienta del host MCP. El servidor aplica un presupuesto de llamadas (~220s) y devuelve un error limpio nombrando el comando CLI exacto para ejecutar en su lugar, con el mismo alcance que la llamada que expiró. Las sincronizaciones fundacionales (navi config update full) siguen siendo intencionalmente solo CLI. La palanca principal para encajar una sincronización dentro del presupuesto es el alcance: days, since, severity, plugin_id, o un par de etiquetas category/value en navi_config_update. Ver skills/navi-core y skills/navi-troubleshooting.

Pruebas

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

Las suites simulan el subproceso de navi y verifican el argv que cada herramienta construye, por lo que no necesitan tenant, ni claves de API, ni navi.db. NAVI_WORKDIR se redirige a un directorio temporal y el binario real de navi nunca se invoca: es seguro ejecutarlas contra una instalación de producción. Ejecútalas después de instalar en una máquina nueva: detectarán un SDK de mcp roto, un Python demasiado antiguo para la sintaxis de tipos, o un checkout incompleto antes de conectar un cliente.

Instalando las skills como skills de Claude

Instálalas desde packetchaos/navi-claude-skills, que genera un paquete navi-skills.plugin para Claude.ai / Claude Cowork / Claude Code. Este repositorio ya no incluye copias empaquetadas: un segundo canal de distribución es una segunda cosa que olvidar actualizar, y es precisamente así como las skills aquí terminaron describiendo un servidor que había avanzado sin ellas. La carpeta skills/ se mantiene porque el servidor MCP la lee directamente.

Estado de validación

server.py compila limpiamente, cada herramienta está anotada, las 20 se registran y las suites en server/tests/ están en verde. Las anotaciones de herramientas requieren mcp >= 1.9; mcp.types.ToolAnnotations se importa detrás de un try/except para que un SDK más antiguo degrade a herramientas sin anotar en lugar de fallar. Un SDK 2.x no degrada de forma elegante: falla directamente, por eso la dependencia está fijada en <2.

No se ha probado en tiempo de ejecución contra un tenant de Tenable en vivo. Las comprobaciones verifican lo que el servidor le pide a navi que haga; no pueden verificar lo que navi y la API de Tenable hacen en respuesta. Antes de confiar en ello, valida con una lectura en vivo: navi_explore_data(subcommand="cve", cve="CVE-2021-44228") — y lee navi://workdir para confirmar que el directorio de trabajo y los estados de gate son los que pretendías.

Consulta docs/verified-findings.md para el inventario por error y docs/gap-ledger.md para el registro de auditoría completo.