Skip to main content
Glama
Home Assistant MCP Server

Home Assistant MCP Server

Official

Manage Energy Dashboard Preferences

ha_manage_energy_prefs
Destructive

Configure Home Assistant Energy Dashboard preferences: manage grid, solar, battery, gas, and water sources, device consumption sensors, and cost tariffs.

Instructions

Manage the Home Assistant Energy Dashboard preferences: grid / solar / battery / gas / water energy sources, device consumption sensors for electricity and water, and cost tariffs.

WHEN NOT TO USE:

  • To create the underlying statistics themselves — they must already exist as HA entities before being referenced here; create them via the relevant integration's config flow first.

WHEN TO USE:

  • mode='get' / 'set': inspect or replace the full Energy Dashboard config. Use 'set' for bulk edits or anything touching multiple top-level keys at once.

  • mode='add_device' / 'remove_device': add or remove a single device-consumption entry. The tool performs a fresh read-modify-write internally.

  • mode='add_source': append a single entry to energy_sources. Same optimistic read-modify-write semantics.

RELATED TOOLS: Use ha_get_history(source="statistics") with the returned statistic IDs for consumption, totals, and trends. Metadata comes directly from the running Core, including stored and display units.

CAVEATS:

  • energy/save_prefs has per-key FULL-REPLACE semantics. Passing {"device_consumption": [<one entry>]} deletes every other device the user had configured — silently, with no error.

  • The per-key config_hash form lets an agent submit only the top-level key it wants to change: config keys must equal the dict keys, and a per-key submission still fully replaces that key's value. A mismatch on any locked key returns RESOURCE_LOCKED with the offending keys in mismatched_keys.

  • dry_run=True skips the hash check entirely for both forms.

  • Writes need an administrator token; Home Assistant rejects the save otherwise.

  • After a successful write, the tool calls energy/validate and returns residual issues (missing stats, unit mismatches) as post_save_validation_errors; the save persists regardless — correct the config and write again if needed.

  • 'add_source' rejects duplicates by (type, stat_energy_from) for solar/battery/gas/water; grid entries are appended without a duplicate check (multiple grid variants are legitimate), so the caller de-duplicates grid sources.

EXAMPLES:

  • ha_manage_energy_prefs(mode="get", include_schema=True)

  • Preview a device: ha_manage_energy_prefs(mode="add_device", stat_consumption="sensor.fridge_energy", dry_run=True)

  • Remove a device: ha_manage_energy_prefs(mode="remove_device", stat_consumption="sensor.fridge_energy")

If a Claude Desktop user gets a 4-minute timeout with no result on this call, read the target back before repeating it, and tell them to wait a few seconds before clicking the manual-approve button, as clicking it too quickly is known to cause hangs in Claude Desktop. This workaround is specific to Claude Desktop.

read get inspect energy dashboard preferences prefs electricity price prices pricing tariff tariffs rate rates cost costs kwh peak off-peak offpeak contract utility bill grid solar battery gas water consumption number_energy_price entity_energy_price stat_energy_from

Input Schema

NameRequiredDescriptionDefault
modeYesOperation mode. Primitives: 'get' reads the current prefs; 'set' writes a full prefs payload.
nameNoDisplay name for mode='add_device'; ignored otherwise.
waterNoIf True, mode='add_device' / 'remove_device' targets 'device_consumption_water' instead of 'device_consumption'.
configNoFull prefs payload for mode='set'. Must contain the top-level keys you intend to replace: 'energy_sources', 'device_consumption', 'device_consumption_water'. Any omitted key is preserved. Call with mode='get' first, mutate the returned config, then pass the whole object back. Ignored by convenience modes.
sourceNoSingle native energy_sources entry for mode='add_source'. Use mode='get', include_schema=True to inspect the running Core's fields and requirements; dry_run=True validates without saving.
dry_runNoIf True, preview without saving. With the component, validates the complete proposal through Core's registered save schema. Without that capability, explicitly reports proposal validation unavailable. Semantic energy/validate checks persisted state only.
config_hashNoHash from a previous mode='get' call. REQUIRED for mode='set' unless dry_run=True. Two forms: str (full-blob lock) or dict (per-key lock, taken from the config_hash_per_key field of mode='get'). Pass the dict form as a native object, NOT a JSON-encoded string — a stringified dict is treated as a full-blob token and will report RESOURCE_LOCKED; clients that can only send strings should use the str full-blob form. Ignored by convenience modes.
include_schemaNoWith mode='get', describe the running Core's save schema. Unavailable without the component.
included_in_statNo'Parent' statistic for mode='add_device'. Set this to a statistic that already INCLUDES this device's consumption (e.g., a whole-home or circuit-level meter that this device feeds into). The Energy Dashboard will subtract this device's reading from the parent so the parent's contribution is not double-counted. Ignored otherwise.
stat_consumptionNoStatistic entity_id for mode='add_device' / 'remove_device' (e.g. 'sensor.fridge_energy'). Required for those modes; ignored otherwise.
include_statisticsNoWith mode='get', include native recorder metadata and resolved output units for all configured statistic references. Ignored for other modes.

Output Schema

NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed5 schema fields changedv8.7.0
    • changedInput schema / properties / config_hash / anyOf
      Previous value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "additionalProperties": {
      -      "type": "string"
      -    },
      -    "propertyNames": {
      -      "enum": [
      -        "energy_sources",
      -        "device_consumption",
      -        "device_consumption_water"
      -      ]
      -    },
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "type": "string"
      +  },
      +  {
      +    "additionalProperties": {
      +      "type": "string"
      +    },
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / dry_run / description
      Previous value: -"If True, no write is performed. For mode='set': runs a local shape check on the proposed config AND calls the server's energy/validate against the CURRENT persisted state. For convenience modes: simulates the mutation against a fresh read and reports what would change without writing — but still raises RESOURCE_ALREADY_EXISTS (duplicate add_device, or duplicate add_source for solar/battery/gas/water), RESOURCE_NOT_FOUND (missing remove_device), or VALIDATION_FAILED (post-mutator shape error) when the proposed mutation is not applicable."New value: +"If True, preview without saving. With the component, validates the complete proposal through Core's registered save schema. Without that capability, explicitly reports proposal validation unavailable. Semantic energy/validate checks persisted state only."
    • addedInput schema / properties / include_schema
      Added value: +{
      +  "default": false,
      +  "description": "With mode='get', describe the running Core's save schema. Unavailable without the component.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / include_statistics
      Added value: +{
      +  "default": false,
      +  "description": "With mode='get', include native recorder metadata and resolved output units for all configured statistic references. Ignored for other modes.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / source / description
      Previous value: -"Single energy_sources entry for mode='add_source'. Must contain 'type' (one of grid|solar|battery|gas|water) and the type-specific required fields (e.g. solar/battery/gas/water require 'stat_energy_from'). Every source type also accepts an optional 'name' (display label in the energy graphs); battery additionally accepts 'stat_soc' (state-of-charge statistic). Note: HA Core's voluptuous schema for grid sources requires the full field set (cost_adjustment_day, stat_energy_to, stat_cost, entity_energy_price, number_energy_price, entity_energy_price_export, number_energy_price_export, stat_compensation) — the local shape check is narrower, so a minimal {'type': 'grid'} passes locally but surfaces in post_save_validation_errors after writing. Pass the unused fields as None to satisfy the server. Required for mode='add_source'; ignored otherwise."New value: +"Single native energy_sources entry for mode='add_source'. Use mode='get', include_schema=True to inspect the running Core's fields and requirements; dry_run=True validates without saving."
  2. Changed7 schema fields changedv8.6.0
    • changedInput schema / properties / config / description
      Previous value: -"Full prefs payload for mode='set'. Must contain the top-level keys you intend to replace: 'energy_sources', 'device_consumption', 'device_consumption_water'. Any top-level key present in this payload REPLACES the existing list entirely; any omitted key is preserved. Call with mode='get' first, mutate the returned config, then pass the whole object back. Ignored by convenience modes."New value: +"Full prefs payload for mode='set'. Must contain the top-level keys you intend to replace: 'energy_sources', 'device_consumption', 'device_consumption_water'. Any omitted key is preserved. Call with mode='get' first, mutate the returned config, then pass the whole object back. Ignored by convenience modes."
    • changedInput schema / properties / config_hash / description
      Previous value: -"Hash from a previous mode='get' call. REQUIRED for mode='set' unless dry_run=True. Two forms: str (full-blob lock) or dict (per-key lock, taken from the config_hash_per_key field of mode='get'). Pass the dict form as a native object, NOT a JSON-encoded string — a stringified dict is treated as a full-blob token and will report RESOURCE_LOCKED; clients that can only send strings should use the str full-blob form. See the tool docstring for fail-closed semantics. Ignored by convenience modes."New value: +"Hash from a previous mode='get' call. REQUIRED for mode='set' unless dry_run=True. Two forms: str (full-blob lock) or dict (per-key lock, taken from the config_hash_per_key field of mode='get'). Pass the dict form as a native object, NOT a JSON-encoded string — a stringified dict is treated as a full-blob token and will report RESOURCE_LOCKED; clients that can only send strings should use the str full-blob form. Ignored by convenience modes."
    • changedInput schema / properties / dry_run / description
      Previous value: -"If True, no write is performed. For mode='set': runs a local shape check on the proposed config AND calls the server's energy/validate against the CURRENT persisted state (Home Assistant's validate endpoint cannot validate an unsubmitted payload). For convenience modes: simulates the mutation against a fresh read and reports what would change without writing — but still raises RESOURCE_ALREADY_EXISTS (duplicate add_device, or duplicate add_source for solar/battery/gas/water), RESOURCE_NOT_FOUND (missing remove_device), or VALIDATION_FAILED (post-mutator shape error) when the proposed mutation is not applicable. Default False."New value: +"If True, no write is performed. For mode='set': runs a local shape check on the proposed config AND calls the server's energy/validate against the CURRENT persisted state. For convenience modes: simulates the mutation against a fresh read and reports what would change without writing — but still raises RESOURCE_ALREADY_EXISTS (duplicate add_device, or duplicate add_source for solar/battery/gas/water), RESOURCE_NOT_FOUND (missing remove_device), or VALIDATION_FAILED (post-mutator shape error) when the proposed mutation is not applicable."
    • changedInput schema / properties / included_in_stat / description
      Previous value: -"Optional 'parent' statistic for mode='add_device'. Set this to a statistic that already INCLUDES this device's consumption (e.g., a whole-home or circuit-level meter that this device feeds into). The Energy Dashboard will subtract this device's reading from the parent so the parent's contribution is not double-counted. Ignored otherwise."New value: +"'Parent' statistic for mode='add_device'. Set this to a statistic that already INCLUDES this device's consumption (e.g., a whole-home or circuit-level meter that this device feeds into). The Energy Dashboard will subtract this device's reading from the parent so the parent's contribution is not double-counted. Ignored otherwise."
    • changedInput schema / properties / mode / description
      Previous value: -"Operation mode. Primitives: 'get' reads the current prefs; 'set' writes a full prefs payload (per-top-level-key full-replace). Convenience modes: 'add_device' / 'remove_device' / 'add_source' perform a single read-modify-write atomically — no config_hash from the caller, the tool fetches it fresh internally."New value: +"Operation mode. Primitives: 'get' reads the current prefs; 'set' writes a full prefs payload."
    • changedInput schema / properties / name / description
      Previous value: -"Optional display name for mode='add_device'. Only used when adding a new device entry; ignored otherwise."New value: +"Display name for mode='add_device'; ignored otherwise."
    • changedInput schema / properties / water / description
      Previous value: -"If True, mode='add_device' / 'remove_device' targets 'device_consumption_water' instead of 'device_consumption'. Default False."New value: +"If True, mode='add_device' / 'remove_device' targets 'device_consumption_water' instead of 'device_consumption'."
  3. First observedv7.14.2

TDQS

A4.7/5.0
Behavior5/5

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

Annotations declare destructiveHint=true, idempotentHint=false, readOnlyHint=false, and the description substantiates that with concrete consequences: full-replace semantics silently delete other devices, RESOURCE_LOCKED mismatch reporting, admin-token requirement, dry_run skipping the hash check, and post_save_validation_errors being returned while the save still persists. This is exactly the behavioral context structured fields cannot carry.

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

Conciseness3/5

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

Purpose is front-loaded and the WHEN NOT TO USE / WHEN TO USE / CAVEATS sections are easy to scan. However, the trailing keyword dump and the lengthy Claude Desktop timeout workaround paragraph dilute focus and blur whether the section is guidance or an operational note, adding bulk that isn't core to tool selection.

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

Completeness5/5

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

Given an 11-parameter tool with an output schema, destructive annotations, and a complex hash-locked write path, the description covers safety, prerequisites, mode selection, failure modes, and validation behavior. Nothing material an agent needs before invoking it is missing.

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?

Schema description coverage is already 100%, so the baseline is 3, but the description adds meaning the schema lacks: add_device/remove_device perform an internal fresh read-modify-write, add_source uses optimistic append semantics with type-specific duplicate rejection, and config_hash dict-vs-str form selection is called out. The mode-to-behavior mapping isn't fully reproduced from the schema, so it earns above baseline.

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 first sentence names the specific resource (Home Assistant Energy Dashboard preferences) and enumerates the exact config domains it governs (grid/solar/battery/gas/water sources, device consumption sensors, cost tariffs). It also names a related sibling (ha_get_history) and its role, so an agent can distinguish it from neighboring tools.

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

Usage Guidelines5/5

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

There is an explicit 'WHEN NOT TO USE' section (statistics must pre-exist as HA entities), a 'WHEN TO USE' section mapping every mode to its intended scenario, and a 'RELATED TOOLS' pointer to ha_get_history with returned statistic IDs. The conditions that select each mode are spelled out rather than inferred.

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

Deploy Server

Other Tools