Skip to content

Releases: czechbol/hass-mcp

v2.2.2

Choose a tag to compare

@github-actions github-actions released this 18 Jul 22:23

Security

  • ha_blueprint get/substitute now reject absolute or ..-laden paths, the
    same guard delete already applied. HA joins the caller's path straight onto
    blueprints/<domain>/ with pathlib, so an unsanitized read op could point at a
    file outside the blueprint folder.
  • ha_registry kind=entity list/get now honor the token owner's per-entity
    read policy: list drops entities the user can't read and get masks them as
    "not found". A restricted non-admin token could previously enumerate the full
    entity registry (and confirm existence of hidden entities via get), bypassing
    the per-entity read policy enforced by the other read tools.
  • ha_history kind=logbook now requires a restricted non-admin token to scope
    by entity_ids; an unscoped call previously returned the whole logbook,
    bypassing the per-entity read policy.
  • ha_yaml_config list/get are now admin-only — they return full
    automation/script/scene logic (and any inlined secrets), matching ha_trace.
  • Internal failures no longer leak raw exception detail to the client. Beyond
    the central JSON-RPC/tool-call handlers, per-tool except Exception paths
    (config flow, blueprint, diagnostics, energy, trace, camera, system, yaml
    reload) and the ws_call bridge now log the cause server-side and return only
    a generic, actionable message. Validation feedback and HA's own user-facing
    errors are unaffected.

2.2.1

Choose a tag to compare

@czechbol czechbol released this 18 Jul 19:32

Security

  • ha_statistics read ops (list_ids, period, metadata) now honor the token owner's per-entity read policy, closing a gap left by 2.2.0 — a restricted non-admin token could read long-term statistics for entities its policy hides. External (non-entity) statistic ids are unaffected.
  • ha_trace is now admin-only (all ops), matching HA's own @require_admin trace commands. Traces embed entity values and automation logic.

v2.2.0

Choose a tag to compare

@github-actions github-actions released this 18 Jul 19:07

Security

  • Read tools now honor the token owner's per-entity read policy (HA
    POLICY_READ), matching what the write path already enforced. A restricted
    non-admin token no longer sees entities its HA policy hides via
    ha_list_states, ha_get_state, ha_describe_entity, ha_search,
    ha_camera_snapshot, or ha_history. ha_render_template requires
    unrestricted read access (it reads state through an unfilterable channel).
    Admins, the owner, and default full-access users are unaffected.

v2.1.0

Choose a tag to compare

@github-actions github-actions released this 07 Jul 20:02
e726822

Security

  • Tool calls now execute as the token's owner instead of a substituted admin
    (admins[0]); ha_auth likewise acts on the caller. Mutating ops fail closed
    with no user.
  • Admin-only operations now require an admin token: mutations on ha_registry,
    ha_config_entries, ha_config_flow, ha_energy, ha_statistics,
    ha_set_state, ha_delete_state, ha_yaml_config, ha_blueprint,
    ha_recorder, ha_system, ha_hacs, plus sensitive reads (ha_system
    logs/get_config, ha_config_entries list/get, ha_diagnostics).
  • ha_blueprint import/delete reject path-traversal; ha_hacs op=download
    reclassified destructive; ha_render_template gains a best-effort render
    guard; ha_fire_event and ha_config_flow/ha_diagnostics/ha_config_entries
    reads are admin-gated.
  • Rate limiter now counts JSON-RPC batches (capped at 100); the endpoint fails
    closed when the integration is unloaded.

Changed

  • Meta-tool permissions are gated per op via write_ops/destructive_ops.
    Destructive ops (delete/remove/purge/revoke/restore/clear) now require
    allow_destructive (default off) rather than allow_write.

v2.1.0-beta.4

v2.1.0-beta.4 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 07 Jul 18:50
1cad498

Security

  • Tool calls now execute as the token's owner instead of a substituted admin
    (admins[0]); ha_auth likewise acts on the caller. Mutating ops fail closed
    with no user.
  • Admin-only operations now require an admin token: mutations on ha_registry,
    ha_config_entries, ha_config_flow, ha_energy, ha_statistics,
    ha_set_state, ha_delete_state, ha_yaml_config, ha_blueprint,
    ha_recorder, ha_system, ha_hacs, plus sensitive reads (ha_system
    logs/get_config, ha_config_entries list/get, ha_diagnostics).
  • ha_blueprint import/delete reject path-traversal; ha_hacs op=download
    reclassified destructive; ha_render_template gains a best-effort render
    guard; ha_fire_event and ha_config_flow/ha_diagnostics/ha_config_entries
    reads are admin-gated.
  • Rate limiter now counts JSON-RPC batches (capped at 100); the endpoint fails
    closed when the integration is unloaded.

Changed

  • Meta-tool permissions are gated per op via write_ops/destructive_ops.
    Destructive ops (delete/remove/purge/revoke/restore/clear) now require
    allow_destructive (default off) rather than allow_write.

v2.1.0-beta.3

v2.1.0-beta.3 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 07 Jul 18:07
f19cca1

Security

  • Tool calls now execute as the token's owner, not a substituted admin.
    Previously every WebSocket-backed call ran as the first active admin
    (admins[0]), so any valid bearer token gained admin rights. Calls now run
    as the Home Assistant user who owns the token, and HA's own permission
    machinery enforces that user's rights. Mutating operations fail closed
    when no authenticated user is present. ha_auth now acts on the calling
    token's own user (it too previously used admins[0], letting any token mint
    an admin long-lived token).
  • Admin-only operations now require an admin token. Tools that mutate via
    direct HA APIs with no per-user check of their own — ha_registry,
    ha_config_entries, ha_config_flow, ha_energy, ha_statistics,
    ha_set_state, ha_delete_state, ha_yaml_config, ha_blueprint,
    ha_recorder, ha_system, ha_hacs — now require the token's user to be an
    administrator (matching Home Assistant's own policy for those operations).
    Their read ops remain available to any token. In particular ha_yaml_config
    (automation/script authoring) and ha_hacs op=download (installs code) were
    previously reachable by any write-enabled token.
  • ha_blueprint now rejects unsafe paths for both op=import (filename)
    and op=delete (path) — path separators that escape, .. segments, and
    non-.yaml targets. Home Assistant's async_remove_blueprint performs an
    unsanitized path join + unlink, so op=delete was an arbitrary-file-delete
    vector; the guard closes it.
  • ha_hacs op=download (installs integration code) is now classed destructive
    (default off) rather than a plain write.
  • Rate limiter now counts JSON-RPC batches. A batch of N messages costs N
    slots and batches are capped (100), so a single request can no longer bypass
    the per-minute limit.
  • The endpoint fails closed when the integration is unloaded. Previously the
    aiohttp view kept serving after unload and fell back to permissive option
    defaults (re-enabling writes); it now rejects requests until the entry is
    loaded again.
  • Sensitive reads now require an admin token. ha_system op=read_error_log
    / read_system_log / get_config (logs may contain secrets; core config
    exposes precise location), ha_config_entries op=list/get, and all
    ha_diagnostics ops now require the token's user to be an administrator.
    Core monitoring reads (states, history, statistics, registry inventory,
    traces) remain available to any token.
  • ha_render_template now bounds execution with a render timeout, so a runaway
    template can't block the event loop. The full (limited=false) engine
    remains the default.
  • Destructive/write ops are now gated per op. Several meta-tools
    (ha_registry, ha_config_entries, ha_blueprint, ha_energy,
    ha_statistics, ha_helper, ha_backup, ha_yaml_config) previously
    declared their gating only in prose or a coarse whole-tool flag, so
    create/update/delete/purge/restore could run with allow_destructive (or
    even allow_write) disabled. Gating is now declarative and enforced
    centrally before the handler runs.

Changed

  • Destructive ops (delete / remove / purge / revoke / restore /
    clear) now require allow_destructive (default off) rather than
    running under allow_write. Workflows that relied on the old behavior must
    enable the toggle.
  • Meta-tool permission gating moved from whole-tool requires_* flags to
    declarative per-op write_ops / destructive_ops. This also fixes
    over-gating: ha_recorder op=info and ha_hacs read ops no longer
    require a write/destructive toggle and reappear in the default tool list.

v2.1.0-beta.2

v2.1.0-beta.2 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 07 Jul 17:45
dcb8047

Security

  • Tool calls now execute as the token's owner, not a substituted admin.
    Previously every WebSocket-backed call ran as the first active admin
    (admins[0]), so any valid bearer token gained admin rights. Calls now run
    as the Home Assistant user who owns the token, and HA's own permission
    machinery enforces that user's rights. Mutating operations fail closed
    when no authenticated user is present. ha_auth now acts on the calling
    token's own user (it too previously used admins[0], letting any token mint
    an admin long-lived token).
  • Admin-only operations now require an admin token. Tools that mutate via
    direct HA APIs with no per-user check of their own — ha_registry,
    ha_config_entries, ha_config_flow, ha_energy, ha_statistics,
    ha_set_state, ha_delete_state, ha_yaml_config, ha_blueprint,
    ha_recorder, ha_system, ha_hacs — now require the token's user to be an
    administrator (matching Home Assistant's own policy for those operations).
    Their read ops remain available to any token. In particular ha_yaml_config
    (automation/script authoring) and ha_hacs op=download (installs code) were
    previously reachable by any write-enabled token.
  • ha_blueprint now rejects unsafe paths for both op=import (filename)
    and op=delete (path) — path separators that escape, .. segments, and
    non-.yaml targets. Home Assistant's async_remove_blueprint performs an
    unsanitized path join + unlink, so op=delete was an arbitrary-file-delete
    vector; the guard closes it.
  • ha_hacs op=download (installs integration code) is now classed destructive
    (default off) rather than a plain write.
  • Rate limiter now counts JSON-RPC batches. A batch of N messages costs N
    slots and batches are capped (100), so a single request can no longer bypass
    the per-minute limit.
  • The endpoint fails closed when the integration is unloaded. Previously the
    aiohttp view kept serving after unload and fell back to permissive option
    defaults (re-enabling writes); it now rejects requests until the entry is
    loaded again.
  • Destructive/write ops are now gated per op. Several meta-tools
    (ha_registry, ha_config_entries, ha_blueprint, ha_energy,
    ha_statistics, ha_helper, ha_backup, ha_yaml_config) previously
    declared their gating only in prose or a coarse whole-tool flag, so
    create/update/delete/purge/restore could run with allow_destructive (or
    even allow_write) disabled. Gating is now declarative and enforced
    centrally before the handler runs.

Changed

  • Destructive ops (delete / remove / purge / revoke / restore /
    clear) now require allow_destructive (default off) rather than
    running under allow_write. Workflows that relied on the old behavior must
    enable the toggle.
  • Meta-tool permission gating moved from whole-tool requires_* flags to
    declarative per-op write_ops / destructive_ops. This also fixes
    over-gating: ha_recorder op=info and ha_hacs read ops no longer
    require a write/destructive toggle and reappear in the default tool list.

v2.1.0-beta.1

v2.1.0-beta.1 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 07 Jul 17:02
dfe3258

Security

  • Tool calls now execute as the token's owner, not a substituted admin.
    Previously every WebSocket-backed call ran as the first active admin
    (admins[0]), so any valid bearer token gained admin rights. Calls now run
    as the Home Assistant user who owns the token, and HA's own permission
    machinery enforces that user's rights. Mutating operations fail closed
    when no authenticated user is present. ha_auth now acts on the calling
    token's own user (it too previously used admins[0], letting any token mint
    an admin long-lived token).
  • Admin-only operations now require an admin token. Tools that mutate via
    direct HA APIs with no per-user check of their own — ha_registry,
    ha_config_entries, ha_config_flow, ha_energy, ha_statistics,
    ha_set_state, ha_delete_state — now require the token's user to be an
    administrator (matching Home Assistant's own policy for those operations).
    Their read ops remain available to any token.
  • ha_blueprint op=import now rejects filename values containing path
    separators or non-.yaml extensions, closing a path-traversal vector.
  • Destructive/write ops are now gated per op. Several meta-tools
    (ha_registry, ha_config_entries, ha_blueprint, ha_energy,
    ha_statistics, ha_helper, ha_backup, ha_yaml_config) previously
    declared their gating only in prose or a coarse whole-tool flag, so
    create/update/delete/purge/restore could run with allow_destructive (or
    even allow_write) disabled. Gating is now declarative and enforced
    centrally before the handler runs.

Changed

  • Destructive ops (delete / remove / purge / revoke / restore /
    clear) now require allow_destructive (default off) rather than
    running under allow_write. Workflows that relied on the old behavior must
    enable the toggle.
  • Meta-tool permission gating moved from whole-tool requires_* flags to
    declarative per-op write_ops / destructive_ops. This also fixes
    over-gating: ha_recorder op=info and ha_hacs read ops no longer
    require a write/destructive toggle and reappear in the default tool list.

v2.0.0

Choose a tag to compare

@github-actions github-actions released this 19 Jun 14:39
211f9c5

Changed

  • Breaking — tool names. Consolidated confusable tools into generic
    meta-tools to reduce tools/list context pollution. Clients that call the
    old names must migrate:
    • ha_logbookha_history with kind=logbook (state history is now
      ha_history with kind=state_changes).
    • ha_conversationha_assist with op=converse;
      ha_intentha_assist with op=handle_intent.
    • ha_get_config / ha_check_config / ha_get_system_health /
      ha_error_log / ha_system_logha_system with
      op=get_config|check_config|get_health|read_error_log|read_system_log|clear_system_log.
  • tools/list now omits tools whose permission class is disabled
    (allow_write/allow_destructive/allow_fire_event) instead of listing
    them and failing the call. A default install lists ~28 tools instead of 32.
    Disabled capabilities are noted in the initialize instructions so they
    stay discoverable. Clients cache the list — reconnect after changing
    options to see the updated set.
  • Slimmed the shared pagination fields (limit/offset) in tool schemas to
    trim catalog weight.
  • Integration display name is now Native MCP for Home Assistant.

Removed

  • Breakingha_describe_service. Its output was byte-identical to a
    single row of ha_list_services; use
    ha_list_services(domain="<d>", service_pattern="<d>.<s>").

1.1.1

Choose a tag to compare

@czechbol czechbol released this 17 May 14:06

Fixed

  • ha_lovelace op=save_config now parses YAML/JSON string inputs to a
    dict before passing to HA's lovelace/config/save WS command.
    Previously a raw string could be persisted verbatim, leaving the
    dashboard unrenderable (Cannot use 'in' operator to search for 'strategy' in <stringified-config>). Non-mapping or unparseable
    strings now raise ToolError instead of bricking the dashboard.
  • ha_lovelace op=config now materializes the orjson.Fragment
    returned by HA's lovelace handler into a plain dict. Previously
    clients received the Python repr "<orjson.Fragment object at 0x…>"
    through the MCP JSON encoder fallback.

Changed

  • ha_lovelace destructive-op error message now points to the
    integration's Configure dialog rather than implying the flag is a
    per-call argument.