zabbix-graphql-api/docs/howtos/cookbook.md
Andreas Hilbig 9a79fc8e4c feat: add MCP tools, refined recipe steps for schema extension verification and update Docker requirements
- 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.
2026-01-31 03:31:40 +01:00

11 KiB

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.

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.

⚙️ Step 2: Configure Environment Variables

Add the new schema and resolver to your .env file:

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 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.

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.

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.

🤖 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.

🤖 AI/MCP

AI agents should prefer using the importHosts MCP tool for provisioning as it allows using names for host groups instead of IDs.

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:

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:

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.

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:

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 and Sample Import Hosts.


🍳 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):
    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:
      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.

  • Prerequisite: Generate the combined schema file (run this in your project root):
    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:
    {
      "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 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.