npm-mcp
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.
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| TLas 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 |
|
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 /tokenstiene dos respuestas posibles: un token o un desafío de 2FA. Si la cuenta tiene 2FA activado, configuraNPM_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 |
|
↪️ Hosts de redirección | 7 |
|
🚫 Hosts 404 | 7 |
|
🔌 Streams | 7 |
|
🔐 Listas de acceso | 5 |
|
📜 Certificados | 10 |
|
👤 Usuarios | 8 |
|
🔑 2FA de usuario | 5 |
|
⚙️ Ajustes | 3 |
|
📋 Registro de auditoría | 2 |
|
ℹ️ Meta | 4 |
|
🧭 Orientación | 1 |
|
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, yrequestTokenacepta 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.expandes un enum por endpoint, no un paso directo: los hosts de proxy aceptanaccess_list,owner,certificate; los certificados solo aceptanowner. 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=1para deshabilitar todas las mutaciones.
Control | Anulación | |
| Rechaza toda herramienta mutadora, comprobado antes de cualquier lectura de salvaguarda | — |
S1 | Rechaza |
|
S2 | Cada | 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 |
|
S7 | Rechaza modificar, deshabilitar, eliminar o | ninguna |
S8 |
|
|
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 dedomain_namesy 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.netdebe protegerapp.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 detectadisable_user_2fa, unDELETEque 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 mientrasis_disabled: truebloqueaba a un administrador.S7 no tiene anulación. Un servidor que puede eliminar sus propias credenciales se bloquea permanentemente.
Configuración
Variable | Significado |
| URL base de la instancia de NPM |
| Correo electrónico de la cuenta |
| Contraseña de la cuenta |
Variable | Valor por defecto | Significado |
| sin configurar | Token entrante. Sin configurar ⇒ sin autenticación entrante |
|
|
|
|
| Dirección de enlace |
|
| Puerto de enlace |
Variable | Valor predeterminado | Pestillos |
|
| — ( |
| derivado de | Lista de denegación, separada por comas |
|
| S1 |
|
| S6 |
|
| S8 |
Variable | Valor predeterminado | Significado |
| sin establecer | Semilla Base32; solo si la cuenta tiene 2FA |
|
| Verificar el certificado de NPM |
|
| Tiempo de espera ascendente, segundos |
|
| Límite de respuesta antes de truncar |
|
| Indicar hacia |
|
|
Implementación
docker build -t npm-mcp:latest .
docker compose up -dEl 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 unNPM_MCP_HTTP_HOSTpersonalizado, la versión ingenua marca un contenedor perfectamente sano como insano para siempre. También falla bajostdio, 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 --checkAproximadamente 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.Lockcuya 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 |
Contrato del producto — decisiones D1–D13, controles S1–S8, criterios de aceptación A1–A10 | |
Las 68 operaciones con campos de cuerpo y obligatoriedad | |
Interfaces internas de los módulos | |
Dos cosas que el documento OpenAPI hace mal, medidas contra una instancia en vivo | |
Copia textual del |
This server cannot be installed
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
- AlicenseBqualityCmaintenanceEnables 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.503MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to manage Nginx Proxy Manager instances through natural language, covering 28 tools for proxy hosts, certificates, streams, and more.MIT
- AlicenseCqualityDmaintenanceMCP server that abstracts the Nginx Proxy Manager API, enabling management of proxy hosts, redirections, streams, certificates, access lists, and users through natural language.54171AGPL 3.0
- AlicenseAqualityAmaintenanceEnables natural language management of FastPanel 2 servers, including creating sites, databases, SSL certificates, and hardening nginx configurations.322MIT
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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