Skip to main content
Glama
4alvit

mcp-venus-os

by 4alvit

MCP Venus OS

CodeQL Scorecards Dependency Review License: MIT Python 3.11+ Development Status GitHub last commit Maintenance Made with Python MCP

MCP (Model Context Protocol) server for Victron Venus OS management. Primary transport is the Venus OS MQTT gateway (N/<portalId>/… reads, W/<portalId>/… writes) so the server can run off-device; direct D-Bus remains available for on-device installs.

Features

  • MQTT read path: subscribes N/<portalId>/# on the Cerbo GX gateway and serves tools from a stale-guarded cache (stale, age_seconds per reading)

  • Write tools over W/ topics: inverter mode, charge-current limit, SoC limit — each write is kept alive (≤60s expiry) and verified by read-back before reporting success

  • Safety constraints: confirmation gate + hard limits enforced before any publish

  • Two server transports: stdio (Claude Code launches the process) or streamable HTTP with optional bearer-token auth (Synology Docker / shared use)

  • Optional D-Bus backend: unchanged behavior for installs running directly on the Cerbo

Related MCP server: Victron VRM MCP Server

Quick Start

Installation

Not yet on PyPI. Install from GitHub:

pip install git+https://github.com/4alvit/mcp-venus-os

Or for development:

git clone https://github.com/4alvit/mcp-venus-os
cd mcp-venus-os
uv sync

Prerequisites (Cerbo GX)

  1. Settings → Services → MQTT Gateway, mode = Local network (listens on LAN :1883)

  2. Note the portal ID shown on the MQTT Gateway page (also com.victronenergy.system/Serial)

  3. Verify: mosquitto_sub -h <cerbo-ip> -t 'N/<portalId>/system/#' -v returns telemetry

Configuration

Create a .env file from .env.sample or set environment variables:

TRANSPORT_BACKEND=mqtt          # mqtt (default) | dbus (on-device only)
SERVER_TRANSPORT=stdio          # stdio (default) | http

# MQTT — Venus OS gateway on the Cerbo
MQTT_HOST=<cerbo-ip>
MQTT_PORT=1883
MQTT_PORTAL_ID=<venus-portal-id>
MQTT_STALE_AFTER_SECONDS=60

# Safety
SAFETY_REQUIRE_CONFIRMATION=true
SAFETY_MAX_CHARGE_CURRENT=100
SAFETY_MAX_DISCHARGE_CURRENT=100
SAFETY_MIN_SOC_LIMIT=10
SAFETY_MAX_SOC_LIMIT=100
SAFETY_ALLOWED_MODES=on,off,charger_only,inverter_only,eco
SAFETY_ENABLE_WRITES=false       # MUST be true to enable any write/control tools

# HTTP mode extras
SERVER_HOST=127.0.0.1           # 0.0.0.0 inside containers
SERVER_PORT=8000
SERVER_AUTH_TOKEN=              # optional bearer token for HTTP mode

Running the Server

uv run mcp-venus-os                   # stdio (Claude Code launches this)
uv run mcp-venus-os --transport http  # or SERVER_TRANSPORT=http

Deployment Matrix

Target

Transport backend

Server transport

Notes

Synology Docker (primary)

mqtt → Cerbo LAN

http :8080

shared endpoint for all machines on the LAN

macOS (fallback)

mqtt → Cerbo LAN

stdio

local process via claude mcp add, no NAS dependency

On-device (Cerbo)

dbus

stdio

legacy mode, no gateway needed

Docker:

cp .env.sample .env   # fill in cerbo IP + portal id (+ token if exposing beyond LAN)
docker compose up -d  # healthcheck hits GET /mcp until the MCP endpoint answers

HTTP Auth Token

HTTP mode is protected by a static bearer token (SERVER_AUTH_TOKEN). Without it the server runs unauthenticated — only sensible on a trusted home LAN.

Generate and apply:

openssl rand -hex 24          # generate once
echo 'SERVER_AUTH_TOKEN=<hex>' >> .env   # add to the deployment .env
docker compose up -d          # restart so the container picks it up

Clients then send Authorization: Bearer <token> on every request. Unauthenticated or wrong-token requests get 401. For Claude Code:

claude mcp add --scope user --transport http venus-os \
  http://<synology-ip>:8080/mcp \
  --header "Authorization: Bearer <token>"

Or via the project-level .mcp.json, which reads the token from the VENUS_MCP_TOKEN environment variable (export VENUS_MCP_TOKEN=<hex> before launching Claude Code):

{
  "mcpServers": {
    "venus-os": {
      "type": "http",
      "url": "http://192.168.167.25:8080/mcp",
      "headers": { "Authorization": "Bearer ${VENUS_MCP_TOKEN}" }
    }
  }
}

Claude Code Registration

Primary (shared Synology HTTP endpoint — see above). Fallback: launch the server locally so it works even when the NAS is down:

claude mcp add --scope user venus-os \
  -e TRANSPORT_BACKEND=mqtt -e MQTT_HOST=<cerbo-ip> -e MQTT_PORTAL_ID=<id> \
  -- uv --directory /path/to/mcp-venus-os run mcp-venus-os

DSM notes (deployed at /volume1/docker/mcp-venus-os/):

  • Plain docker compose (full path /usr/local/bin/docker) works fine; Container Manager is not required.

  • Host port 8000 is taken by Portainer on typical DSM installs — remap in the compose ports: (e.g. "8080:8000").

  • SFTP/scp may be disabled; copy files via ssh ... 'cat > file'.

  • The .env (portal id, token) lives only on the NAS, mode 600.

Container Images

Two registries, both multi-arch (linux/amd64 + linux/arm64):

Registry

Image

Updated on

GitHub Container Registry

ghcr.io/4alvit/mcp-venus-os:latest (+ :<sha>)

every push to main

Docker Hub

alvit/mcp-venus-os:vX.Y.Z + :latest

every v* tag push

docker pull alvit/mcp-venus-os:v0.2.0

The Docker Hub publish workflow (docker-hub-release.yml) needs repository secrets DOCKERHUB_USERNAME and DOCKERHUB_TOKEN (Docker Hub → Account Settings → Security → New Access Token, Read & Write).

Available Tools

Read Tools

Tool

Description

get_battery_soc

Battery SoC, voltage, current, power, temperature (+ stale, age_seconds)

get_pv_power

PV/solar charger power, voltage, current, yields (power falls back to V×I)

get_grid_status

Grid power, voltage, current, frequency from the system/0 aggregates

get_inverter_status

Inverter mode, state, AC/DC power, temperature

list_devices

Devices discovered from received MQTT topics

Write Tools (Requires Confirmation)

Tool

Writes to

Notes

set_inverter_mode

W/…/vebus/<instance>/Mode

mode name → enum code via per-device table; unknown combos rejected before publishing

set_charge_current_limit

W/…/vebus/<instance>/Dc/0/MaxChargeCurrent

Amps

set_soc_limit

W/…/battery/<instance>/SocLimit

% — confirm exact BMS path on target battery

MQTT Tools

Tool

Description

mqtt_connect

Connect to the Cerbo gateway and prime the read cache

mqtt_disconnect

Disconnect; cancels all write keepalives

mqtt_subscribe

Stub — reports "not yet implemented" rather than pretending success

Conditional Tool Groups (context-friendly)

Tools are registered only when their service is present, so installations without them never pay tool-schema context:

Group

Detected via

Tools

control

inverter/state topic (inverter-control)

get_control_state() — grid, per-battery detail, MPPT breakdown, tasmota, EV, water level, booleans, inverter state/setpoint in one JSON

pump

tank/<n>/… topics (dbus-pump)

get_tank_level(instance=0)

ssh

SSH_PASSWORD/SSH_KEY_PATH set

Cerbo management toolkit (below)

Multi-instance reads: instance=0{"readings": [...], "total_power": …} for every device of the type; explicit instance=N → single dict.

Cerbo SSH Management

When SSH credentials are configured, these register alongside the broker-detected groups; 🔒 = confirmation-gated:

Tool

Purpose

cerbo_ssh_available / cerbo_version / cerbo_ip

reachability, firmware version, addresses

cerbo_check_updates

firmware dry run

🔒 cerbo_firmware_update

download + apply firmware

🔒 cerbo_enable_ssh

set root password (stdin→chpasswd)

setuphelper_status

SetupHelper + installed packages

🔒 setuphelper_install_package(package, repo) / 🔒 setuphelper_remove_package(package)

SetupHelper package lifecycle

🔒 cerbo_ssh_exec(command)

arbitrary command, output capped

# .env (local/stdio runs)
SSH_HOST=            # defaults to MQTT_HOST
SSH_USER=root
SSH_KEY_PATH=~/.ssh/id_ed25519    # preferred…
# SSH_PASSWORD=                   # …or password
CERBO_ROOT_PASSWORD=              # used by cerbo_enable_ssh when not passed

Docker deployments mount the key instead of passing secrets through .env:

mkdir keys && cp ~/.ssh/<cerbo-key> keys/cerbo_rsa
chown 999:999 keys/cerbo_rsa   # uid of the container's app user
chmod 600 keys/cerbo_rsa       # compose already mounts ./keys:/app/keys:ro
# compose sets SSH_KEY_PATH=/app/keys/cerbo_rsa; remove those lines to use
# SSH_PASSWORD from .env instead
docker compose up -d

To bootstrap access on a fresh Cerbo: GUI → Settings → General → set the root password once (cerbo_enable_ssh automates it from then on).

Clients can discover the live surface at runtime via the MCP resource venus-os://capabilities (also summarized in server instructions); full reference in docs/CAPABILITIES.md.

MQTT Topic Map

The server speaks the Venus OS MQTT-Gateway protocol:

N/<portalId>/<type>/<instance>/<Path>          reads   (published by Venus)
W/<portalId>/<type>/<instance>/<Path>          writes  (published by us)
W/<portalId>/<type>/<instance>/<Path>/Keepalive  empty payload every 50s while a written value must stay active
R/<portalId>                                   request full re-publish
inverter/state                                 inverter-control aggregate
tank/<n>/Level                                 dbus-pump tank level
  • Reads: on connect we subscribe N/<portalId>/# and cache the last value per topic with its receive time; tool output carries stale + age_seconds (threshold MQTT_STALE_AFTER_SECONDS, default 60).

  • Writes: value published as JSON to W/…; Venus expires writes unless <Path>/Keepalive receives an empty payload at least every 60s — we send every 50s and cancel all keepalives on disconnect/shutdown.

  • Verification: after each write the matching N/… topic is polled for up to 5s (WRITE_VERIFY_TIMEOUT_S); timeout → explicit error, never silent success.

Safety Model

Defense runs in order, before any publish:

  1. Confirmation gate (SAFETY_REQUIRE_CONFIRMATION=true): first call without confirmed=true returns a confirmation prompt instead of writing.

  2. Hard limits: charge/discharge current ≤ configured maxima; SoC limits clamped to [SAFETY_MIN_SOC_LIMIT, SAFETY_MAX_SOC_LIMIT]; inverter modes restricted to SAFETY_ALLOWED_MODES.

  3. Mode enum mapping: only modes with a known device-type enum code reach the wire; anything else is rejected pre-publish.

  4. Read-back verification closes the loop — an unacknowledged write is reported as failed.

Known caveats: vebus/inverter/solarcharger Mode enum tables come from Victron's documented enums but should be sanity-checked against your firmware before relying on non-default modes; the exact SoC-limit path depends on the battery BMS. Also note that acceptance ≠ persistence: when another service owns a path (e.g. a BMS driver continuously asserting /Dc/0/MaxChargeCurrent), Venus acknowledges and echoes the written value but re-applies its own within seconds — verified live, where a 45 A write to a BMS-owned 52 A limit echoed successfully and snapped back ~3 s later despite keepalives. The tool reports acceptance; whether the value sticks depends on which service owns the item.

Configuration options:

  • SAFETY_REQUIRE_CONFIRMATION - Require confirmation for write operations (default: true)

  • SAFETY_MAX_CHARGE_CURRENT - Maximum allowed charge current in Amps (default: 100)

  • SAFETY_MAX_DISCHARGE_CURRENT - Maximum allowed discharge current in Amps (default: 100)

  • SAFETY_MIN_SOC_LIMIT - Minimum allowed SoC limit % (default: 10)

  • SAFETY_MAX_SOC_LIMIT - Maximum allowed SoC limit % (default: 100)

  • SAFETY_ALLOWED_MODES - Comma-separated list of allowed inverter modes

Architecture

graph TD
    subgraph "Venus OS Hardware"
        VOS[Venus OS / Cerbo GX]
        DBUS[(D-Bus System Bus)]
        MQTT_BROKER[(MQTT Broker)]
    end

    subgraph "MCP Server (mcp-venus-os)"
        MCP[FastMCP Server]
        DBUS_CLIENT[D-Bus Client]
        MQTT_CLIENT[MQTT Client]
        SAFETY[Safety Validator]
        TOOLS[MCP Tools]
    end

    subgraph "Clients"
        CLAUDE[Claude Desktop]
        OTHER[Other MCP Clients]
    end

    VOS --> DBUS
    VOS --> MQTT_BROKER

    DBUS --> DBUS_CLIENT
    MQTT_BROKER --> MQTT_CLIENT

    DBUS_CLIENT --> TOOLS
    MQTT_CLIENT --> TOOLS
    SAFETY --> TOOLS

    TOOLS --> MCP
    MCP -.->|stdio/JSON-RPC| CLAUDE
    MCP -.->|stdio/JSON-RPC| OTHER

Development

# Install dev dependencies
uv sync --dev

# Run linter
uv run ruff check src/

# Run type checker
uv run mypy src/

# Run tests
uv run pytest

License

MIT License - see LICENSE file for details.

Available Tools

11 tools
get_battery_socA

Get battery state of charge.

instance=0 returns every discovered battery as readings; instance=N a single device dict.

ParametersJSON Schema
NameRequiredDescriptionDefault
instanceNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations present, the description carries the behavioral disclosure burden and does a good job by revealing the dual-mode output behavior for instance=0 versus instance=N. It does not mention error cases or units, but it makes the core conditional behavior visible beyond what the simple schema shows.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler: the purpose is front-loaded and the parameter behavior is stated compactly. Every word contributes to either identification or correct invocation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter getter with an output schema, the description covers the key behavioral branch and parameter interpretation. It lacks only minor context such as source of the instance index or behavior when no devices are found, but these are not critical given the output schema and simple interface.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema provides only an integer parameter with a default and no description, so schema coverage is 0%. The description fully compensates by explaining that 0 aggregates all batteries under 'readings' and non-zero values select a single device dict, giving the parameter meaning beyond its type and default.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource, 'Get battery state of charge,' which uniquely identifies this read operation among getters like get_pv_power and get_grid_status. It also clarifies that instance=0 returns all discovered batteries while instance=N returns a single device, adding scope and removing ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage context is implied by the resource name and first sentence: the agent should call this when it needs battery state-of-charge data. However, there is no explicit guidance about when to prefer this over list_devices or how to choose a valid instance value, and no exclusions or alternatives are named.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_grid_statusA

Get grid/AC status.

instance=0 returns every discovered grid meter as readings; instance=N a single device dict.

ParametersJSON Schema
NameRequiredDescriptionDefault
instanceNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the behavioral disclosure burden. It explicitly reveals the return-shape distinction between instance=0 and instance=N, and the word 'Get' implies a read-only operation. It does not discuss failure modes or empty discovery, but for a simple status query this is adequate transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: the core purpose is stated first, followed by the essential instance-parameter behavior in two terse clauses. Every line earns its place with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter read-only status tool with an output schema, the description covers the key usage and return distinction. It does not mention error handling or how meters become 'discovered', but those are minor gaps given the output schema and simple nature of the tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema provides only a bare integer parameter with a default, and schema description coverage is 0%. The description fully compensates by explaining the semantic difference: instance=0 returns every discovered grid meter as 'readings', while instance=N returns a single device dict. This is exactly the meaning an agent needs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Get') and identifies the resource ('grid/AC status'). It further clarifies behavior by explaining that instance=0 aggregates all discovered grid meters while instance=N returns a single device dict. It does not explicitly compare itself to siblings, but the resource is distinct enough for an agent to distinguish it.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives concrete guidance on how to use the instance parameter (0 vs N), which is useful. However, it does not explicitly state when to prefer this tool over alternatives like get_battery_soc or get_pv_power. The use case is implied by the resource name rather than clearly framed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_inverter_statusA

Get inverter mode and state.

instance=0 returns every discovered vebus unit as readings; instance=N a single device dict.

ParametersJSON Schema
NameRequiredDescriptionDefault
instanceNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden, and it discloses the key behavioral nuance: instance=0 aggregates all discovered vebus units under 'readings', while instance=N returns a single device dict. The verb 'Get' also signals a read-only operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, with the purpose front-loaded and the only parameter explained immediately after. There is no filler, repetition, or unnecessary detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter, read-only getter with an output schema, the description is largely sufficient. It does not mention a possible dependency on the MQTT tools listed as siblings, but that remains an inference rather than a clear requirement.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema only states that instance is an integer defaulting to 0. The description adds the essential semantics: 0 is a sentinel for all units, and a non-zero value selects a single device, which is entirely absent from the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states the action and object directly ('Get inverter mode and state'), then clarifies the data scope with the instance rule. This makes it clearly distinct from write siblings like set_inverter_mode and from getters for other resources.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit when-to-use guidance, exclusions, or alternatives are provided. The agent must infer from the tool name that it is the read counterpart to set_inverter_mode, and there is no mention of list_devices for enumeration or any MQTT prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_pv_powerA

Get PV/solar charger power data.

instance=0 returns every discovered solarcharger/pvinverter as readings plus total_power; instance=N a single device dict.

ParametersJSON Schema
NameRequiredDescriptionDefault
instanceNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It clearly explains the two behaviors: instance=0 returns all discovered devices with readings plus total_power, while instance=N returns a single device dict. This goes beyond the schema and gives actionable behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no redundant wording. The main purpose is front-loaded, and the parameter detail follows in a compact, readable format.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple single-parameter getter, the description covers the core behavior and output shape. An output schema exists, so detailed return structure can be obtained there. Minor gaps like units or error handling do not undermine usability.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema only defines instance as an integer with default 0 and no description. The tool description compensates by explaining the meaning of instance=0 and instance=N, fully covering the semantic range of the parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource ('Get PV/solar charger power data'), clearly identifying the tool's function. It is distinct from siblings like get_battery_soc, get_grid_status, and get_inverter_status, which target different data domains.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage context is implied by the resource name but not explicitly articulated. The description explains what instance values do but does not state when to prefer this tool over alternatives or mention any exclusions. Minimal but adequate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_devicesA

List all Victron devices visible to the server.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are available, so the description carries the full disclosure burden. It only states the action without mentioning that the operation is read-only, how the returned list is structured, or whether it should be used to obtain device IDs for sibling get_* tools. This goes beyond what the schema covers but still leaves key behavioral traits undisclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that is front-loaded with the verb 'List' and contains no filler. Every word contributes to the meaning, making it appropriately concise and well-structured for such a simple tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given that the tool has zero parameters and an output schema exists separately, the description is nearly complete. It would benefit from a brief note on use with sibling tools or clarification of 'visible to the server,' but these are minor gaps for a straightforward list operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has zero parameters, so there is nothing to explain. The description correctly implies that no arguments are required. Baseline for 0 params is 4, and no additional parameter documentation is needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('List') and a clear resource ('all Victron devices visible to the server'). It distinguishes itself from sibling get_* tools, which retrieve specific metrics, and from set_* tools that modify state. No ambiguity or tautology exists.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not explicitly say when to use this tool vs alternatives, nor does it mention any exclusions. The use case is implied by the nature of listing all devices, and the sibling tools are clearly per-device queries, so an agent can infer it is for discovery/enumeration. However, no explicit routing guidance is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

mqtt_connectB

Connect to MQTT broker for real-time data.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description must disclose behavioral traits, but it only says 'Connect to MQTT broker'. It does not clarify whether the connection is persistent, whether authentication is required, what side effects occur, or if there are any limitations. This is a significant gap for a connection-establishing operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence that effectively states the core action. It is front-loaded and avoids unnecessary detail, though it could provide more context without becoming verbose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simplicity of the tool (0 params) and the presence of an output schema, the description is adequate for basic understanding, but it fails to explain important context such as the relationship to mqtt_subscribe and mqtt_disconnect. The lack of usage guidance and behavioral transparency makes it incomplete for the agent to select and invoke correctly in a sequence of operations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has zero parameters, so there is nothing for the description to clarify. The schema coverage is 100% vacuously, and per the baseline for 0 params, the description does not need to add parameter semantics. It correctly remains silent on parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Connect to MQTT broker') and purpose ('real-time data'), which distinguishes it from sibling tools like mqtt_disconnect and mqtt_subscribe. It is specific and unambiguous, though it does not elaborate on the scope beyond 'real-time data'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool. It does not mention any prerequisites, alternatives, or that it should be called before mqtt_subscribe or after mqtt_disconnect. The agent is left without context for when this is appropriate relative to siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

mqtt_disconnectA

Disconnect from MQTT broker.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden of behavioral disclosure. It only states the action, not what happens if already disconnected, whether subscriptions are cleaned up, or any side effects. This is a significant gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, focused sentence with no wasted words. It is appropriately sized for such a simple operation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the zero-parameter simplicity, the description is adequate but lacks context about prerequisites (e.g., an active connection being required). Sibling tools imply the need to connect first, but the description itself is minimal.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the baseline is 4. The description does not need to explain parameter details, and the schema confirms no parameters exist.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action: 'Disconnect from MQTT broker.' It uses a specific verb and resource, and is distinct from sibling tools like mqtt_connect and mqtt_subscribe.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage (when you want to end the MQTT connection) but provides no explicit when-to-use or alternatives. Sibling tools context helps, but the description itself offers no guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

mqtt_subscribeA

Subscribe to MQTT topic pattern.

Not yet implemented - returns an error.

ParametersJSON Schema
NameRequiredDescriptionDefault
topic_patternYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description explicitly discloses a critical behavioral trait: 'returns an error' because it is 'not yet implemented.' This goes far beyond what annotations (none provided) would convey. It honestly tells the agent that any invocation will fail, which is exactly the kind of behavior an agent needs to know. There is no ambiguity about the tool's current executability.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences, with the core action front-loaded and the critical caveat immediately following. Every word earns its place: the first sentence states the intended purpose, the second explicitly warns of non-implementation and the resulting error. There is no fluff, redundancy, or unnecessary detail, making it highly efficient for an agent to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a stub tool with a single parameter and no annotations, the description is largely complete: it tells the agent the tool is not functional and will return an error, which is the most important fact. The output schema exists, so detailed return values are not the description's responsibility. The only gap is the absence of any guidance on what to do instead (e.g., no mention of an alternative subscription tool or a future implementation date), but this is a minor omission given the tool is clearly non-functional.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema contains one parameter, 'topic_pattern,' with no schema-level description (0% coverage). The tool description says 'Subscribe to MQTT topic pattern,' which essentially restates the parameter name without adding semantics. It does not explain MQTT wildcard syntax (e.g., '+', '#'), the expected format, or any constraints on the pattern. Given the lack of schema coverage, the description fails to compensate, providing minimal added meaning beyond the parameter name.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the intended operation: 'Subscribe to MQTT topic pattern.' This uses a specific verb ('subscribe') and resource ('MQTT topic pattern'), and distinguishes it from siblings like mqtt_connect and mqtt_disconnect by naming a different action. However, the immediate disclaimer 'Not yet implemented - returns an error' tempers the clarity; the agent must reconcile the stated purpose with the actual non-functional behavior. It is not a tautology, and enough detail exists to understand the tool's intent.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides an implicit usage guideline: since the tool is not yet implemented and returns an error, it should not be relied upon for actual MQTT subscriptions. However, it does not explicitly say 'do not use' or recommend any alternative tool or workflow. 'Not yet implemented' implies the agent should avoid calling it, but no when/when-not conditions or sibling alternatives are mentioned, leaving the agent to infer that this tool is currently a stub.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

set_charge_current_limitA

Set maximum charge current limit in Amps.

Requires confirmation for write operations.

ParametersJSON Schema
NameRequiredDescriptionDefault
currentYes
instanceNo
confirmedNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of disclosing behavior. It does state that the operation is a write that requires confirmation, which is important context. However, it does not explain what happens upon confirmation, whether the setting persists, any side effects, or potential errors. The behavioral disclosure is minimal beyond the confirmation note.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The purpose is front-loaded in the first sentence, and the second sentence adds crucial operational guidance. Every word earns its place, making it highly concise and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is relatively simple, and an output schema exists, so return values are covered. However, the description lacks context around the 'instance' parameter and does not elaborate on when or how the tool should be used in a broader workflow. It is adequate but leaves notable gaps, especially given the confirmation semantics that could be more deeply explained.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It explains that 'current' is the maximum charge current in Amps and indirectly explains 'confirmed' via the write-confirmation note. However, it completely omits the 'instance' parameter, leaving its meaning and role unclear. The description only partially clarifies the parameters and fails to cover all three.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's action ('Set maximum charge current limit') with a specific resource and unit ('in Amps'), which unambiguously distinguishes it from sibling tools like set_soc_limit and set_inverter_mode. The verb-resource pairing is precise and self-contained.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description mentions 'Requires confirmation for write operations,' which provides a prerequisite for using the tool. However, it does not explicitly state when to use this tool versus alternatives, nor does it provide scenarios or exclusions. The guidance is limited to the confirmation requirement, so it is only partially helpful.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

set_inverter_modeB

Set inverter mode (on, off, charger_only, inverter_only, eco).

Requires confirmation for write operations.

ParametersJSON Schema
NameRequiredDescriptionDefault
modeYes
instanceNo
confirmedNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Since no annotations are provided, the description carries full disclosure burden. It identifies the operation as a write requiring confirmation, which is useful, but it does not explain what happens when confirmation is missing, whether the change is reversible, or any system impact. Behavior is only partially disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with no filler. The mode list is directly useful, and the confirmation note is a necessary constraint. It is appropriately sized for the information it conveys.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Although an output schema exists, the description lacks essential context: no usage guidance, no parameter semantics for instance/confirmed, and no behavioral consequences beyond confirmation. For a mutation tool with no annotations, this is insufficient for an agent to reliably invoke it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 0% description coverage, so the description must explain all parameters. It lists the mode values but does not define them. The 'instance' parameter is entirely absent, and 'confirmed' is only implied by 'Requires confirmation,' not clearly mapped to the parameter. Significant semantic gaps remain.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Set' and the resource 'inverter mode', and lists the accepted modes. This distinguishes it from sibling setters like set_charge_current_limit and set_soc_limit because the target parameter is explicitly named.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives. The only operational note, 'Requires confirmation for write operations', is a prerequisite rather than a usage condition, and it does not mention preconditions or alternative tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

set_soc_limitB

Set battery SoC limit percentage.

Requires confirmation for write operations.

ParametersJSON Schema
NameRequiredDescriptionDefault
instanceNo
confirmedNo
soc_limitYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses that the tool 'Requires confirmation for write operations,' which adds a key behavioral trait beyond the raw schema. However, it does not clarify how confirmation is provided (e.g., via the confirmed parameter), what happens if not confirmed, or any side effects. With no annotations, the description carries a heavier burden, but this is only partially fulfilled.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise: two sentences, front-loaded with the core purpose. Every sentence earns its place with no redundant or filler content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

While an output schema exists (so return values are presumably covered), the tool has multiple parameters and a confirmation mechanism that is under-specified. The description lacks vital context about how to execute a write (setting confirmed=true?), value ranges for soc_limit, and differences from sibling set tools. This leaves the agent uncertain about safe and correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must explain the parameters. It implies that soc_limit is a percentage, but instance and confirmed are entirely undocumented. The confirmation requirement hints at the confirmed parameter's purpose, but the mechanism and constraints are not explained.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Set battery SoC limit percentage' clearly identifies the action (set) and the resource (battery SoC limit), and it is distinct from sibling tools like get_battery_soc or set_charge_current_limit. The purpose is unambiguous and directly maps to the tool name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives, or any prerequisites or exclusions beyond a vague confirmation requirement. It does not mention that this is for adjusting battery state-of-charge limits in contrast to other charge-related settings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 11 tool updatesv0.1.0
    • First observedget_battery_soc
    • First observedget_grid_status
    • First observedget_inverter_status
    • First observedget_pv_power
    • First observedlist_devices
    • First observedmqtt_connect
    • First observedmqtt_disconnect
    • First observedmqtt_subscribe
    • First observedset_charge_current_limit
    • First observedset_inverter_mode
    • First observedset_soc_limit

TDQS

A3.7/5.0
Disambiguation5/5

Each tool targets a distinct device metric, setting, or MQTT lifecycle action. Read, write, and connection verbs create clear boundaries, and no two tools appear to perform the same operation.

Naming Consistency5/5

Tool names follow a consistent snake_case verb_noun pattern: get_* for reads, set_* for writes, and mqtt_* for connection controls. list_devices is the only slight deviation but remains conventional and predictable.

Tool Count5/5

With 11 tools, the server is well-scoped for a Victron monitoring and control interface. The count is substantial enough to cover core operations without feeling bloated or redundant.

Completeness3/5

The main monitoring and control surface is solid, but there is no direct load/consumption tool, which is a notable gap for energy management. Additionally, mqtt_subscribe is explicitly unimplemented, creating a dead end for real-time streaming workflows.

Maintenance

ActivityActive
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    Connect AI assistants to Victron Energy systems to read real-time solar, battery, grid, and inverter data from your local network via Modbus TCP or MQTT.
    32
    136
    3
    MIT
  • A
    license
    B
    quality
    D
    maintenance
    Read-only MCP server integrating with the Victron VRM API to monitor solar systems, batteries, alarms, and more.
    41
    25
    6
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A powerful MCP server that enables AI assistants like Claude to access, analyze, and optimize solar energy data from FoxESS inverters.
    3
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    MCP server for Solplanet ASW5-T inverter, enabling natural language queries about solar energy system status and control.
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/4alvit/mcp-venus-os'

If you have feedback or need assistance with the MCP directory API, please join our Discord server