ha-mcp-dev 7.9.0.dev766__tar.gz → 7.9.0.dev768__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 (159) hide show
  1. {ha_mcp_dev-7.9.0.dev766/src/ha_mcp_dev.egg-info → ha_mcp_dev-7.9.0.dev768}/PKG-INFO +1 -1
  2. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/pyproject.toml +1 -1
  3. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/__main__.py +17 -2
  4. ha_mcp_dev-7.9.0.dev768/src/ha_mcp/transport_security.py +90 -0
  5. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768/src/ha_mcp_dev.egg-info}/PKG-INFO +1 -1
  6. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp_dev.egg-info/SOURCES.txt +1 -0
  7. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/LICENSE +0 -0
  8. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/MANIFEST.in +0 -0
  9. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/README.md +0 -0
  10. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/setup.cfg +0 -0
  11. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/__init__.py +0 -0
  12. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/_pypi_marker +0 -0
  13. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/_version.py +0 -0
  14. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/auth/__init__.py +0 -0
  15. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/auth/consent_form.py +0 -0
  16. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/auth/provider.py +0 -0
  17. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/backup_manager.py +0 -0
  18. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/client/__init__.py +0 -0
  19. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/client/rest_client.py +0 -0
  20. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/client/supervisor_client.py +0 -0
  21. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/client/websocket_client.py +0 -0
  22. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/client/websocket_listener.py +0 -0
  23. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/config.py +0 -0
  24. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/dashboard_screenshot/__init__.py +0 -0
  25. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/dashboard_screenshot/capture.py +0 -0
  26. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/dashboard_screenshot/provision.py +0 -0
  27. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/errors.py +0 -0
  28. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/policy/__init__.py +0 -0
  29. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/policy/approval_queue.py +0 -0
  30. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/policy/evaluator.py +0 -0
  31. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/policy/handlers.py +0 -0
  32. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/policy/middleware.py +0 -0
  33. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/policy/model.py +0 -0
  34. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/policy/persistence.py +0 -0
  35. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/policy/value_sources.py +0 -0
  36. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/py.typed +0 -0
  37. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/read_only.py +0 -0
  38. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
  39. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
  40. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
  41. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
  42. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/.github/pull_request_template.md +0 -0
  43. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
  44. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
  45. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
  46. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
  47. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
  48. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
  49. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/evals/evals.json +0 -0
  50. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/appdaemon.md +0 -0
  51. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
  52. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +0 -0
  53. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +0 -0
  54. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
  55. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +0 -0
  56. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
  57. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
  58. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
  59. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/scenes.md +0 -0
  60. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
  61. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/yaml-only-integrations.md +0 -0
  62. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/server.py +0 -0
  63. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/settings_ui/__init__.py +0 -0
  64. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/settings_ui/settings.css +0 -0
  65. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/settings_ui/settings.html +0 -0
  66. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/settings_ui/settings.js +0 -0
  67. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/smoke_test.py +0 -0
  68. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/stdio_settings_sidecar.py +0 -0
  69. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/__init__.py +0 -0
  70. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/auto_backup.py +0 -0
  71. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/backup.py +0 -0
  72. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/best_practice_checker.py +0 -0
  73. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/config_entry_flow.py +0 -0
  74. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/device_control.py +0 -0
  75. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/enhanced.py +0 -0
  76. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/helpers.py +0 -0
  77. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/radio/__init__.py +0 -0
  78. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/radio/base.py +0 -0
  79. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/radio/matter.py +0 -0
  80. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/radio/thread.py +0 -0
  81. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/radio/zigbee.py +0 -0
  82. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/radio/zwave.py +0 -0
  83. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/reference_validator.py +0 -0
  84. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/registry.py +0 -0
  85. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/smart_search/__init__.py +0 -0
  86. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/smart_search/_base.py +0 -0
  87. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/smart_search/_config.py +0 -0
  88. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/smart_search/_deep.py +0 -0
  89. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/smart_search/_entities.py +0 -0
  90. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/smart_search/_fetch.py +0 -0
  91. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/smart_search/_overview.py +0 -0
  92. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/smart_search/_scenes.py +0 -0
  93. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/smart_search/_scoring.py +0 -0
  94. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tool_search_hint_middleware.py +0 -0
  95. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_addons.py +0 -0
  96. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_areas.py +0 -0
  97. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_blueprints.py +0 -0
  98. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_bug_report.py +0 -0
  99. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_calendar.py +0 -0
  100. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_camera.py +0 -0
  101. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_categories.py +0 -0
  102. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_code.py +0 -0
  103. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_config_automations.py +0 -0
  104. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
  105. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
  106. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_config_scenes.py +0 -0
  107. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
  108. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_dashboard_screenshot.py +0 -0
  109. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_energy.py +0 -0
  110. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_entities.py +0 -0
  111. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_filesystem.py +0 -0
  112. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_groups.py +0 -0
  113. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_hacs.py +0 -0
  114. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_history.py +0 -0
  115. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_integrations.py +0 -0
  116. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_labels.py +0 -0
  117. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_mcp_component.py +0 -0
  118. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_radio.py +0 -0
  119. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_registry.py +0 -0
  120. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_resources.py +0 -0
  121. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_search.py +0 -0
  122. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_service.py +0 -0
  123. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_services.py +0 -0
  124. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_system.py +0 -0
  125. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_themes.py +0 -0
  126. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_todo.py +0 -0
  127. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_traces.py +0 -0
  128. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_updates.py +0 -0
  129. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_utility.py +0 -0
  130. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
  131. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
  132. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/tools_zones.py +0 -0
  133. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/util_helpers.py +0 -0
  134. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/tools/validation_middleware.py +0 -0
  135. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/transforms/__init__.py +0 -0
  136. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/transforms/categorized_search.py +0 -0
  137. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/transforms/lite_docstrings.py +0 -0
  138. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/update_check.py +0 -0
  139. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/utils/__init__.py +0 -0
  140. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/utils/config_hash.py +0 -0
  141. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/utils/data_paths.py +0 -0
  142. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/utils/domain_handlers.py +0 -0
  143. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/utils/fuzzy_search.py +0 -0
  144. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
  145. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/utils/operation_manager.py +0 -0
  146. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/utils/python_sandbox.py +0 -0
  147. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/utils/skill_loader.py +0 -0
  148. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/utils/usage_logger.py +0 -0
  149. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/visibility/__init__.py +0 -0
  150. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/visibility/model.py +0 -0
  151. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/visibility/persistence.py +0 -0
  152. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp/visibility/resolver.py +0 -0
  153. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
  154. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
  155. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
  156. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
  157. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/tests/__init__.py +0 -0
  158. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/tests/test_constants.py +0 -0
  159. {ha_mcp_dev-7.9.0.dev766 → ha_mcp_dev-7.9.0.dev768}/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.dev766
3
+ Version: 7.9.0.dev768
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.dev766"
7
+ version = "7.9.0.dev768"
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
@@ -318,6 +318,15 @@ def _create_server() -> "HomeAssistantSmartMCPServer":
318
318
  """Create server instance (deferred to avoid import during smoke test)."""
319
319
  from pydantic import ValidationError
320
320
 
321
+ # Every deferred-``mcp`` entry point funnels through here before its
322
+ # Streamable-HTTP app is built -- ha-mcp-web, the add-on, and the
323
+ # ``fastmcp run fastmcp-http.json`` container path -- so default fastmcp's
324
+ # DNS-rebinding guard off once, here, for all of them. Direct-construction
325
+ # paths (_run_oauth_server, the in-process component server) call it themselves.
326
+ from ha_mcp.transport_security import ensure_host_origin_guard_default_off
327
+
328
+ ensure_host_origin_guard_default_off()
329
+
321
330
  try:
322
331
  from ha_mcp.server import HomeAssistantSmartMCPServer
323
332
 
@@ -823,8 +832,6 @@ def _maybe_spawn_settings_sidecar() -> None:
823
832
 
824
833
  def main_dev() -> None:
825
834
  """Run server with DEBUG logging enabled (for ha-mcp-dev package)."""
826
- import os
827
-
828
835
  os.environ["LOG_LEVEL"] = "DEBUG"
829
836
  main()
830
837
 
@@ -1094,6 +1101,8 @@ def _run_http_server(transport: str, default_port: int = 8086) -> None:
1094
1101
  """
1095
1102
  from ha_mcp.settings_ui import register_settings_routes
1096
1103
 
1104
+ # The DNS-rebinding guard is defaulted off in _create_server (reached here via
1105
+ # _get_mcp below, before the app is built) -- see transport_security.
1097
1106
  host, port, path = _get_http_runtime(default_port)
1098
1107
  _warn_if_default_path_exposed(host, port, path)
1099
1108
  # SSE transport answers GET with 200 (the event stream), so a GET->405 there
@@ -1224,6 +1233,12 @@ async def _run_oauth_server(
1224
1233
  """
1225
1234
  from ha_mcp.auth import HomeAssistantOAuthProvider
1226
1235
  from ha_mcp.server import HomeAssistantSmartMCPServer
1236
+ from ha_mcp.transport_security import ensure_host_origin_guard_default_off
1237
+
1238
+ # Browser OAuth clients (Claude.ai / ChatGPT) reach the discovery endpoints
1239
+ # cross-origin, and users front this server with proxies/tunnels on arbitrary
1240
+ # hosts; default fastmcp's DNS-rebinding guard off so it does not 403/421 them.
1241
+ ensure_host_origin_guard_default_off()
1227
1242
 
1228
1243
  # Create OAuth provider
1229
1244
  auth_provider = HomeAssistantOAuthProvider(
@@ -0,0 +1,90 @@
1
+ """Transport-security defaults for ha-mcp's Streamable-HTTP servers.
2
+
3
+ fastmcp >= 3.4.3 ships ``HostOriginGuardMiddleware`` (a DNS-rebinding guard) that
4
+ is **on by default**. Inserted at the front of the Streamable-HTTP ASGI stack, it
5
+ rejects any request whose ``Host`` header is not loopback / an explicitly-allowed
6
+ host with ``421 Misdirected Request``, and any browser ``Origin`` that is not
7
+ same-origin / loopback / explicitly allowed with ``403 Forbidden`` -- before the
8
+ request reaches any route.
9
+
10
+ That default is wrong for ha-mcp. We are *designed* to be reached through
11
+ operator-chosen reverse proxies and tunnels (Cloudflare Tunnel, nginx, Traefik,
12
+ Nabu Casa Remote UI) and via direct LAN IPs, whose ``Host`` values we cannot
13
+ enumerate. Leaving the guard on would ``421`` the majority of real deployments --
14
+ including the plain browser landing page, which is a no-``Origin`` navigation
15
+ that still trips the ``Host`` check.
16
+
17
+ Our security boundary is the high-entropy secret path (and, in OAuth mode, the
18
+ per-user token), not the ``Host`` header. The loopback settings sidecar enforces
19
+ its *own* Host/Origin allow-list (see ``stdio_settings_sidecar``), independent of
20
+ this setting. So defaulting fastmcp's guard off on the main server restores
21
+ exactly the pre-3.4.3 behaviour without giving up the protection that matters.
22
+
23
+ Operators who front ha-mcp differently can re-enable the guard (and pin their
24
+ own allow-lists) via ``FASTMCP_HTTP_HOST_ORIGIN_PROTECTION=true`` plus
25
+ ``FASTMCP_HTTP_ALLOWED_HOSTS`` / ``FASTMCP_HTTP_ALLOWED_ORIGINS``.
26
+ """
27
+
28
+ from __future__ import annotations
29
+
30
+ import logging
31
+ import os
32
+
33
+ logger = logging.getLogger(__name__)
34
+
35
+ #: fastmcp's env var for the Host/Origin (DNS-rebinding) guard. Present as a
36
+ #: field on fastmcp's Settings only from 3.4.3 onward.
37
+ HOST_ORIGIN_PROTECTION_ENV = "FASTMCP_HTTP_HOST_ORIGIN_PROTECTION"
38
+
39
+ #: fastmcp Settings attribute backing the env var above.
40
+ _HOST_ORIGIN_PROTECTION_ATTR = "http_host_origin_protection"
41
+
42
+
43
+ def ensure_host_origin_guard_default_off() -> None:
44
+ """Default fastmcp's Host/Origin guard off for ha-mcp's Streamable-HTTP servers.
45
+
46
+ Idempotent and safe to call from every server-creation path. Call before the
47
+ Streamable-HTTP app is built (``mcp.http_app()`` / ``mcp.run(transport="http")``
48
+ / ``mcp.run_async(...)``): ``http_app`` reads
49
+ ``fastmcp.settings.http_host_origin_protection`` at build time, so mutating
50
+ that singleton beforehand deterministically neutralises the guard.
51
+
52
+ Does nothing when the running fastmcp predates the guard (the setting field is
53
+ absent, i.e. < 3.4.3) or when the operator set the env var explicitly (their
54
+ choice wins). A failed mutation is logged at WARNING and left retryable -- it
55
+ is not recorded as done -- so a later reload re-attempts it.
56
+ """
57
+ try:
58
+ import fastmcp
59
+ except Exception: # pragma: no cover - fastmcp is a hard dependency
60
+ return
61
+
62
+ settings = getattr(fastmcp, "settings", None)
63
+ if settings is None or not hasattr(settings, _HOST_ORIGIN_PROTECTION_ATTR):
64
+ # fastmcp < 3.4.3: no guard exists, nothing to disable.
65
+ return
66
+
67
+ if getattr(settings, _HOST_ORIGIN_PROTECTION_ATTR) is False:
68
+ # Already off -- a prior call, or the operator's own default. Idempotent.
69
+ return
70
+
71
+ if HOST_ORIGIN_PROTECTION_ENV in os.environ:
72
+ # Operator explicitly opted in (guard on); honour their choice.
73
+ return
74
+
75
+ try:
76
+ setattr(settings, _HOST_ORIGIN_PROTECTION_ATTR, False)
77
+ except Exception:
78
+ logger.warning(
79
+ "Could not disable fastmcp's Host/Origin (DNS-rebinding) guard; MCP "
80
+ "reached through a reverse proxy, tunnel, or LAN IP -- and the browser "
81
+ "landing page -- may fail with 421/403. Set %s=false, or pin "
82
+ "FASTMCP_HTTP_ALLOWED_HOSTS / FASTMCP_HTTP_ALLOWED_ORIGINS.",
83
+ HOST_ORIGIN_PROTECTION_ENV,
84
+ exc_info=True,
85
+ )
86
+ return
87
+
88
+ # Belt: honoured by any fresh ``Settings()`` read and by child processes. Set
89
+ # only after a confirmed mutation so a failed attempt stays retryable.
90
+ os.environ.setdefault(HOST_ORIGIN_PROTECTION_ENV, "false")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ha-mcp-dev
3
- Version: 7.9.0.dev766
3
+ Version: 7.9.0.dev768
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
@@ -14,6 +14,7 @@ src/ha_mcp/read_only.py
14
14
  src/ha_mcp/server.py
15
15
  src/ha_mcp/smoke_test.py
16
16
  src/ha_mcp/stdio_settings_sidecar.py
17
+ src/ha_mcp/transport_security.py
17
18
  src/ha_mcp/update_check.py
18
19
  src/ha_mcp/auth/__init__.py
19
20
  src/ha_mcp/auth/consent_form.py