Skip to main content
Glama
README.md
# OSSEC MCP Server

A fully functional **Model Context Protocol (MCP)** server for [OSSEC HIDS](https://www.ossec.net/) (Host-based Intrusion Detection System). This server exposes OSSEC's security monitoring capabilities as MCP tools, resources, and prompts -- enabling AI assistants to query alerts, manage agents, inspect rules, run integrity checks, and more.

## Features

### Tools (26 tools)

| Category | Tool | Description |
|----------|------|-------------|
| **Alerts** | `get_alerts` | Retrieve alerts with filtering by level, group, time range, and search |
| | `get_alert_summary` | Aggregated alert statistics by severity, group, and top rules |
| | `search_alerts` | Free-text search across all alert data |
| **Agents** | `list_agents` | List all managed agents with status |
| | `get_agent_info` | Detailed info for a specific agent |
| | `add_agent` | Register a new agent |
| | `remove_agent` | Remove an agent registration |
| | `restart_agent` | Restart an agent remotely |
| **Rules** | `get_rules` | Search rules by ID, level, group, or keyword |
| | `get_rule_details` | Full rule definition with match criteria |
| | `list_rule_files` | List all rule XML files |
| | `get_decoders` | Search and list log decoders |
| **Syscheck** | `get_syscheck_results` | File Integrity Monitoring results |
| | `run_syscheck_scan` | Trigger a FIM scan |
| | `clear_syscheck_database` | Reset FIM baseline |
| **Rootcheck** | `get_rootcheck_results` | Rootkit/anomaly detection results |
| | `run_rootcheck_scan` | Trigger rootcheck scan |
| **Status** | `get_ossec_status` | Service health for all daemons |
| | `restart_ossec` | Restart all OSSEC services |
| | `get_ossec_logs` | Internal OSSEC logs with filtering |
| | `get_ossec_stats` | Processing statistics |
| | `get_ossec_configuration` | Parsed configuration (full or by section) |
| | `get_ossec_configuration_raw` | Raw ossec.conf XML |
| **Log Test** | `run_logtest` | Test log lines against rules/decoders |
| **Response** | `get_active_responses` | List configured active responses |
| | `run_active_response` | Execute active response on an agent |

### Resources (8 static resources + 3 resource templates)

**Static resources:**

| URI | Description |
|-----|-------------|
| `ossec://status` | Current service status |
| `ossec://alerts/recent` | Last 50 alerts |
| `ossec://alerts/critical` | Critical alerts (level 12+, last 24h) |
| `ossec://agents/list` | All agents |
| `ossec://config/main` | Parsed configuration |
| `ossec://config/raw` | Raw XML configuration |
| `ossec://rules/summary` | Rule files summary |
| `ossec://logs/recent` | Recent internal logs |

**Resource templates (dynamic, parameterized):**

| URI Template | Description |
|--------------|-------------|
| `ossec://agents/{agent_id}` | Specific agent detail |
| `ossec://agents/{agent_id}/syscheck` | Agent FIM results |
| `ossec://agents/{agent_id}/rootcheck` | Agent rootcheck results |

### Prompts (5 prompts)

| Prompt | Description |
|--------|-------------|
| `analyze_alerts` | Structured security alert analysis with recommendations |
| `investigate_agent` | Deep-dive investigation of a specific agent |
| `security_audit` | Comprehensive OSSEC deployment audit |
| `incident_response` | Guided IR workflow for security events |
| `tune_rules` | Rule tuning to reduce false positives |

## Security

This server includes several hardening measures:

- **Secure XML parsing** -- Uses `defusedxml` to prevent XXE and billion laughs attacks when parsing OSSEC rules, decoders, and configuration files.
- **Input validation** -- All user-supplied parameters (`agent_id`, agent `name`, `ip`, `command`, `filename`) are validated against strict regex patterns before being passed to CLI tools or the API, preventing command injection and path traversal.
- **Path traversal prevention** -- Filename parameters used in filesystem `glob()` calls reject path separators and `..` sequences.
- **Error sanitization** -- Error messages returned to clients have filesystem paths stripped to avoid leaking internal directory structure.
- **Bounded resource usage** -- File reads are capped at 10 MB, log tail operations use bounded memory, and query limits are clamped to configured maximums.
- **Secure defaults** -- SSE transport binds to `127.0.0.1` by default (not `0.0.0.0`). API communication always uses HTTPS.
- **No shell execution** -- All subprocess calls use `create_subprocess_exec` with argument lists, never shell strings.

## Installation

### Prerequisites

- Python 3.10+
- OSSEC HIDS installed (local mode) or Wazuh/OSSEC API access (API mode)
- Linux host (or Windows with WSL) for local mode

### Installing OSSEC HIDS

If OSSEC is not already installed, you can compile it from source. Example for Debian/Ubuntu/Kali:

```bash
# Install build dependencies
sudo apt update && sudo apt install -y \
  build-essential make gcc libssl-dev libpcre2-dev \
  zlib1g-dev wget libsystemd-dev

# Download OSSEC 3.7.0
cd /tmp
wget https://github.com/ossec/ossec-hids/archive/refs/tags/3.7.0.tar.gz
tar -zxf 3.7.0.tar.gz
cd ossec-hids-3.7.0

# Create non-interactive install config
cat > etc/preloaded-vars.conf << 'EOF'
USER_LANGUAGE="en"
USER_NO_STOP="y"
USER_INSTALL_TYPE="local"
USER_DIR="/var/ossec"
USER_DELETE_DIR="y"
USER_ENABLE_ACTIVE_RESPONSE="y"
USER_ENABLE_SYSCHECK="y"
USER_ENABLE_ROOTCHECK="y"
USER_ENABLE_EMAIL="n"
USER_ENABLE_SYSLOG="y"
USER_ENABLE_FIREWALL_RESPONSE="n"
USER_WHITE_LIST="127.0.0.1"
EOF

# Compile and install
sudo ./install.sh

# Start OSSEC
sudo /var/ossec/bin/ossec-control start

# Verify
sudo /var/ossec/bin/ossec-control status
```

After installation, the following daemons should be running: `ossec-analysisd`, `ossec-logcollector`, `ossec-syscheckd`, `ossec-monitord`, `ossec-execd`.

### Dependencies

| Package | Purpose |
|---------|---------|
| `mcp` >= 1.0.0 | MCP SDK with FastMCP server framework |
| `pydantic` >= 2.0.0 | Data validation |
| `pydantic-settings` >= 2.0.0 | Environment/file-based configuration |
| `httpx` >= 0.25.0 | Async HTTP client for API mode |
| `python-dateutil` >= 2.8.0 | Timestamp parsing |
| `defusedxml` >= 0.7.0 | Secure XML parsing |

Dev dependencies: `pytest`, `pytest-asyncio`, `ruff`

### Install from source

```bash
# Clone or download the project
cd OSSEC_MCP_SERVER

# Create a virtual environment (recommended)
python3 -m venv .venv
source .venv/bin/activate   # Linux/macOS
# .venv\Scripts\activate    # Windows

# Install the package
pip install -e .

# Or install with dev dependencies
pip install -e '.[dev]'
```

### Configure

```bash
# Copy the example environment file
cp .env.example .env

# Edit with your OSSEC settings
# At minimum, verify OSSEC_PATH points to your installation
```

Configuration is loaded from environment variables or a `.env` file. All options and their defaults:

| Variable | Default | Description |
|----------|---------|-------------|
| `OSSEC_PATH` | `/var/ossec` | OSSEC installation root directory |
| `OSSEC_MODE` | `local` | `local` (CLI tools + filesystem) or `api` (REST API) |
| `OSSEC_API_HOST` | `localhost` | API hostname (API mode only) |
| `OSSEC_API_PORT` | `55000` | API port (API mode only) |
| `OSSEC_API_USER` | `admin` | API username (API mode only) |
| `OSSEC_API_PASSWORD` | *(empty)* | API password (API mode only) |
| `OSSEC_API_SSL_VERIFY` | `true` | Verify TLS certificates for API connections |
| `MCP_TRANSPORT` | `stdio` | MCP transport: `stdio` or `sse` |
| `MCP_HOST` | `127.0.0.1` | SSE bind address (SSE transport only) |
| `MCP_PORT` | `8000` | SSE port (SSE transport only) |
| `MAX_ALERTS` | `500` | Maximum alerts returned per query |
| `MIN_ALERT_LEVEL` | `1` | Default minimum alert level filter |
| `LOG_LEVEL` | `INFO` | Logging level (`DEBUG`, `INFO`, `WARNING`, `ERROR`) |

## Usage

### Run the server

```bash
# stdio transport (default -- for AI tool integration)
ossec-mcp-server

# Or run as a Python module
python -m ossec_mcp
```

If the venv is not activated, use the full path:

```bash
/path/to/OSSEC_MCP_SERVER/.venv/bin/ossec-mcp-server
```

### Sudo / permissions

OSSEC files under `/var/ossec/` are owned by `root` and the `ossec` user. The MCP server must run with elevated privileges to read alerts, logs, rules, and configuration. Without `sudo`, most tools will return `Permission denied`.

There are two ways to handle this:

**Option A -- Inline password (simple, stores password in config):**

Use `sudo -S` to feed the password via stdin, then `exec sudo` to run the server with cached credentials:

```
echo '<PASSWORD>' | sudo -S true 2>/dev/null; exec sudo /path/to/ossec-mcp-server
```

The first command authenticates and caches the credential. The `exec sudo` then runs the server using the cached session -- keeping stdin free for the MCP stdio protocol.

**Option B -- Passwordless sudo (more secure, one-time setup):**

Add a sudoers rule that allows running only this one binary without a password:

```bash
echo 'YOUR_USER ALL=(ALL) NOPASSWD: /path/to/OSSEC_MCP_SERVER/.venv/bin/ossec-mcp-server' \
  | sudo tee /etc/sudoers.d/ossec-mcp
sudo chmod 440 /etc/sudoers.d/ossec-mcp
```

Then the config only needs `sudo` without any password handling:

```
sudo /path/to/ossec-mcp-server
```

All examples below use **Option A** (inline password). Replace `<PASSWORD>` with your Linux sudo password. If you prefer Option B, remove the `echo ... | sudo -S true 2>/dev/null;` prefix and use `sudo` directly.

---

### Integration with AI tools

OSSEC is a Linux HIDS. The MCP server needs access to the OSSEC installation -- either locally on the same Linux host, or remotely via the Wazuh/OSSEC REST API.

**If your editor is running on the same Linux machine as OSSEC**, the commands below work directly. **If your editor is on Windows/macOS and OSSEC is in WSL or a remote server**, see the "Windows with WSL" and "Remote / API mode" sections further down.

---

### VS Code (GitHub Copilot)

A ready-to-use config file is included at `.vscode/mcp.json`. After installing the package into the venv, VS Code will pick it up automatically when you open the project folder.

To configure it manually or in another project, create `.vscode/mcp.json`:

**Native Linux:**

```json
{
  "servers": {
    "ossec": {
      "type": "stdio",
      "command": "bash",
      "args": [
        "-c",
        "echo '<PASSWORD>' | sudo -S true 2>/dev/null; exec sudo /path/to/OSSEC_MCP_SERVER/.venv/bin/ossec-mcp-server"
      ],
      "env": {
        "OSSEC_PATH": "/var/ossec",
        "OSSEC_MODE": "local"
      }
    }
  }
}
```

**Windows with WSL:**

```json
{
  "servers": {
    "ossec": {
      "type": "stdio",
      "command": "wsl.exe",
      "args": [
        "-d", "kali-linux",
        "-e", "bash", "-c",
        "echo '<PASSWORD>' | sudo -S true 2>/dev/null; exec sudo /mnt/d/OSSEC_MCP_SERVER/.venv/bin/ossec-mcp-server"
      ],
      "env": {
        "OSSEC_PATH": "/var/ossec",
        "OSSEC_MODE": "local"
      }
    }
  }
}
```

Then in VS Code: open Copilot Chat, switch to **Agent** mode, and the OSSEC tools will be available.

---

### Claude Code (CLI)

A ready-to-use config file is included at `.mcp.json` in the project root. Claude Code reads this automatically when you run `claude` from this directory.

To add it manually:

```bash
claude mcp add ossec \
  -e OSSEC_PATH=/var/ossec \
  -e OSSEC_MODE=local \
  -- bash -c "echo '<PASSWORD>' | sudo -S true 2>/dev/null; exec sudo /path/to/OSSEC_MCP_SERVER/.venv/bin/ossec-mcp-server"
```

Or create/edit `.mcp.json` in the project root:

```json
{
  "mcpServers": {
    "ossec": {
      "command": "bash",
      "args": [
        "-c",
        "echo '<PASSWORD>' | sudo -S true 2>/dev/null; exec sudo /path/to/OSSEC_MCP_SERVER/.venv/bin/ossec-mcp-server"
      ],
      "env": {
        "OSSEC_PATH": "/var/ossec",
        "OSSEC_MODE": "local"
      }
    }
  }
}
```

For global availability across all projects, add to `~/.claude.json` instead.

---

### Claude Desktop

Edit the config file at:
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
- Linux: `~/.config/Claude/claude_desktop_config.json`

**Native Linux / macOS:**

```json
{
  "mcpServers": {
    "ossec": {
      "command": "bash",
      "args": [
        "-c",
        "echo '<PASSWORD>' | sudo -S true 2>/dev/null; exec sudo /path/to/OSSEC_MCP_SERVER/.venv/bin/ossec-mcp-server"
      ],
      "env": {
        "OSSEC_PATH": "/var/ossec",
        "OSSEC_MODE": "local"
      }
    }
  }
}
```

**Windows with WSL:**

```json
{
  "mcpServers": {
    "ossec": {
      "command": "wsl.exe",
      "args": [
        "-d", "kali-linux",
        "-e", "bash", "-c",
        "echo '<PASSWORD>' | sudo -S true 2>/dev/null; exec sudo /mnt/d/OSSEC_MCP_SERVER/.venv/bin/ossec-mcp-server"
      ],
      "env": {
        "OSSEC_PATH": "/var/ossec",
        "OSSEC_MODE": "local"
      }
    }
  }
}
```

---

### Cursor

A ready-to-use config file is included at `.cursor/mcp.json`. Cursor reads this automatically when you open the project.

To configure manually, create `.cursor/mcp.json` in the project root:

**Native Linux:**

```json
{
  "mcpServers": {
    "ossec": {
      "command": "bash",
      "args": [
        "-c",
        "echo '<PASSWORD>' | sudo -S true 2>/dev/null; exec sudo /path/to/OSSEC_MCP_SERVER/.venv/bin/ossec-mcp-server"
      ],
      "env": {
        "OSSEC_PATH": "/var/ossec",
        "OSSEC_MODE": "local"
      }
    }
  }
}
```

**Windows with WSL:**

```json
{
  "mcpServers": {
    "ossec": {
      "command": "wsl.exe",
      "args": [
        "-d", "kali-linux",
        "-e", "bash", "-c",
        "echo '<PASSWORD>' | sudo -S true 2>/dev/null; exec sudo /mnt/d/OSSEC_MCP_SERVER/.venv/bin/ossec-mcp-server"
      ],
      "env": {
        "OSSEC_PATH": "/var/ossec",
        "OSSEC_MODE": "local"
      }
    }
  }
}
```

---

### Windsurf

Edit `~/.codeium/windsurf/mcp_config.json`:

**Native Linux:**

```json
{
  "mcpServers": {
    "ossec": {
      "command": "bash",
      "args": [
        "-c",
        "echo '<PASSWORD>' | sudo -S true 2>/dev/null; exec sudo /path/to/OSSEC_MCP_SERVER/.venv/bin/ossec-mcp-server"
      ],
      "env": {
        "OSSEC_PATH": "/var/ossec",
        "OSSEC_MODE": "local"
      }
    }
  }
}
```

**Windows with WSL:**

```json
{
  "mcpServers": {
    "ossec": {
      "command": "wsl.exe",
      "args": [
        "-d", "kali-linux",
        "-e", "bash", "-c",
        "echo '<PASSWORD>' | sudo -S true 2>/dev/null; exec sudo /mnt/d/OSSEC_MCP_SERVER/.venv/bin/ossec-mcp-server"
      ],
      "env": {
        "OSSEC_PATH": "/var/ossec",
        "OSSEC_MODE": "local"
      }
    }
  }
}
```

---

### Windows with WSL (summary)

All the per-tool sections above already include **Windows with WSL** examples. The key pattern is:

```
wsl.exe -d <DISTRO> -e bash -c "echo '<PASSWORD>' | sudo -S true 2>/dev/null; exec sudo <ABSOLUTE_PATH_TO_SERVER>"
```

Replace:
- `<DISTRO>` with your WSL distro name (run `wsl -l` to list, e.g., `kali-linux`)
- `<PASSWORD>` with your Linux sudo password
- `<ABSOLUTE_PATH_TO_SERVER>` with the full path, e.g., `/mnt/d/OSSEC_MCP_SERVER/.venv/bin/ossec-mcp-server`

**Claude Code** (on Windows):

```bash
claude mcp add ossec \
  -e OSSEC_PATH=/var/ossec \
  -e OSSEC_MODE=local \
  -- wsl.exe -d kali-linux -e bash -c \
  "echo '<PASSWORD>' | sudo -S true 2>/dev/null; exec sudo /mnt/d/OSSEC_MCP_SERVER/.venv/bin/ossec-mcp-server"
```

---

### Remote / API mode

If OSSEC runs on a remote server and you cannot run the MCP server locally alongside it, use API mode. The MCP server connects to the Wazuh/OSSEC REST API over HTTPS:

```json
{
  "mcpServers": {
    "ossec": {
      "command": "/path/to/OSSEC_MCP_SERVER/.venv/bin/ossec-mcp-server",
      "env": {
        "OSSEC_MODE": "api",
        "OSSEC_API_HOST": "192.168.1.100",
        "OSSEC_API_PORT": "55000",
        "OSSEC_API_USER": "admin",
        "OSSEC_API_PASSWORD": "your-password",
        "OSSEC_API_SSL_VERIFY": "false"
      }
    }
  }
}
```

This works from any machine -- Windows, macOS, or Linux -- as long as it can reach the API endpoint over the network.

---

### SSE transport

For network-accessible deployment (e.g., shared MCP server for multiple clients):

```bash
MCP_TRANSPORT=sse MCP_HOST=0.0.0.0 MCP_PORT=8000 ossec-mcp-server
```

SSE binds to `127.0.0.1` by default. Set `MCP_HOST=0.0.0.0` explicitly to expose it externally.

## Connection Modes

### Local mode (default)

Interacts directly with OSSEC on the same host via:

- **CLI tools**: `ossec-control`, `manage_agents`, `agent_control`, `syscheck_control`, `rootcheck_control`, `ossec-logtest`
- **Filesystem**: Reads alerts (JSON and plain-text formats), internal logs, rule XML files, decoder XML files, and `ossec.conf` directly

Requires the server to run on the same machine as the OSSEC manager, or to have filesystem access to the OSSEC installation directory (e.g., via WSL mounts).

### API mode

Connects to the OSSEC/Wazuh REST API over HTTPS. Use this when the MCP server runs on a different machine than the OSSEC manager. Set `OSSEC_MODE=api` and configure the API connection variables. See the "Remote / API mode" example in the Usage section above.

## OSSEC Alert Levels Reference

| Level | Severity | Description |
|-------|----------|-------------|
| 0 | Ignored | Not classified |
| 1--3 | Low | System notifications, successful events |
| 4--6 | Medium | Errors, warnings, bad configurations |
| 7--9 | High | Bad words detected, first-time events |
| 10--11 | Very High | Multiple failures, integrity changes |
| 12--14 | Critical | Firewall drops, high-impact events |
| 15--16 | Severe | Attack success, critical integrity changes |

## Testing

The project includes four test suites (356 tests total):

```bash
# Activate the virtual environment
source .venv/bin/activate

# Unit and integration tests (167 tests)
python tests/test_comprehensive.py

# Security validation tests (72 tests)
python tests/test_security.py

# Live MCP protocol tests via official SDK client (105 tests)
python tests/test_mcp_sdk_protocol.py

# Live OSSEC integration tests (12 tests) -- requires a running OSSEC installation
sudo .venv/bin/python tests/test_live_ossec.py
```

The security tests validate input sanitization, path traversal prevention, XML safety (defusedxml), error message sanitization, timezone-aware datetime handling, boundary clamping, and exact group matching.

The MCP protocol tests spawn the server as a subprocess and connect a real MCP SDK client to verify initialization, tool listing, tool calls, resource reads, and prompt retrieval over the stdio transport.

The live OSSEC integration tests run the `OssecClient` directly against a real OSSEC installation, exercising service status, log retrieval, rule/decoder parsing, alert queries, syscheck, rootcheck, agent listing, stats, and configuration reads. These require `sudo` since OSSEC files are owned by the `ossec` user.

## Project Structure

```
OSSEC_MCP_SERVER/
├── pyproject.toml                  # Build config, dependencies, entry point
├── .env.example                    # Configuration template
├── .mcp.json                       # Claude Code MCP config (auto-detected)
├── .vscode/mcp.json                # VS Code MCP config (auto-detected)
├── .cursor/mcp.json                # Cursor MCP config (auto-detected)
├── README.md
├── .gitignore
├── src/
│   └── ossec_mcp/
│       ├── __init__.py             # Package version (1.0.0)
│       ├── __main__.py             # python -m ossec_mcp support
│       ├── server.py               # FastMCP server creation and entry point
│       ├── config.py               # Settings via pydantic-settings
│       ├── ossec_client.py         # OSSEC interaction layer (CLI + API)
│       ├── tools/
│       │   ├── alerts.py           # get_alerts, get_alert_summary, search_alerts
│       │   ├── agents.py           # list_agents, get_agent_info, add/remove/restart_agent
│       │   ├── rules.py            # get_rules, get_rule_details, list_rule_files, get_decoders
│       │   ├── syscheck.py         # get_syscheck_results, run_syscheck_scan, clear_syscheck_database
│       │   ├── rootcheck.py        # get_rootcheck_results, run_rootcheck_scan
│       │   ├── status.py           # get_ossec_status, restart_ossec, logs, stats, config
│       │   ├── logtest.py          # run_logtest
│       │   └── active_response.py  # get_active_responses, run_active_response
│       ├── resources/
│       │   └── providers.py        # 8 static resources + 3 resource templates
│       └── prompts/
│           └── templates.py        # 5 prompt templates
└── tests/
    ├── test_comprehensive.py       # 167 unit/integration tests
    ├── test_security.py            # 72 security validation tests
    ├── test_mcp_sdk_protocol.py    # 105 live MCP protocol tests
    └── test_live_ossec.py          # 12 live OSSEC integration tests
```

## License

[MIT](https://github.com/president-xd/ossec-mcp/blob/main/LICENSE)

TDQS

A4.1/5.0

Scored across 26 tools

Disambiguation5/5

Each tool targets a distinct OSSEC functionality or resource. Even closely related tools like get_alerts, search_alerts, and get_alert_summary have clearly separate purposes (recent retrieval, free-text search, summary aggregation). There is no meaningful overlap between any tools.

Naming Consistency5/5

All tools follow a consistent verb_noun pattern in snake_case (e.g., add_agent, get_alerts, run_syscheck_scan). The verbs are descriptive and the nouns are the OSSEC resources. No mixed conventions or irregular names.

Tool Count5/5

With 26 tools, the server covers the full OSSEC management surface—agents, alerts, rules, syscheck, rootcheck, configuration, active responses, logs, stats, and status. Each tool serves a necessary purpose without redundancy, making the set well-scoped for a security monitoring MCP.

Completeness4/5

The tool set provides comprehensive CRUD-like operations for most OSSEC domains, including agent lifecycle, alert analysis, rule management, and scans. Minor gaps exist (e.g., no agent key revocation, no agent rekeying), but these are not critical for typical management workflows.

Maintenance

ActivityInactive
ResponsivenessNo issues