ha-mcp-dev 7.9.0.dev742__tar.gz → 7.9.0.dev743__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 (152) hide show
  1. {ha_mcp_dev-7.9.0.dev742/src/ha_mcp_dev.egg-info → ha_mcp_dev-7.9.0.dev743}/PKG-INFO +1 -1
  2. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/pyproject.toml +1 -1
  3. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/errors.py +42 -2
  4. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_bug_report.py +87 -1
  5. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743/src/ha_mcp_dev.egg-info}/PKG-INFO +1 -1
  6. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/LICENSE +0 -0
  7. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/MANIFEST.in +0 -0
  8. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/README.md +0 -0
  9. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/setup.cfg +0 -0
  10. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/__init__.py +0 -0
  11. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/__main__.py +0 -0
  12. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/_pypi_marker +0 -0
  13. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/_version.py +0 -0
  14. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/auth/__init__.py +0 -0
  15. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/auth/consent_form.py +0 -0
  16. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/auth/provider.py +0 -0
  17. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/backup_manager.py +0 -0
  18. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/client/__init__.py +0 -0
  19. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/client/rest_client.py +0 -0
  20. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/client/supervisor_client.py +0 -0
  21. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/client/websocket_client.py +0 -0
  22. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/client/websocket_listener.py +0 -0
  23. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/config.py +0 -0
  24. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/dashboard_screenshot/__init__.py +0 -0
  25. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/dashboard_screenshot/capture.py +0 -0
  26. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/dashboard_screenshot/provision.py +0 -0
  27. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/policy/__init__.py +0 -0
  28. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/policy/approval_queue.py +0 -0
  29. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/policy/evaluator.py +0 -0
  30. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/policy/handlers.py +0 -0
  31. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/policy/middleware.py +0 -0
  32. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/policy/model.py +0 -0
  33. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/policy/persistence.py +0 -0
  34. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/policy/value_sources.py +0 -0
  35. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/py.typed +0 -0
  36. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/read_only.py +0 -0
  37. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
  38. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
  39. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
  40. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
  41. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/.github/pull_request_template.md +0 -0
  42. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
  43. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
  44. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
  45. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
  46. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
  47. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
  48. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/evals/evals.json +0 -0
  49. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
  50. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +0 -0
  51. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +0 -0
  52. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
  53. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +0 -0
  54. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
  55. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
  56. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
  57. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
  58. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/yaml-only-integrations.md +0 -0
  59. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/server.py +0 -0
  60. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/settings_ui/__init__.py +0 -0
  61. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/settings_ui/settings.css +0 -0
  62. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/settings_ui/settings.html +0 -0
  63. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/settings_ui/settings.js +0 -0
  64. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/smoke_test.py +0 -0
  65. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/stdio_settings_sidecar.py +0 -0
  66. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/__init__.py +0 -0
  67. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/auto_backup.py +0 -0
  68. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/backup.py +0 -0
  69. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/best_practice_checker.py +0 -0
  70. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/config_entry_flow.py +0 -0
  71. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/device_control.py +0 -0
  72. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/enhanced.py +0 -0
  73. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/helpers.py +0 -0
  74. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/radio/__init__.py +0 -0
  75. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/radio/base.py +0 -0
  76. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/radio/matter.py +0 -0
  77. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/radio/thread.py +0 -0
  78. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/radio/zigbee.py +0 -0
  79. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/radio/zwave.py +0 -0
  80. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/reference_validator.py +0 -0
  81. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/registry.py +0 -0
  82. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/smart_search/__init__.py +0 -0
  83. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/smart_search/_base.py +0 -0
  84. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/smart_search/_config.py +0 -0
  85. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/smart_search/_deep.py +0 -0
  86. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/smart_search/_entities.py +0 -0
  87. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/smart_search/_fetch.py +0 -0
  88. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/smart_search/_overview.py +0 -0
  89. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/smart_search/_scenes.py +0 -0
  90. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/smart_search/_scoring.py +0 -0
  91. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tool_search_hint_middleware.py +0 -0
  92. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_addons.py +0 -0
  93. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_areas.py +0 -0
  94. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_blueprints.py +0 -0
  95. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_calendar.py +0 -0
  96. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_camera.py +0 -0
  97. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_categories.py +0 -0
  98. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_code.py +0 -0
  99. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_config_automations.py +0 -0
  100. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
  101. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
  102. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_config_scenes.py +0 -0
  103. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
  104. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_dashboard_screenshot.py +0 -0
  105. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_energy.py +0 -0
  106. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_entities.py +0 -0
  107. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_filesystem.py +0 -0
  108. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_groups.py +0 -0
  109. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_hacs.py +0 -0
  110. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_history.py +0 -0
  111. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_integrations.py +0 -0
  112. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_labels.py +0 -0
  113. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_mcp_component.py +0 -0
  114. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_radio.py +0 -0
  115. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_registry.py +0 -0
  116. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_resources.py +0 -0
  117. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_search.py +0 -0
  118. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_service.py +0 -0
  119. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_services.py +0 -0
  120. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_system.py +0 -0
  121. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_themes.py +0 -0
  122. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_todo.py +0 -0
  123. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_traces.py +0 -0
  124. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_updates.py +0 -0
  125. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_utility.py +0 -0
  126. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
  127. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
  128. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/tools_zones.py +0 -0
  129. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/util_helpers.py +0 -0
  130. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/tools/validation_middleware.py +0 -0
  131. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/transforms/__init__.py +0 -0
  132. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/transforms/categorized_search.py +0 -0
  133. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/transforms/lite_docstrings.py +0 -0
  134. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/update_check.py +0 -0
  135. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/utils/__init__.py +0 -0
  136. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/utils/config_hash.py +0 -0
  137. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/utils/data_paths.py +0 -0
  138. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/utils/domain_handlers.py +0 -0
  139. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/utils/fuzzy_search.py +0 -0
  140. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
  141. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/utils/operation_manager.py +0 -0
  142. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/utils/python_sandbox.py +0 -0
  143. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/utils/skill_loader.py +0 -0
  144. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp/utils/usage_logger.py +0 -0
  145. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp_dev.egg-info/SOURCES.txt +0 -0
  146. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
  147. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
  148. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
  149. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
  150. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/tests/__init__.py +0 -0
  151. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/tests/test_constants.py +0 -0
  152. {ha_mcp_dev-7.9.0.dev742 → ha_mcp_dev-7.9.0.dev743}/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: 7.9.0.dev742
3
+ Version: 7.9.0.dev743
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ha-mcp-dev"
7
- version = "7.9.0.dev742"
7
+ version = "7.9.0.dev743"
8
8
  description = "Home Assistant MCP Server - Complete control of Home Assistant through MCP"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13,<3.14"
@@ -298,15 +298,55 @@ def create_connection_error(
298
298
  return create_error_response(code, message, details, context=context)
299
299
 
300
300
 
301
+ # Authentication-error suggestions for Home Assistant add-on installs. On the
302
+ # add-on the token is managed by the Supervisor, not a user-editable
303
+ # HOMEASSISTANT_TOKEN, so the default "verify your token / create a long-lived
304
+ # token" guidance is a dead end. We deliberately do NOT assert a cause — issue
305
+ # #1694's underlying cause was never reproduced or confirmed — so this points at
306
+ # practical first steps and at where an auth problem actually surfaces
307
+ # (home-assistant.log), without claiming to know why it happened.
308
+ _ADDON_AUTH_INVALID_SUGGESTIONS: list[str] = [
309
+ "On a Home Assistant add-on install the access token is managed by the "
310
+ + "Supervisor, not a HOMEASSISTANT_TOKEN you can change",
311
+ "A Home Assistant Core restart (Settings -> System -> Restart) often "
312
+ + "clears transient WebSocket authentication failures — try that first",
313
+ "Check home-assistant.log for 'invalid authentication' or "
314
+ + "'InsecureKeyLengthWarning' around the time of the failure; if those "
315
+ + "appear, the problem is likely in Home Assistant's auth handling rather "
316
+ + "than ha-mcp's request — capture those lines when reporting",
317
+ ]
318
+
319
+
301
320
  def create_auth_error(
302
321
  message: str,
303
322
  details: str | None = None,
304
323
  expired: bool = False,
305
324
  context: dict[str, Any] | None = None,
306
325
  ) -> dict[str, Any]:
307
- """Create an authentication error response."""
326
+ """Create an authentication error response.
327
+
328
+ On a Home Assistant add-on install (Supervisor-managed) the token is the
329
+ Supervisor token rather than a user-editable HOMEASSISTANT_TOKEN, so the
330
+ default token-centric suggestions don't apply. Substitute add-on-specific
331
+ guidance for an invalid token in that case (see issue #1694). Expired-token
332
+ errors keep the default guidance — token expiry is not the Supervisor-token
333
+ failure mode this swap targets.
334
+ """
308
335
  code = ErrorCode.AUTH_EXPIRED if expired else ErrorCode.AUTH_INVALID_TOKEN
309
- return create_error_response(code, message, details, context=context)
336
+
337
+ suggestions: list[str] | None = None
338
+ if code is ErrorCode.AUTH_INVALID_TOKEN:
339
+ # Lazy import keeps this low-level module free of an import-time
340
+ # dependency on ._version; is_running_in_addon reads SUPERVISOR_TOKEN
341
+ # live so it reflects the current environment.
342
+ from ._version import is_running_in_addon
343
+
344
+ if is_running_in_addon():
345
+ suggestions = _ADDON_AUTH_INVALID_SUGGESTIONS
346
+
347
+ return create_error_response(
348
+ code, message, details, suggestions=suggestions, context=context
349
+ )
310
350
 
311
351
 
312
352
  def create_entity_not_found_error(
@@ -47,6 +47,12 @@ AGENT_BEHAVIOR_URL = (
47
47
  # while still capturing enough recent output to diagnose most issues.
48
48
  _ADDON_LOG_MAX_CHARS = 3000
49
49
 
50
+ # Max characters to include from the Home Assistant error log (home-assistant.log).
51
+ # Slightly larger than the addon cap: this log carries the highest-value
52
+ # diagnostic lines (auth failures, integration tracebacks) and the recent tail
53
+ # is where they land. ~5000 chars ≈ 1250 LLM tokens.
54
+ _CORE_LOG_MAX_CHARS = 5000
55
+
50
56
  # IPv4 sanitization: only redact addresses with strong network context so that
51
57
  # four-segment version strings (e.g. "ha-mcp version 1.2.3.4") are preserved.
52
58
  _IPV4_OCTET = r"(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)"
@@ -408,6 +414,49 @@ async def _fetch_addon_logs() -> str:
408
414
  return ""
409
415
 
410
416
 
417
+ async def _fetch_core_error_log(client: Any) -> str:
418
+ """Fetch the Home Assistant error log (home-assistant.log) via the client.
419
+
420
+ Works on every install type — ``HomeAssistantClient.get_error_log`` routes
421
+ add-on installs to the Supervisor, supervised/HAOS to the hassio proxy, and
422
+ container/pip to ``/api/error_log``. Captured over REST, which stays up even
423
+ when the WebSocket path is failing; that is exactly the failure mode in
424
+ issue #1694, where the high-value auth lines
425
+ (``InsecureKeyLengthWarning``, "invalid authentication") only appeared in
426
+ home-assistant.log, not in the add-on log this tool already captured.
427
+
428
+ Best-effort: returns sanitized text (last ``_CORE_LOG_MAX_CHARS`` chars,
429
+ with a truncation marker prepended) or an empty string on any failure, so a
430
+ log-fetch problem never breaks the bug-report path.
431
+ """
432
+ try:
433
+ raw = await client.get_error_log()
434
+ except Exception as e:
435
+ # Broad by design — the bug-report path must stay robust whatever the
436
+ # client raises (auth, role, connection, transport). Logged at INFO so
437
+ # a missing error log is visible without alarming on a routine 403.
438
+ logger.info(
439
+ "Could not fetch HA error log for bug report: %s (%s)",
440
+ e,
441
+ type(e).__name__,
442
+ )
443
+ return ""
444
+
445
+ if not raw:
446
+ return ""
447
+
448
+ # Strip ANSI, then sanitize, then truncate — sanitizing before truncating
449
+ # keeps a secret straddling the cut boundary from leaking through.
450
+ sanitized = _sanitize_log_text(ANSI_ESCAPE_RE.sub("", raw))
451
+ if len(sanitized) > _CORE_LOG_MAX_CHARS:
452
+ marker = (
453
+ f"[...truncated, showing last {_CORE_LOG_MAX_CHARS} of "
454
+ f"{len(sanitized)} chars...]\n"
455
+ )
456
+ return marker + sanitized[-_CORE_LOG_MAX_CHARS:]
457
+ return sanitized
458
+
459
+
411
460
  def _build_formatted_report(
412
461
  diagnostic_info: dict[str, Any],
413
462
  mcp_transport: str,
@@ -419,6 +468,7 @@ def _build_formatted_report(
419
468
  recent_logs: list[dict[str, Any]],
420
469
  log_summary: str,
421
470
  addon_logs: str,
471
+ core_error_log: str,
422
472
  ) -> str:
423
473
  report_lines = [
424
474
  "=== ha-mcp Bug Report Info ===",
@@ -459,6 +509,8 @@ def _build_formatted_report(
459
509
  )
460
510
  if addon_logs:
461
511
  report_lines.extend(["", "=== Add-on Container Logs ===", addon_logs])
512
+ if core_error_log:
513
+ report_lines.extend(["", "=== Home Assistant Error Log ===", core_error_log])
462
514
  return "\n".join(report_lines)
463
515
 
464
516
 
@@ -530,6 +582,8 @@ class BugReportTools:
530
582
  - `recent_logs`, `startup_logs` — captured ha-mcp tool/server log entries
531
583
  - `addon_logs` — addon container stdout/stderr (HA add-on installs only;
532
584
  empty string otherwise)
585
+ - `core_error_log` — Home Assistant error log (home-assistant.log) over
586
+ REST; carries auth / integration errors that don't show in addon_logs
533
587
  - `suggested_title`, `duplicate_check_urls`, `anonymization_guide`
534
588
  """
535
589
  # Detect installation method, platform, and runtime config.
@@ -583,6 +637,12 @@ class BugReportTools:
583
637
  if install_method == "addon":
584
638
  addon_logs = await _fetch_addon_logs()
585
639
 
640
+ # Fetch the Home Assistant error log (home-assistant.log) on every
641
+ # install type. It's pulled over REST — which stays up even when the
642
+ # WebSocket path is failing — so the report captures auth / integration
643
+ # errors (issue #1694) that never appear in the add-on log above.
644
+ core_error_log = await _fetch_core_error_log(self._client)
645
+
586
646
  # Format logs for inclusion (sanitized summary)
587
647
  log_summary = _format_logs_for_report(recent_logs)
588
648
  startup_log_summary = _format_startup_logs(startup_logs)
@@ -599,6 +659,7 @@ class BugReportTools:
599
659
  recent_logs,
600
660
  log_summary,
601
661
  addon_logs,
662
+ core_error_log,
602
663
  )
603
664
 
604
665
  # Generate suggested title up-front so it can be folded into the
@@ -618,6 +679,7 @@ class BugReportTools:
618
679
  recent_logs,
619
680
  startup_logs,
620
681
  addon_logs=addon_logs,
682
+ core_error_log=core_error_log,
621
683
  submit_url=runtime_bug_submit_url,
622
684
  )
623
685
 
@@ -655,6 +717,8 @@ class BugReportTools:
655
717
  for entry in startup_logs
656
718
  ],
657
719
  "addon_logs": addon_logs,
720
+ # Already sanitized + truncated by _fetch_core_error_log.
721
+ "core_error_log": core_error_log,
658
722
  "log_count": len(recent_logs),
659
723
  "startup_log_count": len(startup_logs),
660
724
  "formatted_report": formatted_report,
@@ -714,6 +778,7 @@ class BugReportTools:
714
778
  " - Agent behavior: see agent_behavior_submit_url\n"
715
779
  " d. Ask them to fill in the description sections\n"
716
780
  " e. For HA add-on installs, the runtime bug template includes a collapsible '📦 Add-on Container Logs' section auto-filled from addon_logs — keep it as-is\n"
781
+ " e2. When present, the template also includes a collapsible 'Home Assistant Error Log' section auto-filled from core_error_log (auth / integration errors) — keep it as-is\n"
717
782
  " f. Remind them to review for any remaining personal information before submitting\n\n"
718
783
  "CRITICAL: Always ANONYMIZE the report BEFORE presenting it in markdown code blocks!"
719
784
  ),
@@ -894,6 +959,7 @@ def _generate_runtime_bug_template(
894
959
  startup_logs: list[dict[str, Any]],
895
960
  *,
896
961
  addon_logs: str = "",
962
+ core_error_log: str = "",
897
963
  submit_url: str = RUNTIME_BUG_URL,
898
964
  ) -> str:
899
965
  """
@@ -950,6 +1016,26 @@ def _generate_runtime_bug_template(
950
1016
  {addon_logs}
951
1017
  ```
952
1018
 
1019
+ </details>
1020
+ """
1021
+
1022
+ # Show the Home Assistant error log section when available (all install
1023
+ # types). This carries the auth / integration errors that diagnose issues
1024
+ # like #1694 and don't appear in the add-on container log above.
1025
+ core_log_section = ""
1026
+ if core_error_log:
1027
+ core_log_section = f"""
1028
+ ---
1029
+
1030
+ ## Home Assistant Error Log
1031
+
1032
+ <details>
1033
+ <summary>Click to expand home-assistant.log (auth / integration errors)</summary>
1034
+
1035
+ ```
1036
+ {core_error_log}
1037
+ ```
1038
+
953
1039
  </details>
954
1040
  """
955
1041
 
@@ -1048,7 +1134,7 @@ server:
1048
1134
  ```
1049
1135
 
1050
1136
  </details>
1051
- {startup_section}{addon_section}
1137
+ {startup_section}{addon_section}{core_log_section}
1052
1138
  ---
1053
1139
 
1054
1140
  ## 💡 Additional Context
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ha-mcp-dev
3
- Version: 7.9.0.dev742
3
+ Version: 7.9.0.dev743
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