# MCP Zabbix [![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![MCP](https://img.shields.io/badge/Model%20Context%20Protocol-1.10%2B-8A2BE2.svg)](https://modelcontextprotocol.io) [![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff) [![Type-checked: mypy](https://img.shields.io/badge/type--checked-mypy-1f5082.svg)](https://mypy-lang.org/) A production-grade [Model Context Protocol](https://modelcontextprotocol.io) server that bridges the Zabbix monitoring API with AI assistants such as Claude Desktop, Cursor, and any other MCP-compatible client. Built on `FastMCP` with an async `httpx` client, typed Pydantic models, structured logging, and a trend-graph renderer that returns both an on-disk PNG and a base64 payload for inline display. --- ## Table of contents - [Architecture](#architecture) - [Highlights](#highlights) - [Available tools](#available-tools) - [Project layout](#project-layout) - [Quick start](#quick-start) - [Local (pip)](#local-pip) - [Local (uv)](#local-uv) - [Docker](#docker) - [Configuration](#configuration) - [MCP client setup](#mcp-client-setup) - [Usage examples](#usage-examples) - [Development](#development) - [License](#license) --- ## Architecture ``` ┌─────────────────────────────────────┐ │ AI Assistant / MCP Client │ │ (Claude Desktop, Cursor, etc.) │ └────────────────┬────────────────────┘ │ │ MCP stdio (JSON-RPC) ▼ ┌──────────────────────────────────────────────────────────┐ │ FastMCP server (main.py) │ │ ┌────────────────────────────────────────────────────┐ │ │ │ @mcp.tool registrations → async handlers │ │ │ └────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌──────────────────┐ ┌────────────┐ ┌──────────────┐ │ │ │ ZabbixClient │ │ Email │ │ Graph │ │ │ │ (httpx async, │ │ (smtplib │ │ (matplotlib │ │ │ │ retry, auth) │ │ thread) │ │ PNG+b64) │ │ │ └────────┬─────────┘ └─────┬──────┘ └──────┬───────┘ │ │ │ │ │ │ │ ┌────────┴──────────────────┴────────────────┴──────┐ │ │ │ core/ : Settings • Logger • Exceptions │ │ │ └───────────────────────────────────────────────────┘ │ └────────────┬────────────────────────┬────────────────────┘ │ │ ▼ ▼ ┌────────────────┐ ┌──────────────────┐ │ Zabbix API │ │ SMTP (Gmail) │ │ (JSON-RPC) │ │ │ └────────────────┘ └──────────────────┘ ``` A request from the AI assistant arrives over MCP stdio, is routed to an async tool handler, which delegates to the service layer (`ZabbixClient`, email, graph). Every layer pulls its configuration from a single `pydantic-settings` Settings object and logs through one rotating handler. --- ## Highlights - **Fully async** — `httpx.AsyncClient` with bearer-token auth, configurable timeout, and exponential-backoff retries for transient failures. - **Typed boundaries** — Pydantic v2 models validate tool inputs (emails, IP addresses, time ranges) before they reach the network. - **Single source of truth for config** — `pydantic-settings` reads from process env then `.env`; secrets are wrapped in `SecretStr`. - **Stdio-safe logging** — rotating file handler + `stderr` stream (never pollutes the MCP protocol on `stdout`). - **Graph rendering** — saves a PNG to disk **and** returns base64 so MCP clients can render inline without a second round-trip. - **Graceful degradation** — the email tool is automatically disabled when SMTP credentials are missing, returning a structured error rather than crashing the server. - **Tested** — async pytest suite with `respx`-mocked HTTP, no real Zabbix required for CI. --- ## Available tools | Tool | Signature | Description | | ---- | --------- | ----------- | | `get_zabbix_host` | `()` | List hosts with interfaces, groups, and tags. | | `get_zabbix_host_group` | `()` | List host groups. | | `get_zabbix_host_by_group` | `(group_id: str)` | Hosts within a group. | | `get_zabbix_item` | `(host_id: str)` | Items configured on a host. | | `get_zabbix_problem` | `()` | Current problems (most recent first). | | `get_zabbix_problem_by_host` | `(host_id: str)` | Problems for a single host. | | `get_zabbix_trend` | `(item_id, start_time, end_time)` | Trend rows for an item. | | `get_zabbix_user` | `()` | Users with roles and access flags. | | `get_zabbix_proxy` | `()` | Proxy inventory. | | `get_zabbix_ha_cluster_nodes` | `()` | HA cluster node state. | | `create_zabbix_host` | `(hostname, ip, group_ids, ...)` | Create a host (agent/snmp/ipmi/jmx). | | `send_email_tool` | `(to_email, subject, body)` | Send via SMTP. | | `construct_graph` | `(item_id, start_time, end_time, item_name)` | Render trend chart (PNG + base64). | All Zabbix tools return the raw `result` payload from the JSON-RPC response. On failure they return a structured `{"error": ..., "type": ...}` envelope rather than throwing. --- ## Project layout ``` mcp_zabbix/ ├── src/mcp_zabbix/ │ ├── __init__.py │ ├── main.py # FastMCP entrypoint + tool registrations │ ├── core/ │ │ ├── config.py # pydantic-settings (env + .env) │ │ ├── logging.py # rotating file + stderr handlers │ │ └── exceptions.py # ZabbixAPIError / EmailError / GraphError │ ├── models/ │ │ └── zabbix.py # Pydantic schemas for tool I/O │ └── services/ │ ├── zabbix.py # async ZabbixClient (retry, auth) │ ├── email.py # SMTP wrapper (asyncio.to_thread) │ └── graph.py # matplotlib renderer (PNG + base64) ├── tests/ │ ├── conftest.py # autouse env stubbing │ ├── test_config.py │ ├── test_zabbix_client.py # respx-mocked HTTP │ └── test_graph.py ├── Dockerfile # python:3.12-slim, non-root user ├── docker-compose.yml # mounts ./logs and ./output ├── pyproject.toml # hatchling build, dev extras, ruff/mypy ├── requirements.txt # mirror of runtime deps for pip users ├── run.sh # convenience launcher (loads .env) ├── .env.example └── LICENSE ``` --- ## Quick start ### Prerequisites - Python **3.10 or newer** - A reachable Zabbix server with a valid API token - (Optional) Gmail / SMTP credentials for the email tool ### Local (pip) ```bash git clone https://github.com/badoss/mcp_zabbix.git cd mcp_zabbix python -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate pip install -e ".[dev]" cp .env.example .env # edit ZABBIX_API_URL / TOKEN ./run.sh # or: mcp-zabbix ``` ### Local (uv) [`uv`](https://docs.astral.sh/uv/) is a fast Rust-based replacement for pip: ```bash uv sync # installs runtime deps uv sync --extra dev # add dev tooling cp .env.example .env uv run mcp-zabbix ``` ### Docker ```bash cp .env.example .env # edit secrets docker compose up --build ``` `./logs` and `./output` are mounted into the container so log files and generated PNGs persist on the host. --- ## Configuration All settings come from environment variables. A `.env` file in the project root is loaded automatically. Full list (see [`.env.example`](.env.example)): ### Zabbix | Variable | Default | Description | | -------- | ------- | ----------- | | `ZABBIX_API_URL` | — *(required)* | Full URL to `api_jsonrpc.php`. | | `ZABBIX_API_TOKEN` | — *(required)* | Bearer token (stored as `SecretStr`). | | `ZABBIX_REQUEST_TIMEOUT` | `30` | HTTP timeout in seconds. | | `ZABBIX_MAX_RETRIES` | `3` | Transient-failure retry budget. | ### SMTP (optional) | Variable | Default | Description | | -------- | ------- | ----------- | | `SMTP_HOST` | `smtp.gmail.com` | SMTP server host. | | `SMTP_PORT` | `587` | SMTP server port (STARTTLS). | | `SMTP_USER` | _empty_ | Login user; **required to enable email**. | | `SMTP_PASSWORD` | _empty_ | Login password or Gmail app password. | | `SMTP_FROM_NAME` | `MCP Zabbix` | Display name in the `From` header. | > **Gmail note:** enable 2FA and create an *app password* — > regular account passwords are no longer accepted by Google's SMTP. ### Runtime | Variable | Default | Description | | -------- | ------- | ----------- | | `LOG_LEVEL` | `INFO` | `DEBUG` / `INFO` / `WARNING` / `ERROR` / `CRITICAL`. | | `LOG_DIR` | `logs` | Rotating log directory (`5 MB × 3 backups`). | | `GRAPH_OUTPUT_DIR` | `output` | Where trend PNGs are written. | --- ## MCP client setup ### Claude Desktop / Cursor (uv launcher) `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows): ```json { "mcpServers": { "mcp-zabbix": { "command": "uv", "args": [ "run", "--directory", "/absolute/path/to/mcp_zabbix", "mcp-zabbix" ] } } } ``` ### pip-installed virtualenv ```json { "mcpServers": { "mcp-zabbix": { "command": "/absolute/path/to/mcp_zabbix/.venv/bin/mcp-zabbix" } } } ``` ### Docker ```json { "mcpServers": { "mcp-zabbix": { "command": "docker", "args": ["compose", "-f", "/absolute/path/to/docker-compose.yml", "run", "--rm", "mcp-zabbix"] } } } ``` Restart your MCP client after editing the config — the tools should then show up in its tool palette. --- ## Usage examples Once connected, prompt your assistant in plain language; it will pick the right tool automatically. **List monitored hosts** > Show me every Zabbix host along with its group memberships. **Investigate problems on a host** > What active problems does host `10084` have? Group them by severity. **Render a trend chart** > Plot the last 24 hours of CPU utilization for item `50134` and call the > chart "Web-01 CPU". The `construct_graph` tool returns the on-disk path plus a base64-encoded PNG — most MCP clients will render the chart inline. **Send an alert email** > Email `oncall@example.com` with subject "P1: DB latency" and a one-line > body describing the current problem. The email tool returns `{"status": "sent", ...}` on success, or a structured error envelope if SMTP isn't configured. --- ## Development ```bash pip install -e ".[dev]" # run the test suite (async + respx-mocked HTTP) pytest # lint & format ruff check src tests ruff format src tests # strict type-check mypy src ``` The test suite uses `pytest-asyncio` (auto mode) and `respx` to mock `httpx`. No real Zabbix server is required for CI. To run the server against your local Zabbix: ```bash cp .env.example .env $EDITOR .env ./run.sh ``` --- ## License Released under the [MIT License](LICENSE). ## Support - **Bug reports & feature requests:** [GitHub Issues](https://github.com/badoss/mcp_zabbix/issues) - **Zabbix API reference:** - **MCP specification:**