Skip to main content
Glama

npm-mcp

Model Context Protocol-Server für Nginx Proxy Manager

Verwalten Sie Reverse-Proxy-Routing, TLS-Zertifikate, Zugriffslisten und Stream-Weiterleitungen im Dialog – mit Leitplanken, die davon ausgehen, dass Sie es letztendlich auf die Produktion ausrichten werden.

Python FastMCP NPM Tests Tools Ruff


Inhalt


Related MCP server: npm-mcp

Warum es das gibt

Nginx Proxy Manager hat eine vollständige REST-API und keinen MCP-Server. Dies ist genau dieser Server – aber der interessante Teil ist nicht die technische Infrastruktur, sondern die Beschränkungen.

Ein Reverse-Proxy ist ein Single Point of Failure für alles dahinter. Ein Agent mit Schreibzugriff auf einen solchen kann Dienste lahmlegen, die er nie anfassen sollte. Das Design beginnt also genau dort:

Tools werden aus dem OpenAPI-Dokument der API selbst generiert, nicht handgeschrieben. Das Dokument ist im Repository festgeschrieben, und ein Drift-Test lässt die CI fehlschlagen, wenn sich die Upstream-Oberfläche ändert – statt dass Tools zur Laufzeit still 404 liefern.

Jedes Ergebnis durchläuft eine Schwärzungsgrenze, die im Zweifel blockiert. Sie wirft bei allem, was sie nicht prüfen kann, einen Fehler, statt es durchzureichen.

Leitplanken sind mutationsgetestet. Jede Sicherheitskontrolle hat einen Test, der nachweislich rot wird, wenn die Kontrolle deaktiviert ist.


So funktioniert es

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

Tool-Signaturen werden beim Import aus dem festgeschriebenen Dokument erzeugt, daher bietet create_proxy_host 18 typisierte Argumente mit echten Enums – kein undurchsichtiger **kwargs-Durchgriff.


Schnellstart

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 bedient unter /mcp. Ein abschließender Schrägstrich erzeugt eine 307-Weiterleitung, was einige Clients falsch behandeln – lassen Sie nicht zu, dass ein Proxy den Pfad umschreibt.

[!TIP] Rufen Sie zuerst get_guidance auf. Es meldet Antwortstrukturen, die Unterscheidung zwischen Deaktivieren und Löschen, welche Verriegelungen derzeit offen sind und die aktive Liste geschützter Domains.


Authentifizierung

Zwei Ebenen, die leicht zu verwechseln sind:

Richtung

Mechanismus

Eingehend

client → npm-mcp

Optional Authorization: Bearer … über NPM_MCP_BEARER_TOKEN, verglichen mit hmac.compare_digest. Nicht gesetzt ⇒ keinerlei Authentifizierung.

Ausgehend

npm-mcp → NPM

Kontozugangsdaten → kurzlebiges JWT, automatisch erneuert. Aufrufer sehen oder übermitteln es nie.

NPM vergibt keine langlebigen API-Schlüssel; deshalb hält der Server Zugangsdaten, statt ein Token zu akzeptieren.

[!IMPORTANT] POST /tokens hat zwei mögliche Antworten: ein Token oder eine 2FA-Herausforderung. Wenn das Konto 2FA aktiviert hat, setzen Sie NPM_TOTP_SECRET – andernfalls schlägt der Server beim Start fehl und benennt beide Abhilfen, statt gesund hochzufahren und beim ersten Tool-Aufruf zu brechen.


Tool-Katalog

66 Tools = 65 API-Operationen + get_guidance.

Familie

#

Repräsentative Tools

🔀 Proxy-Hosts

7

get_proxy_hosts · create_proxy_host · update_proxy_host · delete_proxy_host · enable_proxy_host · disable_proxy_host

↪️ Weiterleitungs-Hosts

7

*_redirection_host

🚫 404-Hosts

7

create_404_host · *_dead_host

🔌 Streams

7

*_stream

🔐 Zugriffslisten

5

get_access_lists · create_access_list · update_access_list · delete_access_list

📜 Zertifikate

10

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

👤 Benutzer

8

get_users · create_user · update_user · update_user_auth · update_user_permissions · login_as_user

🔑 Benutzer-2FA

5

setup_user_2fa · enable_user_2fa · disable_user_2fa · get_user_2fa_status · regen_user_2fa_codes

⚙️ Einstellungen

3

get_settings · update_setting

📋 Audit-Log

2

get_audit_logs · get_audit_log

ℹ️ Meta

4

health · check_version · reports_hosts · schema

🧭 Anleitung

1

get_guidance

Die Namen leiten sich aus der OpenAPI-operationId ab, daher sind Listenoperationen get_* und nicht list_*.

[!WARNING] Drei Operationen sind bewusst nicht exponiert: requestToken, refreshToken, loginWith2FA. Sie sind die eigene Auth-Infrastruktur des Servers, und requestToken akzeptiert eine beliebige Identität und ein beliebiges Geheimnis – es zu registrieren würde diesen Server in ein Orakel zum Testen von Zugangsdaten gegen NPM verwandeln, mit jedem Versuch, der dem Dienstkonto zugeschrieben würde.

  • Es gibt keine Paginierung. Kein einziger Endpunkt akzeptiert limit/offset. Die Tools akzeptieren sie und schneiden clientseitig; die Tool-Beschreibungen sagen das.

  • expand ist ein Pro-Endpunkt-Enum, kein Durchgriff – Proxy-Hosts akzeptiert access_list,owner,certificate; Zertifikate nur owner. Werte außerhalb des Enums werden abgelehnt, bevor die Anfrage gesendet wird.


Sicherheitsmodell

[!CAUTION] Schreibvorgänge sind standardmäßig aktiviert. Dieser Server kann die Routing-Tabelle für jeden Dienst hinter dem Proxy neu schreiben. Setzen Sie NPM_READ_ONLY=1, um alle Mutationen zu deaktivieren.

Kontrolle

Überschreibung

NPM_READ_ONLY

Lehnt jedes mutierende Tool ab; wird geprüft, bevor irgendeine Leitplanke gelesen wird

S1

Verweigert delete / disable / update auf geschützten Hosts sowie auf den Zertifikaten und Zugriffslisten, von denen diese Hosts abhängen

NPM_ALLOW_SELF_MUTATION

S2

Jedes DELETE erfordert confirm: true; ohne dies gibt das Tool zurück, was betroffen wäre, und schreibt nichts

pro Aufruf

S5

Jede Mutation erzeugt eine Audit-Zeile; NPMs eigenes Audit-Log ist abfragbar

S6

Jede mutierende Operation unter /users oder /settings ist verriegelt

NPM_ALLOW_ACCOUNT_MUTATION

S7

Verweigert, das eigene Konto zu ändern, zu deaktivieren, zu löschen oder login_as darauf anzuwenden

keine

S8

download_certificate gibt TLS-Private Keys zurück, daher ist es verriegelt

NPM_ALLOW_CERT_EXPORT

  • S1 matcht JEDE geschützte Domain, nicht ALLE. ALLE würde es erlauben, die Leitplanke durch die Tools, die sie schützt, zu entwaffnen: Fügen Sie einem Host eine unzusammenhängende Domain hinzu, und der Schutz verpufft.

  • S1 deckt update ab, nicht nur delete/disable. Sonst entfernen Sie den geschützten Namen aus domain_names und löschen dann sauber – gleiche Störung.

  • S1 matcht auf den aktuellen Upstream-Zustand, niemals auf den übermittelten Body. Würde die Anfrage geprüft, könnte der Strip-then-Update-Pfad direkt durchlaufen.

  • S1-Wildcards matchen in beide Richtungen. NPM_PROTECTED_DOMAINS=*.example.net muss app.example.net schützen. Es matchte einmal nichts und unterdrückte die Warnung „ungeschützt“, weil der Wert explizit gesetzt war.

  • S2 wird über die HTTP-Methode eingegrenzt, nicht über ein Namenspräfix. Eine delete_*-Regel übersieht disable_user_2fa – ein DELETE, das jemandem den zweiten Faktor entzieht.

  • S6 ist eine Regel, keine Liste. Eine aufgezählte Version ließ update_user stillschweigend aus, sodass die Verriegelung geschlossen blieb, während is_disabled: true einen Admin aussperrte.

  • S7 hat keine Überschreibung. Ein Server, der seine eigenen Zugangsdaten löschen kann, sperrt sich dauerhaft aus.


Konfiguration

Variable

Bedeutung

NPM_URL

Basis-URL der NPM-Instanz

NPM_IDENTITY

Konto-E-Mail

NPM_SECRET

Konto-Passwort

Variable

Standard

Bedeutung

NPM_MCP_BEARER_TOKEN

nicht gesetzt

Eingehendes Token. Nicht gesetzt ⇒ keine eingehende Authentifizierung

NPM_MCP_TRANSPORT

streamable-http

stdio | streamable-http

NPM_MCP_HTTP_HOST

0.0.0.0

Bind-Adresse

NPM_MCP_HTTP_PORT

8000

Bind-Port

Variable

Standard

Hebt

NPM_READ_ONLY

0

— (1 blockiert alle Schreibvorgänge)

NPM_PROTECTED_DOMAINS

aus NPM_URL abgeleitet

S1-Blockliste, per Komma getrennt

NPM_ALLOW_SELF_MUTATION

0

S1

NPM_ALLOW_ACCOUNT_MUTATION

0

S6

NPM_ALLOW_CERT_EXPORT

0

S8

Variable

Standard

Bedeutung

NPM_TOTP_SECRET

nicht gesetzt

Base32-Startwert; nur falls das Konto 2FA aktiviert hat

NPM_TLS_VERIFY

1

NPM-Zertifikat verifizieren

NPM_TIMEOUT

30

Upstream-Timeout (Sekunden)

NPM_MAX_RESPONSE_CHARS

50000

Antwortlimit vor der Kürzung

NPM_GUIDANCE_GATE

1

Hinweis auf get_guidance bei frühen Mutationen

LOG_LEVEL

INFO


Deployment

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

Der Container tritt einem vorhandenen Docker-Netzwerk neben NPM bei und veröffentlicht keine Ports. NPM erreicht ihn über den Container-DNS und terminiert TLS, sodass das Bearer-Token niemals im Klartext über die Leitung geht.

  • Kein build:-Schlüssel in der Compose-Datei. Ein Compose-String-Deployment (z. B. Portainer) liefert keinen Build-Kontext mit. Das Image wird deshalb zuerst gebaut und über ein Tag referenziert.

  • Der Healthcheck löst den Bind-Host auf, statt 127.0.0.1 hartzukodieren. Mit einem benutzerdefinierten NPM_MCP_HTTP_HOST markiert die naive Variante einen völlig gesunden Container für immer als ungesund. Unter stdio schlägt sie zusätzlich fehl, da dort überhaupt nichts lauscht.

  • Die authentifizierende Aufwärmphase läuft in der Serverlebensdauer. So führt eine Fehlkonfiguration zu einem fehlgeschlagenen Healthcheck, statt dass der Container grün wird und erst bei der ersten Verwendung bricht.


Testing

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

Rund 4.700 Zeilen Tests gegenüber 3.300 Zeilen Quellcode – aber die bloße Anzahl zählt weniger als die Struktur:

  • 🧬 Mutationsverifizierte Schutzvorkehrungen – für jede Sicherheitsabschirmung existiert ein Test, der nachweislich fehlschlägt, wenn die Absicherung abgeschaltet ist. Entstanden nach der Entdeckung eines asyncio.Lock, dessen Entfernung die Testsuite grün ließ.

  • 🌐 Null Netzwerkzugriff – jeder Upstream-Aufruf ist mit respx gemockt. Ein Test, der das Netzwerk braucht, ist ein kaputter Test.

  • 🔍 A7-Sweep – alle 65 Werkzeuge werden gegen einen Upstream aufgerufen, der Geheimnisse in vier Verschachtelungsebenen liefert; eine Negativkontrolle sichert ab, dass das Fixture diese Geheimnisse wirklich enthält, sodass der Sweep nicht ins Leere laufen kann.

  • 📐 Schema-Drifit-Schutz – Operationszahlen, Payload-Strukturen und die eingepackte Datendatei werden alle überprüft; dadurch scheitert ein Upstream-Upgrade hier statt in der Produktion.


Designhinweise

Dokument

Inhalt

spec.md

Produktvertrag – Entscheidungen D1–D13, Schutzvorkehrungen S1–S8, Abnahmekriterien A1–A10

docs/api-surface.md

Alle 68 Operationen mit Body-Feld und Pflichtfeld-Kennzeichnung

docs/module-contract.md

Schnittstellen der internen Module

docs/findings.md

Zwei Dinge, die das OpenAPI-Dokument falsch angibt, gemessen an einer Live-Instanz

npm_mcp/data/npm-openapi.json

Unveränderte Kopie der /api/schema der Instanz – hoch im Paket, da sie eine Laufzeichenabhängigkeit und keine Dokumentation ist

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