zapi-mcp
MCP server for the Zabbix API that provides a daily_brief summary of active problems and category-specific metrics, along with tools to query problems, hosts, and item values.
README
<!-- mcp-name: io.github.shigechika/zapi-mcp -->
zapi-mcp
English | 日本語
MCP (Model Context Protocol) server for the Zabbix API.
Built for network operations: a single daily_brief call summarizes active
problems plus site-specific categories (DHCP pool usage, SNAT session usage,
core-network problems, …), and individual tools query problems, hosts, and item
values. Organization-specific tags live in a config file, not the code, so the
server stays generic.
Version-adaptive auth: works against Zabbix 6.0 LTS (user + auth field) and
forward-compatible with 6.4 / 7.0 (username + Authorization: Bearer).
Features
| Tool | Description |
|---|---|
health_check |
Server version, Zabbix connectivity/auth, detected API version, and configured daily_brief categories — call at session start or after a timeout |
daily_brief |
Morning patrol: active problems (Warning+) plus one section per configured category |
get_problems |
Active problems by severity and tag, newest-first with age; header shows the true total (showing N of TOTAL when capped); output includes eventid |
get_hosts |
List hosts filtered by role/tag/group, with IP and tags |
get_host_items |
Current item values for a host (server-side host filter) |
acknowledge_problem |
Acknowledge problems and add a message (does not close them) |
Setup
# uv
uv pip install zapi-mcp
# pip
pip install zapi-mcp
Or from source:
git clone https://github.com/shigechika/zapi-mcp.git
cd zapi-mcp
# uv
uv sync
# pip
pip install -e .
Configuration
Set the following environment variables:
| Variable | Description | Default |
|---|---|---|
ZABBIX_URL |
Zabbix base URL (e.g. https://zabbix.example.com); /api_jsonrpc.php is appended if absent |
required |
ZABBIX_USER |
Zabbix API user | required |
ZABBIX_PASSWORD |
Zabbix API password | required |
ZABBIX_CATEGORIES_INI |
Path to a categories INI file for daily_brief (optional) |
— |
ZABBIX_BRIEF_RECENT_HOURS |
daily_brief "recent" window in hours; problems older than this are folded to a count |
24 |
ZABBIX_BRIEF_PROBLEM_LIMIT |
Max active problems daily_brief fetches per call before counting the rest |
1000 |
The API user needs read permission for the host groups you query, plus
acknowledge permission if you use acknowledge_problem.
Active problems in daily_brief
Problems are grouped by severity and listed newest-first, each annotated with
its age (e.g. 3h ago). Problems older than the recent window
(ZABBIX_BRIEF_RECENT_HOURS, default 24h) are folded to a single
… and N older (stale; oldest …) line — so a backlog of alerts that Zabbix
keeps active because their recovery is never auto-confirmed (ICMP ping down, RDP
down, …) doesn't bury what just happened. Section headers carry the true total
and show showing N of TOTAL when the fetch is capped, never a silent truncation.
Categories for daily_brief (optional)
daily_brief always lists active problems. To add site-specific sections —
DHCP pool exhaustion, SNAT session usage, core-network problems — point
ZABBIX_CATEGORIES_INI at an INI file. Each [section] is one category:
[dhcp]
name = DHCP Pool Usage
tag = dhcp-pool-usage ; Zabbix host tag identifying the group
item_key = usage ; report current values for this exact item key
threshold = 80 ; flag values >= this
[snat]
name = SNAT Session Pool
tag = snat-pool-usage
item_key_search = .usage ; substring match (catches pool.node0.usage etc.)
threshold = 80
[core]
name = Core Network
tag = role
tag_value = main ; tag must equal this value
; no item key -> report active problems instead
tag(required): host tag identifying the category. Withtag_value, the tag must equal it (Equal); without, any host carrying the tag matches (Exists).item_key/item_key_search: when either is set, the section reports current item values sorted high-to-low.item_keymatches the key exactly; useitem_key_searchfor keys that embed an id (e.g..usagecatchespool.node0.usage). When neither is set, it reports active problems for the tag.threshold: optional; values at or above it are flagged.
See categories.ini.example. When the variable is
unset or the file is missing, daily_brief reports active problems only.
Usage
Claude Code
Add to .mcp.json:
{
"mcpServers": {
"zapi-mcp": {
"type": "stdio",
"command": "zapi-mcp",
"env": {
"ZABBIX_URL": "https://zabbix.example.com",
"ZABBIX_USER": "api-user",
"ZABBIX_PASSWORD": "",
"ZABBIX_CATEGORIES_INI": "/path/to/categories.ini"
}
}
}
}
Claude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"zapi-mcp": {
"command": "zapi-mcp",
"env": {
"ZABBIX_URL": "https://zabbix.example.com",
"ZABBIX_USER": "api-user",
"ZABBIX_PASSWORD": ""
}
}
}
}
Direct Execution
export ZABBIX_URL=https://zabbix.example.com
export ZABBIX_USER=api-user
export ZABBIX_PASSWORD=your-password
zapi-mcp
CLI Options
zapi-mcp --version # Print version and exit
zapi-mcp --check # Verify environment variables and authentication, then exit
zapi-mcp --brief # Print the daily_brief to stdout and exit (handy for cron)
zapi-mcp # Start MCP server (STDIO, default)
--check exit codes: 0 success, 1 config error, 2 auth/connection error.
--brief exit codes: 0 success, 1 a section failed (auth, the active-problems
fetch, or category loading — see the embedded Error: line in the output).
Development
git clone https://github.com/shigechika/zapi-mcp.git
cd zapi-mcp
# uv
uv sync --dev
uv run pytest -v
uv run ruff check .
# pip
python3 -m venv .venv
.venv/bin/pip install -e . && .venv/bin/pip install pytest pytest-cov respx ruff
.venv/bin/pytest -v
.venv/bin/ruff check .
Live smoke test
pytest checks logic against fixtures; it cannot tell you that a tool has
stopped returning real data. scripts/smoke_test.py runs every registered
tool against the configured Zabbix and fails on empty, malformed or error
answers:
# needs the same ZABBIX_* environment variables as the server
uv run python scripts/smoke_test.py
uv run python scripts/smoke_test.py --only get_problems --traceback
- Read-only.
acknowledge_problemis skipped by name — an acknowledgement is visible to every operator and cannot be quietly undone — and a test enforces that. The report prints tool names and statuses only, never payloads; server-authored error text is redacted too, since Zabbix quotes the host it was asked about.--tracebackstill shows the full text on the operator's own terminal. - Arguments that would identify real hosts, groups or tag values are
discovered at run time, never written into
scripts/smoke_probes.py. Two tests enforce that: one refuses those parameters as literals, the other bans anything address-shaped (mail address, URL, hostname, IPv4, IPv6) anywhere in the file. - An empty answer is a real observation here — a monitoring system with nothing wrong is the goal — so probes assert the envelope the tool must produce rather than a row count.
- CI enforces the cheap half: a tool registered without a probe spec fails the
build (
tests/test_smoke_probes.py), so adding a tool forces the question "how would we know it works?". scripts/smoke_harness.pyis the engine and holds no Zabbix knowledge: it is kept identical across the servers that share it, so fix engine bugs once and sync the file rather than patching this copy.
Releasing
Releases are automated with release-please.
Merging Conventional Commits (feat:, fix:, …)
to main keeps a release PR open with the next version and changelog. Merging
that PR tags vX.Y.Z and publishes a GitHub Release, whose release: published
event triggers the release workflow to build and publish to PyPI and the MCP
Registry. release-please owns the version in zapi_mcp/__init__.py and
server.json (do not bump them by hand).
[!IMPORTANT] The release-please workflow should be given a repository secret
RELEASE_PLEASE_TOKEN(a PAT withcontents: write+pull-requests: write). The defaultGITHUB_TOKENcannot create the Release that triggers the downstreamreleaseworkflow (GitHub blocks workflow runs triggered byGITHUB_TOKEN), so without the PAT nothing gets published. The workflow falls back toGITHUB_TOKENwhen the secret is unset so PR CI keeps working on forks.
Roadmap
- Streamable HTTP transport + OAuth2 for remote / mobile use
- Visual rendering of key metrics
License
MIT
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。
mcp-server-qdrant
这个仓库展示了如何为向量搜索引擎 Qdrant 创建一个 MCP (Managed Control Plane) 服务器的示例。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。