Reads nginx access/error logs directly from a mounted NPM log directory, enabling agents to debug proxy issues without SSH access. Requires mounting NPM's /data/logs volume and setting NPM_LOG_DIR. Also includes a feature request PRD for proposing a native log API upstream.
6.3 KiB
NPM MCP Server
MCP server for Nginx Proxy Manager - manage your reverse proxy through AI assistants.
Quick Start (Docker)
The easiest way to run the NPM MCP server - no cloning required!
# Download the compose file
curl -O https://raw.githubusercontent.com/b3nw/nginx-proxy-manager-mcp/main/compose.yaml
# Edit the environment variables, then start
docker compose up -d
Or run directly:
docker run -d \
--name npm-mcp \
-p 8000:8000 \
-e NPM_API_URL=http://your-npm:81/api \
-e NPM_IDENTITY=admin@example.com \
-e NPM_SECRET=yourpassword \
-e NPM_MCP_TRANSPORT=http \
ghcr.io/b3nw/nginx-proxy-manager-mcp:latest
Installation (Local)
# Using uv (recommended)
uv pip install -e .
# Or with pip
pip install -e .
Configuration
Copy env.example to .env and configure:
NPM_API_URL=http://your-npm-instance:81/api
NPM_IDENTITY=admin@example.com
NPM_SECRET=yourpassword
# Optional: Server settings
NPM_MCP_PORT=8000
NPM_MCP_TRANSPORT=stdio # or "http"
# Optional: Default values for create_proxy_host (JSON)
NPM_PROXY_DEFAULTS='{"certificate_id": 24, "ssl_forced": true}'
Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
NPM_API_URL |
Yes | http://localhost:81/api |
NPM API endpoint |
NPM_IDENTITY |
Yes | - | NPM user email |
NPM_SECRET |
Yes | - | NPM user password |
NPM_MCP_HOST |
No | 0.0.0.0 |
MCP server bind address |
NPM_MCP_PORT |
No | 8000 |
MCP server port |
NPM_MCP_TRANSPORT |
No | stdio |
Transport mode (stdio or http) |
NPM_LOG_DIR |
No | - | Path to mounted NPM log directory (enables get_proxy_host_logs) |
NPM_PROXY_DEFAULTS |
No | {} |
JSON defaults for create_proxy_host |
NPM_PROXY_DEFAULTS Keys
Configure default values for proxy host creation:
NPM_PROXY_DEFAULTS='{"certificate_id": 24, "ssl_forced": true, "block_exploits": true}'
| Key | Type | Default | Description |
|---|---|---|---|
forward_scheme |
string | "http" |
Backend protocol (http or https) |
certificate_id |
int | 0 |
SSL certificate ID (use list_certificates to find) |
ssl_forced |
bool | true |
Force HTTPS redirect |
block_exploits |
bool | true |
Enable common exploit blocking |
allow_websocket_upgrade |
bool | true |
Allow WebSocket connections |
access_list_id |
int | 0 |
Access list ID (use list_access_lists to find) |
advanced_config |
string | "" |
Custom nginx configuration block |
Usage
Stdio Mode (for Claude Desktop, etc.)
npm-mcp
# or
python -m npm_mcp.main --transport stdio
HTTP Mode (for remote agents)
npm-mcp --transport http
# Starts server on http://0.0.0.0:8000
Claude Desktop Configuration
Add to your claude_desktop_config.json:
{
"mcpServers": {
"npm": {
"command": "npm-mcp",
"env": {
"NPM_API_URL": "http://localhost:81/api",
"NPM_IDENTITY": "admin@example.com",
"NPM_SECRET": "yourpassword"
}
}
}
}
Available Tools
| Tool | Description |
|---|---|
list_proxy_hosts |
List all proxy hosts |
get_proxy_host_details |
Get full config for a specific host |
get_proxy_host_logs |
Retrieve nginx access/error logs for a proxy host (requires log mount) |
get_system_health |
Check NPM version and status |
search_audit_logs |
Query audit log entries |
list_certificates |
List SSL certificates |
list_access_lists |
List access lists for authentication/IP restrictions |
create_proxy_host |
Create a new proxy host |
update_proxy_host |
Update an existing proxy host (v0.0.3+) |
create_certificate |
Provision a new Let's Encrypt SSL certificate (v0.0.3+) |
Log Access Setup
The get_proxy_host_logs tool reads nginx log files directly from disk. Since NPM has no API for log retrieval, you need to mount NPM's log directory into the MCP container.
NPM writes per-host logs to /data/logs/ inside its container:
proxy-host-{id}_access.log— HTTP request log (client IP, status, path, user agent)proxy-host-{id}_error.log— nginx error log (upstream failures, config issues)
Docker Compose (same stack)
If NPM and the MCP server share a compose stack with a named volume:
services:
nginx-proxy-manager:
image: jc21/nginx-proxy-manager:latest
volumes:
- npm_data:/data
npm-mcp:
image: ghcr.io/b3nw/nginx-proxy-manager-mcp:latest
environment:
- NPM_API_URL=http://nginx-proxy-manager:81/api
- NPM_IDENTITY=admin@example.com
- NPM_SECRET=yourpassword
- NPM_LOG_DIR=/data/npm-logs
volumes:
# Mount NPM's /data volume — logs are in /data/logs/ inside it
- npm_data:/data/npm-logs:ro
depends_on:
- nginx-proxy-manager
volumes:
npm_data:
Note: NPM stores logs under
/data/logs/inside its data volume. When you mount the full/datavolume to/data/npm-logs, the MCP server looks for logs at/data/npm-logs/logs/. SetNPM_LOG_DIRto match your mount path plus/logs.
If you mounted the full data volume:
NPM_LOG_DIR=/data/npm-logs/logs
Bind Mount (separate stacks)
If NPM uses a bind mount (e.g., ./npm-data:/data), mount the logs subdirectory directly:
npm-mcp:
volumes:
- /path/to/npm-data/logs:/data/npm-logs:ro
environment:
- NPM_LOG_DIR=/data/npm-logs
Docker Run
docker run -d \
--name npm-mcp \
-p 8000:8000 \
-v npm_data:/data/npm-logs:ro \
-e NPM_API_URL=http://your-npm:81/api \
-e NPM_IDENTITY=admin@example.com \
-e NPM_SECRET=yourpassword \
-e NPM_LOG_DIR=/data/npm-logs/logs \
-e NPM_MCP_TRANSPORT=http \
ghcr.io/b3nw/nginx-proxy-manager-mcp:latest
Local Development (non-Docker)
Point NPM_LOG_DIR at wherever NPM's logs are on your filesystem:
NPM_LOG_DIR=/path/to/npm/data/logs npm-mcp
Verifying the Mount
After starting, call get_system_health — if the log directory is mounted and accessible
the tool will confirm it. You can also call get_proxy_host_logs with any host ID to
verify logs are readable.
Development
# Install with dev dependencies
uv pip install -e ".[dev]"
# Run tests
pytest
# Lint
ruff check src/
License
MIT