Skip to main content
Glama

npm-mcp

Servidor del Model Context Protocol para Nginx Proxy Manager

Gestiona el enrutamiento de proxy inverso, los certificados TLS, las listas de acceso y los reenvíos de flujo de forma conversacional, con salvaguardas que asumen que tarde o temprano lo apuntarás a producción.

Python FastMCP NPM Tests Tools Ruff


Contenido


Related MCP server: npm-mcp

Por qué existe

Nginx Proxy Manager tiene una API REST completa y ningún servidor MCP. Este es ese servidor, pero la parte interesante no es la fontanería, sino las restricciones.

Un proxy inverso es un punto único de fallo para todo lo que hay detrás. Un agente con acceso de escritura a uno puede tumbar servicios a los que nunca se le pidió tocar. Así que el diseño parte de ahí:

Las herramientas se generan a partir del propio documento OpenAPI de la API, no se escriben a mano. El documento está fijado en el árbol de código, y una prueba de deriva hace fallar el CI si la superficie aguas arriba cambia, en lugar de que las herramientas devuelvan 404 silenciosamente en tiempo de ejecución.

Cada resultado cruza un límite de redacción que falla en modo cerrado. Lanza una excepción ante cualquier cosa que no pueda inspeccionar, en lugar de pasarla.

Las salvaguardas se prueban mediante mutación. Cada control de seguridad tiene una prueba que demuestra que se pone en rojo cuando el control está desactivado.


Cómo funciona

flowchart LR
    C["MCP Client"] -->|"Bearer (optional)"| S

    subgraph S["npm-mcp"]
        direction TB
        A["Bearer verifier<br/><i>hmac.compare_digest</i>"] --> G["Guardrails<br/><i>S1 · S2 · S6 · S7 · S8</i>"]
        G --> T["66 generated tools"]
        T --> R["serialize_result()<br/><i>redact + cap</i>"]
    end

    S -->|"JWT, auto-refreshed"| N["Nginx Proxy Manager"]
    P["npm-openapi.json<br/><i>pinned, in-package</i>"] -.->|generates| T

Las firmas de las herramientas se construyen a partir del documento fijado en el momento de la importación, por lo que create_proxy_host expone 18 argumentos tipados con enums reales, no un passthrough opaco de **kwargs.


Inicio rápido

uv sync
cp .env.example .env    # then fill in NPM_URL / NPM_IDENTITY / NPM_SECRET
uv run npm-mcp
{
  "mcpServers": {
    "npm": {
      "command": "uv",
      "args": ["run", "npm-mcp"],
      "env": {
        "NPM_URL": "https://nginx-proxy-manager.example.net",
        "NPM_IDENTITY": "npm-mcp@example.net",
        "NPM_SECRET": "…",
        "NPM_MCP_TRANSPORT": "stdio"
      }
    }
  }
}
{
  "mcpServers": {
    "npm": {
      "type": "http",
      "url": "https://npm-mcp.example.net/mcp",
      "headers": { "Authorization": "Bearer <NPM_MCP_BEARER_TOKEN>" }
    }
  }
}

FastMCP sirve en /mcp. Una barra final redirige con 307, lo que algunos clientes gestionan mal: no dejes que un proxy reescriba la ruta.

[!TIP] Llama primero a get_guidance. Informa de las formas de las respuestas, la distinción entre deshabilitar y eliminar, qué pestillos están actualmente abiertos y la lista activa de dominios protegidos.


Autenticación

Dos capas, fáciles de confundir:

Dirección

Mecanismo

Entrante

cliente → npm-mcp

Authorization: Bearer … opcional mediante NPM_MCP_BEARER_TOKEN, comparado con hmac.compare_digest. Sin valor ⇒ sin autenticación.

Saliente

npm-mcp → NPM

Credenciales de cuenta → JWT de corta duración, renovado automáticamente. Los llamadores nunca lo ven ni lo aportan.

NPM no emite claves API de larga duración, por eso el servidor guarda las credenciales en lugar de aceptar un token.

[!IMPORTANT] POST /tokens tiene dos respuestas posibles: un token o un desafío de 2FA. Si la cuenta tiene 2FA activado, configura NPM_TOTP_SECRET; de lo contrario, el servidor falla al arrancar, indicando ambos remedios, en lugar de levantarse sano y romperse en la primera llamada a una herramienta.


Catálogo de herramientas

66 herramientas = 65 operaciones de API + get_guidance.

Familia

#

Herramientas representativas

🔀 Hosts proxy

7

get_proxy_hosts · create_proxy_host · update_proxy_host · delete_proxy_host · enable_proxy_host · disable_proxy_host

↪️ Hosts de redirección

7

*_redirection_host

🚫 Hosts 404

7

create_404_host · *_dead_host

🔌 Streams

7

*_stream

🔐 Listas de acceso

5

get_access_lists · create_access_list · update_access_list · delete_access_list

📜 Certificados

10

get_certificates · create_certificate · renew_certificate · upload_certificate · validate_certificates · download_certificate · test_http_reach · get_dns_providers

👤 Usuarios

8

get_users · create_user · update_user · update_user_auth · update_user_permissions · login_as_user

🔑 2FA de usuario

5

setup_user_2fa · enable_user_2fa · disable_user_2fa · get_user_2fa_status · regen_user_2fa_codes

⚙️ Ajustes

3

get_settings · update_setting

📋 Registro de auditoría

2

get_audit_logs · get_audit_log

ℹ️ Meta

4

health · check_version · reports_hosts · schema

🧭 Orientación

1

get_guidance

Los nombres derivan del operationId de OpenAPI, por lo que las operaciones de listado son get_*, no list_*.

[!WARNING] Tres operaciones no se exponen deliberadamente: requestToken, refreshToken, loginWith2FA. Son la fontanería de autenticación del propio servidor, y requestToken acepta una identidad y un secreto arbitrarios: registrarla convertiría este servidor en un oráculo de prueba de credenciales contra NPM, con cada intento atribuido a la cuenta de servicio.

  • No existe paginación. Ni un solo endpoint acepta limit/offset. Las herramientas los aceptan y los recortan en el lado del cliente; las descripciones de las herramientas lo indican.

  • expand es un enum por endpoint, no un paso directo: los hosts de proxy aceptan access_list,owner,certificate; los certificados solo aceptan owner. Los valores fuera del enum se rechazan antes de enviar la solicitud.


Modelo de seguridad

[!CAUTION] Las escrituras están habilitadas por defecto. Este servidor puede reescribir la tabla de enrutamiento de todos los servicios detrás del proxy. Configura NPM_READ_ONLY=1 para deshabilitar todas las mutaciones.

Control

Anulación

NPM_READ_ONLY

Rechaza toda herramienta mutadora, comprobado antes de cualquier lectura de salvaguarda

S1

Rechaza delete / disable / update en hosts protegidos, y en los certificados y listas de acceso de los que dependen esos hosts

NPM_ALLOW_SELF_MUTATION

S2

Cada DELETE requiere confirm: true; sin él, la herramienta devuelve lo que se vería afectado y no escribe nada

por llamada

S5

Cada mutación emite una línea de auditoría; el registro de auditoría propio de NPM es consultable

S6

Toda operación mutativa bajo /users o /settings está bloqueada

NPM_ALLOW_ACCOUNT_MUTATION

S7

Rechaza modificar, deshabilitar, eliminar o login_as su propia cuenta

ninguna

S8

download_certificate devuelve claves privadas TLS, por lo que está bloqueada

NPM_ALLOW_CERT_EXPORT

  • S1 coincide con CUALQUIER dominio protegido, no con TODOS. TODOS permitiría desarmar la salvaguarda a través de las propias herramientas que protege: añade un dominio no relacionado a un host y la protección se evapora.

  • S1 cubre update, no solo delete/disable. De lo contrario, se elimina el nombre protegido de domain_names y luego se borra limpiamente: el mismo apagón.

  • S1 coincide con el estado actual aguas arriba, nunca con el cuerpo enviado. Comprobar la solicitud permitiría que la ruta de quitar-y-actualizar pasara directamente.

  • Los comodines de S1 coinciden en ambas direcciones. NPM_PROTECTED_DOMAINS=*.example.net debe proteger app.example.net. Una vez no coincidía con nada y suprimía la advertencia de "no protegido", porque el valor estaba establecido explícitamente.

  • S2 se limita por método HTTP, no por prefijo de nombre. Una regla delete_* no detecta disable_user_2fa, un DELETE que elimina el segundo factor de alguien.

  • S6 es una regla, no una lista. Una versión enumerada omitía silenciosamente update_user, por lo que el pestillo permanecía cerrado mientras is_disabled: true bloqueaba a un administrador.

  • S7 no tiene anulación. Un servidor que puede eliminar sus propias credenciales se bloquea permanentemente.


Configuración

Variable

Significado

NPM_URL

URL base de la instancia de NPM

NPM_IDENTITY

Correo electrónico de la cuenta

NPM_SECRET

Contraseña de la cuenta

Variable

Valor por defecto

Significado

NPM_MCP_BEARER_TOKEN

sin configurar

Token entrante. Sin configurar ⇒ sin autenticación entrante

NPM_MCP_TRANSPORT

streamable-http

stdio | streamable-http

NPM_MCP_HTTP_HOST

0.0.0.0

Dirección de enlace

NPM_MCP_HTTP_PORT

8000

Puerto de enlace

Variable

Valor predeterminado

Pestillos

NPM_READ_ONLY

0

— (1 bloquea todas las escrituras)

NPM_PROTECTED_DOMAINS

derivado de NPM_URL

Lista de denegación, separada por comas

NPM_ALLOW_SELF_MUTATION

0

S1

NPM_ALLOW_ACCOUNT_MUTATION

0

S6

NPM_ALLOW_CERT_EXPORT

0

S8

Variable

Valor predeterminado

Significado

NPM_TOTP_SECRET

sin establecer

Semilla Base32; solo si la cuenta tiene 2FA

NPM_TLS_VERIFY

1

Verificar el certificado de NPM

NPM_TIMEOUT

30

Tiempo de espera ascendente, segundos

NPM_MAX_RESPONSE_CHARS

50000

Límite de respuesta antes de truncar

NPM_GUIDANCE_GATE

1

Indicar hacia get_guidance en mutaciones tempranas

LOG_LEVEL

INFO


Implementación

docker build -t npm-mcp:latest .
docker compose up -d

El contenedor se une a una red Docker existente junto a NPM y publica ningún puerto. NPM lo alcanza mediante DNS de contenedor y termina TLS, por lo que el token Bearer nunca cruza el cable en texto plano.

  • Sin clave build: en el archivo compose. Una implementación de string compose (Portainer, por ejemplo) no incluye contexto de compilación, por lo que la imagen se construye primero y se referencia por etiqueta.

  • El healthcheck resuelve el host de enlace en lugar de fijar 127.0.0.1. Con un NPM_MCP_HTTP_HOST personalizado, la versión ingenua marca un contenedor perfectamente sano como insano para siempre. También falla bajo stdio, donde no hay nada escuchando en absoluto.

  • La autenticación de arranque se ejecuta durante la vida útil del servidor, por lo que una configuración incorrecta hace fallar el healthcheck en lugar de arrancar correctamente y romperse en el primer uso.


Pruebas

uv run pytest              # 420 tests
uv run ruff check
uv run ruff format --check

Aproximadamente 4.700 líneas de pruebas contra 3.300 líneas de código fuente, pero la cantidad importa menos que la forma:

  • 🧬 Guardarraíles verificados por mutación — cada control de seguridad tiene una prueba que demuestra fallar cuando el control está deshabilitado. Escrito tras descubrir un asyncio.Lock cuya eliminación mantenía la suite en verde.

  • 🌐 Cero acceso a la red — cada llamada ascendente está simulada con respx. Una prueba que necesite la red es una prueba rota.

  • 🔍 Barrido A7 — las 65 herramientas se invocan contra un ascendente que devuelve secretos a cuatro niveles de profundidad, con un control negativo que verifica que el fixture realmente los contiene, para que el barrido no pase de forma vacua.

  • 📐 Guardián de deriva de esquema — los recuentos de operaciones, las formas de las cargas útiles y el archivo de datos empaquetado se verifican todos, por lo que una actualización ascendente falla aquí en lugar de en producción.


Notas de diseño

Documento

Contenido

spec.md

Contrato del producto — decisiones D1–D13, controles S1–S8, criterios de aceptación A1–A10

docs/api-surface.md

Las 68 operaciones con campos de cuerpo y obligatoriedad

docs/module-contract.md

Interfaces internas de los módulos

docs/findings.md

Dos cosas que el documento OpenAPI hace mal, medidas contra una instancia en vivo

npm_mcp/data/npm-openapi.json

Copia textual del /api/schema de la instancia — dentro del paquete, porque es una dependencia en tiempo de ejecución, no documentación

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    B
    quality
    C
    maintenance
    Enables management of Nginx Proxy Manager instances for configuring proxy hosts, requesting Let's Encrypt SSL certificates, and managing access lists. It allows users to control their web proxy infrastructure through natural language commands in MCP-compatible environments.
    50
    3
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to manage Nginx Proxy Manager instances through natural language, covering 28 tools for proxy hosts, certificates, streams, and more.
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Enables natural language management of FastPanel 2 servers, including creating sites, databases, SSL certificates, and hardening nginx configurations.
    32
    2
    MIT

View all related MCP servers

Related MCP Connectors

  • Let AI operate servers without SSH. Choose actions, approve risky changes, and audit every step.

  • Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.

  • MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/omichelbraga/nginx-proxy-manager-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server