Metadata-Version: 2.4
Name: bibliocommons-mcp-pritunl
Version: 1.2.0
Summary: MCP server for Pritunl Enterprise VPN management
Author-email: Cody Lusk <cody.lusk@bibliocommons.com>
License: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: fastmcp>=3.2.4
Requires-Dist: requests>=2.33.1
Requires-Dist: fastapi>=0.136.1
Requires-Dist: uvicorn>=0.46.0
Requires-Dist: python-multipart>=0.0.27
Provides-Extra: dev
Requires-Dist: pytest>=9.0.3; extra == "dev"
Requires-Dist: pytest-asyncio>=1.3.0; extra == "dev"
Requires-Dist: pytest-cov>=7.1.0; extra == "dev"
Requires-Dist: httpx>=0.28.1; extra == "dev"

# Pritunl VPN MCP Server

MCP server for managing Pritunl Enterprise VPN instances. Provides 35 tools for organizations, users, servers, routes, hosts, and settings.

## Prerequisites

- Python 3.10+
- Pritunl Enterprise subscription (required for API access)
- API token and secret from Pritunl admin console

## Configuration

**Authentication**: Pritunl uses HMAC-based API authentication with a token/secret pair. Generate these in the Pritunl web console under Users → API Keys.

### Option 1: config.json

```bash
cp config.json.example config.json
# Edit config.json with your API credentials
```

### Option 2: Environment Variables

```bash
export PRITUNL_HOST="vpn.example.com:443"
export PRITUNL_API_TOKEN="your-api-token"
export PRITUNL_API_SECRET="your-api-secret"
export PRITUNL_VERIFY_SSL="true"
export PRITUNL_TIMEOUT="30"
```

### Configuration Fields

| Field | Env Var | Required | Default | Description |
|---|---|---|---|---|
| `host` | `PRITUNL_HOST` | Yes | — | Pritunl server hostname and port (e.g., `vpn.example.com:443`). The client prepends `https://` automatically, so do not include the scheme. |
| `api_token` | `PRITUNL_API_TOKEN` | Yes | — | API token |
| `api_secret` | `PRITUNL_API_SECRET` | Yes | — | API secret |
| `verify_ssl` | `PRITUNL_VERIFY_SSL` | No | `true` | Verify TLS certificates |
| `timeout` | `PRITUNL_TIMEOUT` | No | `30` | Request timeout in seconds |

The config file path can also be set via `PRITUNL_CONFIG` env var or `--config` CLI flag.

## Installation

### Option 1: Using uv (Recommended)

[uv](https://github.com/astral-sh/uv) is a fast Python package manager. Install it first:

```bash
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
```

No additional installation needed — `uvx` will handle dependencies automatically.

### Option 2: Using pip

```bash
pip install bibliocommons-mcp-pritunl
# or for development
pip install -e ".[dev]"
```

## AI Client Setup

### VS Code (with MCP Extension)

```json
{
  "mcp.servers": {
    "pritunl": {
      "command": "uvx",
      "args": ["--from", "/absolute/path/to/pritunl", "bibliocommons-mcp-pritunl"]
    }
  }
}
```

### Claude Desktop

Config location:
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`

```json
{
  "mcpServers": {
    "pritunl": {
      "command": "uvx",
      "args": ["--from", "/absolute/path/to/pritunl", "bibliocommons-mcp-pritunl"]
    }
  }
}
```

### Kiro IDE

```json
{
  "mcpServers": {
    "pritunl": {
      "command": "uvx",
      "args": ["--from", "/absolute/path/to/pritunl", "bibliocommons-mcp-pritunl"]
    }
  }
}
```

### Kiro CLI

Create or edit `~/.kiro/settings/mcp.json` (user level) or `<project-root>/.kiro/settings/mcp.json` (project level):

```json
{
  "mcpServers": {
    "pritunl": {
      "command": "uvx",
      "args": ["--from", "/absolute/path/to/pritunl", "bibliocommons-mcp-pritunl"]
    }
  }
}
```

### Configuration Notes

- Replace `/absolute/path/to/pritunl` with the actual path to the server directory.
- **Using `uvx`**: Automatically manages dependencies in isolated environments.
- **Using `python` directly**: Requires `pip install bibliocommons-mcp-pritunl` first. Use `"command": "python", "args": ["-m", "bibliocommons_mcp_pritunl"]` instead.
- Restart your AI client after adding the configuration.

For other AI clients (Amazon Q, GitHub Copilot, Cline, Zed, Cursor), see [docs/ai-clients.md](docs/ai-clients.md).

## Docker

```bash
# Pull from Docker Hub (private)
docker pull bibliocommons/mcp-pritunl:latest

# Run in stdio mode
docker run -i --rm \
  -v /path/to/config.json:/config.json:ro \
  bibliocommons/mcp-pritunl:latest \
  --config /config.json

# Run in HTTP mode
docker run -d --rm \
  -v /path/to/config.json:/config.json:ro \
  -p 8000:8000 \
  bibliocommons/mcp-pritunl:latest \
  --config /config.json --transport http --port 8000

# Run in expanded mode
docker run -i --rm \
  -v /path/to/config.json:/config.json:ro \
  bibliocommons/mcp-pritunl:latest \
  --config /config.json --expanded
```

## Web UI

A REST API with interactive Swagger documentation is available:

```bash
python -m bibliocommons_mcp_pritunl.webui
```

Access the Swagger UI at: http://localhost:8000/docs

## Standalone MCP Server

```bash
python -m bibliocommons_mcp_pritunl
```

### CLI Flags

| Flag | Env Var | Description |
|------|---------|-------------|
| `--config PATH` | `PRITUNL_CONFIG` | Path to config.json |
| `--read-only` | `PRITUNL_READ_ONLY` | Exclude destructive tools |
| `--expanded` | `PRITUNL_EXPANDED` | Register all tools individually instead of gateway mode |
| `--transport stdio\|http` | `PRITUNL_TRANSPORT` | Transport mode (default: stdio) |
| `--port PORT` | `PRITUNL_PORT` | HTTP port (default: 8000) |
| `--version` | — | Show version and exit |

## Gateway Mode (Default)

By default, the server exposes 2 tools instead of 35 individual tools:

| Tool | Purpose |
|------|---------|
| `pritunl_api` | Execute any Pritunl VPN action by name with a params dict |
| `pritunl_help` | Search available actions, parameters, and descriptions |

The AI assistant calls `pritunl_help` to discover available actions, then calls `pritunl_api(action="list_servers", params={})` to execute them.

To register all individual tools (previous behavior), use `--expanded`:

```bash
python -m bibliocommons_mcp_pritunl --expanded
```

## Available Tools

### Status (2 tools)

| Tool | Description |
|---|---|
| `get_status` | Get Pritunl system status (server count, host count, org count, online users) |
| `get_events` | Get real-time event stream from Pritunl |

### Organizations (5 tools)

| Tool | Description |
|---|---|
| `list_organizations` | List all organizations |
| `get_organization` | Get organization details by ID |
| `create_organization` | Create a new organization |
| `update_organization` | Update an organization's name |
| `delete_organization` | Delete an organization |

### Users (7 tools)

| Tool | Description |
|---|---|
| `list_users` | List all users in an organization |
| `get_user` | Get user details by organization and user ID |
| `create_user` | Create a new user in an organization |
| `update_user` | Update a user's properties (name, email, disabled status) |
| `delete_user` | Delete a user from an organization |
| `get_user_audit` | Get audit log for a specific user |
| `get_user_key_download_url` | Get temporary key download links for a user |

### Servers (10 tools)

| Tool | Description |
|---|---|
| `list_servers` | List all VPN servers |
| `get_server` | Get VPN server details by ID |
| `create_server` | Create a new VPN server |
| `update_server` | Update a VPN server (merges changes with current config) |
| `delete_server` | Delete a VPN server |
| `start_server` | Start a VPN server |
| `stop_server` | Stop a VPN server |
| `restart_server` | Restart a VPN server |
| `get_server_output` | Get server log output |
| `get_server_bandwidth` | Get server bandwidth statistics (periods: 1m, 5m, 30m, 2h, 1d) |

### Server Routes (4 tools)

| Tool | Description |
|---|---|
| `list_server_routes` | List all routes on a VPN server |
| `add_server_route` | Add a route to a VPN server |
| `update_server_route` | Update a route on a VPN server |
| `delete_server_route` | Delete a route from a VPN server |

### Server Organizations (2 tools)

| Tool | Description |
|---|---|
| `attach_organization` | Attach an organization to a VPN server |
| `detach_organization` | Detach an organization from a VPN server |

### Hosts (3 tools)

| Tool | Description |
|---|---|
| `list_hosts` | List all Pritunl hosts |
| `get_host` | Get host details by ID |
| `list_server_hosts` | List hosts attached to a VPN server |

### Settings (2 tools)

| Tool | Description |
|---|---|
| `get_settings` | Get global Pritunl settings |
| `update_settings` | Update global Pritunl settings (merges changes with current) |

## Read-Only Mode

Exclude all destructive (create/update/delete) tools:

```bash
# CLI flag
python -m bibliocommons_mcp_pritunl --read-only

# Environment variable
export PRITUNL_READ_ONLY=true
```

In read-only mode, the following 20 tools are excluded: `create_organization`, `update_organization`, `delete_organization`, `create_user`, `update_user`, `delete_user`, `create_server`, `update_server`, `delete_server`, `start_server`, `stop_server`, `restart_server`, `add_server_route`, `update_server_route`, `delete_server_route`, `attach_organization`, `detach_organization`, `update_settings`.

## Development

```bash
# Install with dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run tests with coverage
pytest --cov=bibliocommons_mcp_pritunl
```

## License

MIT
