{
  "markdown": "# Zabbix AI CLI MCP — Zabbix MCP server and CLI for AI agents\n\n[![CI](https://github.com/stufently/zabbix-ai-cli-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/stufently/zabbix-ai-cli-mcp/actions/workflows/ci.yml)\n[![Go Reference](https://pkg.go.dev/badge/github.com/stufently/zabbix-ai-cli-mcp.svg)](https://pkg.go.dev/github.com/stufently/zabbix-ai-cli-mcp)\n[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)\n[![Zabbix](https://img.shields.io/badge/Zabbix-6.4%2B-red.svg)](#compatibility)\n[![MCP](https://img.shields.io/badge/MCP-stdio%20%7C%20streamable%20HTTP-green.svg)](docs/mcp.md)\n\n**`zabbix-ai-cli-mcp` is a Zabbix MCP server and command-line client in one Go\nbinary.** It gives Claude Code, Claude Desktop, Codex, Cursor and any other\nModel Context Protocol client task-shaped access to Zabbix — what is broken\nright now, why a host is silent, why an alert never arrived — with bounded\noutput, a stable JSON contract, and no change to Zabbix without a person's\napproval.\n\nIt is for the people who get paged: SRE and DevOps teams running Zabbix who want\nan agent to triage an incident without handing it the whole API.\n\n**Requires Zabbix 6.4 or newer.** Bearer-token authentication arrived in 6.4 and\nis the only scheme implemented; earlier versions expect the token in the request\nbody instead.\n\nIt never contacts a language model. The AI decides, this program executes,\nZabbix monitors.\n\n```bash\nzabbix-ai-cli-mcp login\nzabbix-ai-cli-mcp problems list\nzabbix-ai-cli-mcp host investigate server01\nzabbix-ai-cli-mcp alert why 757474\nzabbix-ai-cli-mcp mcp\n```\n\n## Why not another Zabbix API wrapper\n\nWrapping `host.get`, `problem.get` and `history.get` hands the agent the API's\nsharp edges along with its power. On a current Zabbix 7.4 server:\n\n- `problem.get` has no `selectHosts`, so a problem list arrives without hosts.\n- `history.get` defaults to the numeric-unsigned table and returns **nothing** for\n  a float item — silently, with no error.\n- `item.lastvalue` and `item.lastclock` still exist and have returned a constant\n  `\"0\"` for several major releases.\n- `host.available` was removed in 5.4; availability lives on the interface.\n- `event.acknowledge` takes a bitmask whose own documentation contradicts itself.\n- `searchWildcardsEnabled: true` **disables** implicit substring matching, turning\n  a name fragment into an exact match that quietly finds nothing.\n\nEvery one of those produces a confident, wrong answer rather than an error. This\ntool absorbs them behind commands that describe the task instead of the endpoint.\n\n## What it does\n\n| Command | Answers |\n| --- | --- |\n| `problems list` | What is broken now — including suppressed problems, with the maintenance window that hides them named |\n| `host investigate` | One call: host state, active problems, recent events, silent and unsupported items, maintenance |\n| `host status` | A handful of fields instead of twelve thousand characters of configuration |\n| `alert why` | Why a notification did or did not arrive — suppression, delivery attempts, actions, media types, per-recipient severity filters |\n| `resolve` | Turns a notification pasted out of chat into event, host and trigger identifiers |\n| `unreachable` | Monitored hosts Zabbix cannot poll, with the error it recorded |\n| `metrics latest` / `history` | Values with the right history type, human units and `min/avg/max` |\n| `maintenance` | Open, extend, end or remove windows, with host patterns like `ms*` |\n| `api call` | The escape hatch, under the same rules |\n\n## Safety\n\nRead operations always run immediately. Whether anything else does is one\nsetting, `allow_write`, and it is **on by default**.\n\n```toml\n# ~/.config/zabbix-ai-cli-mcp/config.toml\nallow_write = true            # the default; omit the key and you get this\n\n[profiles.prod]\nurl = \"https://zabbix.example.com\"\nallow_write = false           # this one profile is an exception\n```\n\n**If you are not sure, set `allow_write = false`.** It costs one command per\nchange and it is the right default for an installation you cannot afford to\nhave an agent surprise you in. A profile override beats the file-wide setting,\nand `ZABBIX_AI_CLI_MCP_ALLOW_WRITE` beats both — that is how a container is\ntold, without owning the config file.\n\n| Caller | `allow_write = true` | `allow_write = false` |\n| --- | --- | --- |\n| CLI, a person at a terminal | `--apply` makes the change | plan, then `approve` |\n| MCP, an agent | `zabbix_write` makes the change | plan, then `approve` at a terminal |\n\nWith writes off, no tool and no flag applies anything: a change is described,\nand a person runs `zabbix-ai-cli-mcp approve <plan-id>` in their own terminal.\nA confirmation an agent could send would be a confirmation prompt injection\ncould send, so none is offered — the approval lives outside the model's context.\n\nWith writes on, the agent applies the change itself and every change lands in\nan audit log with the profile, the parameters, the objects touched and whether\na person or a model asked for it. `zabbix-ai-cli-mcp mcp --read-only` refuses\nboth paths regardless of the setting, and an HTTP endpoint that can write\nrefuses to start without a bearer token.\n\nEverything else holds either way: a profile's `scopes` still bound what it may\ntouch, the risk registry still refuses methods that hand out credentials or run\ncode, and a plan is still re-checked against live Zabbix before it executes.\n\n```\n$ zabbix-ai-cli-mcp maintenance create \"ms*\" --for 2h\n\nPLAN pl_cc89d2e87d15\n\nCreate maintenance \"ms* (2h0m)\" for 2h0m, 2026-08-21T05:39:00Z to 2026-08-21T07:39:00Z\n\nAffects:\n  host ms1.8qw.ru\n  host ms10.8qw.ru\n  ...\n\nRisk: write\nExpires: 2026-08-21T05:54:22Z\n\nNothing has changed yet.\nTo apply it: zabbix-ai-cli-mcp approve pl_cc89d2e87d15\n```\n\nBefore a plan runs, its parameters are re-hashed, its deadline checked and its\npreconditions re-read from Zabbix. A window that has been replaced since the plan\nwas made is refused, not deleted. Every applied change is appended to an audit log.\n\nThis matters more than a refusal would. When the tool this replaces blocked a\nwrite, the work was done anyway with a token copied out of a container — losing\nthe audit trail without preventing anything. A permitted path that is recorded\nbeats a refusal that gets routed around.\n\n## Install\n\n> Prebuilt archives and the `ghcr.io` image are published with each tagged\n> release. Until the first tag lands, build from source with either method\n> below.\n\nFor a host-native binary, use Go 1.25 or newer:\n\n```bash\ngo install github.com/stufently/zabbix-ai-cli-mcp/cmd/zabbix-ai-cli-mcp@latest\n\n# Or build the current checkout.\nmkdir -p bin\ngo build -trimpath -o bin/zabbix-ai-cli-mcp ./cmd/zabbix-ai-cli-mcp\n```\n\nThe Make targets are container-first and do not require Go on the host:\n\n```bash\nmake build      # Linux binary in ./bin, built inside Docker\nmake docker     # Linux container image for the MCP server\n```\n\n## Configure\n\n```bash\nzabbix-ai-cli-mcp login --profile prod\n```\n\nIt asks for the URL and the API token, verifies the token against the server, and\nstores it. The token is never accepted as a flag, because flag values are visible\nin shell history and in the process list; pipe it in instead:\n\n```bash\nprintf %s \"$TOKEN\" | zabbix-ai-cli-mcp login --profile prod --url https://zabbix.example.com --token-stdin\n```\n\nA profile that names no scopes may do anything the write setting allows.\nNaming any scope narrows it to exactly those:\n\n```bash\nzabbix-ai-cli-mcp profile scopes prod --add maintenance\nzabbix-ai-cli-mcp profile show prod        # what it may do, writes included\n```\n\nSee [docs/authentication.md](docs/authentication.md) for the resolution order and\nthe headless and container cases.\n\n## Add the Zabbix MCP server to your AI client\n\nThe MCP client never sees the Zabbix token. It is resolved inside the server\nprocess from the profile you configured, so the credential never enters a\nmodel's context or a client's configuration file.\n\n### Claude Code\n\n```bash\nclaude mcp add zabbix -- zabbix-ai-cli-mcp mcp --profile prod\nzabbix-ai-cli-mcp skills install claude\n```\n\n### Claude Desktop\n\n`claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"zabbix\": {\n      \"command\": \"zabbix-ai-cli-mcp\",\n      \"args\": [\"mcp\", \"--profile\", \"prod\"]\n    }\n  }\n}\n```\n\n### Codex\n\n```toml\n# ~/.codex/config.toml\n[mcp_servers.zabbix]\ncommand = \"zabbix-ai-cli-mcp\"\nargs = [\"mcp\", \"--profile\", \"prod\"]\n```\n\n```bash\nzabbix-ai-cli-mcp skills install codex\n```\n\n### Cursor, Windsurf, VS Code and other MCP clients\n\nAny client that speaks stdio takes the same two fields — command\n`zabbix-ai-cli-mcp`, arguments `[\"mcp\", \"--profile\", \"prod\"]`. For a client that\nwants HTTP instead:\n\n```bash\nzabbix-ai-cli-mcp mcp --http 127.0.0.1:8000 --bearer-token \"$MCP_TOKEN\"\n```\n\nA server that can write refuses to start on HTTP without a bearer token, even on\nloopback: without one, every process on the machine could change Zabbix through\nit. It refuses a routable address unless you pass `--allow-remote` together with a\nbearer token, because an unauthenticated MCP endpoint is an unauthenticated\nroute into Zabbix. See [docs/mcp.md](docs/mcp.md).\n\n### Docker\n\n```bash\ndocker run --rm -i \\\n  -e ZABBIX_AI_CLI_MCP_URL=https://zabbix.example.com \\\n  -e ZABBIX_AI_CLI_MCP_TOKEN_FILE=/run/secrets/zabbix \\\n  -v /path/to/token:/run/secrets/zabbix:ro \\\n  ghcr.io/stufently/zabbix-ai-cli-mcp:latest mcp\n```\n\n## MCP tools\n\nFifteen tools, not two hundred. A large tool surface costs an agent context\nbefore it has done anything, and most of it is never called.\n\n```\nzabbix_problems           zabbix_metrics_latest      zabbix_unreachable\nzabbix_problem            zabbix_metrics_history     zabbix_maintenance_list\nzabbix_hosts              zabbix_alert_why           zabbix_api_call\nzabbix_host_status        zabbix_resolve             zabbix_plan_create\nzabbix_host_investigate                              zabbix_plan_status\n                                                     zabbix_write\n```\n\nWrite operations do not get one tool each. `zabbix_write` and\n`zabbix_plan_create` take an `operation` enum generated from the same registry\nthe CLI is built from, so the tool surface does not grow as operations are\nadded. `zabbix_write` is offered only where `allow_write` permits it.\n\n## JSON contract\n\n```json\n{\n  \"ok\": true,\n  \"data\": {},\n  \"warnings\": [],\n  \"meta\": {\n    \"returned\": 50,\n    \"total\": 381,\n    \"truncated\": true,\n    \"truncated_reason\": \"row_limit\",\n    \"partial\": false,\n    \"zabbix_version\": \"7.4.10\"\n  }\n}\n```\n\nErrors carry a stable code, whether retrying is worthwhile, and what to do next:\n\n```json\n{\n  \"ok\": false,\n  \"error\": {\n    \"code\": \"AUTHENTICATION_FAILED\",\n    \"message\": \"Zabbix rejected the configured API token\",\n    \"retryable\": false,\n    \"suggestion\": \"run 'zabbix-ai-cli-mcp login' to configure a new token\"\n  }\n}\n```\n\n`zabbix-ai-cli-mcp schema` prints every operation, its parameters and its JSON Schema,\nso an agent can learn the tool programmatically instead of guessing at flags.\n\nFull details in [docs/json-output.md](docs/json-output.md).\n\n## Documentation\n\n- [Authentication and profiles](docs/authentication.md)\n- [Command line](docs/cli.md)\n- [MCP server](docs/mcp.md)\n- [Skills](docs/skills.md)\n- [JSON output and exit codes](docs/json-output.md)\n- [Security model](docs/security.md)\n- [Architecture and design decisions](docs/architecture.md)\n\n## FAQ\n\n### What is a Zabbix MCP server?\n\nAn MCP server is a small program that exposes a system to an AI client over the\nModel Context Protocol. A Zabbix MCP server lets Claude, Codex, Cursor and\nsimilar clients query Zabbix — problems, hosts, items, events, maintenance — as\ntools, instead of the model guessing at `curl` calls against the JSON-RPC API.\n\n### Can an AI agent change my Zabbix through this?\n\nThat is yours to decide, and the setting is `allow_write`. Left alone it is on,\nand an agent can open a maintenance window or acknowledge an event itself —\nevery change audited, and bounded by the profile's scopes and the risk\nregistry.\n\nSet `allow_write = false` and it cannot. A write then produces a plan and\nstops; applying it is a command you run in your own terminal,\n`zabbix-ai-cli-mcp approve <plan-id>`. No MCP parameter applies anything in\nthat mode, and a test fails the build if one is ever added.\n\n### Does it send my monitoring data to an AI provider?\n\nNo. This program never contacts a language model. It talks to Zabbix and prints\nJSON. Whatever your MCP client does with that output is between you and your\nclient.\n\n### Which Zabbix versions are supported?\n\nZabbix 6.4 and newer, because bearer-token authentication arrived in 6.4.\nDeveloped and tested against Zabbix 7.4.\n\n### Do I need Go installed?\n\nNo. `make build` compiles inside Docker and needs nothing on the host but\nDocker itself. `go install` is there for a host-native binary, and each tagged\nrelease publishes archives for Linux, macOS and Windows with checksums, along with a\ncontainer image on `ghcr.io`.\n\n### How is this different from an MCP server that wraps the Zabbix API?\n\nA thin wrapper hands the agent the API's sharp edges: `problem.get` without\nhosts, `history.get` silently returning nothing for float items, `lastvalue`\nfrozen at `\"0\"`. Those produce confident wrong answers rather than errors. This\ntool answers questions — \"what is broken\", \"why did this alert not arrive\" — and\nabsorbs the traps behind them. It also ships fifteen tools rather than two\nhundred, because a large tool surface spends an agent's context before it does\nany work.\n\n### Can I still call the raw Zabbix API?\n\nYes, through `api call`, under the same rules as everything else. Methods that hand out\ncredentials or execute code are refused outright — including the long way round,\nsuch as creating a script and having an action run it.\n\n### Does it work without an AI client at all?\n\nYes. It is a normal CLI with human-readable tables, JSON output and documented\nexit codes, so it is equally usable from a shell or a CI job.\n\n## Compatibility\n\nZabbix 6.4 and newer. Bearer-token authentication arrived in 6.4 and is the only\nscheme implemented. Version-dependent behaviour is asserted explicitly, so an\nincompatibility is reported rather than returning an empty result.\n\nDeveloped and tested against Zabbix 7.4.\n\n## License\n\nApache-2.0. See [LICENSE](LICENSE).\n\nZabbix is a trademark of Zabbix LLC.\nThis project is an independent open-source project and is not affiliated with or\nendorsed by Zabbix LLC.\n",
  "bytes": 14507,
  "sha": "dad34109c2bb7fbcfc29c89421fc28f317e9772e70638cb9c7f704da3bb4ec84",
  "repo_slug": "stufently/zabbix-ai-cli-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_stufently_zabbix_ai_cli_mcp_5487dbcc/readme"
}