mirror of
https://github.com/b3nw/nginx-proxy-manager-mcp.git
synced 2026-05-19 23:35:47 -05:00
feat: Add configurable defaults via NPM_PROXY_DEFAULTS env var
- Add NPM_PROXY_DEFAULTS JSON environment variable for default settings - Merge user overrides with base defaults (certificate_id, ssl_forced, etc.) - Update create_proxy_host to use None defaults and pull from config - Update env.example with documentation and examples
This commit is contained in:
@@ -7,3 +7,8 @@ NPM_SECRET=changeme
|
||||
NPM_MCP_HOST=0.0.0.0
|
||||
NPM_MCP_PORT=8000
|
||||
NPM_MCP_TRANSPORT=stdio # stdio or http
|
||||
|
||||
# Proxy Host Creation Defaults (JSON)
|
||||
# Set default values for create_proxy_host tool parameters
|
||||
# Example with wildcard cert: NPM_PROXY_DEFAULTS='{"certificate_id": 24, "ssl_forced": true}'
|
||||
# NPM_PROXY_DEFAULTS='{"certificate_id": 0, "ssl_forced": true, "block_exploits": true, "allow_websocket_upgrade": true}'
|
||||
|
||||
@@ -1,7 +1,21 @@
|
||||
"""Configuration management using pydantic-settings."""
|
||||
|
||||
from typing import Any
|
||||
|
||||
from pydantic import field_validator
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
|
||||
# Default values for proxy host creation
|
||||
DEFAULT_PROXY_SETTINGS: dict[str, Any] = {
|
||||
"forward_scheme": "http",
|
||||
"certificate_id": 0,
|
||||
"ssl_forced": True,
|
||||
"block_exploits": True,
|
||||
"allow_websocket_upgrade": True,
|
||||
"access_list_id": 0,
|
||||
"advanced_config": "",
|
||||
}
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
"""Application settings loaded from environment variables."""
|
||||
@@ -23,5 +37,30 @@ class Settings(BaseSettings):
|
||||
mcp_port: int = 8000
|
||||
mcp_transport: str = "stdio" # "stdio" or "http"
|
||||
|
||||
# Proxy host creation defaults (JSON string)
|
||||
# Example: '{"certificate_id": 24, "ssl_forced": true}'
|
||||
proxy_defaults: dict[str, Any] = {}
|
||||
|
||||
@field_validator("proxy_defaults", mode="before")
|
||||
@classmethod
|
||||
def parse_proxy_defaults(cls, v: Any) -> dict[str, Any]:
|
||||
"""Parse JSON string to dict, or pass through if already dict."""
|
||||
if isinstance(v, dict):
|
||||
return v
|
||||
if isinstance(v, str) and v.strip():
|
||||
import json
|
||||
|
||||
try:
|
||||
return json.loads(v)
|
||||
except json.JSONDecodeError as e:
|
||||
raise ValueError(f"Invalid JSON in NPM_PROXY_DEFAULTS: {e}") from e
|
||||
return {}
|
||||
|
||||
def get_proxy_defaults(self) -> dict[str, Any]:
|
||||
"""Get merged proxy defaults (base defaults + user overrides)."""
|
||||
merged = DEFAULT_PROXY_SETTINGS.copy()
|
||||
merged.update(self.proxy_defaults)
|
||||
return merged
|
||||
|
||||
|
||||
settings = Settings()
|
||||
|
||||
@@ -291,13 +291,13 @@ async def create_proxy_host(
|
||||
domain_names: list[str],
|
||||
forward_host: str,
|
||||
forward_port: int,
|
||||
forward_scheme: str = "http",
|
||||
certificate_id: int = 0,
|
||||
ssl_forced: bool = True,
|
||||
block_exploits: bool = True,
|
||||
allow_websocket_upgrade: bool = True,
|
||||
access_list_id: int = 0,
|
||||
advanced_config: str = "",
|
||||
forward_scheme: str | None = None,
|
||||
certificate_id: int | None = None,
|
||||
ssl_forced: bool | None = None,
|
||||
block_exploits: bool | None = None,
|
||||
allow_websocket_upgrade: bool | None = None,
|
||||
access_list_id: int | None = None,
|
||||
advanced_config: str | None = None,
|
||||
) -> str:
|
||||
"""Create a new proxy host in Nginx Proxy Manager.
|
||||
|
||||
@@ -305,18 +305,22 @@ async def create_proxy_host(
|
||||
domain_names: List of domain names (e.g., ["app.ext.ben.io"])
|
||||
forward_host: Backend host/IP to forward to (e.g., "192.168.1.100" or "container-name")
|
||||
forward_port: Backend port to forward to (e.g., 8080)
|
||||
forward_scheme: Backend protocol - "http" or "https" (default: "http")
|
||||
forward_scheme: Backend protocol - "http" or "https" (default from config)
|
||||
certificate_id: SSL certificate ID. Use list_certificates to find available certs.
|
||||
Use 0 for no SSL, or the ID of a matching wildcard cert.
|
||||
ssl_forced: Force HTTPS redirect (default: True)
|
||||
block_exploits: Enable common exploit blocking (default: True)
|
||||
allow_websocket_upgrade: Allow WebSocket connections (default: True)
|
||||
Use 0 for no SSL, or the ID of a wildcard cert. (default from config)
|
||||
ssl_forced: Force HTTPS redirect (default from config)
|
||||
block_exploits: Enable common exploit blocking (default from config)
|
||||
allow_websocket_upgrade: Allow WebSocket connections (default from config)
|
||||
access_list_id: Access list ID for authentication. Use list_access_lists to find.
|
||||
Use 0 for no access restrictions (default: 0)
|
||||
advanced_config: Custom nginx configuration block (default: "")
|
||||
Use 0 for no access restrictions. (default from config)
|
||||
advanced_config: Custom nginx configuration block (default from config)
|
||||
|
||||
Returns:
|
||||
JSON with created proxy host details including the new host ID.
|
||||
Details of the created proxy host including the new host ID.
|
||||
|
||||
Note:
|
||||
Default values can be configured via NPM_PROXY_DEFAULTS environment variable.
|
||||
Example: NPM_PROXY_DEFAULTS='{"certificate_id": 24, "ssl_forced": true}'
|
||||
|
||||
Example:
|
||||
create_proxy_host(
|
||||
@@ -324,22 +328,36 @@ async def create_proxy_host(
|
||||
forward_host="10.0.0.50",
|
||||
forward_port=3000,
|
||||
certificate_id=24, # *.ext.ben.io wildcard
|
||||
ssl_forced=True
|
||||
)
|
||||
"""
|
||||
try:
|
||||
# Get defaults from config, then override with provided values
|
||||
defaults = settings.get_proxy_defaults()
|
||||
|
||||
client = get_client()
|
||||
host = await client.create_proxy_host(
|
||||
domain_names=domain_names,
|
||||
forward_host=forward_host,
|
||||
forward_port=forward_port,
|
||||
forward_scheme=forward_scheme,
|
||||
certificate_id=certificate_id,
|
||||
ssl_forced=ssl_forced,
|
||||
block_exploits=block_exploits,
|
||||
allow_websocket_upgrade=allow_websocket_upgrade,
|
||||
access_list_id=access_list_id,
|
||||
advanced_config=advanced_config,
|
||||
forward_scheme=forward_scheme
|
||||
if forward_scheme is not None
|
||||
else defaults["forward_scheme"],
|
||||
certificate_id=certificate_id
|
||||
if certificate_id is not None
|
||||
else defaults["certificate_id"],
|
||||
ssl_forced=ssl_forced if ssl_forced is not None else defaults["ssl_forced"],
|
||||
block_exploits=block_exploits
|
||||
if block_exploits is not None
|
||||
else defaults["block_exploits"],
|
||||
allow_websocket_upgrade=allow_websocket_upgrade
|
||||
if allow_websocket_upgrade is not None
|
||||
else defaults["allow_websocket_upgrade"],
|
||||
access_list_id=access_list_id
|
||||
if access_list_id is not None
|
||||
else defaults["access_list_id"],
|
||||
advanced_config=advanced_config
|
||||
if advanced_config is not None
|
||||
else defaults["advanced_config"],
|
||||
)
|
||||
|
||||
domains = ", ".join(host.domain_names)
|
||||
|
||||
Reference in New Issue
Block a user