
Wazuh
STDIOProduction-ready MCP server integrating Wazuh SIEM with LLMs for security data analysis
Production-ready MCP server integrating Wazuh SIEM with LLMs for security data analysis
A production-ready Model Context Protocol (MCP) server for seamless integration between Wazuh SIEM and Large Language Models (LLMs).
Why? Combine the power of Wazuh's comprehensive security monitoring with the reasoning capabilities of large language models—enabling natural language queries and intelligent analysis of your security data.
python -m venv .venv && source .venv/bin/activate pip install git+https://github.com/socfortress/wazuh-mcp-server.git
.whl
filepip install wazuh_mcp_server-*.whl
python-package-distributions
artifactpip install wazuh_mcp_server-*.whl
Create a .env
file in your project directory:
# Wazuh Manager Configuration WAZUH_PROD_URL=https://your-wazuh-manager:55000 WAZUH_PROD_USERNAME=your-username WAZUH_PROD_PASSWORD=your-password WAZUH_PROD_SSL_VERIFY=false WAZUH_PROD_TIMEOUT=30 # MCP Server Configuration MCP_SERVER_HOST=127.0.0.1 MCP_SERVER_PORT=8000 # Logging Configuration LOG_LEVEL=INFO # Tool Filtering (optional) # WAZUH_DISABLED_TOOLS=DeleteAgentTool,RestartManagerTool # WAZUH_DISABLED_CATEGORIES=dangerous,write # WAZUH_READ_ONLY=false
# Using the CLI command wazuh-mcp-server # Or using the Python module python -m wazuh_mcp_server # With custom configuration wazuh-mcp-server --host 0.0.0.0 --port 8080 --log-level DEBUG
The server will start and be available at http://127.0.0.1:8000
(or your configured host/port).
git clone https://github.com/socfortress/wazuh-mcp-server.git cd wazuh-mcp-server # Create virtual environment python -m venv .venv source .venv/bin/activate # On Windows: .venv\Scripts\activate # Install in development mode pip install -e ".[dev]" # Install pre-commit hooks (optional) pre-commit install
Variable | Description | Default | Required |
---|---|---|---|
WAZUH_PROD_URL | Wazuh Manager API URL | None | ✅ |
WAZUH_PROD_USERNAME | Wazuh username | None | ✅ |
WAZUH_PROD_PASSWORD | Wazuh password | None | ✅ |
WAZUH_PROD_SSL_VERIFY | SSL verification | true | ❌ |
WAZUH_PROD_TIMEOUT | Request timeout (seconds) | 30 | ❌ |
MCP_SERVER_HOST | Server host | 127.0.0.1 | ❌ |
MCP_SERVER_PORT | Server port | 8000 | ❌ |
LOG_LEVEL | Logging level | INFO | ❌ |
WAZUH_DISABLED_TOOLS | Comma-separated list of disabled tools | None | ❌ |
WAZUH_DISABLED_CATEGORIES | Comma-separated list of disabled categories | None | ❌ |
WAZUH_READ_ONLY | Enable read-only mode | false | ❌ |
wazuh-mcp-server --help
Available options:
--host
: Host to bind server to (default: 127.0.0.1)--port
: Port to bind server to (default: 8000)--log-level
: Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)--wazuh-url
: Wazuh Manager URL (overrides env var)--wazuh-username
: Wazuh username (overrides env var)--wazuh-password
: Wazuh password (overrides env var)--no-ssl-verify
: Disable SSL certificate verificationfrom wazuh_mcp_server import Config, create_server # Create server with environment configuration config = Config.from_env() server = create_server(config) # Start the server server.start()
from wazuh_mcp_server.config import WazuhConfig, ServerConfig, Config # Create custom configuration wazuh_config = WazuhConfig( url="https://your-wazuh-manager:55000", username="admin", password="password", ssl_verify=False ) server_config = ServerConfig( host="0.0.0.0", port=8080, log_level="DEBUG" ) config = Config(wazuh=wazuh_config, server=server_config) server = create_server(config)
from langchain_mcp_adapters.client import MultiServerMCPClient from langchain_openai import ChatOpenAI from langchain.agents import AgentType, initialize_agent # Initialize LLM model = ChatOpenAI(model="gpt-4") # Connect to Wazuh MCP server client = MultiServerMCPClient({ "wazuh-mcp-server": { "transport": "sse", "url": "http://127.0.0.1:8000/sse/", } }) # Get tools and create agent tools = await client.get_tools() agent = initialize_agent( tools=tools, llm=model, agent=AgentType.OPENAI_FUNCTIONS, verbose=True ) # Query your Wazuh data response = await agent.ainvoke({ "input": "Show me all active agents and their status" }) # Get network ports information ports_response = await agent.ainvoke({ "input": "Show me all listening TCP ports on agent 000" })
The server exposes the following MCP tools:
status
(optional): Filter by agent status (e.g., ["active"])limit
(optional): Maximum number of agents to return (default: 500)offset
(optional): Offset for pagination (default: 0)agent_id
(required): Agent ID to get ports fromlimit
(optional): Maximum number of ports to return (default: 500)offset
(optional): Offset for pagination (default: 0)protocol
(optional): Filter by protocol (tcp, udp)local_ip
(optional): Filter by local IP addresslocal_port
(optional): Filter by local portremote_ip
(optional): Filter by remote IP addressstate
(optional): Filter by state (listening, established, etc.)process
(optional): Filter by process namepid
(optional): Filter by process IDtx_queue
(optional): Filter by tx_queuesort
(optional): Sort results by field(s)search
(optional): Search for elements containing the specified stringselect
(optional): Select which fields to returnq
(optional): Query to filter results bydistinct
(optional): Look for distinct valuesagent_id
(required): Agent ID to get packages fromlimit
(optional): Maximum number of packages to return (default: 500)offset
(optional): Offset for pagination (default: 0)vendor
(optional): Filter by package vendorname
(optional): Filter by package namearchitecture
(optional): Filter by package architectureformat
(optional): Filter by package format (e.g., 'deb', 'rpm')version
(optional): Filter by package versionsort
(optional): Sort results by field(s)search
(optional): Search for elements containing the specified stringselect
(optional): Select which fields to returnq
(optional): Query to filter results bydistinct
(optional): Look for distinct valuesagent_id
(required): Agent ID to get processes fromlimit
(optional): Maximum number of processes to return (default: 500)offset
(optional): Offset for pagination (default: 0)pid
(optional): Filter by process PIDstate
(optional): Filter by process stateppid
(optional): Filter by process parent PIDegroup
(optional): Filter by process egroupeuser
(optional): Filter by process euserfgroup
(optional): Filter by process fgroupname
(optional): Filter by process namenlwp
(optional): Filter by process nlwppgrp
(optional): Filter by process pgrppriority
(optional): Filter by process priorityrgroup
(optional): Filter by process rgroupruser
(optional): Filter by process rusersgroup
(optional): Filter by process sgroupsuser
(optional): Filter by process susersort
(optional): Sort results by field(s)search
(optional): Search for elements containing the specified stringselect
(optional): Select which fields to returnq
(optional): Query to filter results bydistinct
(optional): Look for distinct valuesrule_ids
(optional): List of rule IDs to filter bylimit
(optional): Maximum number of rules to return (default: 500)offset
(optional): Offset for pagination (default: 0)select
(optional): Select which fields to returnsort
(optional): Sort results by field(s)search
(optional): Search for elements containing the specified stringq
(optional): Query to filter results bystatus
(optional): Filter by status (enabled, disabled, all)group
(optional): Filter by rule grouplevel
(optional): Filter by rule level (e.g., '4' or '2-4')filename
(optional): Filter by filenamerelative_dirname
(optional): Filter by relative directory namepci_dss
(optional): Filter by PCI_DSS requirementgdpr
(optional): Filter by GDPR requirementgpg13
(optional): Filter by GPG13 requirementhipaa
(optional): Filter by HIPAA requirementnist_800_53
(optional): Filter by NIST-800-53 requirementtsc
(optional): Filter by TSC requirementmitre
(optional): Filter by MITRE technique IDdistinct
(optional): Look for distinct valuesfilename
(required): Filename of the rule file to get content fromraw
(optional): Format response in plain text (default: false)relative_dirname
(optional): Filter by relative directory nameagent_id
(required): Agent ID to get SCA results fromname
(optional): Filter by policy namedescription
(optional): Filter by policy descriptionreferences
(optional): Filter by referenceslimit
(optional): Maximum number of SCA policies to return (default: 500)offset
(optional): Offset for pagination (default: 0)sort
(optional): Sort results by field(s)search
(optional): Search for elements containing the specified stringselect
(optional): Select which fields to returnq
(optional): Query to filter results bydistinct
(optional): Look for distinct valuesgit clone https://github.com/socfortress/wazuh-mcp-server.git cd wazuh-mcp-server # Create virtual environment python -m venv .venv source .venv/bin/activate # Install in development mode with dev dependencies pip install -e ".[dev]" # Install pre-commit hooks pre-commit install
# Run all tests pytest # Run with coverage pytest --cov=wazuh_mcp_server # Run specific test file pytest tests/test_client.py # Run with verbose output pytest -v
# Install build dependencies pip install build twine # Build the package python -m build # Check the package twine check dist/* # Test installation pip install dist/*.whl
This project uses GitHub Actions for automated building and testing:
main
and develop
branches triggers a buildCreate and push a git tag:
git tag v1.0.0 git push origin v1.0.0
The GitHub Action will automatically:
Visit the Actions page and download the python-package-distributions
artifact from any successful build.
WAZUH_PROD_SSL_VERIFY=true
)WAZUH_READ_ONLY=true
when write operations aren't neededWAZUH_DISABLED_TOOLS
wazuh-mcp-server/
├── wazuh_mcp_server/ # Main package
│ ├── __init__.py # Package initialization
│ ├── __main__.py # CLI entry point
│ ├── client.py # Wazuh API client
│ ├── config.py # Configuration management
│ ├── server.py # MCP server implementation
│ └── exceptions.py # Custom exceptions
├── tests/ # Test suite
│ ├── conftest.py # Test configuration
│ ├── test_client.py # Client tests
│ ├── test_config.py # Configuration tests
│ └── test_server.py # Server tests
├── .github/workflows/ # GitHub Actions
│ └── publish.yml # CI/CD pipeline
├── requirements.txt # Dependencies
├── pyproject.toml # Package configuration
├── .env.example # Environment template
├── Dockerfile # Docker configuration
└── README.md # This file
We welcome contributions! Please follow these steps:
git checkout -b feature/amazing-feature
)pytest
black .
, isort .
, flake8 .
git commit -m 'Add amazing feature'
)git push origin feature/amazing-feature
)This project is licensed under the MIT License - see the LICENSE file for details.
Made with ❤️ by SOCFortress