Skip to main content
Glama
Home Assistant MCP Server

Home Assistant MCP Server

Official

Manage Backups

ha_manage_backup
Destructive

Create, list, restore, and delete Home Assistant backups at two scopes: full snapshots for system-wide recovery, or per-entity edit backups to undo recent changes without an HA restart.

Instructions

Manage Home Assistant backups — both full HA snapshots AND per-edit auto-backups.

Pick the scope first, then the action. Wrong scope routes through the wrong code path:

scope

action

What it does

snapshot

create

Without any include_*: a full Home Assistant backup, made as Home Assistant's own automatic backup (its contents and locations, Home Assistant Cloud included) and counted by its retention like a scheduled backup; with no automatic-backup locations configured, a manual backup on the default location with the contents of the automatic-backup settings. Either way it holds the apps those settings select: Home Assistant's backup setup selects every app, but settings that select none give a full backup with no apps (on a Supervisor install the configuration, usually its database, the ssl folder and any folders the settings select). The result's addons lists the apps it holds, and on a Supervisor install its note says when there are none. With any include_*: a custom backup of just those parts (e.g. one app; on Supervisor installs Home Assistant's configuration brings the ssl folder along) on the default location. Needs the default backup password. Can take a while on a large instance; progress heartbeats are sent while waiting.

snapshot

list

List full HA tarball snapshots as Home Assistant reports them (id, name, date, per-location size). Read-only — use to discover a backup_id or confirm a backup landed; a non-empty agent_errors means the list is partial.

snapshot

restore

Restore from a full HA tarball. Replaces Home Assistant's configuration plus what restore_database / restore_addons / restore_folders select; other apps and folders stay as they are. safety_backup first backs up what the restore replaces. Restarts HA. Last-resort recovery.

snapshot

delete

Delete one full HA tarball by backup_id (confirm=True required). Disabled by default (enable_snapshot_delete setting) and layered with guards even when enabled — see below.

edits

create

On-demand snapshot of one entity (domain + entity_id required). Use before the user manually edits in the HA UI. Same handler path the decorator takes on writes; bypasses the enable_auto_backup toggle.

edits

list

List per-entity auto-backups (lightweight). Filter by domain and/or entity_id.

edits

view

Read one auto-backup file by name; returns YAML and parsed config.

edits

diff

Compare one auto-backup against the entity's current config. RFC 6902 JSON-Patch + add/remove/replace counts; bounded output. Read-only — fetches the live config, makes no changes.

edits

restore

Re-apply one auto-backup. Existing flow helpers (template, group, utility_meter, …), config subentries and integration config entries require a fresh per-entity backup; other domains follow auto-backup settings and may proceed without one. A deleted flow helper is recreated with a new config-entry ID and its saved entity IDs are restored if unoccupied; a deleted subentry is recreated with a new subentry ID. An integration config entry's snapshot holds its metadata, its enabled state and its options, which are kept only when the ha_mcp_tools component serves the read, its secrets.yaml scrub ran, and no value is a redaction placeholder; a restore re-enables the entry first when needed, then puts back differing options through its options flow, and reports options it cannot put back (none kept, or empty ones) as not restored. It holds neither the entry's data nor its subentries, so a deleted integration config entry cannot be recreated. No HA restart.

edits

delete

Delete one auto-backup by backup_name, or bulk-delete by filter.

When to use which scope:

  • scope="edits": ha-mcp's own per-entity YAML backups of automations, scripts, scenes, dashboards and helpers. Use them to undo a recent edit by the agent. Lightweight, fast, no restart.

  • scope="snapshot": Home Assistant's own backups — a full backup (create without include_*), or a custom backup of some parts, such as one or more apps (include_addons). Restore one only for system-wide recovery (mass config corruption, a broken app update with that app in restore_addons, etc.).

A snapshot backup is the user's call: before a change that cannot be undone, you may ask the user whether they want one first; make it only when they say so. A full backup is large, and an unrequested one can push an older backup out of retention.

(snapshot, delete) is off by default and layered even when enabled: a human must set enable_snapshot_delete=true (env var, web settings UI, or add-on Supervisor options) — an agent cannot turn this on itself. When enabled, a delete call is still refused if: the target is a scheduled/automatic backup; it's younger than snapshot_delete_min_age_days (default 7, 0 disables the floor); or it's the single newest snapshot remaining. These guarantee at least one recovery point always survives an agent's own mistakes.

Human-managed backup controls: enable_snapshot_actions=false (ENABLE_SNAPSHOT_ACTIONS) blocks every snapshot action, including listing. backup_read_only=true (BACKUP_READ_ONLY) allows edits list/view/diff and snapshot list when snapshots are enabled; it blocks explicit create/restore/delete in both scopes. Automatic pre-edit capture still follows enable_auto_backup. A human must change these controls in the Backups tab, app configuration, or environment; developer tools cannot change them. Global and connection Read Only Mode still restrict writes.

enable_auto_backup and scope="edits": the automatic-on-write capture (every wrapped tool call) is gated by enable_auto_backup=true — if the listing is empty, check the toggle (web settings UI or ENABLE_AUTO_BACKUP=true env var). The explicit (edits, create) action bypasses the toggle since the request is explicit; list / view / restore / delete operate on whatever's already on disk regardless of the toggle's current state.

Flow-helper filters: edits.create accepts a flow helper's entity ID and returns its stable config-entry ID as entity_id. Use that returned ID for edits.list and bulk edits.delete; those filters do not resolve entity aliases. After recreation, the restore result reports the replacement config-entry ID and entity_id_mapping separately.

Examples:

  • Full backup, when the user asks for one: ha_manage_backup(scope="snapshot", action="create")

  • Backup of one app: ha_manage_backup(scope="snapshot", action="create", include_addons=["core_mosquitto"])

  • List snapshots (to discover a backup_id or confirm one landed): ha_manage_backup(scope="snapshot", action="list")

  • Restore a snapshot's configuration (the database follows the backup): ha_manage_backup(scope="snapshot", action="restore", backup_id="dd7550ed")

  • Restore a snapshot with one of its apps: ha_manage_backup(scope="snapshot", action="restore", backup_id="dd7550ed", restore_addons=["core_mosquitto"])

  • Restore after a backup of what it replaces, when the user chose one: ha_manage_backup(scope="snapshot", action="restore", backup_id="dd7550ed", safety_backup=True)

  • Delete an old snapshot (requires enable_snapshot_delete=true): ha_manage_backup(scope="snapshot", action="delete", backup_id="dd7550ed", confirm=True)

  • On-demand entity snapshot before a manual UI edit: ha_manage_backup(scope="edits", action="create", domain="helper_input_boolean", entity_id="welcome_home_active")

  • List recent auto-backups for one automation: ha_manage_backup(scope="edits", action="list", domain="automation", entity_id="welcome_home")

  • View an auto-backup: ha_manage_backup(scope="edits", action="view", backup_name="automation.welcome_home.20260521_153000.yaml")

  • Diff an auto-backup vs current state: ha_manage_backup(scope="edits", action="diff", backup_name="automation.welcome_home.20260521_153000.yaml")

  • Restore an auto-backup: ha_manage_backup(scope="edits", action="restore", backup_name="automation.welcome_home.20260521_153000.yaml")

  • Delete one auto-backup: ha_manage_backup(scope="edits", action="delete", backup_name="...")

  • Bulk-delete old auto-backups: ha_manage_backup(scope="edits", action="delete", older_than_days=30)

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.

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": {
      "scope": "<scope>",
      "action": "<action>"
    },
    "name": "ha_manage_backup"
  }
}

Input Schema

NameRequiredDescriptionDefault
nameNo(snapshot.create) Tarball name. Auto-generated if not provided. Home Assistant names a full backup made with its automatic-backup settings itself.
limitNo(edits.list / snapshot.list) Maximum number of entries to return.
scopeYes'snapshot' for full HA tarballs; 'edits' for per-entity auto-backups.
actionYesOperation to perform. Valid (scope, action) combinations are listed in the tool description.
domainNo(edits.create / edits.list / edits.delete) Filter auto-backups by domain (e.g. 'automation', 'helper_timer'). Required for edits.create.
confirmNo(snapshot.delete) Must be True to confirm deletion.
backup_idNo(snapshot.restore / snapshot.delete) Tarball ID (e.g. 'dd7550ed').
entity_idNo(edits.create / edits.list / edits.delete) Filter auto-backups by entity ID. Required for edits.create.
backup_nameNo(edits.view / edits.restore / edits.delete) Auto-backup filename (format '<domain>.<entity_id>.<timestamp>[_NN].yaml'). Not a tarball ID.
safety_backupNo(snapshot.restore) Back up what the restore replaces (configuration, plus the database, apps and folders it restores) first, as a manual backup on the default location. Off by default; offer it to the user, who decides. Needs the default backup password.
include_addonsNo(snapshot.create) Custom backup: slugs of the installed apps (add-ons) to include. Supervisor installs only.
restore_addonsNo(snapshot.restore) Slugs of apps (add-ons) in the backup to restore, from its `addons` in the snapshot list. Default: none. Supervisor installs only.
include_foldersNo(snapshot.create) Custom backup: folders to include (`share`, `addons/local`, `ssl`, `media`). Supervisor installs only.
older_than_daysNo(edits.delete) Bulk-delete auto-backups older than this many days.
restore_foldersNo(snapshot.restore) Folders in the backup to restore, from its `folders` in the snapshot list (`share`, `addons/local`, `ssl`, `media`). Default: none. Supervisor installs only.
include_databaseNo(snapshot.create) Custom backup: include the database (history); needs include_homeassistant=True.
restore_databaseNo(snapshot.restore) Include the database in the restore. Default: restore it when the backup contains it. Must be false for a backup without one; on Supervisor installs it must match the backup.
include_all_addonsNo(snapshot.create) Custom backup: include every app (add-on); not together with include_addons. Supervisor installs only.
include_homeassistantNo(snapshot.create) Custom backup: include Home Assistant's configuration.

Output Schema

NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed13 schema fields changedv9.0.0
    • addedInput schema / properties / include_addons
      Added value: +{
      +  "anyOf": [
      +    {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "(snapshot.create) Custom backup: slugs of the installed apps (add-ons) to include. Supervisor installs only."
      +}
    • addedInput schema / properties / include_all_addons
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "boolean"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "(snapshot.create) Custom backup: include every app (add-on); not together with include_addons. Supervisor installs only."
      +}
    • addedInput schema / properties / include_database
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "boolean"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "(snapshot.create) Custom backup: include the database (history); needs include_homeassistant=True."
      +}
    • addedInput schema / properties / include_folders
      Added value: +{
      +  "anyOf": [
      +    {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "(snapshot.create) Custom backup: folders to include (`share`, `addons/local`, `ssl`, `media`). Supervisor installs only."
      +}
    • addedInput schema / properties / include_homeassistant
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "boolean"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "(snapshot.create) Custom backup: include Home Assistant's configuration."
      +}
    • changedInput schema / properties / name / description
      Previous value: -"(snapshot.create) Tarball name. Auto-generated if not provided."New value: +"(snapshot.create) Tarball name. Auto-generated if not provided. Home Assistant names a full backup made with its automatic-backup settings itself."
    • addedInput schema / properties / restore_addons
      Added value: +{
      +  "anyOf": [
      +    {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "(snapshot.restore) Slugs of apps (add-ons) in the backup to restore, from its `addons` in the snapshot list. Default: none. Supervisor installs only."
      +}
    • addedInput schema / properties / restore_database / anyOf
      Added value: +[
      +  {
      +    "type": "boolean"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / restore_database / default
      Previous value: -falseNew value: +null
    • changedInput schema / properties / restore_database / description
      Previous value: -"(snapshot.restore) Include the database in the restore; otherwise config only."New value: +"(snapshot.restore) Include the database in the restore. Default: restore it when the backup contains it. Must be false for a backup without one; on Supervisor installs it must match the backup."
    • removedInput schema / properties / restore_database / type
      Removed value: -"boolean"
    • addedInput schema / properties / restore_folders
      Added value: +{
      +  "anyOf": [
      +    {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "(snapshot.restore) Folders in the backup to restore, from its `folders` in the snapshot list (`share`, `addons/local`, `ssl`, `media`). Default: none. Supervisor installs only."
      +}
    • addedInput schema / properties / safety_backup
      Added value: +{
      +  "default": false,
      +  "description": "(snapshot.restore) Back up what the restore replaces (configuration, plus the database, apps and folders it restores) first, as a manual backup on the default location. Off by default; offer it to the user, who decides. Needs the default backup password.",
      +  "type": "boolean"
      +}
  2. Changed2 schema fields changedv8.6.0
    • changedInput schema / properties / confirm / description
      Previous value: -"(snapshot.delete) Must be True to confirm deletion — a safety measure against accidental calls."New value: +"(snapshot.delete) Must be True to confirm deletion."
    • changedInput schema / properties / restore_database / description
      Previous value: -"(snapshot.restore) Include database in the restore. Default false (config-only)."New value: +"(snapshot.restore) Include the database in the restore; otherwise config only."
  3. Changed1 schema field changedv8.5.0
    • changedInput schema / properties / backup_name / description
      Previous value: -"(edits.view / edits.restore / edits.delete) Auto-backup filename (format '<domain>.<entity_id>.<timestamp>.yaml'). Not a tarball ID."New value: +"(edits.view / edits.restore / edits.delete) Auto-backup filename (format '<domain>.<entity_id>.<timestamp>[_NN].yaml'). Not a tarball ID."
  4. Changed2 schema fields changedv8.4.1
    • changedInput schema / properties / domain / description
      Previous value: -"(edits.list / edits.delete) Filter auto-backups by domain (e.g. 'automation', 'helper_timer')."New value: +"(edits.create / edits.list / edits.delete) Filter auto-backups by domain (e.g. 'automation', 'helper_timer'). Required for edits.create."
    • changedInput schema / properties / entity_id / description
      Previous value: -"(edits.list / edits.delete) Filter auto-backups by entity ID."New value: +"(edits.create / edits.list / edits.delete) Filter auto-backups by entity ID. Required for edits.create."
  5. 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 only say destructiveHint=true and readOnlyHint=false; the description goes far beyond by disclosing that snapshot restore restarts HA while edits restore does not, that snapshot delete is disabled by default and guarded by age/newest-snapshot floors, that enable_snapshot_actions/backup_read_only/enable_auto_backup are human-only controls, that a default backup password is needed, and that progress heartbeats are sent during long creates. It also warns about retention eviction and a Claude Desktop timeout workaround.

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

Conciseness2/5

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

The 'Pick the scope first' instruction is correctly front-loaded and the table/section/example structure is navigable, but the description is grossly oversized for a tool description — the (snapshot, create) cell alone is a multi-clause run-on of ~200 words. Substantial content is repeated three times (table row, 'When to use which scope' section, examples), and the Claude Desktop timeout workaround is appended without a heading, which reads as unrelated.

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 19-parameter, multi-mode tool with an output schema and destructive annotations, the description covers the decision logic, per-action side effects, restart behavior, permission gates, and failure modes. Nothing an agent needs to invoke a given (scope, action) pair correctly is missing.

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

Parameters5/5

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

Schema coverage is 100%, so a 3 would be the baseline, but the description adds genuine cross-parameter meaning: include_* presence flips snapshot.create from full to custom backup, include_all_addons cannot combine with include_addons, include_database requires include_homeassistant, restore_database must match the backup, and backup_name (filename format) is explicitly not a backup_id. It also explains that edits.create on a flow helper returns a config-entry ID to be used for later list/delete filters.

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

Purpose5/5

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

The description names a specific verb+resource (manage Home Assistant backups) and immediately splits it into two named scopes ('snapshot' for full HA tarballs, 'edits' for per-entity auto-backups), with a table mapping every (scope, action) pair to concrete behavior. An agent can distinguish this tool from siblings like ha_config_set_automation or ha_restart without opening the schema.

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 to use which scope' section that names the condition selecting each scope (undo a recent agent edit vs system-wide recovery), plus exclusions ('Restore one only for system-wide recovery') and a policy constraint ('A snapshot backup is the user's call'). Fourteen worked examples map user intents to exact call signatures.

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