ha-mcp-dev 8.2.0.dev2358__tar.gz → 8.2.0.dev2360__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (276) hide show
  1. {ha_mcp_dev-8.2.0.dev2358/src/ha_mcp_dev.egg-info → ha_mcp_dev-8.2.0.dev2360}/PKG-INFO +26 -26
  2. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/README.md +25 -25
  3. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/pyproject.toml +1 -1
  4. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/config.py +1 -1
  5. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/dashboard_screenshot/provision.py +21 -19
  6. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/policy/middleware.py +8 -1
  7. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/policy/persistence.py +49 -1
  8. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/read_only.py +16 -4
  9. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/redaction.py +3 -3
  10. ha_mcp_dev-8.2.0.dev2360/src/ha_mcp/renamed_tools.py +43 -0
  11. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/server.py +9 -2
  12. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/_persistence.py +29 -4
  13. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/locales/en.json +28 -28
  14. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/settings.js +4 -4
  15. ha_mcp_dev-8.2.0.dev2360/src/ha_mcp/tools/renamed_tool_middleware.py +78 -0
  16. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_addons.py +76 -68
  17. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_dashboard_screenshot.py +5 -4
  18. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_dev.py +13 -5
  19. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_energy.py +1 -1
  20. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_hacs.py +1 -1
  21. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_integrations.py +1 -1
  22. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_search.py +1 -1
  23. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_utility.py +5 -5
  24. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/transforms/categorized_search.py +23 -8
  25. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/update_check.py +4 -1
  26. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360/src/ha_mcp_dev.egg-info}/PKG-INFO +26 -26
  27. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp_dev.egg-info/SOURCES.txt +2 -0
  28. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/LICENSE +0 -0
  29. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/MANIFEST.in +0 -0
  30. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/setup.cfg +0 -0
  31. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/__init__.py +0 -0
  32. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/__main__.py +0 -0
  33. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_pypi_marker +0 -0
  34. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_rich_compat.py +0 -0
  35. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/__init__.py +0 -0
  36. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/requirements.txt +0 -0
  37. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/LICENSE +0 -0
  38. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/MANIFEST.sha256 +0 -0
  39. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/VENDORED +0 -0
  40. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/__init__.py +0 -0
  41. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/__main__.py +0 -0
  42. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/asyncio/__init__.py +0 -0
  43. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/asyncio/client.py +0 -0
  44. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/asyncio/connection.py +0 -0
  45. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/asyncio/messages.py +0 -0
  46. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/asyncio/router.py +0 -0
  47. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/asyncio/server.py +0 -0
  48. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/auth.py +0 -0
  49. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/cli.py +0 -0
  50. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/client.py +0 -0
  51. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/connection.py +0 -0
  52. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/datastructures.py +0 -0
  53. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/exceptions.py +0 -0
  54. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/extensions/__init__.py +0 -0
  55. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/extensions/base.py +0 -0
  56. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/extensions/permessage_deflate.py +0 -0
  57. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/frames.py +0 -0
  58. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/headers.py +0 -0
  59. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/http11.py +0 -0
  60. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/imports.py +0 -0
  61. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/legacy/__init__.py +0 -0
  62. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/legacy/auth.py +0 -0
  63. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/legacy/client.py +0 -0
  64. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/legacy/exceptions.py +0 -0
  65. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/legacy/framing.py +0 -0
  66. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/legacy/handshake.py +0 -0
  67. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/legacy/http.py +0 -0
  68. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/legacy/protocol.py +0 -0
  69. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/legacy/server.py +0 -0
  70. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/protocol.py +0 -0
  71. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/proxy.py +0 -0
  72. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/py.typed +0 -0
  73. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/server.py +0 -0
  74. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/streams.py +0 -0
  75. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/sync/__init__.py +0 -0
  76. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/sync/client.py +0 -0
  77. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/sync/connection.py +0 -0
  78. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/sync/messages.py +0 -0
  79. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/sync/router.py +0 -0
  80. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/sync/server.py +0 -0
  81. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/sync/utils.py +0 -0
  82. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/trio/__init__.py +0 -0
  83. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/trio/client.py +0 -0
  84. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/trio/connection.py +0 -0
  85. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/trio/messages.py +0 -0
  86. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/trio/router.py +0 -0
  87. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/trio/server.py +0 -0
  88. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/trio/utils.py +0 -0
  89. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/typing.py +0 -0
  90. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/uri.py +0 -0
  91. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/utils.py +0 -0
  92. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_vendor/websockets/version.py +0 -0
  93. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/_version.py +0 -0
  94. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/auth/__init__.py +0 -0
  95. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/auth/consent_form.py +0 -0
  96. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/auth/oidc_compat.py +0 -0
  97. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/auth/provider.py +0 -0
  98. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/backup_manager.py +0 -0
  99. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/browser_landing.py +0 -0
  100. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/client/__init__.py +0 -0
  101. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/client/rest_client.py +0 -0
  102. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/client/supervisor_client.py +0 -0
  103. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/client/websocket_client.py +0 -0
  104. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/client/websocket_listener.py +0 -0
  105. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/dashboard_screenshot/__init__.py +0 -0
  106. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/dashboard_screenshot/capture.py +0 -0
  107. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/dashboard_screenshot/content.py +0 -0
  108. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/dashboard_screenshot/paths.py +0 -0
  109. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/dashboard_screenshot/theme_guard.py +0 -0
  110. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/errors.py +0 -0
  111. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/hacs_auto_refresh.py +0 -0
  112. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/llm_exposure.py +0 -0
  113. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/policy/__init__.py +0 -0
  114. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/policy/approval_queue.py +0 -0
  115. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/policy/editing.py +0 -0
  116. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/policy/evaluator.py +0 -0
  117. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/policy/handlers.py +0 -0
  118. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/policy/model.py +0 -0
  119. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/policy/value_sources.py +0 -0
  120. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/py.typed +0 -0
  121. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
  122. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
  123. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
  124. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
  125. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/.github/pull_request_template.md +0 -0
  126. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
  127. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
  128. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
  129. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
  130. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
  131. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
  132. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/evals/evals.json +0 -0
  133. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/appdaemon.md +0 -0
  134. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
  135. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/blueprint-guide.md +0 -0
  136. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +0 -0
  137. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +0 -0
  138. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
  139. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +0 -0
  140. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
  141. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
  142. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
  143. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/scenes.md +0 -0
  144. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
  145. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/yaml-only-integrations.md +0 -0
  146. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/__init__.py +0 -0
  147. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/_handlers_advanced.py +0 -0
  148. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/_handlers_backups.py +0 -0
  149. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/_handlers_fs.py +0 -0
  150. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/_handlers_server.py +0 -0
  151. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/_handlers_theme.py +0 -0
  152. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/_handlers_tools.py +0 -0
  153. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/_i18n.py +0 -0
  154. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/_supervisor.py +0 -0
  155. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/_theme.py +0 -0
  156. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/_tools_meta.py +0 -0
  157. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/locales/README.md +0 -0
  158. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/locales/cs.json +0 -0
  159. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/locales/de.json +0 -0
  160. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/locales/eo.json +0 -0
  161. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/locales/es.json +0 -0
  162. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/locales/fr.json +0 -0
  163. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/locales/it.json +0 -0
  164. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/locales/nl.json +0 -0
  165. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/locales/pl.json +0 -0
  166. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/locales/ru.json +0 -0
  167. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/locales/sv.json +0 -0
  168. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/locales/zh-Hans.json +0 -0
  169. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/settings.css +0 -0
  170. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/settings_ui/settings.html +0 -0
  171. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/smoke_test.py +0 -0
  172. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/stdio_settings_sidecar.py +0 -0
  173. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/strict_bps.py +0 -0
  174. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/__init__.py +0 -0
  175. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/auto_backup.py +0 -0
  176. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/backup.py +0 -0
  177. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/best_practice_checker.py +0 -0
  178. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/best_practice_result.py +0 -0
  179. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/best_practice_variables.py +0 -0
  180. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/component_api.py +0 -0
  181. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/component_config_entries.py +0 -0
  182. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/component_config_reads.py +0 -0
  183. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/component_devices.py +0 -0
  184. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/component_registries.py +0 -0
  185. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/component_registry_lookup.py +0 -0
  186. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/config_entry_flow.py +0 -0
  187. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/config_entry_flow_form.py +0 -0
  188. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/config_entry_flow_menu.py +0 -0
  189. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/config_entry_flow_walker.py +0 -0
  190. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/config_entry_identity.py +0 -0
  191. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/config_entry_reconfigure.py +0 -0
  192. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/config_entry_reload_watch.py +0 -0
  193. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/device_control.py +0 -0
  194. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/error_log_parsing.py +0 -0
  195. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/hacs_registration.py +0 -0
  196. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/helpers.py +0 -0
  197. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/integration_reconfigure.py +0 -0
  198. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/radio/__init__.py +0 -0
  199. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/radio/base.py +0 -0
  200. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/radio/matter.py +0 -0
  201. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/radio/thread.py +0 -0
  202. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/radio/zigbee.py +0 -0
  203. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/radio/zwave.py +0 -0
  204. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/reference_validator.py +0 -0
  205. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/registry.py +0 -0
  206. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/smart_search/__init__.py +0 -0
  207. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/smart_search/_base.py +0 -0
  208. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/smart_search/_config.py +0 -0
  209. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/smart_search/_deep.py +0 -0
  210. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/smart_search/_entities.py +0 -0
  211. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/smart_search/_fetch.py +0 -0
  212. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/smart_search/_overview.py +0 -0
  213. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/smart_search/_scenes.py +0 -0
  214. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/smart_search/_scoring.py +0 -0
  215. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tool_search_hint_middleware.py +0 -0
  216. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_areas.py +0 -0
  217. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_assist_pipeline.py +0 -0
  218. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_blueprints.py +0 -0
  219. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_bug_report.py +0 -0
  220. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_calendar.py +0 -0
  221. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_camera.py +0 -0
  222. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_categories.py +0 -0
  223. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_code.py +0 -0
  224. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_config_automations.py +0 -0
  225. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
  226. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
  227. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_config_scenes.py +0 -0
  228. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
  229. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_entities.py +0 -0
  230. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_filesystem.py +0 -0
  231. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_groups.py +0 -0
  232. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_history.py +0 -0
  233. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_labels.py +0 -0
  234. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_radio.py +0 -0
  235. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_registry.py +0 -0
  236. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_resources.py +0 -0
  237. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_security_policy.py +0 -0
  238. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_service.py +0 -0
  239. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_services.py +0 -0
  240. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_system.py +0 -0
  241. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_themes.py +0 -0
  242. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_todo.py +0 -0
  243. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_traces.py +0 -0
  244. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_updates.py +0 -0
  245. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
  246. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
  247. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_yaml_read.py +0 -0
  248. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/tools_zones.py +0 -0
  249. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/util_helpers.py +0 -0
  250. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/tools/validation_middleware.py +0 -0
  251. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/transforms/__init__.py +0 -0
  252. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/transforms/lite_docstrings.py +0 -0
  253. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/transport_security.py +0 -0
  254. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/utils/__init__.py +0 -0
  255. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/utils/config_hash.py +0 -0
  256. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/utils/config_write_lock.py +0 -0
  257. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/utils/data_paths.py +0 -0
  258. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/utils/domain_handlers.py +0 -0
  259. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/utils/fuzzy_search.py +0 -0
  260. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
  261. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/utils/operation_manager.py +0 -0
  262. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/utils/python_sandbox.py +0 -0
  263. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/utils/skill_loader.py +0 -0
  264. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/utils/usage_logger.py +0 -0
  265. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/visibility/__init__.py +0 -0
  266. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/visibility/enforcement.py +0 -0
  267. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/visibility/model.py +0 -0
  268. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/visibility/persistence.py +0 -0
  269. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp/visibility/resolver.py +0 -0
  270. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
  271. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
  272. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
  273. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
  274. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/tests/__init__.py +0 -0
  275. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/tests/test_constants.py +0 -0
  276. {ha_mcp_dev-8.2.0.dev2358 → ha_mcp_dev-8.2.0.dev2360}/tests/test_env_manager.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ha-mcp-dev
3
- Version: 8.2.0.dev2358
3
+ Version: 8.2.0.dev2360
4
4
  Summary: Home Assistant MCP Server - Complete control of Home Assistant through MCP
5
5
  Author-email: Julien <github@qc-h.net>
6
6
  License: MIT
@@ -82,37 +82,37 @@ The recommended way to run ha-mcp is the **HA-MCP Custom Component**. It install
82
82
 
83
83
  **Connect URL.** The Configure screen gives you a Home Assistant webhook URL for remote clients — `https://<your-ha-domain>/api/webhook/<webhook-id>` through Nabu Casa or any reverse proxy already pointed at Home Assistant (locally, `http://<ha-host>:8123/api/webhook/<webhook-id>`). For clients on the same network, the server is also reachable directly at `http://<ha-ip>:9584/private_<random>`.
84
84
 
85
- - **Replaces other install methods:** the in-process server is a complete, standalone ha-mcp install — it takes the place of the add-on, Docker, and uvx/PyPI (stdio) methods. Run only one; do not run the in-process server alongside another install.
85
+ - **Replaces other install methods:** the in-process server is a complete, standalone ha-mcp install — it takes the place of the app (add-on), Docker, and uvx/PyPI (stdio) methods. Run only one; do not run the in-process server alongside another install.
86
86
  - **Local only?** Turn off **Remote access via webhook** in the entry options — no webhook is registered at all, while the direct port and sidebar panel keep working.
87
87
  - **Settings panel:** while the server runs, an admin-only **HA-MCP** panel appears in the Home Assistant sidebar for managing tools, feature flags, backups, and themes.
88
88
  - **Optional authentication:** set **Webhook authentication** to `ha_auth` to require a Home Assistant account sign-in instead of using the secret URL as the credential.
89
89
  - **Manual install (no HACS):** copy `custom_components/ha_mcp_tools/` from this repository into your Home Assistant `config/custom_components/` directory, then restart and add the integration as above.
90
90
 
91
- The component's second entry type, the **File & YAML services entry** (**HA-MCP File & YAML Tools**), is only needed if you enable ha-mcp's opt-in file and YAML editing tools (feature flags, off by default) — skip it otherwise; you can add it later at any time. It works with any server type (in-process, add-on, Docker, or stdio).
91
+ The component's second entry type, the **File & YAML services entry** (**HA-MCP File & YAML Tools**), is only needed if you enable ha-mcp's opt-in file and YAML editing tools (feature flags, off by default) — skip it otherwise; you can add it later at any time. It works with any server type (in-process, app, Docker, or stdio).
92
92
 
93
93
  [Full in-process server documentation →](docs/in-process-server.md) · [Setup Wizard for client-specific config →](https://homeassistant-ai.github.io/ha-mcp/setup/)
94
94
 
95
- ### 🏠 Home Assistant App (add-on)
95
+ ### 🏠 Home Assistant app (add-on)
96
96
 
97
- Prefer to run ha-mcp as a Home Assistant **app / add-on**? On **Home Assistant OS** and **Supervised** installs it is a close second — no access token to manage, and it works with Claude Desktop, Claude.ai, ChatGPT, and any other MCP client on your local network or configured for remote access.
97
+ Prefer to run ha-mcp as a Home Assistant **app (add-on)**? On **Home Assistant OS** and **Supervised** installs it is a close second — no access token to manage, and it works with Claude Desktop, Claude.ai, ChatGPT, and any other MCP client on your local network or configured for remote access.
98
98
 
99
99
  1. Add the repository to your Home Assistant instance:
100
100
 
101
101
  [![Add Repository](https://my.home-assistant.io/badges/supervisor_add_addon_repository.svg)](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2Fhomeassistant-ai%2Fha-mcp)
102
102
 
103
- If that opens the App Store without an add-repository dialog (a [known Home Assistant issue](https://github.com/home-assistant/my.home-assistant.io/issues/698)), add it manually: **App Store → ⋮ → Repositories**, then paste `https://github.com/homeassistant-ai/ha-mcp`.
103
+ If that opens the App store without an add-repository dialog (a [known Home Assistant issue](https://github.com/home-assistant/my.home-assistant.io/issues/698)), add it manually: **Settings → Apps → Install app → ⋮ → Repositories**, then paste `https://github.com/homeassistant-ai/ha-mcp`.
104
104
 
105
- 2. Install **"Home Assistant MCP Server"** from the App Store and click **Start**. *(Home Assistant 2026.2 renamed "Add-ons" to "Apps"; on older versions this is the Add-on Store.)*
105
+ 2. Install **"Home Assistant MCP Server"** from **Settings → Apps → Install app** and click **Start**. *(Home Assistant 2026.2 renamed "Add-ons" to "Apps"; on older versions this is the Add-on store.)*
106
106
  3. Open the **Logs** tab to find your unique MCP URL.
107
107
  4. Connect your AI client to that URL — **no token or credential setup needed**.
108
108
 
109
- [Full add-on documentation →](homeassistant-addon/DOCS.md)
109
+ [Full app documentation →](homeassistant-addon/DOCS.md)
110
110
 
111
- > ⚠️ **Configure exactly one install method per client.** The custom component, the add-on, Docker/PyPI, and local stdio are independent ways to run the same server — pick one and point your AI client at that single URL. Keeping two entries for the same server in one client (for example a local `uvx ha-mcp@latest` entry with `HOMEASSISTANT_URL` / `HOMEASSISTANT_TOKEN` alongside an add-on or component URL) is a known cause of connection hangs.
111
+ > ⚠️ **Configure exactly one install method per client.** The custom component, the app, Docker/PyPI, and local stdio are independent ways to run the same server — pick one and point your AI client at that single URL. Keeping two entries for the same server in one client (for example a local `uvx ha-mcp@latest` entry with `HOMEASSISTANT_URL` / `HOMEASSISTANT_TOKEN` alongside an app or component URL) is a known cause of connection hangs.
112
112
 
113
113
  ### Other install methods
114
114
 
115
- These run the server outside Home Assistant — useful for **Container** / **Core** installs (which can't run add-ons) or a separate host. The [Setup Wizard](https://homeassistant-ai.github.io/ha-mcp/setup/) generates the exact client-specific config for each.
115
+ These run the server outside Home Assistant — useful for **Container** / **Core** installs (which can't run apps) or a separate host. The [Setup Wizard](https://homeassistant-ai.github.io/ha-mcp/setup/) generates the exact client-specific config for each.
116
116
 
117
117
  - **Docker (HTTP server):** run `ghcr.io/homeassistant-ai/ha-mcp` in HTTP mode, pointed at your Home Assistant URL and a long-lived token, and connect your client to its secret URL. See the [Setup Wizard](https://homeassistant-ai.github.io/ha-mcp/setup/) for the full command and per-client config.
118
118
  - **PyPI / uvx (HTTP server):** run the published `ha-mcp` package with `uvx ha-mcp@latest` (or pip) as a streamable-HTTP server the same way. Details in the [Setup Wizard](https://homeassistant-ai.github.io/ha-mcp/setup/).
@@ -122,15 +122,15 @@ These run the server outside Home Assistant — useful for **Container** / **Cor
122
122
  > ⚠️ **stdio has known transport issues.** The stdio transport has connection problems that streamable HTTP does not ([#1713](https://github.com/homeassistant-ai/ha-mcp/issues/1713)). It is recommended only for demo/testing tinkering — for a real setup, use the custom component or an HTTP method above.
123
123
 
124
124
  <details>
125
- <summary><b>🌐 Remote access (Nabu Casa / Webhook Proxy add-on / OpenAI Tunnel)</b></summary>
125
+ <summary><b>🌐 Remote access (Nabu Casa / Webhook Proxy app / OpenAI Tunnel)</b></summary>
126
126
 
127
- > **Using the HA-MCP custom component?** You do not need the **Webhook Proxy** — the component has its own built-in webhook for remote access (see the **Get Started** quick start at the top). The proxy is for the **add-on** (it can also front another external server via its `mcp_server_url` option). The **OpenAI Tunnel** below is different: it applies to **any** install method when Home Assistant isn't publicly reachable at all (no Nabu Casa or reverse proxy).
127
+ > **Using the HA-MCP custom component?** You do not need the **Webhook Proxy** — the component has its own built-in webhook for remote access (see the **Get Started** quick start at the top). The proxy is for the **app** (it can also front another external server via its `mcp_server_url` option). The **OpenAI Tunnel** below is different: it applies to **any** install method when Home Assistant isn't publicly reachable at all (no Nabu Casa or reverse proxy).
128
128
 
129
- Already have **Nabu Casa** or another reverse proxy pointing at your Home Assistant? The Webhook Proxy add-on routes MCP traffic through your existing setup — no separate tunnel or port forwarding needed.
129
+ Already have **Nabu Casa** or another reverse proxy pointing at your Home Assistant? The Webhook Proxy app routes MCP traffic through your existing setup — no separate tunnel or port forwarding needed.
130
130
 
131
- 1. Install the **MCP Server add-on** (see above) and the **Webhook Proxy** add-on from the same store
131
+ 1. Install the **MCP Server app** (see above) and the **Webhook Proxy** app from the same store
132
132
  2. Start the webhook proxy and **restart Home Assistant** when prompted
133
- 3. Copy the webhook URL from the add-on logs:
133
+ 3. Copy the webhook URL from the app logs:
134
134
  ```
135
135
  MCP Server URL (remote): https://xxxxx.ui.nabu.casa/api/webhook/mcp_xxxxxxxx
136
136
  ```
@@ -241,7 +241,7 @@ Spend less time configuring, more time enjoying your smart home.
241
241
  | **🏠 Control** | Any service, bulk device control, real-time states |
242
242
  | **🔧 Manage** | Automations, scripts, helpers, dashboards, areas, zones, groups, calendars, blueprints |
243
243
  | **📊 Monitor** | History, statistics, camera snapshots, automation traces, ZHA devices |
244
- | **💾 System** | Backup/restore, updates, add-ons, device registry |
244
+ | **💾 System** | Backup/restore, updates, apps, device registry |
245
245
  | **🔒 Safety** | Read Only Mode toggle, per-tool enable/disable, tool security policies (user approval), automatic edit backups |
246
246
 
247
247
  <details>
@@ -251,7 +251,7 @@ Spend less time configuring, more time enjoying your smart home.
251
251
 
252
252
  | Category | Tools |
253
253
  |----------|-------|
254
- | **Add-ons** | `ha_get_addon`, `ha_manage_addon` |
254
+ | **Apps (add-ons)** | `ha_get_app`, `ha_manage_app` |
255
255
  | **Areas & Floors** | `ha_list_floors_areas`, `ha_remove_area_or_floor`, `ha_set_area_or_floor` |
256
256
  | **Assist** | `ha_manage_pipeline` |
257
257
  | **Automations** | `ha_config_get_automation`, `ha_config_remove_automation`, `ha_config_set_automation` |
@@ -300,7 +300,7 @@ ha-mcp is a standalone server built for **configuring, building, and debugging**
300
300
  | Build & edit dashboards | No | Yes |
301
301
  | Debug automations from traces, read history & logs | No | Yes |
302
302
  | Manage helpers, areas, zones, labels, groups | No | Yes |
303
- | Backups, add-ons, HACS, device & entity registry | No | Yes |
303
+ | Backups, apps, HACS, device & entity registry | No | Yes |
304
304
 
305
305
  **Rule of thumb:** Use the built-in integration for voice-style control of devices you have already exposed; use ha-mcp when you want an AI assistant that can also build and maintain your Home Assistant setup.
306
306
 
@@ -364,12 +364,12 @@ For setups *without* deferred tool support — models like Claude Haiku, Gemini,
364
364
 
365
365
  If your model can't see the tools or your Home Assistant, it may be getting handed the whole tool catalog at once and struggling with it. It's recommended to try the following to see if it helps:
366
366
 
367
- - **Enable tool search** (`ENABLE_TOOL_SEARCH=true`, or the add-on option below). Instead of listing every tool up front, the server defers the catalog behind a search interface so the model pulls in only the tools it needs, when it needs them.
367
+ - **Enable tool search** (`ENABLE_TOOL_SEARCH=true`, or the app option below). Instead of listing every tool up front, the server defers the catalog behind a search interface so the model pulls in only the tools it needs, when it needs them.
368
368
  - **Raise the model's context window above the default.** Local runtimes ship with small defaults (Ollama's `num_ctx` is one example) that can't hold a large tool set plus the conversation — increase it well beyond the default.
369
369
 
370
370
  ### Enable search-based discovery
371
371
 
372
- Set ENABLE_TOOL_SEARCH=true (or toggle the option in the HA add-on). The full catalog is replaced in the tool list with four entry points plus a small set of always-visible "pinned" tools (ha_search, ha_get_overview, ha_report_issue, etc.). All tools remain callable directly by name once discovered:
372
+ Set ENABLE_TOOL_SEARCH=true (or toggle the option in the HA app). The full catalog is replaced in the tool list with four entry points plus a small set of always-visible "pinned" tools (ha_search, ha_get_overview, ha_report_issue, etc.). All tools remain callable directly by name once discovered:
373
373
 
374
374
  | Tool | Purpose |
375
375
  |------|---------|
@@ -394,9 +394,9 @@ The proxy split lets MCP clients apply different permission policies per categor
394
394
 
395
395
  Leave it off in clients with deferred tool loading (claude.ai, Claude Desktop, Claude Code); the full catalog has no idle cost there, direct calls skip the search step, and the client's built-in tool search is the better choice — there is no benefit to running ha-mcp's on top of it. Whether tools are deferred depends on the client and model combination: the same model can behave differently per client — GitHub Copilot CLI running Claude Sonnet/Opus inlines the full catalog and still benefits from tool search here. Some Codex models and ChatGPT include deferred tools too — check your client/model directly to confirm its features so you don't leave this enabled unnecessarily.
396
396
 
397
- > 🔄 **Refresh your client's tool list after changing this (or any) setting.** Toggling `ENABLE_TOOL_SEARCH` (or changing pinned/disabled tools, Read Only Mode, etc.) changes the tools the server exposes, but your AI client keeps serving its **cached** tool list until it re-fetches. Restarting the add-on or Home Assistant does **not** refresh the client — reconnect or refresh the MCP server in your client (e.g. re-add/refresh the connector in ChatGPT, or close and reopen Claude Desktop). If you skip this, newly enabled tools won't appear in the client at all, and tools the server no longer exposes still show as available but return `Unknown tool` when called. ChatGPT sometimes keeps serving the stale list even after the connector is removed and re-added under the same name — if tools are still missing after re-adding, delete the connector and create a new one with a **different name**.
397
+ > 🔄 **Refresh your client's tool list after changing this (or any) setting.** Toggling `ENABLE_TOOL_SEARCH` (or changing pinned/disabled tools, Read Only Mode, etc.) changes the tools the server exposes, but your AI client keeps serving its **cached** tool list until it re-fetches. Restarting the app or Home Assistant does **not** refresh the client — reconnect or refresh the MCP server in your client (e.g. re-add/refresh the connector in ChatGPT, or close and reopen Claude Desktop). If you skip this, newly enabled tools won't appear in the client at all, and tools the server no longer exposes still show as available but return `Unknown tool` when called. ChatGPT sometimes keeps serving the stale list even after the connector is removed and re-added under the same name — if tools are still missing after re-adding, delete the connector and create a new one with a **different name**.
398
398
 
399
- For the HA add-on, the same option is documented in [`homeassistant-addon/DOCS.md`](homeassistant-addon/DOCS.md#enable_tool_search) along with the in-add-on settings UI for fine-grained tool enable/disable/pin.
399
+ For the HA app, the same option is documented in [`homeassistant-addon/DOCS.md`](homeassistant-addon/DOCS.md#enable_tool_search) along with the in-add-on settings UI for fine-grained tool enable/disable/pin.
400
400
 
401
401
  ---
402
402
 
@@ -404,7 +404,7 @@ For the HA add-on, the same option is documented in [`homeassistant-addon/DOCS.m
404
404
 
405
405
  Want early access to new features and fixes? Dev releases (`.devN`) are published on every push to master.
406
406
 
407
- **[Dev Channel Documentation](docs/dev-channel.md)** — Instructions for pip/uvx, Docker, and Home Assistant add-on.
407
+ **[Dev Channel Documentation](docs/dev-channel.md)** — Instructions for pip/uvx, Docker, and Home Assistant app.
408
408
 
409
409
  ---
410
410
 
@@ -478,17 +478,17 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
478
478
  - **[@TomasDJo](https://github.com/TomasDJo)** — Category support for automations, scripts, and scenes.
479
479
  - **[@bzelch](https://github.com/bzelch)** — `python_transform` support for automations and scripts.
480
480
  - **[@gcormier](https://github.com/gcormier)** — Windows installer improvements: removed unused variable and fixed terminal closing after install.
481
- - **[@ekobres](https://github.com/ekobres)** — Feature flags for `HAMCP_ENABLE_FILESYSTEM_TOOLS` and the (since removed) `HAMCP_ENABLE_CUSTOM_COMPONENT_INTEGRATION` in the add-on config, with beta tagging in source and docs.
481
+ - **[@ekobres](https://github.com/ekobres)** — Feature flags for `HAMCP_ENABLE_FILESYSTEM_TOOLS` and the (since removed) `HAMCP_ENABLE_CUSTOM_COMPONENT_INTEGRATION` in the app config, with beta tagging in source and docs.
482
482
  - **[@w3z315](https://github.com/w3z315)** — Financial support via [GitHub Sponsors](https://github.com/sponsors/julienld). Thank you! ☕
483
483
  - **[@griffinmartin](https://github.com/griffinmartin)** — Added OpenCode (by Anomaly) as a selectable AI client in the setup wizard, with both stdio and streamable HTTP support.
484
- - **[@hhopke](https://github.com/hhopke)** — Fixed addon API calls to route through HA Core ingress proxy instead of direct container connections, fixing `ha_manage_addon` proxy mode on addon installs.
484
+ - **[@hhopke](https://github.com/hhopke)** — Fixed app (add-on) API calls to route through HA Core ingress proxy instead of direct container connections, fixing `ha_manage_addon` (now `ha_manage_app`) proxy mode on app installs.
485
485
  - **[@tomwilkie](https://github.com/tomwilkie)** — JMESPath middleware exploration (#1147) whose review-time token-measurement data informed the design of #1199 and #1225.
486
486
  - **[@SealKan](https://github.com/SealKan)** — `fields=`/`attribute_keys=` projection on six read-heavy tools (#1225), `ha_call_event` tool (#1239), dashboards-list helper refactor (#1207), `for:`-field duration-math detector in the best-practice checker (#1264), persistent DCR OAuth client registrations across restarts (#1265), and issue-triage prompt token-budgeting (#1522).
487
487
  - **[@KarelTestSpecial](https://github.com/KarelTestSpecial)** — Cached YAML instance to prevent CPU spikes during bulk edits (#1371).
488
488
  - **[@corgan2222](https://github.com/corgan2222)** — HA brand assets for custom integration (#1317).
489
489
  - **[@drseanwing](https://github.com/drseanwing)** — Progress emission via FastMCP `Context` in long-running tools (#1124); tool-discovery / categorized-search docs (#1123).
490
490
  - **[@fnordpig](https://github.com/fnordpig)** — Config subentry support (#1393) and Assist pipeline management tool (#1392).
491
- - **[@paul43210](https://github.com/paul43210)** — `array_patch` mode in `ha_manage_addon` for atomic GET-modify-POST (#1063).
491
+ - **[@paul43210](https://github.com/paul43210)** — `array_patch` mode in `ha_manage_app` for atomic GET-modify-POST (#1063).
492
492
  - **[@L1AD](https://github.com/L1AD)** — Filed #966 proposing tool security policies; pointed to PolicyLayer's MCP-security work as prior art that inspired the predicate DSL shape.
493
493
  - **[@nightcityblade](https://github.com/nightcityblade)** — Updated stale Home Assistant Advanced Mode references after HA 2026.6 made formerly advanced options available by default (#1533).
494
494
  - **[@emmelutzer](https://github.com/emmelutzer)** — Financial support via [GitHub Sponsors](https://github.com/sponsors/julienld). Thank you! ☕
@@ -50,37 +50,37 @@ The recommended way to run ha-mcp is the **HA-MCP Custom Component**. It install
50
50
 
51
51
  **Connect URL.** The Configure screen gives you a Home Assistant webhook URL for remote clients — `https://<your-ha-domain>/api/webhook/<webhook-id>` through Nabu Casa or any reverse proxy already pointed at Home Assistant (locally, `http://<ha-host>:8123/api/webhook/<webhook-id>`). For clients on the same network, the server is also reachable directly at `http://<ha-ip>:9584/private_<random>`.
52
52
 
53
- - **Replaces other install methods:** the in-process server is a complete, standalone ha-mcp install — it takes the place of the add-on, Docker, and uvx/PyPI (stdio) methods. Run only one; do not run the in-process server alongside another install.
53
+ - **Replaces other install methods:** the in-process server is a complete, standalone ha-mcp install — it takes the place of the app (add-on), Docker, and uvx/PyPI (stdio) methods. Run only one; do not run the in-process server alongside another install.
54
54
  - **Local only?** Turn off **Remote access via webhook** in the entry options — no webhook is registered at all, while the direct port and sidebar panel keep working.
55
55
  - **Settings panel:** while the server runs, an admin-only **HA-MCP** panel appears in the Home Assistant sidebar for managing tools, feature flags, backups, and themes.
56
56
  - **Optional authentication:** set **Webhook authentication** to `ha_auth` to require a Home Assistant account sign-in instead of using the secret URL as the credential.
57
57
  - **Manual install (no HACS):** copy `custom_components/ha_mcp_tools/` from this repository into your Home Assistant `config/custom_components/` directory, then restart and add the integration as above.
58
58
 
59
- The component's second entry type, the **File & YAML services entry** (**HA-MCP File & YAML Tools**), is only needed if you enable ha-mcp's opt-in file and YAML editing tools (feature flags, off by default) — skip it otherwise; you can add it later at any time. It works with any server type (in-process, add-on, Docker, or stdio).
59
+ The component's second entry type, the **File & YAML services entry** (**HA-MCP File & YAML Tools**), is only needed if you enable ha-mcp's opt-in file and YAML editing tools (feature flags, off by default) — skip it otherwise; you can add it later at any time. It works with any server type (in-process, app, Docker, or stdio).
60
60
 
61
61
  [Full in-process server documentation →](docs/in-process-server.md) · [Setup Wizard for client-specific config →](https://homeassistant-ai.github.io/ha-mcp/setup/)
62
62
 
63
- ### 🏠 Home Assistant App (add-on)
63
+ ### 🏠 Home Assistant app (add-on)
64
64
 
65
- Prefer to run ha-mcp as a Home Assistant **app / add-on**? On **Home Assistant OS** and **Supervised** installs it is a close second — no access token to manage, and it works with Claude Desktop, Claude.ai, ChatGPT, and any other MCP client on your local network or configured for remote access.
65
+ Prefer to run ha-mcp as a Home Assistant **app (add-on)**? On **Home Assistant OS** and **Supervised** installs it is a close second — no access token to manage, and it works with Claude Desktop, Claude.ai, ChatGPT, and any other MCP client on your local network or configured for remote access.
66
66
 
67
67
  1. Add the repository to your Home Assistant instance:
68
68
 
69
69
  [![Add Repository](https://my.home-assistant.io/badges/supervisor_add_addon_repository.svg)](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2Fhomeassistant-ai%2Fha-mcp)
70
70
 
71
- If that opens the App Store without an add-repository dialog (a [known Home Assistant issue](https://github.com/home-assistant/my.home-assistant.io/issues/698)), add it manually: **App Store → ⋮ → Repositories**, then paste `https://github.com/homeassistant-ai/ha-mcp`.
71
+ If that opens the App store without an add-repository dialog (a [known Home Assistant issue](https://github.com/home-assistant/my.home-assistant.io/issues/698)), add it manually: **Settings → Apps → Install app → ⋮ → Repositories**, then paste `https://github.com/homeassistant-ai/ha-mcp`.
72
72
 
73
- 2. Install **"Home Assistant MCP Server"** from the App Store and click **Start**. *(Home Assistant 2026.2 renamed "Add-ons" to "Apps"; on older versions this is the Add-on Store.)*
73
+ 2. Install **"Home Assistant MCP Server"** from **Settings → Apps → Install app** and click **Start**. *(Home Assistant 2026.2 renamed "Add-ons" to "Apps"; on older versions this is the Add-on store.)*
74
74
  3. Open the **Logs** tab to find your unique MCP URL.
75
75
  4. Connect your AI client to that URL — **no token or credential setup needed**.
76
76
 
77
- [Full add-on documentation →](homeassistant-addon/DOCS.md)
77
+ [Full app documentation →](homeassistant-addon/DOCS.md)
78
78
 
79
- > ⚠️ **Configure exactly one install method per client.** The custom component, the add-on, Docker/PyPI, and local stdio are independent ways to run the same server — pick one and point your AI client at that single URL. Keeping two entries for the same server in one client (for example a local `uvx ha-mcp@latest` entry with `HOMEASSISTANT_URL` / `HOMEASSISTANT_TOKEN` alongside an add-on or component URL) is a known cause of connection hangs.
79
+ > ⚠️ **Configure exactly one install method per client.** The custom component, the app, Docker/PyPI, and local stdio are independent ways to run the same server — pick one and point your AI client at that single URL. Keeping two entries for the same server in one client (for example a local `uvx ha-mcp@latest` entry with `HOMEASSISTANT_URL` / `HOMEASSISTANT_TOKEN` alongside an app or component URL) is a known cause of connection hangs.
80
80
 
81
81
  ### Other install methods
82
82
 
83
- These run the server outside Home Assistant — useful for **Container** / **Core** installs (which can't run add-ons) or a separate host. The [Setup Wizard](https://homeassistant-ai.github.io/ha-mcp/setup/) generates the exact client-specific config for each.
83
+ These run the server outside Home Assistant — useful for **Container** / **Core** installs (which can't run apps) or a separate host. The [Setup Wizard](https://homeassistant-ai.github.io/ha-mcp/setup/) generates the exact client-specific config for each.
84
84
 
85
85
  - **Docker (HTTP server):** run `ghcr.io/homeassistant-ai/ha-mcp` in HTTP mode, pointed at your Home Assistant URL and a long-lived token, and connect your client to its secret URL. See the [Setup Wizard](https://homeassistant-ai.github.io/ha-mcp/setup/) for the full command and per-client config.
86
86
  - **PyPI / uvx (HTTP server):** run the published `ha-mcp` package with `uvx ha-mcp@latest` (or pip) as a streamable-HTTP server the same way. Details in the [Setup Wizard](https://homeassistant-ai.github.io/ha-mcp/setup/).
@@ -90,15 +90,15 @@ These run the server outside Home Assistant — useful for **Container** / **Cor
90
90
  > ⚠️ **stdio has known transport issues.** The stdio transport has connection problems that streamable HTTP does not ([#1713](https://github.com/homeassistant-ai/ha-mcp/issues/1713)). It is recommended only for demo/testing tinkering — for a real setup, use the custom component or an HTTP method above.
91
91
 
92
92
  <details>
93
- <summary><b>🌐 Remote access (Nabu Casa / Webhook Proxy add-on / OpenAI Tunnel)</b></summary>
93
+ <summary><b>🌐 Remote access (Nabu Casa / Webhook Proxy app / OpenAI Tunnel)</b></summary>
94
94
 
95
- > **Using the HA-MCP custom component?** You do not need the **Webhook Proxy** — the component has its own built-in webhook for remote access (see the **Get Started** quick start at the top). The proxy is for the **add-on** (it can also front another external server via its `mcp_server_url` option). The **OpenAI Tunnel** below is different: it applies to **any** install method when Home Assistant isn't publicly reachable at all (no Nabu Casa or reverse proxy).
95
+ > **Using the HA-MCP custom component?** You do not need the **Webhook Proxy** — the component has its own built-in webhook for remote access (see the **Get Started** quick start at the top). The proxy is for the **app** (it can also front another external server via its `mcp_server_url` option). The **OpenAI Tunnel** below is different: it applies to **any** install method when Home Assistant isn't publicly reachable at all (no Nabu Casa or reverse proxy).
96
96
 
97
- Already have **Nabu Casa** or another reverse proxy pointing at your Home Assistant? The Webhook Proxy add-on routes MCP traffic through your existing setup — no separate tunnel or port forwarding needed.
97
+ Already have **Nabu Casa** or another reverse proxy pointing at your Home Assistant? The Webhook Proxy app routes MCP traffic through your existing setup — no separate tunnel or port forwarding needed.
98
98
 
99
- 1. Install the **MCP Server add-on** (see above) and the **Webhook Proxy** add-on from the same store
99
+ 1. Install the **MCP Server app** (see above) and the **Webhook Proxy** app from the same store
100
100
  2. Start the webhook proxy and **restart Home Assistant** when prompted
101
- 3. Copy the webhook URL from the add-on logs:
101
+ 3. Copy the webhook URL from the app logs:
102
102
  ```
103
103
  MCP Server URL (remote): https://xxxxx.ui.nabu.casa/api/webhook/mcp_xxxxxxxx
104
104
  ```
@@ -209,7 +209,7 @@ Spend less time configuring, more time enjoying your smart home.
209
209
  | **🏠 Control** | Any service, bulk device control, real-time states |
210
210
  | **🔧 Manage** | Automations, scripts, helpers, dashboards, areas, zones, groups, calendars, blueprints |
211
211
  | **📊 Monitor** | History, statistics, camera snapshots, automation traces, ZHA devices |
212
- | **💾 System** | Backup/restore, updates, add-ons, device registry |
212
+ | **💾 System** | Backup/restore, updates, apps, device registry |
213
213
  | **🔒 Safety** | Read Only Mode toggle, per-tool enable/disable, tool security policies (user approval), automatic edit backups |
214
214
 
215
215
  <details>
@@ -219,7 +219,7 @@ Spend less time configuring, more time enjoying your smart home.
219
219
 
220
220
  | Category | Tools |
221
221
  |----------|-------|
222
- | **Add-ons** | `ha_get_addon`, `ha_manage_addon` |
222
+ | **Apps (add-ons)** | `ha_get_app`, `ha_manage_app` |
223
223
  | **Areas & Floors** | `ha_list_floors_areas`, `ha_remove_area_or_floor`, `ha_set_area_or_floor` |
224
224
  | **Assist** | `ha_manage_pipeline` |
225
225
  | **Automations** | `ha_config_get_automation`, `ha_config_remove_automation`, `ha_config_set_automation` |
@@ -268,7 +268,7 @@ ha-mcp is a standalone server built for **configuring, building, and debugging**
268
268
  | Build & edit dashboards | No | Yes |
269
269
  | Debug automations from traces, read history & logs | No | Yes |
270
270
  | Manage helpers, areas, zones, labels, groups | No | Yes |
271
- | Backups, add-ons, HACS, device & entity registry | No | Yes |
271
+ | Backups, apps, HACS, device & entity registry | No | Yes |
272
272
 
273
273
  **Rule of thumb:** Use the built-in integration for voice-style control of devices you have already exposed; use ha-mcp when you want an AI assistant that can also build and maintain your Home Assistant setup.
274
274
 
@@ -332,12 +332,12 @@ For setups *without* deferred tool support — models like Claude Haiku, Gemini,
332
332
 
333
333
  If your model can't see the tools or your Home Assistant, it may be getting handed the whole tool catalog at once and struggling with it. It's recommended to try the following to see if it helps:
334
334
 
335
- - **Enable tool search** (`ENABLE_TOOL_SEARCH=true`, or the add-on option below). Instead of listing every tool up front, the server defers the catalog behind a search interface so the model pulls in only the tools it needs, when it needs them.
335
+ - **Enable tool search** (`ENABLE_TOOL_SEARCH=true`, or the app option below). Instead of listing every tool up front, the server defers the catalog behind a search interface so the model pulls in only the tools it needs, when it needs them.
336
336
  - **Raise the model's context window above the default.** Local runtimes ship with small defaults (Ollama's `num_ctx` is one example) that can't hold a large tool set plus the conversation — increase it well beyond the default.
337
337
 
338
338
  ### Enable search-based discovery
339
339
 
340
- Set ENABLE_TOOL_SEARCH=true (or toggle the option in the HA add-on). The full catalog is replaced in the tool list with four entry points plus a small set of always-visible "pinned" tools (ha_search, ha_get_overview, ha_report_issue, etc.). All tools remain callable directly by name once discovered:
340
+ Set ENABLE_TOOL_SEARCH=true (or toggle the option in the HA app). The full catalog is replaced in the tool list with four entry points plus a small set of always-visible "pinned" tools (ha_search, ha_get_overview, ha_report_issue, etc.). All tools remain callable directly by name once discovered:
341
341
 
342
342
  | Tool | Purpose |
343
343
  |------|---------|
@@ -362,9 +362,9 @@ The proxy split lets MCP clients apply different permission policies per categor
362
362
 
363
363
  Leave it off in clients with deferred tool loading (claude.ai, Claude Desktop, Claude Code); the full catalog has no idle cost there, direct calls skip the search step, and the client's built-in tool search is the better choice — there is no benefit to running ha-mcp's on top of it. Whether tools are deferred depends on the client and model combination: the same model can behave differently per client — GitHub Copilot CLI running Claude Sonnet/Opus inlines the full catalog and still benefits from tool search here. Some Codex models and ChatGPT include deferred tools too — check your client/model directly to confirm its features so you don't leave this enabled unnecessarily.
364
364
 
365
- > 🔄 **Refresh your client's tool list after changing this (or any) setting.** Toggling `ENABLE_TOOL_SEARCH` (or changing pinned/disabled tools, Read Only Mode, etc.) changes the tools the server exposes, but your AI client keeps serving its **cached** tool list until it re-fetches. Restarting the add-on or Home Assistant does **not** refresh the client — reconnect or refresh the MCP server in your client (e.g. re-add/refresh the connector in ChatGPT, or close and reopen Claude Desktop). If you skip this, newly enabled tools won't appear in the client at all, and tools the server no longer exposes still show as available but return `Unknown tool` when called. ChatGPT sometimes keeps serving the stale list even after the connector is removed and re-added under the same name — if tools are still missing after re-adding, delete the connector and create a new one with a **different name**.
365
+ > 🔄 **Refresh your client's tool list after changing this (or any) setting.** Toggling `ENABLE_TOOL_SEARCH` (or changing pinned/disabled tools, Read Only Mode, etc.) changes the tools the server exposes, but your AI client keeps serving its **cached** tool list until it re-fetches. Restarting the app or Home Assistant does **not** refresh the client — reconnect or refresh the MCP server in your client (e.g. re-add/refresh the connector in ChatGPT, or close and reopen Claude Desktop). If you skip this, newly enabled tools won't appear in the client at all, and tools the server no longer exposes still show as available but return `Unknown tool` when called. ChatGPT sometimes keeps serving the stale list even after the connector is removed and re-added under the same name — if tools are still missing after re-adding, delete the connector and create a new one with a **different name**.
366
366
 
367
- For the HA add-on, the same option is documented in [`homeassistant-addon/DOCS.md`](homeassistant-addon/DOCS.md#enable_tool_search) along with the in-add-on settings UI for fine-grained tool enable/disable/pin.
367
+ For the HA app, the same option is documented in [`homeassistant-addon/DOCS.md`](homeassistant-addon/DOCS.md#enable_tool_search) along with the in-add-on settings UI for fine-grained tool enable/disable/pin.
368
368
 
369
369
  ---
370
370
 
@@ -372,7 +372,7 @@ For the HA add-on, the same option is documented in [`homeassistant-addon/DOCS.m
372
372
 
373
373
  Want early access to new features and fixes? Dev releases (`.devN`) are published on every push to master.
374
374
 
375
- **[Dev Channel Documentation](docs/dev-channel.md)** — Instructions for pip/uvx, Docker, and Home Assistant add-on.
375
+ **[Dev Channel Documentation](docs/dev-channel.md)** — Instructions for pip/uvx, Docker, and Home Assistant app.
376
376
 
377
377
  ---
378
378
 
@@ -446,17 +446,17 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
446
446
  - **[@TomasDJo](https://github.com/TomasDJo)** — Category support for automations, scripts, and scenes.
447
447
  - **[@bzelch](https://github.com/bzelch)** — `python_transform` support for automations and scripts.
448
448
  - **[@gcormier](https://github.com/gcormier)** — Windows installer improvements: removed unused variable and fixed terminal closing after install.
449
- - **[@ekobres](https://github.com/ekobres)** — Feature flags for `HAMCP_ENABLE_FILESYSTEM_TOOLS` and the (since removed) `HAMCP_ENABLE_CUSTOM_COMPONENT_INTEGRATION` in the add-on config, with beta tagging in source and docs.
449
+ - **[@ekobres](https://github.com/ekobres)** — Feature flags for `HAMCP_ENABLE_FILESYSTEM_TOOLS` and the (since removed) `HAMCP_ENABLE_CUSTOM_COMPONENT_INTEGRATION` in the app config, with beta tagging in source and docs.
450
450
  - **[@w3z315](https://github.com/w3z315)** — Financial support via [GitHub Sponsors](https://github.com/sponsors/julienld). Thank you! ☕
451
451
  - **[@griffinmartin](https://github.com/griffinmartin)** — Added OpenCode (by Anomaly) as a selectable AI client in the setup wizard, with both stdio and streamable HTTP support.
452
- - **[@hhopke](https://github.com/hhopke)** — Fixed addon API calls to route through HA Core ingress proxy instead of direct container connections, fixing `ha_manage_addon` proxy mode on addon installs.
452
+ - **[@hhopke](https://github.com/hhopke)** — Fixed app (add-on) API calls to route through HA Core ingress proxy instead of direct container connections, fixing `ha_manage_addon` (now `ha_manage_app`) proxy mode on app installs.
453
453
  - **[@tomwilkie](https://github.com/tomwilkie)** — JMESPath middleware exploration (#1147) whose review-time token-measurement data informed the design of #1199 and #1225.
454
454
  - **[@SealKan](https://github.com/SealKan)** — `fields=`/`attribute_keys=` projection on six read-heavy tools (#1225), `ha_call_event` tool (#1239), dashboards-list helper refactor (#1207), `for:`-field duration-math detector in the best-practice checker (#1264), persistent DCR OAuth client registrations across restarts (#1265), and issue-triage prompt token-budgeting (#1522).
455
455
  - **[@KarelTestSpecial](https://github.com/KarelTestSpecial)** — Cached YAML instance to prevent CPU spikes during bulk edits (#1371).
456
456
  - **[@corgan2222](https://github.com/corgan2222)** — HA brand assets for custom integration (#1317).
457
457
  - **[@drseanwing](https://github.com/drseanwing)** — Progress emission via FastMCP `Context` in long-running tools (#1124); tool-discovery / categorized-search docs (#1123).
458
458
  - **[@fnordpig](https://github.com/fnordpig)** — Config subentry support (#1393) and Assist pipeline management tool (#1392).
459
- - **[@paul43210](https://github.com/paul43210)** — `array_patch` mode in `ha_manage_addon` for atomic GET-modify-POST (#1063).
459
+ - **[@paul43210](https://github.com/paul43210)** — `array_patch` mode in `ha_manage_app` for atomic GET-modify-POST (#1063).
460
460
  - **[@L1AD](https://github.com/L1AD)** — Filed #966 proposing tool security policies; pointed to PolicyLayer's MCP-security work as prior art that inspired the predicate DSL shape.
461
461
  - **[@nightcityblade](https://github.com/nightcityblade)** — Updated stale Home Assistant Advanced Mode references after HA 2026.6 made formerly advanced options available by default (#1533).
462
462
  - **[@emmelutzer](https://github.com/emmelutzer)** — Financial support via [GitHub Sponsors](https://github.com/sponsors/julienld). Thank you! ☕
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ha-mcp-dev"
7
- version = "8.2.0.dev2358"
7
+ version = "8.2.0.dev2360"
8
8
  description = "Home Assistant MCP Server - Complete control of Home Assistant through MCP"
9
9
  readme = "README.md"
10
10
  # Upper bound widened to <3.15 so the package installs on Home Assistant's
@@ -341,7 +341,7 @@ class Settings(BaseSettings):
341
341
  # either direction, and it is absent from the add-on config schemas
342
342
  # like enable_dev_mode. A leash on those surfaces, NOT a sandbox: dev
343
343
  # mode's update_source/restart can still replace the running server
344
- # build, and in add-on mode ha_manage_addon can reach the add-on's
344
+ # build, and in add-on mode ha_manage_app can reach the add-on's
345
345
  # own options and ingress — gate those tools with policy rules (or
346
346
  # keep dev mode off) where that boundary matters.
347
347
  dev_tools_security_policy_access: bool = Field(
@@ -13,8 +13,8 @@ startup, never silently installed):
13
13
  2. **HA OS / Supervised** — ``SUPERVISOR_TOKEN`` is present. The Puppet
14
14
  add-on (slug ``*_puppet``) is discovered via the Supervisor REST API and
15
15
  reached on the internal network by its hostname. The user must have
16
- installed + started it themselves (add balloob's add-on repository, then
17
- install "Puppet") — we never auto-install.
16
+ installed + started it themselves (add balloob's repository to the App
17
+ store, then install "Puppet") — we never auto-install.
18
18
  3. **Neither** (stdio / standalone) — a clear :class:`ToolError` explaining
19
19
  how to enable it.
20
20
  """
@@ -68,16 +68,17 @@ _REPO_URL = "https://github.com/balloob/home-assistant-addons"
68
68
  # reused across every engine-troubleshooting message here and in capture.py so
69
69
  # a copy edit only has to happen once.
70
70
  TOKEN_HINT = (
71
- "set the add-on's 'access_token' option to a Home Assistant long-lived "
71
+ "set the app's 'access_token' option to a Home Assistant long-lived "
72
72
  "access token (create one in Profile > Security, ideally for a dedicated "
73
73
  "low-privilege user) and (re)start it"
74
74
  )
75
75
 
76
76
  _INSTALL_HELP = (
77
77
  "Dashboard screenshot mode is enabled, but the Puppet screenshot engine "
78
- "add-on is not installed. On HA OS / Supervised: (1) add balloob's add-on "
79
- f"repository ({_REPO_URL}) under Settings > Add-ons > Add-on Store > "
80
- "Repositories, then install the 'Puppet' add-on; and (2) it REQUIRES a "
78
+ "app (add-on) is not installed. On HA OS / Supervised: (1) add balloob's "
79
+ f"repository ({_REPO_URL}) under Settings > Apps > Install app > ⋮ > "
80
+ "Repositories (Settings > Add-ons > Add-on store before Home Assistant "
81
+ "2026.2), then install the 'Puppet' app; and (2) it REQUIRES a "
81
82
  f"token — {TOKEN_HINT}. Without a token the engine only serves a "
82
83
  "configuration-instructions page. On Docker / Container, run the Puppet "
83
84
  "image as a sidecar (with its access_token set) and point ha-mcp at it via "
@@ -85,14 +86,15 @@ _INSTALL_HELP = (
85
86
  )
86
87
 
87
88
  _NOT_STARTED_HELP = (
88
- "The Puppet screenshot engine add-on is installed but not started. Open "
89
- f"Settings > Add-ons > Puppet, {TOKEN_HINT} (enable 'Start on boot' to keep "
89
+ "The Puppet screenshot engine app (add-on) is installed but not started. "
90
+ "Open Settings > Apps > Puppet (Settings > Add-ons > Puppet before Home "
91
+ f"Assistant 2026.2), {TOKEN_HINT} (enable 'Start on boot' to keep "
90
92
  "it available)."
91
93
  )
92
94
 
93
95
  _STDIO_HELP = (
94
96
  "Dashboard screenshot mode needs either HA OS / Supervised (add balloob's "
95
- "add-on repository and install the 'Puppet' add-on) or a Puppet sidecar "
97
+ "repository to the App store and install the 'Puppet' app) or a Puppet sidecar "
96
98
  "reachable via HAMCP_DASHBOARD_SCREENSHOT_ENGINE_URL. This deployment "
97
99
  "(stdio / standalone) can host neither — see docs/beta.md."
98
100
  )
@@ -116,10 +118,10 @@ def _select_started_verified_puppet(
116
118
  raise_tool_error(
117
119
  create_error_response(
118
120
  ErrorCode.CONFIG_VALIDATION_FAILED,
119
- "Installed *_puppet add-ons did not match Puppet's expected schema.",
121
+ "Installed *_puppet apps did not match Puppet's expected schema.",
120
122
  context={"matched_slugs": [slug for slug, _ in addon_infos]},
121
123
  suggestions=[
122
- "Verify the installed screenshot engine is balloob's Puppet add-on"
124
+ "Verify the installed screenshot engine is balloob's Puppet app"
123
125
  ],
124
126
  )
125
127
  )
@@ -128,7 +130,7 @@ def _select_started_verified_puppet(
128
130
  raise_tool_error(
129
131
  create_error_response(
130
132
  ErrorCode.SERVICE_CALL_FAILED,
131
- "The schema-verified Puppet add-on is not started.",
133
+ "The schema-verified Puppet app is not started.",
132
134
  details=_NOT_STARTED_HELP,
133
135
  context={"matched_slugs": [slug for slug, _ in verified]},
134
136
  )
@@ -137,7 +139,7 @@ def _select_started_verified_puppet(
137
139
  raise_tool_error(
138
140
  create_error_response(
139
141
  ErrorCode.CONFIG_VALIDATION_FAILED,
140
- "Multiple started Puppet add-ons matched the expected schema; "
142
+ "Multiple started Puppet apps matched the expected schema; "
141
143
  "refusing an ambiguous target.",
142
144
  context={"matched_slugs": [slug for slug, _ in started]},
143
145
  )
@@ -188,7 +190,7 @@ async def resolve_engine() -> EngineTarget:
188
190
  "Dashboard screenshot mode is not available in this deployment.",
189
191
  details=_STDIO_HELP,
190
192
  suggestions=[
191
- "Use HA OS / Supervised and install the screenshot engine add-on",
193
+ "Use HA OS / Supervised and install the screenshot engine app",
192
194
  "Or run the engine as a sidecar and set "
193
195
  + "HAMCP_DASHBOARD_SCREENSHOT_ENGINE_URL",
194
196
  ],
@@ -251,7 +253,7 @@ async def _discover_engine_via_supervisor() -> EngineTarget:
251
253
  raise_tool_error(
252
254
  create_error_response(
253
255
  ErrorCode.RESOURCE_NOT_FOUND,
254
- "The Puppet screenshot engine add-on is not installed.",
256
+ "The Puppet screenshot engine app is not installed.",
255
257
  details=_INSTALL_HELP,
256
258
  )
257
259
  )
@@ -259,7 +261,7 @@ async def _discover_engine_via_supervisor() -> EngineTarget:
259
261
  # The /addons list is only reliable for slug discovery (the
260
262
  # repo-hash prefix is not known ahead of time). Per-addon details
261
263
  # are authoritative on /addons/<slug>/info — the same source
262
- # ha_manage_addon trusts.
264
+ # ha_manage_app trusts.
263
265
  addon_infos: list[tuple[str, dict[str, Any]]] = []
264
266
  for match in matches:
265
267
  slug = str(match["slug"])
@@ -273,7 +275,7 @@ async def _discover_engine_via_supervisor() -> EngineTarget:
273
275
  raise_tool_error(
274
276
  create_error_response(
275
277
  ErrorCode.SERVICE_CALL_FAILED,
276
- f"Screenshot engine add-on '{slug}' is started but "
278
+ f"Screenshot engine app '{slug}' is started but "
277
279
  "the Supervisor returned no hostname/ip_address.",
278
280
  context={"slug": slug},
279
281
  )
@@ -293,10 +295,10 @@ async def _discover_engine_via_supervisor() -> EngineTarget:
293
295
  create_error_response(
294
296
  ErrorCode.CONNECTION_FAILED,
295
297
  "Could not query the Supervisor to locate the Puppet "
296
- "screenshot engine add-on.",
298
+ "screenshot engine app.",
297
299
  details=str(e),
298
300
  suggestions=[
299
- "Verify the Puppet add-on is installed and started",
301
+ "Verify the Puppet app is installed and started",
300
302
  "Or set HAMCP_DASHBOARD_SCREENSHOT_ENGINE_URL explicitly",
301
303
  ],
302
304
  )
@@ -12,6 +12,7 @@ from anyio.to_thread import run_sync as run_in_thread
12
12
  from fastmcp.server.middleware.middleware import CallNext, Middleware, MiddlewareContext
13
13
 
14
14
  from ..errors import ErrorCode, create_error_response
15
+ from ..renamed_tools import current_tool_name
15
16
  from ..tools.helpers import raise_tool_error, safe_progress
16
17
  from .approval_queue import ApprovalQueue, PendingApproval, compute_args_hash
17
18
  from .evaluator import Verdict, evaluate, find_matching_rule
@@ -100,7 +101,13 @@ class PolicyMiddleware(Middleware):
100
101
  ],
101
102
  )
102
103
  )
103
- name = context.message.name
104
+ # RenamedToolAliasMiddleware runs ahead of this one and normally
105
+ # rewrites a retired name before it arrives. Resolving it again costs a
106
+ # dict lookup and removes the ordering dependency, which here is the
107
+ # difference between gated and ungated: rules are keyed on the current
108
+ # name, and ``evaluate`` returns ALLOW when nothing matches, so a gate
109
+ # reading a stale name lets the call through.
110
+ name = current_tool_name(context.message.name)
104
111
  args = context.message.arguments or {}
105
112
 
106
113
  if _passes_ungated(name, args):
@@ -8,6 +8,7 @@ from pathlib import Path
8
8
 
9
9
  from pydantic import ValidationError
10
10
 
11
+ from ..renamed_tools import RENAMED_TOOLS, current_tool_name
11
12
  from .model import Policy, Rule
12
13
 
13
14
  logger = logging.getLogger(__name__)
@@ -24,9 +25,56 @@ def load_policy(data_dir: Path) -> Policy:
24
25
  except json.JSONDecodeError as e:
25
26
  raise ValueError(f"tool_policy.json is not valid JSON: {e}") from e
26
27
  try:
27
- return Policy.model_validate(raw)
28
+ policy = Policy.model_validate(raw)
28
29
  except ValidationError as e:
29
30
  raise ValueError(f"tool_policy.json failed schema validation: {e}") from e
31
+ return _follow_renamed_tools(policy)
32
+
33
+
34
+ def _follow_renamed_tools(policy: Policy) -> Policy:
35
+ """Point rules naming a retired tool at the name it answers to today.
36
+
37
+ A rule is a gate: left on the old name it matches nothing, so a tool the
38
+ user had put behind approval or denial would run ungated after the rename,
39
+ with the rule still visible in the editor as if it applied.
40
+
41
+ Re-keying can leave two rules on one tool, and both are kept on purpose:
42
+ gating is additive — ANY matching rule requires approval — so dropping
43
+ either would weaken the gate the user configured. What the duplication does
44
+ decide is ``remember_minutes``, which the middleware reads off the FIRST
45
+ matching rule, so an inherited rule moves behind the rules that already
46
+ name the current tool: the one authored against the tool as it is called
47
+ today is the deliberate one.
48
+
49
+ Nothing else moves. An inherited rule with no same-tool counterpart keeps
50
+ its position, so a ``*`` rule that used to sit behind it still does — this
51
+ re-keying is not the place to change which rule answers for a tool that
52
+ only ever had one.
53
+ """
54
+ if not any(rule.tool_name in RENAMED_TOOLS for rule in policy.rules):
55
+ return policy
56
+
57
+ resolved: list[tuple[Rule, bool]] = [
58
+ (rule.model_copy(update={"tool_name": current_tool_name(rule.tool_name)}), True)
59
+ if rule.tool_name in RENAMED_TOOLS
60
+ else (rule, False)
61
+ for rule in policy.rules
62
+ ]
63
+ authored: dict[str, int] = {
64
+ rule.tool_name: index
65
+ for index, (rule, inherited) in enumerate(resolved)
66
+ if not inherited
67
+ }
68
+
69
+ def anchor(index: int) -> tuple[int, int]:
70
+ rule, inherited = resolved[index]
71
+ if not inherited:
72
+ return (index, 0)
73
+ # Sort right behind the last rule authored on this tool, or stay put.
74
+ return (authored.get(rule.tool_name, index), 1)
75
+
76
+ order = sorted(range(len(resolved)), key=anchor)
77
+ return policy.model_copy(update={"rules": [resolved[index][0] for index in order]})
30
78
 
31
79
 
32
80
  def migrate_policy_any_semantics(data_dir: Path) -> bool: