Skip to main content
Glama
Home Assistant MCP Server

Home Assistant MCP Server

Official

Create or Update Helper

ha_config_set_helper
Destructive

Create or update Home Assistant helpers, including storage types, helper flows, and config subentries, while preserving omitted fields during updates.

Instructions

Create or update Home Assistant helpers: storage types, every helper flow HA lists, and config subentries.

MUST call ha_get_skill_guide OR refer to your locally installed skills first. helper-selection.md ships under skill_content by default.

SIMPLE types (pass config dict): input_boolean, input_button, input_select, input_number, input_text, input_datetime, counter, timer, schedule, zone, person, tag. Create requires name; update requires helper_id.

FLOW types (pass config dict, Config Entry Flow API): every helper flow Home Assistant lists, read from it at call time — template, group, utility_meter, derivative, min_max, threshold, integration, statistics, trend, ... and custom helper integrations. Create requires name; for updates pass the existing entry_id as helper_id (options flows reject the name key). Do not create otp here although Home Assistant lists it: the user sets it up in the HA UI, since its secret is a credential they enroll in an authenticator app.

CONFIG_SUBENTRY type (Config Subentry Flow API): pass entry_id, subentry_type and config; pass subentry_id to reconfigure an existing subentry, omit it to create one.

Behavior:

  • UPDATE preserves type-specific fields not re-passed (a rename never wipes initial/icon/etc.); flow-helper and config subentry updates behave the same way (see config).

  • Omitted action falls back to the helper_id-presence discriminator (SIMPLE/FLOW) or the subentry_id-presence discriminator (config subentries).

  • For flow-based helpers, config keys not declared by any step's data_schema are silently ignored by HA. Validation errors carry the helper's data_schema (and menu_options for menu-rooted helpers like template/group when no sub-type is chosen yet), so a follow-up call can self-correct without a separate schema-discovery round-trip.

  • Flows that present more than one menu (e.g. an MQTT device subentry reconfigure looping through its summary menu) take next_step_id as a LIST of successive selections, consumed one per menu encounter.

EXAMPLES:

  • input_number: ha_config_set_helper(helper_type="input_number", name="Target", config={"min": 0, "max": 100, "step": 5})

  • template sensor: ha_config_set_helper(helper_type="template", name="Room Temp", config={"next_step_id": "sensor", "state": "{{ states('sensor.x')|float }}", "unit_of_measurement": "°C"})

  • group: ha_config_set_helper(helper_type="group", name="Kitchen Lights", config={"group_type": "light", "entities": ["light.a", "light.b"]})

  • config subentry: ha_config_set_helper(helper_type="config_subentry", entry_id="01HXYZ...", subentry_type="conversation", config={"name": "Local agent", "model": "gemma3:27b"})

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.

create update new add helper input_boolean input_button input_number input_text input_datetime input_select counter timer schedule zone person tag template group utility_meter derivative min_max threshold integration statistics trend random filter tod generic_thermostat switch_as_x generic_hygrostat history_stats mold_indicator

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "helper_type": "<helper_type>"
    },
    "name": "ha_config_set_helper"
  }
}

Input Schema

NameRequiredDescriptionDefault
iconNoMaterial Design Icon (e.g., 'mdi:bell'); '' or ' ' clears it, except a zone's stored icon (the icon in the zone's own config, as the Home Assistant UI stores it; ha_get_zone shows it), which cannot be removed. On create, a storage helper's icon goes into its stored config when Home Assistant's schema for the type has an icon field, otherwise (person, tag, a new zone, or without the ha_mcp_tools component) into the entity registry; an update always sets the registry icon, and the stored icon too where the schema has one. Restoring a storage helper's automatic backup also puts back its registry icon, unless the backup predates registry icons being recorded; a flow helper's backup holds no icon, so its restore does not set one
nameNoDisplay name for simple/flow helper creation. Optional on helper update. Ignored for helper_type='config_subentry', which uses entry_id/subentry_type/subentry_id instead. For flow-based helper updates (template, group, utility_meter, ...), this is ignored because options flows don't expose renaming; change the resulting entity's display name with ha_set_entity(name=...).
waitNoWait for helper entity to be queryable before returning. Set to False for bulk operations.
actionNoExplicit intent: 'create' a new helper or 'update' an existing one. Pass it so a helper_id typo fails as 'helper not found' instead of creating a helper.
configNoType-specific fields. On update it is a patch: a field you omit keeps its current value. SIMPLE types take these keys: input_select: options (list, required), initial. input_number: min, max (required), step, unit_of_measurement, mode ('box'/'slider'), initial. input_text: min, max (length), mode ('text'/'password'), initial, unit_of_measurement, pattern (regex the value must match). input_datetime: has_date, has_time, initial. input_boolean: initial. counter: initial (starting value), minimum, maximum, step, restore (default true). timer: duration ('HH:MM:SS' or seconds), restore (default false). schedule: monday..sunday, each a list of {'from': 'HH:MM', 'to': 'HH:MM'} with optional 'data' dict of extra attributes. zone: latitude, longitude (both required), radius (meters, default 100), passive (won't trigger person state changes). person: user_id, device_trackers (device_tracker entity IDs), picture (URL). tag: tag_id (omit on create to auto-generate), description. On input_* types, `initial` — even false/0 — disables last-state restore and forces that value on every HA restart. ha_config_list_helpers(helper_type, describe=True) lists a type's fields. FLOW types and config_subentry take the flow's fields; a field set to null is cleared where the schema allows that field to be empty. A field two steps declare gets your one value both times; pass step_values={'<step_id>': {'<field>': <value>}} to give a step its own value, or to leave it out of that step; a LIST of those objects supplies one per encounter when the flow presents a step more than once.
labelsNoLabels to categorize the helper
area_idNoArea ID for the helper; '' or ' ' clears it
categoryNoCategory ID for this helper (ha_config_get_category(scope='helpers') lists them, ha_config_set_category() creates one); '' or ' ' clears it.
entry_idNoParent config entry ID when helper_type='config_subentry'. Use ha_get_integration() to find entry IDs.
helper_idNoThe helper's storage id ('my_button'), not the name of its entity, or its full entity_id ('input_button.my_button'). Omit to create a new helper.
helper_typeYesType of helper to create or update.
subentry_idNoExisting config subentry ID to reconfigure when helper_type='config_subentry'.
MandatoryBPSNo
subentry_typeNoIntegration-defined subentry type when helper_type='config_subentry'.
BestPracticeKeyNoRead-receipt for the home-assistant-best-practices skill; required when strict best-practices mode is enabled. Not a secret or credential: the current value is an attestation phrase published openly at the top of the skill content served by ha_get_skill_guide. Read that content, then pass the value back verbatim — this round-trip is the server's designed protocol confirming the practices were read before writing.
show_advanced_optionsNoWhen helper_type='config_subentry', ask older Home Assistant versions to expose advanced flow options. No-op on HA 2026.6+; pending removal before HA 2027.6.

Output Schema

NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changedv9.0.0
    • changedInput schema / properties / helper_id / description
      Previous value: -"Bare ID ('my_button') or full entity ID ('input_button.my_button'). Omit to create a new helper."New value: +"The helper's storage id ('my_button'), not the name of its entity, or its full entity_id ('input_button.my_button'). Omit to create a new helper."
    • changedInput schema / properties / icon / description
      Previous value: -"Material Design Icon (e.g., 'mdi:bell'); '' or ' ' clears it, except a zone's stored icon (the icon in the zone's own config, set at creation or by ha_set_zone; ha_get_zone shows it), which cannot be removed"New value: +"Material Design Icon (e.g., 'mdi:bell'); '' or ' ' clears it, except a zone's stored icon (the icon in the zone's own config, as the Home Assistant UI stores it; ha_get_zone shows it), which cannot be removed. On create, a storage helper's icon goes into its stored config when Home Assistant's schema for the type has an icon field, otherwise (person, tag, a new zone, or without the ha_mcp_tools component) into the entity registry; an update always sets the registry icon, and the stored icon too where the schema has one. Restoring a storage helper's automatic backup also puts back its registry icon, unless the backup predates registry icons being recorded; a flow helper's backup holds no icon, so its restore does not set one"
  2. Changed35 schema fields changedv8.7.0
    • changedInput schema / properties / area_id / description
      Previous value: -"Area/room ID to assign the helper to"New value: +"Area ID for the helper; '' or ' ' clears it"
    • changedInput schema / properties / category / description
      Previous value: -"Category ID to assign to this helper. Use ha_config_get_category(scope='helpers') to list available categories, or ha_config_set_category() to create one."New value: +"Category ID for this helper (ha_config_get_category(scope='helpers') lists them, ha_config_set_category() creates one); '' or ' ' clears it."
    • changedInput schema / properties / config / description
      Previous value: -"Config dict for flow-based helper types and helper_type='config_subentry'. Ignored for simple helper types. On update it is a patch: a field you omit keeps its current value, and a field set to null is cleared where the schema allows that field to be empty. A field two steps declare gets your one value both times; pass step_values={'<step_id>': {'<field>': <value>}} to give a step its own value, or to leave it out of that step; a LIST of those objects supplies one per encounter when the flow presents a step more than once."New value: +"Type-specific fields. On update it is a patch: a field you omit keeps its current value. SIMPLE types take these keys: input_select: options (list, required), initial. input_number: min, max (required), step, unit_of_measurement, mode ('box'/'slider'), initial. input_text: min, max (length), mode ('text'/'password'), initial, unit_of_measurement, pattern (regex the value must match). input_datetime: has_date, has_time, initial. input_boolean: initial. counter: initial (starting value), minimum, maximum, step, restore (default true). timer: duration ('HH:MM:SS' or seconds), restore (default false). schedule: monday..sunday, each a list of {'from': 'HH:MM', 'to': 'HH:MM'} with optional 'data' dict of extra attributes. zone: latitude, longitude (both required), radius (meters, default 100), passive (won't trigger person state changes). person: user_id, device_trackers (device_tracker entity IDs), picture (URL). tag: tag_id (omit on create to auto-generate), description. On input_* types, `initial` — even false/0 — disables last-state restore and forces that value on every HA restart. ha_config_list_helpers(helper_type, describe=True) lists a type's fields. FLOW types and config_subentry take the flow's fields; a field set to null is cleared where the schema allows that field to be empty. A field two steps declare gets your one value both times; pass step_values={'<step_id>': {'<field>': <value>}} to give a step its own value, or to leave it out of that step; a LIST of those objects supplies one per encounter when the flow presents a step more than once."
    • removedInput schema / properties / description
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "string"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Description for tag"
      -}
    • removedInput schema / properties / device_trackers
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "items": {
      -        "type": "string"
      -      },
      -      "type": "array"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "List of device_tracker entity IDs for person"
      -}
    • removedInput schema / properties / duration
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "string"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Default duration for timer in format 'HH:MM:SS' or seconds (e.g., '0:05:00' for 5 minutes)"
      -}
    • removedInput schema / properties / friday
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "items": {
      -        "additionalProperties": true,
      -        "type": "object"
      -      },
      -      "type": "array"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Schedule time ranges for Friday; same shape as monday."
      -}
    • removedInput schema / properties / has_date
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "boolean"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Include date component for input_datetime"
      -}
    • removedInput schema / properties / has_time
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "boolean"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Include time component for input_datetime"
      -}
    • addedInput schema / properties / helper_type / anyOf
      Added value: +[
      +  {
      +    "enum": [
      +      "input_button",
      +      "input_boolean",
      +      "input_select",
      +      "input_number",
      +      "input_text",
      +      "input_datetime",
      +      "counter",
      +      "timer",
      +      "schedule",
      +      "zone",
      +      "person",
      +      "tag"
      +    ],
      +    "type": "string"
      +  },
      +  {
      +    "const": "config_subentry",
      +    "type": "string"
      +  },
      +  {
      +    "type": "string"
      +  }
      +]
    • changedInput schema / properties / helper_type / description
      Previous value: -"Type of helper entity to create or update"New value: +"Type of helper to create or update."
    • removedInput schema / properties / helper_type / enum
      Removed value: -[
      -  "counter",
      -  "config_subentry",
      -  "derivative",
      -  "filter",
      -  "generic_hygrostat",
      -  "generic_thermostat",
      -  "group",
      -  "history_stats",
      -  "input_boolean",
      -  "input_button",
      -  "input_datetime",
      -  "input_number",
      -  "input_select",
      -  "input_text",
      -  "integration",
      -  "min_max",
      -  "mold_indicator",
      -  "person",
      -  "random",
      -  "schedule",
      -  "statistics",
      -  "switch_as_x",
      -  "tag",
      -  "template",
      -  "threshold",
      -  "timer",
      -  "tod",
      -  "trend",
      -  "utility_meter",
      -  "zone"
      -]
    • removedInput schema / properties / helper_type / type
      Removed value: -"string"
    • changedInput schema / properties / icon / description
      Previous value: -"Material Design Icon (e.g., 'mdi:bell', 'mdi:toggle-switch')"New value: +"Material Design Icon (e.g., 'mdi:bell'); '' or ' ' clears it, except a zone's stored icon (the icon in the zone's own config, set at creation or by ha_set_zone; ha_get_zone shows it), which cannot be removed"
    • removedInput schema / properties / initial
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "string"
      -    },
      -    {
      -      "type": "integer"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Initial value for applicable helper types. For input_boolean, input_select, input_number, input_text, and input_datetime: setting `initial` — even to false/0 — disables last-state restore and forces that value on every HA restart; omit unless you want the helper to reset to that value on every restart instead of restoring its last state. For counter, `initial` is just the starting value — restore-on-restart is controlled separately by `restore` (default True)."
      -}
    • removedInput schema / properties / latitude
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "number"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Latitude for zone (required for zone)"
      -}
    • removedInput schema / properties / longitude
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "number"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Longitude for zone (required for zone)"
      -}
    • removedInput schema / properties / max_value
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "number"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Maximum value (input_number/counter) or maximum length (input_text). Also accepts shorthand 'max'."
      -}
    • removedInput schema / properties / min_value
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "number"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Minimum value (input_number/counter) or minimum length (input_text). Also accepts shorthand 'min'."
      -}
    • removedInput schema / properties / mode
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "string"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Display mode: 'box'/'slider' for input_number, 'text'/'password' for input_text"
      -}
    • removedInput schema / properties / monday
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "items": {
      -        "additionalProperties": true,
      -        "type": "object"
      -      },
      -      "type": "array"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Schedule time ranges for Monday. List of {'from': 'HH:MM', 'to': 'HH:MM'} dicts. Optional 'data' dict for additional attributes (e.g. {'from': '07:00', 'to': '22:00', 'data': {'mode': 'comfort'}})"
      -}
    • removedInput schema / properties / options
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "string"
      -    },
      -    {
      -      "items": {
      -        "type": "string"
      -      },
      -      "type": "array"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "List of options for input_select (required for input_select)"
      -}
    • removedInput schema / properties / passive
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "boolean"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Passive zone (won't trigger state changes for person entities)"
      -}
    • removedInput schema / properties / picture
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "string"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Picture URL for person entity"
      -}
    • removedInput schema / properties / radius
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "number"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Radius in meters for zone (default: 100)"
      -}
    • removedInput schema / properties / restore
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "boolean"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Restore state after restart (counter, timer). Defaults to True for counter, False for timer"
      -}
    • removedInput schema / properties / saturday
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "items": {
      -        "additionalProperties": true,
      -        "type": "object"
      -      },
      -      "type": "array"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Schedule time ranges for Saturday; same shape as monday."
      -}
    • removedInput schema / properties / step
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "number"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Step/increment value for input_number or counter"
      -}
    • removedInput schema / properties / sunday
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "items": {
      -        "additionalProperties": true,
      -        "type": "object"
      -      },
      -      "type": "array"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Schedule time ranges for Sunday; same shape as monday."
      -}
    • removedInput schema / properties / tag_id
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "string"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Tag ID. On create, omit to auto-generate a uuid4 hex. On update, the existing tag_id is required (passed via helper_id)."
      -}
    • removedInput schema / properties / thursday
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "items": {
      -        "additionalProperties": true,
      -        "type": "object"
      -      },
      -      "type": "array"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Schedule time ranges for Thursday; same shape as monday."
      -}
    • removedInput schema / properties / tuesday
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "items": {
      -        "additionalProperties": true,
      -        "type": "object"
      -      },
      -      "type": "array"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Schedule time ranges for Tuesday; same shape as monday."
      -}
    • removedInput schema / properties / unit_of_measurement
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "string"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Unit of measurement for input_number (e.g., '°C', '%', 'W'). Also accepts shorthand 'unit'."
      -}
    • removedInput schema / properties / user_id
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "string"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "User ID to link to person entity"
      -}
    • removedInput schema / properties / wednesday
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "items": {
      -        "additionalProperties": true,
      -        "type": "object"
      -      },
      -      "type": "array"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Schedule time ranges for Wednesday; same shape as monday."
      -}
  3. Changed13 schema fields changedv8.6.0
    • changedInput schema / properties / action / description
      Previous value: -"Explicit intent: 'create' a new helper or 'update' an existing one. When omitted, falls back to the implicit discriminator: presence of helper_id => update, absence => create. Pass 'create' or 'update' to disambiguate (e.g. so a typo in helper_id surfaces as a clear 'helper not found' error instead of being mistaken for a create call)."New value: +"Explicit intent: 'create' a new helper or 'update' an existing one. Pass it so a helper_id typo fails as 'helper not found' instead of creating a helper."
    • changedInput schema / properties / config / description
      Previous value: -"Config dict for flow-based helper types and helper_type='config_subentry' (template, group, utility_meter, derivative, min_max, threshold, integration, statistics, trend, random, filter, tod, generic_thermostat, switch_as_x, generic_hygrostat, history_stats, mold_indicator). Ignored for simple helper types. On update it is a patch: a field you omit keeps its current value, and a field set to null is cleared where the schema allows that field to be empty. A field two steps declare gets your one value both times; pass step_values={'<step_id>': {'<field>': <value>}} to give a step its own value, or to leave it out of that step; a LIST of those objects supplies one per encounter when the flow presents a step more than once. Field set is delivered as data_schema on the first validation error."New value: +"Config dict for flow-based helper types and helper_type='config_subentry'. Ignored for simple helper types. On update it is a patch: a field you omit keeps its current value, and a field set to null is cleared where the schema allows that field to be empty. A field two steps declare gets your one value both times; pass step_values={'<step_id>': {'<field>': <value>}} to give a step its own value, or to leave it out of that step; a LIST of those objects supplies one per encounter when the flow presents a step more than once."
    • changedInput schema / properties / friday / description
      Previous value: -"Schedule time ranges for Friday. List of {'from': 'HH:MM', 'to': 'HH:MM'} dicts. Optional 'data' dict for additional attributes."New value: +"Schedule time ranges for Friday; same shape as monday."
    • changedInput schema / properties / helper_id / description
      Previous value: -"REQUIRED when updating an existing helper. Bare ID ('my_button') or full entity ID ('input_button.my_button'). Omit to create a new helper."New value: +"Bare ID ('my_button') or full entity ID ('input_button.my_button'). Omit to create a new helper."
    • changedInput schema / properties / name / description
      Previous value: -"Display name for simple/flow helper creation. Required when creating a helper without helper_id. Optional on helper update. Ignored for helper_type='config_subentry', which uses entry_id/subentry_type/subentry_id instead. For flow-based helper updates (template, group, utility_meter, ...), this is typically ignored because options flows don't expose renaming. Rename a flow helper by deleting and recreating instead."New value: +"Display name for simple/flow helper creation. Optional on helper update. Ignored for helper_type='config_subentry', which uses entry_id/subentry_type/subentry_id instead. For flow-based helper updates (template, group, utility_meter, ...), this is ignored because options flows don't expose renaming; change the resulting entity's display name with ha_set_entity(name=...)."
    • changedInput schema / properties / saturday / description
      Previous value: -"Schedule time ranges for Saturday. List of {'from': 'HH:MM', 'to': 'HH:MM'} dicts. Optional 'data' dict for additional attributes."New value: +"Schedule time ranges for Saturday; same shape as monday."
    • changedInput schema / properties / subentry_id / description
      Previous value: -"Existing config subentry ID to reconfigure when helper_type='config_subentry'. Omit to create."New value: +"Existing config subentry ID to reconfigure when helper_type='config_subentry'."
    • changedInput schema / properties / sunday / description
      Previous value: -"Schedule time ranges for Sunday. List of {'from': 'HH:MM', 'to': 'HH:MM'} dicts. Optional 'data' dict for additional attributes."New value: +"Schedule time ranges for Sunday; same shape as monday."
    • changedInput schema / properties / tag_id / description
      Previous value: -"Tag ID for tag. On create, omit to auto-generate a unique uuid4 hex (HA's tag/create requires this field; the tool fills it in for you). On update, the tag's existing tag_id is required (passed via helper_id)."New value: +"Tag ID. On create, omit to auto-generate a uuid4 hex. On update, the existing tag_id is required (passed via helper_id)."
    • changedInput schema / properties / thursday / description
      Previous value: -"Schedule time ranges for Thursday. List of {'from': 'HH:MM', 'to': 'HH:MM'} dicts. Optional 'data' dict for additional attributes."New value: +"Schedule time ranges for Thursday; same shape as monday."
    • changedInput schema / properties / tuesday / description
      Previous value: -"Schedule time ranges for Tuesday. List of {'from': 'HH:MM', 'to': 'HH:MM'} dicts. Optional 'data' dict for additional attributes."New value: +"Schedule time ranges for Tuesday; same shape as monday."
    • changedInput schema / properties / wait / description
      Previous value: -"Wait for helper entity to be queryable before returning. Default: True. Set to False for bulk operations."New value: +"Wait for helper entity to be queryable before returning. Set to False for bulk operations."
    • changedInput schema / properties / wednesday / description
      Previous value: -"Schedule time ranges for Wednesday. List of {'from': 'HH:MM', 'to': 'HH:MM'} dicts. Optional 'data' dict for additional attributes."New value: +"Schedule time ranges for Wednesday; same shape as monday."
  4. Changed1 schema field changedv8.4.1
    • changedInput schema / properties / config / description
      Previous value: -"Config dict for flow-based helper types and helper_type='config_subentry' (template, group, utility_meter, derivative, min_max, threshold, integration, statistics, trend, random, filter, tod, generic_thermostat, switch_as_x, generic_hygrostat, history_stats, mold_indicator). Ignored for simple helper types. Field set is delivered as data_schema on the first validation error."New value: +"Config dict for flow-based helper types and helper_type='config_subentry' (template, group, utility_meter, derivative, min_max, threshold, integration, statistics, trend, random, filter, tod, generic_thermostat, switch_as_x, generic_hygrostat, history_stats, mold_indicator). Ignored for simple helper types. On update it is a patch: a field you omit keeps its current value, and a field set to null is cleared where the schema allows that field to be empty. A field two steps declare gets your one value both times; pass step_values={'<step_id>': {'<field>': <value>}} to give a step its own value, or to leave it out of that step; a LIST of those objects supplies one per encounter when the flow presents a step more than once. Field set is delivered as data_schema on the first validation error."
  5. Changed2 schema fields changedv8.3.0
    • changedInput schema / properties / config / description
      Previous value: -"Config dict for flow-based helper types and helper_type='config_subentry' (template, group, utility_meter, derivative, min_max, threshold, integration, statistics, trend, random, filter, tod, generic_thermostat, switch_as_x, generic_hygrostat). Ignored for simple helper types. Field set is delivered as data_schema on the first validation error."New value: +"Config dict for flow-based helper types and helper_type='config_subentry' (template, group, utility_meter, derivative, min_max, threshold, integration, statistics, trend, random, filter, tod, generic_thermostat, switch_as_x, generic_hygrostat, history_stats, mold_indicator). Ignored for simple helper types. Field set is delivered as data_schema on the first validation error."
    • changedInput schema / properties / helper_type / enum
      Previous value: -[
      -  "counter",
      -  "config_subentry",
      -  "derivative",
      -  "filter",
      -  "generic_hygrostat",
      -  "generic_thermostat",
      -  "group",
      -  "input_boolean",
      -  "input_button",
      -  "input_datetime",
      -  "input_number",
      -  "input_select",
      -  "input_text",
      -  "integration",
      -  "min_max",
      -  "person",
      -  "random",
      -  "schedule",
      -  "statistics",
      -  "switch_as_x",
      -  "tag",
      -  "template",
      -  "threshold",
      -  "timer",
      -  "tod",
      -  "trend",
      -  "utility_meter",
      -  "zone"
      -]New value: +[
      +  "counter",
      +  "config_subentry",
      +  "derivative",
      +  "filter",
      +  "generic_hygrostat",
      +  "generic_thermostat",
      +  "group",
      +  "history_stats",
      +  "input_boolean",
      +  "input_button",
      +  "input_datetime",
      +  "input_number",
      +  "input_select",
      +  "input_text",
      +  "integration",
      +  "min_max",
      +  "mold_indicator",
      +  "person",
      +  "random",
      +  "schedule",
      +  "statistics",
      +  "switch_as_x",
      +  "tag",
      +  "template",
      +  "threshold",
      +  "timer",
      +  "tod",
      +  "trend",
      +  "utility_meter",
      +  "zone"
      +]
  6. First observedv7.14.2

TDQS

A4.5/5.0
Behavior5/5

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

Goes far beyond the annotations (destructiveHint=true, idempotentHint=false): it states that UPDATE is a patch that preserves type-specific fields, that the omitted `action` falls back to a helper_id/subentry_id presence discriminator, that undeclared flow config keys are silently ignored, that validation errors return data_schema/menu_options enabling self-correction, and that repeated menus take `next_step_id` as a list. It even discloses an environment-specific hang/timeout behavior on Claude Desktop, which annotations could never convey.

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?

Well front-loaded and sectioned (purpose → prerequisite → type families → behavior → examples), but bloated: the Claude Desktop timeout paragraph and the trailing keyword dump ('create update new add helper input_boolean...') do not earn their space and read as SEO filler. Roughly a third of the text could be cut with no loss of actionable signal.

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?

For a 16-parameter destructive mutation tool, the description covers everything an agent needs: the prerequisite skill call, the type taxonomy, create vs update discriminators, patch semantics on update, config-key expectations, flow self-correction via validation errors, and four concrete examples. With an output schema present, no return-value prose is required, so nothing material 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 94%, so the baseline is 3; the description adds real value on top by explaining the `action` fallback semantics, the create-vs-update discriminator per family, and the shape of `config` per type (e.g. input_datetime has_date/has_time, zone lat/long required) plus the `step_values` escape hatch. It slightly duplicates the schema's own type-by-type key list rather than adding new meaning, which keeps it off a 5.

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?

Opens with a specific verb+resource ('Create or update Home Assistant helpers') and immediately scopes it into three distinct families (storage/SIMPLE types, FLOW types read from HA at call time, and config subentries), which is exactly the taxonomy the schema's helper_type accepts. An agent can tell this apart from ha_config_list_helpers or ha_remove_helpers_integrations without opening a schema.

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

Usage Guidelines4/5

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

Gives an explicit prerequisite ('MUST call ha_get_skill_guide OR refer to your locally installed skills first'), an explicit exclusion ('Do not create otp here... user sets it up in the HA UI'), and per-family create/update rules (create needs name, update needs helper_id; flow updates use entry_id because options flows reject name). It stops short of naming read/delete siblings as alternatives, so the routing guidance is context-rich but not fully comparative.

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