sigenergy-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@sigenergy-mcpwhat's my solar generation, battery charge, and grid usage?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
sigenergy-mcp
An MCP server for monitoring and controlling a Sigenergy energy system (SigenStor, Sigen hybrid inverters) locally over Modbus TCP — no cloud account needed.
It exposes live PV, battery, grid and load data, inverter details and Sigen EV charger status as MCP tools, and (optionally) control tools for remote EMS mode, battery charge/discharge limits, grid export/import limits, SOC limits and EV charging.
Prerequisites
Enable Modbus TCP on your Sigenergy system. In the mySigen app (installer account) go to the device → Settings → Communication → Modbus TCP Server and turn it on. Your installer can do this for you if you don't have access.
Give the system a static IP / DHCP reservation on your LAN.
Note the Modbus device ids: the plant (whole system, aggregated by the EMS) is
247; inverters start at1(multiple inverters are1,2, …). A Sigen AC charger normally takes id1, so the inverter is moved to another id (e.g.2). A DC charger answers on its inverter's id. If you're unsure, run thediscover_devicestool once — it reports the ids and the settings to use.Python 3.10+.
Related MCP server: EG4 MCP Server
Install
pip install git+https://github.com/aydho/sigenergy-mcp
# or, from a checkout
pip install -e .Or run without installing using uv:
uvx --from git+https://github.com/aydho/sigenergy-mcp sigenergy-mcp --host 192.168.1.50Configuration
Environment variable | CLI flag | Default | Description |
|
| — | IP address of the Sigenergy system (required) |
|
|
| Modbus TCP port |
|
|
| Plant device id |
|
|
| Comma-separated inverter device ids |
|
| — | AC charger (EVAC) device ids, usually |
|
| — | DC charger (EVDC) ids = the inverter's id |
|
|
| Enable control (write) tools |
|
| — | File to append a JSON line to for every write |
| — | Bearer token required by the HTTP transport | |
| — | Allowed | |
|
| Modbus request timeout, seconds | |
|
| Python log level |
Writes are off by default: the control tools aren't even listed to the client until you opt in.
Claude Desktop / Claude Code
{
"mcpServers": {
"sigenergy": {
"command": "sigenergy-mcp",
"env": {
"SIGENERGY_HOST": "192.168.1.50",
"SIGENERGY_INVERTER_IDS": "2",
"SIGENERGY_AC_CHARGER_IDS": "1",
"SIGENERGY_ALLOW_WRITES": "false"
}
}
}
}With Claude Code:
claude mcp add sigenergy -e SIGENERGY_HOST=192.168.1.50 -- sigenergy-mcpHTTP transport
To run it as a network service (e.g. on a Raspberry Pi next to the inverter):
export SIGENERGY_HTTP_TOKEN=$(openssl rand -hex 32)
export SIGENERGY_HTTP_ALLOWED_HOSTS=pi.local:8000,192.168.1.20:8000
sigenergy-mcp --host 192.168.1.50 --transport streamable-http --http-host 0.0.0.0 --http-port 8000
# MCP endpoint: http://<pi>:8000/mcp — clients send "Authorization: Bearer <token>"claude mcp add --transport http sigenergy http://pi.local:8000/mcp \
--header "Authorization: Bearer $SIGENERGY_HTTP_TOKEN"The server refuses to listen on a non-loopback address without a token (override with
--allow-unauthenticated only if an authenticating proxy sits in front).
Security
Modbus TCP itself has no authentication or encryption. Anything that can reach the Sigenergy system on port 502 can read every register and change its settings; the device id is just an address, not a secret. This server can't change that, so:
Never port-forward 502 to the inverter. Keep it on your LAN, ideally on its own VLAN/IoT network with firewall rules so only the machine running this server (or Home Assistant) can reach port 502.
SIGENERGY_ALLOW_WRITESonly controls what this server will do. It doesn't stop other devices on your network writing to the inverter directly.
What the server does to protect its own interface:
Read-only by default. Without
SIGENERGY_ALLOW_WRITES=truethe control tools are removed from the server, so a client can't see or call them. Every write is still range- and enum-checked.Audit log. Set
SIGENERGY_AUDIT_LOG=~/sigenergy-audit.jsonlto record every write attempt (time, device, register, previous value, new value, success or error), so you can see and undo what was changed.HTTP transport. It binds to
127.0.0.1by default, with Host/Origin checks against DNS rebinding. When exposed on the network it requires a bearer token (SIGENERGY_HTTP_TOKEN), compared in constant time; setSIGENERGY_HTTP_ALLOWED_HOSTSto keep the Host/Origin checks too. Pass the token in the environment rather than on the command line so it doesn't show inps.TLS. The server speaks plain HTTP. For HTTPS or access from outside your home, put it behind Tailscale / WireGuard or a reverse proxy such as Caddy rather than opening a port.
Tools
Monitoring (read-only)
Tool | Description |
| PV, battery, grid and load power, SOC, EMS mode, running state, decoded active alarms |
| SOC, SOH, power, rated/available energy, power limits, cut-off SOCs |
| Grid power (total and per phase), on/off-grid status |
| kWh counters: PV today/yesterday/lifetime, load, battery charge/discharge, grid import/export |
| Per-inverter power, battery, energy counters, temperatures, AC phases, PV strings |
| Model, serial number, firmware, ratings |
| AC charger state (no vehicle / connected / charging…), power, energy, alarms; DC charger state, power, vehicle SOC, session energy |
| Scan device ids to find the plant, inverters and EV chargers, with suggested settings |
| Current remote EMS settings, power limits and SOC limits |
| All named registers with address, type, unit and gain |
| Read named registers |
| Read any address (for registers not in the map) |
Control (requires SIGENERGY_ALLOW_WRITES=true)
Tool | Description |
| Enable remote EMS and set mode (standby, self-consumption, command charge/discharge…) |
| Enable/disable remote EMS (disable to hand control back to the built-in EMS) |
| Max charge / discharge power (kW) |
| Max grid export / import (kW) |
| Limit PV output (kW) |
| Backup SOC, charge cut-off and discharge cut-off (%) |
| Start or stop charging on the AC or DC charger |
| AC charging current (A), checked against the charger's rated and breaker current |
| DC charger max charge / discharge (V2G) power (kW) |
| Write any writable register in the map by name |
Sign conventions
grid_active_power> 0 = importing from the grid, < 0 = exporting.ess_power> 0 = battery charging, < 0 = discharging.load_poweris read from the system's load register (30282) on newer firmware, otherwise derived as plant AC output + grid power + third-party PV − AC charger power (so it excludes EV charging).
Example: force-charge the battery from the grid at 5 kW
set_remote_ems_mode(mode=3)— command charging (grid first)set_battery_power_limits(max_charge_kw=5)Later,
set_remote_ems_enabled(false)to return to normal operation.
Register map
The register map lives in src/sigenergy_mcp/registers.py
and follows the Sigenergy Modbus Protocol (V2.x). Available registers can vary with
firmware version; registers the device rejects are reported per-register in an
errors field instead of failing the whole call. Registers that answer "illegal data
address" are remembered per device and skipped on later calls. Use read_raw_registers
for anything not yet mapped.
Addresses, types and gains are cross-checked against TypQxQ/Sigenergy-Local-Modbus, the field-tested Home Assistant integration; alarm bit descriptions are adapted from it (MIT).
Development
pip install -e '.[dev]'
pytestThe tests run the MCP tools end-to-end against an in-process pymodbus simulator.
Disclaimer
Not affiliated with Sigenergy. Writing Modbus registers changes how your system operates — use the control tools at your own risk and check settings in the mySigen app afterwards.
Available Tools
12 toolsdiscover_devicesARead-only
Scan Modbus device ids to find the plant, inverters, DC chargers and AC chargers.
Probes ids 1..max_device_id in order and stops at the first id that doesn't answer. Use the result to set SIGENERGY_INVERTER_IDS, SIGENERGY_AC_CHARGER_IDS and SIGENERGY_DC_CHARGER_IDS.
| Name | Required | Description | Default |
|---|---|---|---|
| max_device_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover readOnlyHint and openWorldHint, so the description focuses on the scan algorithm — sequential probing and stop-on-first-miss — which is important non-obvious behavior. It doesn't mention timeouts, error handling, or scan duration, but the core behavioral trait (early termination) is disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loaded with purpose then the probing mechanism and downstream use. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Output schema exists, so return values needn't be described. Given annotations and the simple one-parameter surface, the description covers what's needed to call correctly, though it could note that a full miss-heavy scan may take time or that max_device_id bounds the scan cost.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% and the single parameter max_device_id has only a default of 16, no description. The description implies the parameter is the upper bound of the probe range, which adds some meaning, but doesn't explain the default or valid range beyond the name.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Scan/probe) and resource (Modbus device ids for plant, inverters, DC/AC chargers). It clearly distinguishes itself from read-oriented siblings like get_inverter_status or read_registers by being a discovery tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains it probes ids 1..max_device_id in order and stops at the first non-answering id, and says to use the result to set environment variables. It doesn't name an alternative tool or say when NOT to use it, but the context of use (bootstrapping configuration) is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_battery_statusBRead-only
Battery (ESS) state for the whole plant: SOC, SOH, power, capacity, available energy and limits.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds only a list of returned metrics, which is largely duplicated by the existing output schema, and says nothing about whether values are instantaneous snapshots, cached, or how often they refresh.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with the resource named first and no filler. Slightly over-enumerated on returned fields given an output schema already exists, but nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-param read-only status tool with annotations and a full output schema, the description is essentially sufficient – the return shape is documented elsewhere. What is missing is the usage framing that would tell an agent when to prefer this over the other *_status siblings.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the schema is empty and there is nothing for the description to disambiguate. Baseline 4 applies for a no-argument tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource (Battery/ESS state) and scope (whole plant), and enumerates the metrics returned (SOC, SOH, power, capacity, energy, limits). It is clearly distinguishable from get_grid_status or get_inverter_status by name, but never explicitly says what it is not, so sibling differentiation is only implied.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no mention of the sibling status tools (get_inverter_status, get_grid_status, get_plant_status), and no stated preconditions. The agent must infer from the name alone that this is the battery-specific status call rather than a plant-wide one.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_control_settingsBRead-only
Current plant control settings: remote EMS enable/mode, power limits and SOC limits.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds the useful detail of which control values are returned, but says nothing about whether these settings are cached, how fresh they are, or whether a companion setter tool exists. With annotations carrying the behavioral load, a 3 is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single compact sentence with the resource front-loaded and the returned fields listed in order of importance. No filler, though the fragment lacks a verb, making it slightly less self-explanatory than it could be.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description need not explain return values, and it correctly stops at naming the setting categories. For a zero-parameter read-only tool this is close to complete; only the distinction from sibling status tools is left implicit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes no parameters, so the baseline of 4 applies. There is no argument semantics for the description to clarify beyond the returned field list, which it does provide.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the specific resource (plant control settings) and enumerates what it exposes: remote EMS enable/mode, power limits, and SOC limits. That is enough to distinguish it from status siblings like get_plant_status or get_battery_status, which report measurements rather than configured control values.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit guidance on when to call this versus the many sibling status tools, nor any stated prerequisites or exclusions. The intended use (inspecting current control configuration) is only inferred from the field list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_energy_totalsARead-only
Plant energy counters (kWh): PV, load, battery, grid import/export and EV charger totals.
These registers need Modbus protocol V2.5+ firmware; any the system doesn't support are listed in errors.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint/openWorldHint annotations, the description discloses a real operational prerequisite (Modbus protocol V2.5+ firmware) and the failure mode (unsupported registers appear in `errors`). That is meaningful context an agent could not derive from annotations alone, though no rate-limit or caching behavior is mentioned.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the resource and payload categories, followed by the firmware caveat. Every clause carries information; no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be spelled out, yet the description still adds the non-obvious `errors` field semantics and the firmware gate. For a zero-parameter read tool this is close to complete, missing only the error/empty-state behavior when the firmware is too old.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4. The description correctly implies no filtering input is needed for this aggregate read.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource (plant energy counters in kWh) and enumerates the sub-categories covered: PV, load, battery, grid import/export, EV charger. This is clearly distinct from status-oriented siblings like get_plant_status or get_battery_status, though it does not explicitly name a sibling it should not be confused with.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the content — an agent can infer this is the cumulative-totals tool rather than a live-status tool. However there is no explicit when-to-use/when-not statement nor any reference to alternative tools for per-device counters, leaving routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_ev_charger_statusARead-only
Status of every configured Sigen EV charger.
AC chargers (EVAC): state (IEC 61851: no vehicle / connected / charging...), charging power, energy, ratings, alarms. DC chargers (EVDC, built into a SigenStor): state, output power, vehicle SOC, session energy and duration, lifetime totals and power limits.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is free. The description adds real value by spelling out the per-charger-type payload (states, power, SOC, session duration, lifetime totals, limits), but says nothing about behavior such as what happens with zero configured chargers or how current the readings are.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded summary sentence, then a compact two-line enumeration keyed by charger type. No filler, though the payload listing is slightly redundant against the output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described, and with no parameters there is little else to cover. The AC/DC breakdown is a nice completeness touch; only the absent usage conditions keep this short of full marks.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so the baseline of 4 applies. The description correctly implies an unfiltered, whole-system read, matching the empty argument object.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Status of every configured Sigen EV charger') and then enumerates the returned data separately for AC (EVAC) and DC (EVDC) hardware. The resource is unambiguous relative to siblings like get_battery_status, get_inverter_status, and get_grid_status.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to call this versus alternatives, no preconditions, and no exclusions. 'Every configured' hints there is no filtering argument, but the agent gets no explicit usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_grid_statusBRead-only
Grid connection point: total and per-phase active/reactive power and on/off-grid status.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety and locality profile is covered. The description adds the scope of returned data (total plus per-phase, active and reactive, grid connection state), which is useful context, but it discloses nothing about freshness, caching, or error behavior beyond that.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single telegraphic sentence with the resource front-loaded and zero filler. Every clause carries content and nothing is repeated from the schema or annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, read-only tool with an output schema documenting return values and annotations covering safety, the description is serviceable but thin: it offers no usage guidance or sibling routing, which is the one thing structured fields cannot supply. It is adequate rather than complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters and schema coverage is 100%, so there is nothing for the description to compensate for; the baseline of 4 applies. No parameter syntax or defaults are needed for a no-argument read.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a distinct resource (the grid connection point) and enumerates the data it exposes (total and per-phase active/reactive power, on/off-grid status), which is enough to separate it from get_plant_status, get_inverter_status, and get_battery_status by device scope. It stops short of a clear verb and never explicitly contrasts itself with those siblings, so it is clear but not maximally differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to call this versus the many sibling status tools (get_plant_status, get_energy_totals, get_inverter_status). An agent must infer that this is the tool for grid-connection data purely from the resource name in the sentence.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_inverter_infoARead-only
Static inverter information: model, serial number, firmware and ratings.
Args: inverter_id: Modbus device id of the inverter. Omit to read every configured inverter.
| Name | Required | Description | Default |
|---|---|---|---|
| inverter_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds genuine value beyond that: it establishes the data is static rather than live status, and it discloses the fan-out behavior when inverter_id is omitted (reads every configured inverter). It does not mention connection prerequisites or error behavior, but the core behavioral profile is clear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the resource and payload fields, followed by a compact Args block. Every sentence carries information; the docstring-style 'Args:' formatting is slightly mechanical but not wasteful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the single parameter is documented. The main omission is any routing help relative to the many sibling status/read tools, but for a simple static-read tool the description is otherwise sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must carry the parameter alone, and it does: inverter_id is identified as a Modbus device id, marked optional via 'Omit', and its fallback semantics are spelled out. This fully compensates for the missing schema description, though it adds no range/format detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Static inverter information') and enumerates the returned fields: model, serial number, firmware and ratings. The word 'Static' implicitly contrasts with the dynamic sibling get_inverter_status, but it never names that sibling, so the distinction is left to inference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The only usage guidance is parameter-level: 'Omit to read every configured inverter.' There is no explicit when-to-use-this vs get_inverter_status or the other status tools, so tool selection is only implied by the 'static' framing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_inverter_statusARead-only
Detailed live data for a hybrid inverter: power, battery, temperatures, AC voltages/currents and PV strings.
Args: inverter_id: Modbus device id of the inverter. Omit to read every configured inverter.
| Name | Required | Description | Default |
|---|---|---|---|
| inverter_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds real behavioral context beyond that: the call returns live (real-time) data rather than cached/config values, and omitting the id fans out across every configured inverter. No rate-limit or error behavior is mentioned, keeping it out of the top band.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences plus a short Args block, with the resource and returned fields front-loaded. Efficient and scannable; the Args block slightly duplicates schema structure but earns its place by supplying the omitted-id semantics.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be detailed, and the read-only annotations cover the mutation question. With a single optional parameter whose meaning is explained, the definition supplies everything required to invoke it correctly; only sibling routing is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the burden, and it does compensate: inverter_id is identified as a Modbus device id and the null/default case is explained as 'read every configured inverter.' That meaningfully exceeds the bare integer/anyOf schema, though it doesn't give format or valid-range details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific resource (hybrid inverter status) and enumerates the data returned (power, battery, temperatures, AC voltages/currents, PV strings). It distinguishes itself from siblings somewhat by emphasizing 'live data,' which separates it from get_inverter_info, but it never names that sibling explicitly, so the boundary must be inferred.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The only guidance is the parameter-level note that omitting inverter_id reads every configured inverter. There is no statement of when to prefer this tool over get_inverter_info, get_plant_status, or get_battery_status, so the agent must infer routing from the 'live data' framing alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_plant_statusARead-only
Live overview of the whole system: PV, battery, grid and load power, battery SOC, mode and active alarms.
load_power comes from the system's own load register on newer firmware; otherwise it is derived as
plant AC output + grid power + third-party PV - AC EV charger power.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds genuinely non-obvious behavior: it discloses that load_power is a derived proxy on older firmware (plant AC output + grid power + third-party PV - AC EV charger power) rather than a measured register, which prevents the agent from misreporting the value. It does not mention polling/rate considerations, keeping it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The primary sentence front-loads the resource and its contents in a colon-delimited list with no filler. The second paragraph earns its place by qualifying one field, though the hard line break mid-sentence makes it read slightly awkwardly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-argument, read-only snapshot tool with an output schema, the description is close to sufficient: the output schema supplies the field types and the description supplies the aggregation scope plus the one semantic trap (derived load_power). It omits alarm/mode enumeration semantics, which the output schema likely covers only as types.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so there is nothing for the description to disambiguate; the baseline for a no-param tool is 4. The field-level note about load_power is a return-value caveat rather than a parameter concern.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('live overview of the whole system') and enumerates exactly what is returned: PV, battery, grid and load power, battery SOC, mode and active alarms. The 'whole system' framing distinguishes it from the narrower siblings get_grid_status, get_battery_status and get_inverter_status without the agent needing to open a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Live overview' implies a real-time snapshot use case, which implicitly contrasts with get_energy_totals (historical aggregates), but the description never states when to prefer the per-component siblings or when this aggregate is unnecessary. Usage is inferred rather than stated, so this lands at the minimum-viable level.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_registersBRead-only
List the named registers known to this server for the plant or an inverter.
| Name | Required | Description | Default |
|---|---|---|---|
| scope | No | plant |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so safety and locality are covered. The description adds one useful behavioral hint — that the register set is server-known rather than device-probed — but says nothing about pagination, size of the returned list, or auth requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler; the resource and scope constraint land immediately.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and one optional parameter is a light burden. Still, for a listing tool sitting beside read_registers and read_raw_registers, the definition should say how the three relate — that omission is the main completeness gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description only mentions "the plant or an inverter," omitting two of the four enum values (ac_charger, dc_charger). This is less compensation than the gap requires and could mislead an agent about the valid scope set.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ("List") and resource ("named registers") plus the scope of the listing, so an agent can tell it apart from value-reading siblings like read_registers and read_raw_registers. It stops short of explicitly contrasting itself with those siblings, which is the only thing keeping it off a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase "known to this server" implies this is a discovery/metadata call rather than a value read, but the description never states when to use this instead of read_registers or read_raw_registers. Usage is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_raw_registersARead-only
Read arbitrary registers by address, for registers not in the built-in map.
Args: address: Start register address as given in the Sigenergy Modbus protocol (e.g. 30014). count: Number of 16-bit words to read (1-125). device_id: Modbus device id. Defaults to the plant id (247). register_type: "input" (function 0x04) or "holding" (0x03). Defaults to input for 3xxxx, holding otherwise. data_type: Optionally decode the words as this type.
| Name | Required | Description | Default |
|---|---|---|---|
| count | No | ||
| address | Yes | ||
| data_type | No | ||
| device_id | No | ||
| register_type | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint already covering the safety profile, the description adds real operational context: valid count range (1-125), the device_id default (plant id 247), the function codes behind each register_type, and the default-selection rule tied to 3xxxx addresses. It does not mention rate limits or error behavior, but for a safe read this is substantial added value.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded one-line summary followed by an Args block per parameter; every line carries information. The only minor redundancy is per-parameter text that partially restates enum values already in the schema, but it is not wasted space.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Output schema exists, so return values need not be described, and the description covers all five inputs including defaults and format examples. It is essentially complete for the task, with only minor gaps around error conditions or multi-register decoding behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden and largely does: it explains address format with a concrete example (30014), count units and bounds, device_id default, the semantics of both register_type values with their Modbus function codes, and the purpose of data_type. This substantially exceeds what the bare schema conveys.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Read arbitrary registers by address') plus the scope that separates it from siblings ('registers not in the built-in map'), implicitly contrasting with read_registers/list_registers. An agent can pick it out without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'for registers not in the built-in map' gives a clear condition for choosing this tool over the mapped-register siblings. It stops short of naming the alternative tool or stating explicit exclusions, but the routing signal is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_registersARead-only
Read named registers (see list_registers) and return scaled values with units.
Args: names: Register names, e.g. ["ess_soc", "pv_power"]. scope: "plant" (system level), "inverter", "ac_charger" or "dc_charger". device_id: Modbus device id. Defaults to the plant id (247) or the first configured device of that kind.
| Name | Required | Description | Default |
|---|---|---|---|
| names | Yes | ||
| scope | No | plant | |
| device_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already tells the agent this is a safe read, and the description adds real behavioral context: values are scaled with units, and device_id resolves to the plant id (247) or the first configured device of that scope when omitted. It does not mention failure modes, invalid-name behavior, or batching/rate limits, so it is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The one-line summary is front-loaded and followed by a tight three-item Args block. Minor redundancy with the schema's enum list, but every line carries information and nothing is padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With readOnly/openWorld annotations and an output schema present, return values need not be described. All three parameters, the scope set, and the device resolution fallback are covered, leaving only error/degraded-read behavior unstated for a tool of this complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden and largely does: it gives example names, explains each scope enum value (e.g. 'plant (system level)'), and, most importantly, documents the device_id default resolution logic that the schema only shows as null. Only the array item typing and required-ness are left to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource (read named registers) and adds the outcome (scaled values with units), which distinguishes it from read_raw_registers. It also cross-references list_registers for name discovery. It stops short of explicitly contrasting itself with read_raw_registers, so it is clear but not fully sibling-differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The parenthetical 'see list_registers' implies you must enumerate names first, which is useful routing guidance. However, there is no explicit statement of when to choose this over read_raw_registers or how scope selection relates to the sibling status tools (get_inverter_status, get_battery_status, etc.). Usage is implied rather than stated.
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.
12 tool updates
v0.1.0- First observed
discover_devices - First observed
get_battery_status - First observed
get_control_settings - First observed
get_energy_totals - First observed
get_ev_charger_status - First observed
get_grid_status - First observed
get_inverter_info - First observed
get_inverter_status - First observed
get_plant_status - First observed
list_registers - First observed
read_raw_registers - First observed
read_registers
TDQS
Scored across 12 tools
Each tool targets a distinct subsystem (plant, grid, battery, inverter, EV charger, energy totals, registers), so boundaries are mostly clear. The only mild overlap is that get_plant_status summarizes data also exposed by the individual status tools, but descriptions clarify the live-overview vs subsystem-detail distinction.
Names follow a consistent verb_noun snake_case pattern (get_*_status, get_*_info, list_registers, read_registers, read_raw_registers, discover_devices). The verbs (get/list/read/discover) map predictably to action type.
12 tools is well within the sweet spot for a monitoring/inspection domain, and each earns its place by covering a distinct device or data access layer.
The read surface is thorough: live status, static info, energy counters, settings, named-register and raw-register access, device discovery, and EV charging. The notable gap is write/control operations (e.g. setting power or SOC limits) implied by get_control_settings, though read_raw_registers partially mitigates unmapped reads.
Maintenance
Related MCP Connectors
Protocol-native energy infrastructure orchestration for AI data centers. Provides 46 MCP tools across 8 grid protocols (IEC-61850, DNP3, Modbus, OCPP, OpenADR, IEEE 2030.5, IEC 60870-5-104, ICCP) with 5 core API primitives: connect, dispatch, settle, comply, and intel. Enables AI agents to programmatically interact with substations, grid interfaces, and energy assets for real-time workload-grid coordination.
Home energy for AI assistants: live Power flow, Energy history, solar forecast, and device control.
Operate a network of EV charge points over OCPP: status, sessions, tariffs, prices, remote commands
Unofficial integration! ## ✨ Key Features ### 💰 Financial Intelligence - **Smart Charging Cost An…
Related MCP Servers
- AlicenseAqualityAmaintenanceConnect 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.3262 npm4MIT
- AlicenseNot gradedqualityDmaintenanceMCP server for EG4 solar inverters, enabling real-time monitoring, performance analysis, battery health, alerts, maintenance insights, and historical data via natural language.MIT
- FlicenseAqualityDmaintenanceEnables monitoring and control of IDM Navigator 2.0 heat pumps via Modbus TCP.13-
- AlicenseNot gradedqualityCmaintenanceEnables Entra-authorized monitoring and control of an EG4 inverter via MCP, with OBO delegation and safety gates.MIT