Experiences with Checkmk MCP Server and locally hosted LLMs?

I’m aware that Checkmk recommends strong models like “Anthropic’s Sonnet or Opus, or OpenAI’s ChatGPT 5.6” for use with the MCP server.

Nevertheless, out of curiosity, I tried to connect the MCP with tiny locally hosted LLMs. Up to now, I had no success.

First try was with openweb-ui and ollama (0.9.6). I had trouble connecting openweb-ui with the MCP server. Authorization wouldn’t succeed, since the Checkmk authorization windows wouldn’t show up.

Then I went to LibreChat (0.8.8), again with ollama. LibreChat was able to connect to the MCP server (green icon). And then I’m able to enable the Checkmk tool in my chat.

But whatever I try, I don’t see any traffic in the mcp-server.log (apart from “GET / HTTP/1.1” 200 and sometimes a “GET /.well-known/oauth-protected-resource/main/check_mk/mcp HTTP/1.1” 200).

I tried qwen2.5:7b, which was said to have a good support for tool calling. I also tried llama3.2:3b and mistral:7b.

I tried a few simple sentences like “Show me the CPU load on myhost01 for the last six hours.”, but never got anything that seemed to correspond to communication with the MCP.

In fact at the moment, qwen2.5:7b seems to stall as soon as I enable the Checkmk tool in the chat: When I ask the above question without Checkmk tool enabled, I get an immediate answert (“use top…”). When I enable the Checkmk tool and ask the same question, the chats runs for minutes without any reaction.

I have no experience with other MCP tools, so I can’t compare.

So I’d be glad to hear your experiences with Checkmk MCP server and ollama/LibreChat (or other local LLMs).

After reading your post i made some smaller test with “LM Studio” and three models (gpt-oss-20b, qwen3.8-27b and qwen3.5-9b) all models are producing some results.
I don’t want to judge if this will be helpful in a day to day business, but it was working. One thing you must keep in mind, the context length needed in my local tests was every time around 30-40k minimum. 20k context crashed regularly.
With only 16GB VRAM context is very limited :smiley:

For me, qwen3.5-9b yielded the best result in terms of the balance between time and response quality.

Small example from my test.

What is the current status of my CO2 device?
First thought was the longest time. 6,5 seconds

The user is asking about the current status of their “CO2 device”. This sounds like they want to check a host or service in their monitoring system. I need to use the get_hosts function to find information about this device.

However, I don’t know the exact host name for the “CO2 device”. The user might have named it something specific. Let me try to query for hosts that might be related to CO2. I could try searching for hosts with “CO2” in their name, or I could first get a monitoring overview to see what’s available.

Actually, let me think about this more carefully. The user is asking about “my CO2 device” which suggests they have a specific host/service named something like “co2-device”, “co2-sensor”, etc. Since I don’t know the exact name, I should probably:

  1. First try to get hosts with “CO2” in the name
  2. Or get a monitoring overview to see what’s available

Let me start by trying to find hosts that might be related to CO2. I’ll use get_hosts with host_name parameter set to something like “co2” but looking at the function definition, it seems host_name expects exact matches or an array of exact matches, not a wildcard pattern.

Actually, looking at the get_hosts function more carefully:

  • host_name: “Only these exact hosts. A host name not visible on this site fails the whole call and is named, so a typo can’t read as an all-clear.”

So I need to know the exact host name. Since the user said “CO2 device”, they might have named it something like:

  • co2-device
  • CO2-device
  • co2-sensor
  • co2-monitor

But I don’t want to guess. Let me first get a monitoring overview to see what hosts are available, or I could try searching for hosts with common naming patterns.

Actually, let me try a different approach. Let me get the monitoring overview first to see what’s on the site, and then I can identify if there’s a CO2-related host.

Tool call - get_monitoring_overview

Result
[
  {
    "type": "text",
    "text": "{\n  \"hosts\": {\n    \"total_matched\": 25,\n    \"state_counts\": {\n      \"UP\": 25,\n      \"DOWN\": 0,\n      \"UNREACH\": 0,\n      \"PENDING\": 0\n    },\n    \"unhandled_state_counts\": {\n      \"DOWN\": 0,\n      \"UNREACH\": 0\n    }\n  },\n  \"services\": {\n    \"total_matched\": 408,\n    \"state_counts\": {\n      \"OK\": 402,\n      \"WARN\": 0,\n      \"CRIT\": 6,\n      \"UNKNOWN\": 0,\n      \"PENDING\": 0\n    },\n    \"unhandled_state_counts\": {\n      \"WARN\": 0,\n      \"CRIT\": 6,\n      \"UNKNOWN\": 0\n    }\n  }\n}"
  }
]
Thought for 3.6 seconds

The monitoring overview shows there are 25 hosts and 408 services, but it doesn’t give me specific host names. I need to find the CO2 device specifically. Let me try to get hosts with “CO2” in their name. Since the API requires exact matches, I’ll need to try different common naming patterns.

Let me try searching for hosts that might be named “co2-device”, “co2-sensor”, or similar. Actually, let me first try to get all hosts to see what’s available, but that might be too much data.

Actually, a better approach would be to try some common naming patterns. Let me try “co2” as a host name first, and if that doesn’t work, I’ll try other variations.

Wait, looking at the get_hosts function again, host_name can be an array of exact host names. So I could try multiple common patterns at once. But that might still not work if the naming convention is different.

Let me try a different approach - let me search for hosts with “co2” in their name by trying some common variations. I’ll start with just “co2” as a simple test.

To shorten this a little bit - the llm find the host “CO2” sees that it is up.

Thought after state is up found

Perfect! I found the CO2 device. It’s in the UP state. Let me also check if there are any services on this host to provide a more complete status. Let me get the services for the CO2 host.

Tool call - get_services

Thought after service result fetched

Great! Now I have a complete picture of the CO2 device status. Let me summarize this information for the user.

Key findings:

  • Host “CO2” is in UP state
  • Most services are OK, but there are 2 CRITICAL services:
    1. “CO2 board co2” - showing 1235 ppm (critical threshold at 1200 ppm)
    2. “CO2 level (ppm)” - showing CO2/ventilation control with Watterott CO2-Ampel, Co 2 ppm: 1235.00 (critical at 1200 ppm)

Both of these are measuring the same thing - the CO2 concentration is at 1235 ppm, which exceeds the critical threshold of 1200 ppm. This is a concerning situation that needs attention.

Let me provide a clear summary to the user.

Result of question to LLM.

Your CO2 device is currently online and monitored, but there’s an urgent issue with the CO2 concentration levels!

Current Status Summary

Host: CO2

  • State: :white_check_mark: UP (online)
  • Last check: 2026-10-10T08:12:03+00:00
  • Acknowledged: No
  • In downtime: No

:warning: Critical Alert - CO2 Levels!

Two services are in CRITICAL state:

  1. CO2 board co2: 1235 ppm :cross_mark:

    • Warning threshold: 1000 ppm
    • Critical threshold: 1200 ppm
    • Last OK: 2026-10-10T05:30:30+00:00 (about 3 hours ago)
  2. CO2 level (ppm): 1235.00 ppm :cross_mark:

    • Warning threshold: 1000 ppm
    • Critical threshold: 1200 ppm
    • Last OK: 2026-10-10T05:30:30+00:00 (about 3 hours ago)

Other Sensors (All OK :white_check_mark:)

  • Pressure: 960.2 hPa
  • Lighting: 152 lux
  • Temperature 1: 19.9°C
  • Temperature 2: 24.4°C
  • Humidity: 48.8%

Recommendation

The CO2 level has exceeded the critical threshold (1200 ppm) and is currently at 1235 ppm. This indicates poor ventilation in the room. You should:

  • Open windows/doors to improve airflow
  • Activate any ventilation systems
  • Consider the Watterott CO2-Ampel for automatic control

The high CO2 level has persisted for approximately 3 hours without improvement.


Conclusion - for a 9B model not bad

With more general questions like “What device inside my environment had yesterday the highest memory usage?” you get no good result. Most times your LLM is stuck in a loop there.

Seems the LLM did not check the name of the plug-in that actually delivered the data. :grin:

Yeah there where some more such small things over all the tests.

I also was playing with the mcp server the last 4 weeks.

I hooked up an Hermes agent to the mcp which works amazingly. My LLM backend is a locally hosted vllm with an 8xh200 system (I know that’s a lot) and a qwen3.8 27b model. Hermes sends me a daily digest of my infrastructure in the morning. Sometimes it’s even suggesting changes on the monitored servers.

The only thing I found out to be a little bit frustrating is that the mcp server does not seems to reauthenticating so every 48 hours the session expires and need to reauth manually. This was at least in 2.5.0p13. now I have updated to 15, maybe it changed but I have not found anything regarding this in the changelog.

@Annikaf and @Sara could you please have a look?

Thank you!

Hey @andreas-doehler,

thank you for sharing your testing results, really interesting to read! And also thank you for sharing your feedback about the 48h reauthentication, we will look into this.

Best,

Annika

@andreas-doehler , danke für den Tipp mit LMstudio, hatte ich noch nicht probiert. Habe allerdings versehentlich LMstudio Bionics installiert - und siehe da, damit kamen mit qwen2.5:8b auch auf Anhieb Ergebnisse aus Checkmk! Allerdings garniert mit häufigen Crashes der App (sicher auf meine unterdimensionierte Testhardware zurückzuführen).

Habe jetzt aber realisiert, dass Bionic nochmal was anderes als LMstudio ist und versuche jetzt gerade LMstudio.

Wie hast Du denn Checkmk MCP mit LMstudio verbunden? Ich scheitere da gerade (weil LMstudio kein oauth2 kann??), ähnlich wie meine Bemühungen bei openweb-ui…

Die Config in LMStudio schaut so aus.
mcp.json

{
  "mcpServers": {
    "checkmk": {
      "url": "https://CMKHOST/SITE/check_mk/mcp"
    }
  }
}

Danach erhalte ich, wenn ich einen Chat offen habe und die Integration aktiviere, eine Aufforderung zur Authentifizierung.


Das ganze erfolgt dann im Browser.
Lustig ist hier, dass er fragt ob nur read oder read/write Access ich erlauben will.

Denke mal das ist was für @Annikaf :wink:
Nach erfolgreicher Anmeldung kannst dann noch auswählen welche Tools erlaubt werden sollen.