npm package: @kukolabs/mcp-nginx-proxy-manager
Description: MCP server for Nginx Proxy Manager — stdio, HTTP, and SSE transports
Latest version: 0.1.6

# Nginx Proxy Manager MCP Server

A Model Context Protocol (MCP) server providing **50 tools** for complete management of [Nginx Proxy Manager](https://nginxproxymanager.com/) through a type-safe TypeScript interface.

## Features

- **Full API Coverage** — Proxy hosts, redirection hosts, 404 hosts, TCP/UDP streams, access lists, SSL certificates, users, settings, and audit log
- **Multiple Transports** — stdio (default), HTTP (Streamable), and SSE — select via `MCP_TRANSPORT`
- **Readonly Mode** — Lock out all mutating tools with `NPM_READONLY=true` or `--readonly`
- **Rich Errors** — Every error includes a Reason and Suggestion to help diagnose problems without guessing
- **CLI or Env Vars** — Configure via environment variables or command-line flags, CLI takes precedence

## Prerequisites

- Node.js 18 or higher
- A running Nginx Proxy Manager instance with API access
- NPM admin username and password

## Installation

```bash
# Global install
npm install -g @kukolabs/mcp-nginx-proxy-manager

# Or run without installing
npx -y @kukolabs/mcp-nginx-proxy-manager
```

## MCP Configuration

The `mcpServers` config format is standard across Claude Desktop, Claude Code, Cursor, and other MCP clients.

### Via npx (no install required)

```json
{
  "mcpServers": {
    "nginx-proxy-manager": {
      "command": "npx",
      "args": ["-y", "@kukolabs/mcp-nginx-proxy-manager"],
      "env": {
        "NPM_URL": "http://192.168.1.10:81",
        "NPM_USERNAME": "admin@example.com",
        "NPM_PASSWORD": "your-password"
      }
    }
  }
}
```

### Via global install

```json
{
  "mcpServers": {
    "nginx-proxy-manager": {
      "command": "mcp-nginx-proxy-manager",
      "env": {
        "NPM_URL": "http://192.168.1.10:81",
        "NPM_USERNAME": "admin@example.com",
        "NPM_PASSWORD": "your-password"
      }
    }
  }
}
```

### Via local build

```json
{
  "mcpServers": {
    "nginx-proxy-manager": {
      "command": "node",
      "args": ["/path/to/mcp-nginx-proxy-manager/dist/index.js"],
      "env": {
        "NPM_URL": "http://192.168.1.10:81",
        "NPM_USERNAME": "admin@example.com",
        "NPM_PASSWORD": "your-password"
      }
    }
  }
}
```

### Via Docker / remote (HTTP transport)

```json
{
  "mcpServers": {
    "nginx-proxy-manager": {
      "type": "http",
      "url": "http://localhost:8000/mcp"
    }
  }
}
```

See the [Docker](#docker) section below for how to run the container.

## Testing Manually

Test the server before connecting it to your MCP client:

```bash
node dist/index.js \
  --url http://192.168.1.10:81 \
  --username admin@example.com \
  --password your-password
```

Expected output on stderr:

```
@kukolabs/mcp-nginx-proxy-manager v0.1.5
Transport: stdio
NPM URL:   http://192.168.1.10:81
Tools:     50 total — proxy-hosts: 7, redirection-hosts: 7, dead-hosts: 7, streams: 7, access-lists: 5, certificates: 6, users: 6, settings: 3, reports: 1, audit-log: 1
```

Once configured, ask Claude:

- "List all proxy hosts"
- "Create a proxy host for app.example.com pointing to 192.168.1.20:8080"
- "Show me the SSL certificates"
- "Get the hosts report"

## Configuration Reference

### Environment Variables

| Variable | Default | Description |
|---|---|---|
| `NPM_URL` | `http://localhost:81` | Nginx Proxy Manager base URL |
| `NPM_USERNAME` | _(required)_ | Admin email address |
| `NPM_PASSWORD` | _(required)_ | Admin password |
| `NPM_READONLY` | `false` | Set to `true` to block all mutating tools |
| `MCP_TRANSPORT` | `stdio` | Transport mode: `stdio`, `http`, or `sse` |
| `MCP_PORT` | `8000` | Port for HTTP/SSE transport |
| `MCP_HOST` | `127.0.0.1` | Bind address for HTTP/SSE transport |
| `MCP_BASE_PATH` | _(empty)_ | URL prefix for HTTP/SSE endpoints |
| `MCP_AUTH_TOKEN` | _(none)_ | Bearer token required for HTTP/SSE connections |

### CLI Flags

CLI flags take precedence over environment variables.

| Flag | Env Equivalent | Description |
|---|---|---|
| `--url <url>` | `NPM_URL` | NPM base URL |
| `--username <user>` | `NPM_USERNAME` | Admin email |
| `--password <pass>` | `NPM_PASSWORD` | Admin password |
| `--readonly` | `NPM_READONLY=true` | Enable readonly mode |
| `--transport <mode>` | `MCP_TRANSPORT` | `stdio`, `http`, or `sse` |
| `--port <port>` | `MCP_PORT` | HTTP/SSE port |
| `--host <host>` | `MCP_HOST` | HTTP/SSE bind address |
| `--base-path <path>` | `MCP_BASE_PATH` | HTTP/SSE URL prefix |
| `--auth-token <token>` | `MCP_AUTH_TOKEN` | HTTP/SSE bearer token |

### HTTP and SSE Transports

```bash
# HTTP (Streamable)
node dist/index.js --transport http --port 8000 --auth-token my-secret-token
# Endpoint: http://127.0.0.1:8000/mcp

# SSE
node dist/index.js --transport sse --port 8000
# Connect: GET http://127.0.0.1:8000/sse
# Post:    POST http://127.0.0.1:8000/message?sessionId=<id>
```

> **Security note:** HTTP/SSE bind to `127.0.0.1` by default. For external access use a reverse proxy with TLS and set `MCP_AUTH_TOKEN`.

## Docker

```bash
docker run -p 127.0.0.1:8000:8000 \
  -e NPM_URL=http://192.168.1.10:81 \
  -e NPM_USERNAME=admin@example.com \
  -e NPM_PASSWORD=your-password \
  -e MCP_TRANSPORT=http \
  ghcr.io/kukolabs/mcp-nginx-proxy-manager:latest
```

Or with docker compose — copy `docker/docker-compose.yml` and add a `.env` file.

## Readonly Mode

When `NPM_READONLY=true` (or `--readonly`), all tools that create, update, or delete resources return an error immediately without calling the NPM API:

```
✗ Server is in read-only mode
  Reason: NPM_READONLY=true
  Suggestion: Remove NPM_READONLY or set it to false to enable write operations
```

This is useful for giving Claude read-only access to audit a configuration without risk of changes.

## Troubleshooting

### Authentication errors

```
✗ Authentication failed
  Reason: Invalid identity or secret
  Suggestion: Check NPM_USERNAME and NPM_PASSWORD env vars
```

Verify the username is the full email address and the password is correct. The server caches the JWT token and auto-refreshes it 60 seconds before expiry.

### Cannot reach NPM

```
✗ Cannot reach Nginx Proxy Manager
  Reason: connect ECONNREFUSED 192.168.1.10:81
  Suggestion: Check NPM_URL (currently: http://192.168.1.10:81) and that NPM is running
```

Check that `NPM_URL` points to the correct host and port, and that NPM is running.

### Checking MCP logs

```bash
# Claude Code writes MCP stderr to its log
tail -f ~/.claude/logs/mcp-*.log
```

## Development

```bash
git clone https://github.com/KukoLabs/mcp-nginx-proxy-manager.git
cd mcp-nginx-proxy-manager
npm install
npm run build      # compile TypeScript
npm test           # unit tests
```

### Running integration tests

Integration tests require a live NPM instance:

```bash
NPM_URL=http://localhost:81 NPM_USERNAME=admin@test.com NPM_PASSWORD=changeme \
  npm run test:integration
```

## License

MIT — see [LICENSE](./LICENSE)