proxmox-docs-mcp
by gilberth
README.md
# proxmox-docs-mcp
Servidor MCP de **solo lectura** que indexa la guía oficial de administración de Proxmox VE
y la expone como herramientas y recursos MCP.
- Fuente canónica única: `https://pve.proxmox.com/pve-docs/pve-admin-guide.html`
- El servidor **no** responde con conocimiento propio: solo devuelve fragmentos recuperables
de la guía, cada uno con su URL oficial y ancla, más metadatos de frescura.
## Requisitos
- Node.js >= 22
- pnpm (este proyecto usa exclusivamente pnpm; no uses npm ni yarn)
## Instalación
```bash
pnpm install
```
`better-sqlite3` se compila de forma nativa durante la instalación.
## Configuración
Todas las variables tienen valores por defecto seguros (ver `.env.example`):
| Variable | Predeterminado | Descripción |
|---|---|---|
| `PROXMOX_DOC_URL` | URL oficial | Debe usar `https://pve.proxmox.com`. |
| `PROXMOX_DOC_DATA_DIR` | `.data` | Directorio persistente de SQLite y metadatos. |
| `PROXMOX_DOC_REFRESH_TTL_SECONDS` | `21600` | TTL antes de revalidar la fuente (6 h). |
| `PROXMOX_DOC_HTTP_TIMEOUT_MS` | `30000` | Timeout de descarga. |
| `PROXMOX_DOC_MAX_DOWNLOAD_BYTES` | `10000000` | Límite defensivo de descarga. |
| `MCP_TRANSPORT` | `stdio` | `stdio` o `http`. |
| `MCP_HTTP_HOST` | `127.0.0.1` | Host de escucha del transporte HTTP. |
| `MCP_HTTP_PORT` | `8093` | Puerto del transporte HTTP. |
| `MCP_HTTP_PATH` | `/mcp` | Ruta del endpoint MCP. |
| `LOG_LEVEL` | `info` | `debug` \| `info` \| `warn` \| `error`. |
La configuración se valida al inicio y falla con mensajes específicos ante valores inválidos.
## Uso local
### stdio (clientes de escritorio)
Configuración de cliente MCP:
```json
{
"mcpServers": {
"proxmox-docs": {
"command": "pnpm",
"args": ["--dir", "/ruta/absoluta/al/proyecto", "dev:stdio"]
}
}
}
```
`stdout` queda reservado para mensajes MCP; todos los logs van a `stderr`.
### Streamable HTTP (local)
```bash
pnpm dev:http
# endpoint MCP: http://127.0.0.1:8093/mcp
# health check: http://127.0.0.1:8093/healthz
```
El servidor HTTP escucha solo en `127.0.0.1` y valida `Host` y `Origin` antes de
entregar la petición al handler MCP.
### Inspector
```bash
pnpm dlx @modelcontextprotocol/inspector pnpm dev:stdio
```
Para HTTP, arranca `pnpm dev:http` y conecta el Inspector a `http://127.0.0.1:8093/mcp`.
## Contrato MCP
### Herramientas
| Herramienta | Descripción |
|---|---|
| `search_proxmox_docs` | Busca fragmentos en la guía (`query`, `limit` ≤ 10, `sectionPrefix` opcional). La guía está en inglés: traduce las consultas a términos técnicos en inglés conservando comandos, rutas y opciones literales. |
| `get_proxmox_section` | Lee una sección localizada por la búsqueda (`sectionId`, `cursor` opcional, `maxChars` ≤ 20000). Devuelve `nextCursor` si queda contenido. |
| `get_proxmox_doc_status` | Informa URL canónica, `ETag`, `Last-Modified`, fechas de comprobación y de última sincronización correcta, conteo de secciones/fragmentos y si la copia está vencida. |
| `refresh_proxmox_docs` | Fuerza una comprobación condicional inmediata: `not_modified`, `updated`, `stale_fallback` o `failed_no_cache`. No modifica Proxmox. |
Todas las herramientas se anotan como no destructivas y de solo lectura
(`refresh_proxmox_docs` añade `openWorldHint` por hacer una petición de red).
### Recursos
- `proxmox-docs://status` — estado y metadatos de la fuente (`application/json`).
- `proxmox-docs://section/{sectionId}` — lectura direccionable de una sección (`application/json`).
## Frescura y modo vencido (`stale`)
- El TTL predeterminado es 6 horas. En el primer arranque, el servidor descarga e indexa
una copia válida antes de quedar listo.
- `304 Not Modified` se trata como sincronización correcta y no reconstruye el índice.
- Si una actualización falla (timeout, error HTTP, HTML inválido, fallo de indexado) y existe
una copia válida, las respuestas siguen sirviéndose con `stale: true` y la fecha de la
última sincronización correcta. Una actualización fallida **nunca** reemplaza la última
copia válida.
- Una instalación sin ninguna copia válida devuelve un error accionable.
## Pruebas
```bash
pnpm test # suite determinista (sin red)
pnpm typecheck # tsc --noEmit (tsconfig.json: src + test)
pnpm build # tsc -p tsconfig.build.json -> dist/src
pnpm test:live # prueba real contra la guía oficial (requiere red; RUN_LIVE_PROXMOX_TESTS=1)
```
`evals/proxmox-docs.xml` contiene diez preguntas verificables resueltas mediante las
herramientas de recuperación contra un índice real.
## Archivos de datos
`PROXMOX_DOC_DATA_DIR` (por defecto `.data/`) contiene `proxmox-docs.sqlite` con el HTML
almacenado, las secciones, los fragmentos y el índice FTS5. Está en `.gitignore`; el índice
puede reconstruirse desde el HTML almacenado sin volver a descargarlo.
## Límite de seguridad
- Fuente restringida a HTTPS en `pve.proxmox.com`; el HTML se trata como dato no confiable
(sin scripts, eventos ni contenido embebido).
- Consultas SQLite siempre parametrizadas.
- No hay credenciales de Proxmox: la documentación es pública.
- El servidor HTTP escucha solo en loopback; la publicación remota es una fase separada.
## Despliegue remoto
El despliegue en el LXC 134 vía Cloudflare Tunnel es una fase separada que se ejecuta con el
skill `mcp-deployer` después de validar el servidor localmente. Su primer paso obligatorio es
elegir entre **URL secreta** u **OAuth 2.1 con PocketID**. Nada en LXC 134 se toca hasta esa
elección.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues