Skip to main content
Glama

Wazuh MCP Server

by gensecaihq
setup-monorepo.py11.4 kB
#!/usr/bin/env python3 """ Wazuh MCP Server - Monorepo Setup Tool Converts the current dual-branch structure into a monorepo with shared core. """ import os import shutil import subprocess import sys from pathlib import Path from typing import List, Dict class MonorepoConverter: """Converts Wazuh MCP Server to monorepo architecture.""" def __init__(self, repo_root: Path): self.repo_root = repo_root self.packages_dir = repo_root / "packages" def setup_directory_structure(self): """Create the new monorepo directory structure.""" print("🏗️ Creating monorepo directory structure...") # Create main packages directory self.packages_dir.mkdir(exist_ok=True) # Create package subdirectories for package in ["core", "stdio", "remote"]: package_dir = self.packages_dir / package package_dir.mkdir(exist_ok=True) # Create src directory for each package src_dir = package_dir / "src" src_dir.mkdir(exist_ok=True) print(f" ✓ Created packages/{package}/src/") def extract_core_components(self): """Extract shared components to core package.""" print("📦 Extracting core components...") # Define what goes into core core_modules = [ "api/", "analyzers/", "tools/", "utils/", "config.py" ] src_dir = Path("src/wazuh_mcp_server") core_src = self.packages_dir / "core" / "src" / "wazuh_mcp_core" core_src.mkdir(exist_ok=True) # Copy core modules for module in core_modules: src_path = src_dir / module if src_path.exists(): dest_path = core_src / module if src_path.is_dir(): shutil.copytree(src_path, dest_path, dirs_exist_ok=True) else: shutil.copy2(src_path, dest_path) print(f" ✓ Extracted {module}") # Create core __init__.py init_file = core_src / "__init__.py" init_file.write_text('"""Wazuh MCP Core - Shared library for all transports."""\n__version__ = "1.0.0"\n') def create_stdio_package(self): """Create STDIO transport package.""" print("📡 Creating STDIO transport package...") stdio_src = self.packages_dir / "stdio" / "src" / "wazuh_mcp_stdio" stdio_src.mkdir(exist_ok=True) # Copy STDIO-specific files from main branch stdio_files = [ "server.py", "main.py", "__init__.py", "__version__.py" ] src_dir = Path("src/wazuh_mcp_server") for file in stdio_files: src_file = src_dir / file if src_file.exists(): dest_file = stdio_src / file shutil.copy2(src_file, dest_file) print(f" ✓ Copied {file}") # Create STDIO-specific transport adapter transport_dir = stdio_src / "transport" transport_dir.mkdir(exist_ok=True) adapter_code = '''"""STDIO Transport Adapter for Wazuh MCP.""" import json from typing import Any, Dict from wazuh_mcp_core.tools.base import WazuhTool class STDIOToolAdapter: """Adapts core tools for FastMCP STDIO transport.""" def __init__(self, mcp_app): self.mcp_app = mcp_app def register_tool(self, tool_instance: WazuhTool): """Register a core tool with FastMCP.""" @self.mcp_app.tool(**tool_instance.schema) async def tool_wrapper(**kwargs) -> str: result = await tool_instance.execute(**kwargs) return json.dumps(result, indent=2) return tool_wrapper ''' (transport_dir / "adapter.py").write_text(adapter_code) (transport_dir / "__init__.py").write_text("") def create_remote_package(self): """Create Remote transport package (from mcp-remote branch).""" print("🌐 Creating Remote transport package...") remote_src = self.packages_dir / "remote" / "src" / "wazuh_mcp_remote" remote_src.mkdir(exist_ok=True) # Note: This would need to be run when on mcp-remote branch # or files copied from that branch print(" ℹ️ Remote package structure created (files need to be copied from mcp-remote branch)") def create_pyproject_configs(self): """Create pyproject.toml for each package.""" print("⚙️ Creating package configurations...") # Core package config core_config = '''[build-system] requires = ["setuptools>=64", "wheel"] build-backend = "setuptools.build_meta" [project] name = "wazuh-mcp-core" version = "1.0.0" description = "Shared core library for Wazuh MCP implementations" readme = "README.md" license = {text = "MIT"} authors = [{name = "GenSec AI Team"}] keywords = ["wazuh", "security", "mcp", "core"] requires-python = ">=3.11" dependencies = [ "aiohttp>=3.12.14,<4.0.0", "pydantic>=2.11.7,<3.0.0", "python-dotenv>=1.1.1,<2.0.0", "python-dateutil>=2.9.0", "psutil>=7.0.0", ] [project.urls] Homepage = "https://github.com/gensecaihq/Wazuh-MCP-Server" Repository = "https://github.com/gensecaihq/Wazuh-MCP-Server" [tool.setuptools] package-dir = {"" = "src"} [tool.setuptools.packages.find] where = ["src"] include = ["wazuh_mcp_core*"] ''' # STDIO package config stdio_config = '''[build-system] requires = ["setuptools>=64", "wheel"] build-backend = "setuptools.build_meta" [project] name = "wazuh-mcp-stdio" version = "2.1.0" description = "FastMCP STDIO transport for Wazuh SIEM integration" readme = "README.md" license = {text = "MIT"} authors = [{name = "GenSec AI Team"}] keywords = ["wazuh", "security", "mcp", "stdio", "fastmcp"] requires-python = ">=3.11" dependencies = [ "wazuh-mcp-core>=1.0.0,<2.0.0", "fastmcp>=2.10.6", ] [project.scripts] wazuh-mcp-server = "wazuh_mcp_stdio.main:main" [project.urls] Homepage = "https://github.com/gensecaihq/Wazuh-MCP-Server" Repository = "https://github.com/gensecaihq/Wazuh-MCP-Server" [tool.setuptools] package-dir = {"" = "src"} [tool.setuptools.packages.find] where = ["src"] include = ["wazuh_mcp_stdio*"] ''' # Remote package config remote_config = '''[build-system] requires = ["setuptools>=64", "wheel"] build-backend = "setuptools.build_meta" [project] name = "wazuh-mcp-remote" version = "3.0.0" description = "Remote MCP server with HTTP/SSE transport for Wazuh" readme = "README.md" license = {text = "MIT"} authors = [{name = "GenSec AI Team"}] keywords = ["wazuh", "security", "mcp", "remote", "sse", "http"] requires-python = ">=3.11" dependencies = [ "wazuh-mcp-core>=1.0.0,<2.0.0", "fastapi>=0.115.0", "uvicorn[standard]>=0.32.0", "prometheus-client>=0.20.0", "python-jose[cryptography]>=3.3.0", "passlib[bcrypt]>=1.7.4", ] [project.scripts] wazuh-mcp-remote = "wazuh_mcp_remote.main:main" [project.urls] Homepage = "https://github.com/gensecaihq/Wazuh-MCP-Server" Repository = "https://github.com/gensecaihq/Wazuh-MCP-Server" [tool.setuptools] package-dir = {"" = "src"} [tool.setuptools.packages.find] where = ["src"] include = ["wazuh_mcp_remote*"] ''' # Write configs (self.packages_dir / "core" / "pyproject.toml").write_text(core_config) (self.packages_dir / "stdio" / "pyproject.toml").write_text(stdio_config) (self.packages_dir / "remote" / "pyproject.toml").write_text(remote_config) print(" ✓ Created pyproject.toml for all packages") def create_ci_workflows(self): """Create GitHub Actions workflows for each package.""" print("🔄 Creating CI/CD workflows...") workflows_dir = Path(".github/workflows") workflows_dir.mkdir(parents=True, exist_ok=True) # Multi-package test workflow test_workflow = '''name: Multi-Package Tests on: push: branches: [ main, develop ] pull_request: branches: [ main ] jobs: test: strategy: matrix: package: [core, stdio] python-version: ["3.11", "3.12"] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - name: Install dependencies for ${{ matrix.package }} run: | cd packages/${{ matrix.package }} python -m pip install --upgrade pip pip install -e . pip install pytest pytest-asyncio - name: Test ${{ matrix.package }} run: | cd packages/${{ matrix.package }} pytest tests/ -v ''' (workflows_dir / "packages.yml").write_text(test_workflow) print(" ✓ Created GitHub Actions workflow") def update_imports(self): """Update import statements to use new package structure.""" print("🔧 Updating import statements...") # This would require more sophisticated AST manipulation # For now, just create guidance guidance = ''' # Import Update Guide ## Old imports (main branch): from wazuh_mcp_server.api.wazuh_client import WazuhClient from wazuh_mcp_server.analyzers.security_analyzer import SecurityAnalyzer ## New imports (monorepo): from wazuh_mcp_core.api.wazuh_client import WazuhClient from wazuh_mcp_core.analyzers.security_analyzer import SecurityAnalyzer # STDIO transport: from wazuh_mcp_stdio.server import mcp from wazuh_mcp_stdio.transport.adapter import STDIOToolAdapter # Remote transport: from wazuh_mcp_remote.server import app from wazuh_mcp_remote.transport.adapter import RemoteToolAdapter ''' (self.packages_dir / "IMPORT_GUIDE.md").write_text(guidance) print(" ✓ Created import update guide") def run_conversion(self): """Run the complete monorepo conversion.""" print("🚀 Starting monorepo conversion...") print("="*50) try: self.setup_directory_structure() self.extract_core_components() self.create_stdio_package() self.create_remote_package() self.create_pyproject_configs() self.create_ci_workflows() self.update_imports() print("="*50) print("✅ Monorepo conversion completed successfully!") print(f"📁 New structure created in: {self.packages_dir}") print("\n📋 Next steps:") print("1. Review the generated package structure") print("2. Copy remote branch files to packages/remote/") print("3. Update import statements throughout the codebase") print("4. Test each package independently") print("5. Update documentation") except Exception as e: print(f"❌ Error during conversion: {e}") sys.exit(1) if __name__ == "__main__": repo_root = Path(__file__).parent.parent converter = MonorepoConverter(repo_root) converter.run_conversion()

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/gensecaihq/Wazuh-MCP-Server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server