- Add mcp/operations/importHosts.graphql for flexible, name-based host provisioning.
- Split schema verification operations into createVerificationHost.graphql and verifySchemaExtension.graphql to support Apollo MCP server requirements.
- Improve mcp/operations/createHost.graphql with better type mapping and error message retrieval.
- Fix syntax error in importHosts.graphql by replacing unsupported triple-quote docstrings with standard comments.
- Add src/test/mcp_operations_validation.test.ts to automatically validate MCP operations against the GraphQL schema.
- Update docs/howtos/cookbook.md with 🤖 AI/MCP guidance and refined recipe steps for schema extension verification.
- Update README.md, docs/howtos/mcp.md, and .junie/guidelines.md to:
- Add Docker (v27+) and Docker Compose (v2.29+) version requirements to the Tech Stack.
- Enforce the use of docker compose (without hyphen) for all commands in the Environment guidelines.
- Replace legacy docker-compose references across all documentation with the new command format.
321 lines
11 KiB
Markdown
321 lines
11 KiB
Markdown
# Zabbix GraphQL API Cookbook
|
|
|
|
This cookbook provides step-by-step "recipes" for common tasks. These instructions are designed to be easy for humans to follow and structured enough for AI agents (using the MCP server) to generate test cases.
|
|
|
|
## 🤖 AI-Based Test Generation
|
|
|
|
To generate a test case from a recipe:
|
|
- Start the `zabbix-graphql` MCP server.
|
|
- Provide the recipe to your AI agent.
|
|
- Ask the agent to "Implement a test case for this recipe using the Zabbix GraphQL API".
|
|
- The agent will use the MCP server to explore the schema and generate appropriate GraphQL operations.
|
|
|
|
---
|
|
|
|
## 🍳 Recipe: Extending Schema with a New Device Type
|
|
|
|
This recipe shows how to add support for a new specialized device type without modifying the core API code. We will use the `DistanceTrackerDevice` as an example.
|
|
|
|
### 📋 Prerequisites
|
|
- Zabbix Template Group `Templates/Roadwork/Devices` exists.
|
|
- Zabbix GraphQL API is running.
|
|
|
|
### 🛠️ Step 1: Define the Schema Extension
|
|
Create a new `.graphql` file in `schema/extensions/` (e.g. `distance_tracker.graphql`).
|
|
|
|
> **Advice**: A new device type must always implement both the `Host` and `Device` interfaces to ensure compatibility with the API's core logic and resolvers.
|
|
|
|
```graphql
|
|
type DistanceTrackerDevice implements Host & Device {
|
|
# Mandatory Host & Device fields
|
|
hostid: ID!
|
|
host: String!
|
|
deviceType: String
|
|
hostgroups: [HostGroup!]
|
|
name: String
|
|
tags: DeviceConfig
|
|
|
|
# Specialized state for this device
|
|
state: DistanceTrackerState
|
|
}
|
|
|
|
type DistanceTrackerState implements DeviceState {
|
|
operational: OperationalDeviceData
|
|
current: DistanceTrackerValues
|
|
}
|
|
|
|
type DistanceTrackerValues {
|
|
timeFrom: Time
|
|
timeUntil: Time
|
|
count: Int
|
|
# The distances are modelled using a type which is already defined in location_tracker_commons.graphql
|
|
distances: [SensorDistanceValue!]
|
|
}
|
|
```
|
|
|
|
> **Reference**: This example is based on the already prepared sample: [location_tracker_devices.graphql](../../schema/extensions/location_tracker_devices.graphql).
|
|
|
|
### ⚙️ Step 2: Configure Environment Variables
|
|
Add the new schema and resolver to your `.env` file:
|
|
```env
|
|
ADDITIONAL_SCHEMAS=./schema/extensions/distance_tracker.graphql,./schema/extensions/location_tracker_commons.graphql
|
|
ADDITIONAL_RESOLVERS=DistanceTrackerDevice
|
|
```
|
|
Restart the API server.
|
|
|
|
### 🚀 Step 3: Execution/Action (Choose Method)
|
|
|
|
#### Method A: Manual Creation in Zabbix
|
|
If you prefer to configure Zabbix manually:
|
|
1. **Create Template**: Create a template named `DISTANCE_TRACKER`.
|
|
2. **Create Items**: Add items with keys that match the GraphQL fields (using hierarchical mapping):
|
|
* `state.current.timeFrom`
|
|
* `state.current.timeUntil`
|
|
* `state.current.count`
|
|
* `state.current.json_distances` (maps to `distances` array via `json_` prefix)
|
|
3. **Add Tag**: Add a host tag to the template with name `deviceType` and value `DistanceTrackerDevice`.
|
|
|
|
#### Method B: Automated Import
|
|
Execute the `importTemplates` mutation to create the template and items automatically.
|
|
> **Reference**: Use the [Sample: Distance Tracker Import](../../docs/queries/sample_import_distance_tracker_template.graphql) for a complete mutation and variables example.
|
|
|
|
### ✅ Step 4: Verify the Extension
|
|
Verify that the new type is available and correctly mapped by creating a test host and querying it.
|
|
|
|
#### 1. Create a Test Host
|
|
Use the `importHosts` mutation (or `createHost` if IDs are already known) to create a host and explicitly set its `deviceType` to `DistanceTrackerDevice`.
|
|
|
|
```graphql
|
|
mutation CreateTestDistanceTracker($host: String!, $groupNames: [String!]!) {
|
|
importHosts(hosts: [{
|
|
deviceKey: $host,
|
|
deviceType: "DistanceTrackerDevice",
|
|
groupNames: $groupNames
|
|
}]) {
|
|
hostid
|
|
message
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 2. Query the Device
|
|
Query the newly created device. Use the `tag_deviceType: ["DistanceTrackerDevice"]` argument to ensure you only retrieve devices of this specific type and prevent showing all devices of any type.
|
|
|
|
```graphql
|
|
query VerifyNewDeviceType {
|
|
# 1. Check if the type exists in the schema
|
|
__type(name: "DistanceTrackerDevice") {
|
|
name
|
|
fields {
|
|
name
|
|
}
|
|
}
|
|
# 2. Query the specific device
|
|
allDevices(tag_deviceType: ["DistanceTrackerDevice"]) {
|
|
... on DistanceTrackerDevice {
|
|
name
|
|
state {
|
|
current {
|
|
count
|
|
distances {
|
|
distance
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
> **Reference**: See how items map to fields in the [Zabbix to GraphQL Mapping](../../README.md#zabbix-to-graphql-mapping).
|
|
|
|
### 🤖 AI/MCP
|
|
AI agents can use the generalized `verifySchemaExtension.graphql` operations to automate this step:
|
|
- **CreateVerificationHost**: Automatically imports a test host with the correct `deviceType`.
|
|
- **VerifySchemaExtension**: Queries the newly created device to verify it is correctly mapped to the new type.
|
|
|
|
---
|
|
|
|
## 🍳 Recipe: Provisioning a New Host
|
|
|
|
### 📋 Prerequisites
|
|
- A target Host Group exists in Zabbix.
|
|
- At least one Template exists in Zabbix.
|
|
|
|
### 🛠️ Step 1: Prepare the Host Object
|
|
Define the host name, groups, and templates to link.
|
|
|
|
### 🚀 Step 2: Execute `createHost` Mutation
|
|
For more details on the input fields, see the [Reference: createHost](../../schema/mutations.graphql).
|
|
|
|
### 🤖 AI/MCP
|
|
AI agents should prefer using the `importHosts` MCP tool for provisioning as it allows using names for host groups instead of IDs.
|
|
|
|
```graphql
|
|
mutation CreateNewHost($host: String!, $groups: [Int!]!, $templates: [Int!]!) {
|
|
createHost(host: $host, hostgroupids: $groups, templateids: $templates) {
|
|
hostids
|
|
error {
|
|
message
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### ✅ Step 3: Verify Host Creation
|
|
Check if the host is correctly provisioned and linked to groups:
|
|
```graphql
|
|
query VerifyHost($host: String!) {
|
|
allHosts(filter_host: $host) {
|
|
hostid
|
|
host
|
|
hostgroups {
|
|
name
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🍳 Recipe: Managing User Permissions
|
|
|
|
### 🛠️ Step 1: Create Permission Template Group
|
|
Create a template group with the prefix `Permissions/` in Zabbix (e.g. `Permissions/Read-Only-Access`).
|
|
|
|
### ⚙️ Step 2: Assign to User Group
|
|
In Zabbix, give a User Group `Read` access to this template group.
|
|
|
|
### ✅ Step 3: Verify via API
|
|
Verify that the current user has the expected permissions:
|
|
```graphql
|
|
query CheckMyPermissions {
|
|
hasPermissions(permissions: [
|
|
{ objectName: "Read-Only-Access", permission: READ }
|
|
])
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🍳 Recipe: Bulk Import of Templates and Hosts
|
|
|
|
This recipe guides you through performing a mass import of multiple templates and hosts in a single operation.
|
|
|
|
### 🛠️ Step 1: Prepare Template Import
|
|
Use the `importTemplates` mutation. You can provide multiple template definitions in the `templates` array.
|
|
|
|
### ⚙️ Step 2: Prepare Host Import
|
|
Use the `importHosts` mutation. Link them to the newly imported templates using their names or IDs.
|
|
|
|
### 🚀 Step 3: Combined Operation (Optional)
|
|
You can execute both mutations in a single GraphQL request to ensure atomic-like provisioning of your infrastructure.
|
|
|
|
```graphql
|
|
mutation BulkProvisioning($templates: [CreateTemplate!]!, $hosts: [CreateHost!]!) {
|
|
importTemplates(templates: $templates) {
|
|
templateid
|
|
host
|
|
message
|
|
}
|
|
importHosts(hosts: $hosts) {
|
|
hostid
|
|
deviceKey
|
|
message
|
|
}
|
|
}
|
|
```
|
|
|
|
### ✅ Step 4: Verify Bulk Import
|
|
Verify that all entities were created and linked correctly:
|
|
```graphql
|
|
query VerifyBulkImport($pattern: String!) {
|
|
allHosts(name_pattern: $pattern) {
|
|
hostid
|
|
host
|
|
... on ZabbixHost {
|
|
parentTemplates {
|
|
name
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
For detailed examples of the input structures, refer to [Sample Import Templates](../../docs/queries/sample_import_templates_mutation.graphql) and [Sample Import Hosts](../../docs/queries/sample_import_hosts_mutation.graphql).
|
|
|
|
---
|
|
|
|
## 🍳 Recipe: Setting up GraphQL MCP for AI Agents
|
|
|
|
This recipe guides you through setting up the Model Context Protocol (MCP) server to enable AI agents like **Junie** or **Claude** to interact with your Zabbix data through the GraphQL API.
|
|
|
|
### 📋 Prerequisites
|
|
- **Zabbix GraphQL API**: Ensure the API is running (e.g. `npm run start`).
|
|
- **Docker**: Installed and running for the MCP server container.
|
|
|
|
### 🛠️ Step 1: Configure the MCP Server
|
|
Choose one of the following setups:
|
|
|
|
#### Setup A: JetBrains IDE (AI Chat & Junie)
|
|
Configure the IDE to use the GraphQL MCP server for both the built-in AI Chat and the **Junie agent**.
|
|
- **Prerequisite**: Generate the combined schema file (run this in your project root):
|
|
```bash
|
|
cat schema/*.graphql > schema.graphql
|
|
```
|
|
- **Open Settings**: Navigate to `File` > `Settings` (Windows/Linux) or `IntelliJ IDEA` > `Settings` (macOS).
|
|
- **Navigate to MCP**: Go to `Tools` > `AI Assistant` > `MCP Servers`.
|
|
- **Add Server**: Click the **+** button and configure:
|
|
- **Name**: `Zabbix GraphQL`
|
|
- **Type**: `Command`
|
|
- **Command**: `docker`
|
|
- **Arguments**:
|
|
```text
|
|
run -i --rm -v ${PROJECT_DIR}/mcp-config.yaml:/mcp-config.yaml -v ${PROJECT_DIR}/schema.graphql:/mcp-data/schema.graphql:ro -v ${PROJECT_DIR}/mcp/operations:/mcp/operations -e APOLLO_GRAPH_REF=local@main ghcr.io/apollographql/apollo-mcp-server:latest /mcp-config.yaml
|
|
```
|
|
|
|
#### Setup B: Claude Desktop
|
|
Connect Claude Desktop to the Zabbix GraphQL API by referring to the [Apollo GraphQL MCP Documentation](https://github.com/apollographql/apollo-mcp-server).
|
|
- **Prerequisite**: Generate the combined schema file (run this in your project root):
|
|
```bash
|
|
cat schema/*.graphql > schema.graphql
|
|
```
|
|
- **Edit Configuration**: Open the Claude Desktop configuration file (e.g. `%APPDATA%\Claude\claude_desktop_config.json` on Windows).
|
|
- **Add to mcpServers**: Insert the following configuration in the `mcpServers` section:
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"zabbix-graphql": {
|
|
"command": "docker",
|
|
"args": [
|
|
"run",
|
|
"-i",
|
|
"--rm",
|
|
"-v", "C:/path/to/your/project/mcp-config.yaml:/mcp-config.yaml",
|
|
"-v", "C:/path/to/your/project/schema.graphql:/mcp-data/schema.graphql:ro",
|
|
"-v", "C:/path/to/your/project/mcp/operations:/mcp/operations",
|
|
"-e", "APOLLO_GRAPH_REF=local@main",
|
|
"ghcr.io/apollographql/apollo-mcp-server:latest",
|
|
"/mcp-config.yaml"
|
|
]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
- **Restart Claude**: Fully restart the Claude Desktop application to apply the changes.
|
|
|
|
### 🚀 Step 2: Use an AI Agent
|
|
Provide the recipe to your AI agent and ask it to perform a task.
|
|
- **Example**: "Use MCP to list the configured Zabbix hosts".
|
|
|
|
### ✅ Step 3: Verify via Agent
|
|
Confirm that the agent can successfully interact with the API:
|
|
- Ask: "What is the current version of the Zabbix API?"
|
|
- The agent should use the `apiVersion` query and respond with the version number.
|
|
|
|
### 💡 Alternative: Using Pre-running MCP Server
|
|
If you already have the MCP server running locally (e.g. via `docker compose`), you can use a simpler configuration.
|
|
- **Sample Configuration**: See [.ai/mcp/mcp.json](../../.ai/mcp/mcp.json) for a sample that connects to a running MCP server via HTTP.
|
|
- **Usage**: Use this `url`-based configuration in your Claude Desktop or IDE settings instead of the `command`-based setup if you prefer to manage the MCP server lifecycle separately.
|
|
|
|
> **Reference**: For more details on the benefits of GraphQL for MCP, see the [MCP & Agent Integration Guide](./mcp.md).
|