ha-mcp-dev 7.6.0.dev642__tar.gz → 7.6.0.dev643__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 (136) hide show
  1. {ha_mcp_dev-7.6.0.dev642/src/ha_mcp_dev.egg-info → ha_mcp_dev-7.6.0.dev643}/PKG-INFO +1 -1
  2. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/pyproject.toml +1 -1
  3. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/__main__.py +23 -0
  4. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/settings_ui.py +23 -0
  5. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_search.py +29 -4
  6. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643/src/ha_mcp_dev.egg-info}/PKG-INFO +1 -1
  7. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/LICENSE +0 -0
  8. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/MANIFEST.in +0 -0
  9. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/README.md +0 -0
  10. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/setup.cfg +0 -0
  11. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/__init__.py +0 -0
  12. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/_pypi_marker +0 -0
  13. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/_version.py +0 -0
  14. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/auth/__init__.py +0 -0
  15. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/auth/consent_form.py +0 -0
  16. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/auth/provider.py +0 -0
  17. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/backup_manager.py +0 -0
  18. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/client/__init__.py +0 -0
  19. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/client/rest_client.py +0 -0
  20. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/client/supervisor_client.py +0 -0
  21. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/client/websocket_client.py +0 -0
  22. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/client/websocket_listener.py +0 -0
  23. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/config.py +0 -0
  24. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/errors.py +0 -0
  25. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/policy/__init__.py +0 -0
  26. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/policy/approval_queue.py +0 -0
  27. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/policy/evaluator.py +0 -0
  28. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/policy/handlers.py +0 -0
  29. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/policy/middleware.py +0 -0
  30. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/policy/model.py +0 -0
  31. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/policy/persistence.py +0 -0
  32. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/policy/value_sources.py +0 -0
  33. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/py.typed +0 -0
  34. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
  35. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
  36. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
  37. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
  38. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/resources/skills-vendor/.github/pull_request_template.md +0 -0
  39. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
  40. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
  41. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
  42. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
  43. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
  44. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
  45. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/evals/evals.json +0 -0
  46. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
  47. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +0 -0
  48. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +0 -0
  49. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
  50. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +0 -0
  51. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
  52. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
  53. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
  54. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
  55. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/yaml-only-integrations.md +0 -0
  56. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/server.py +0 -0
  57. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/settings.css +0 -0
  58. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/settings.js +0 -0
  59. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/smoke_test.py +0 -0
  60. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/stdio_settings_sidecar.py +0 -0
  61. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/__init__.py +0 -0
  62. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/auto_backup.py +0 -0
  63. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/backup.py +0 -0
  64. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/best_practice_checker.py +0 -0
  65. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/device_control.py +0 -0
  66. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/enhanced.py +0 -0
  67. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/helpers.py +0 -0
  68. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/reference_validator.py +0 -0
  69. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/registry.py +0 -0
  70. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/smart_search/__init__.py +0 -0
  71. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/smart_search/_base.py +0 -0
  72. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/smart_search/_config.py +0 -0
  73. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/smart_search/_deep.py +0 -0
  74. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/smart_search/_entities.py +0 -0
  75. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/smart_search/_fetch.py +0 -0
  76. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/smart_search/_overview.py +0 -0
  77. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/smart_search/_scenes.py +0 -0
  78. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/smart_search/_scoring.py +0 -0
  79. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_addons.py +0 -0
  80. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_areas.py +0 -0
  81. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_blueprints.py +0 -0
  82. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_bug_report.py +0 -0
  83. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_calendar.py +0 -0
  84. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_camera.py +0 -0
  85. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_categories.py +0 -0
  86. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_code.py +0 -0
  87. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_config_automations.py +0 -0
  88. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
  89. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_config_entry_flow.py +0 -0
  90. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
  91. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_config_scenes.py +0 -0
  92. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
  93. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_energy.py +0 -0
  94. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_entities.py +0 -0
  95. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_filesystem.py +0 -0
  96. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_groups.py +0 -0
  97. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_hacs.py +0 -0
  98. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_history.py +0 -0
  99. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_integrations.py +0 -0
  100. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_labels.py +0 -0
  101. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_mcp_component.py +0 -0
  102. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_registry.py +0 -0
  103. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_resources.py +0 -0
  104. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_service.py +0 -0
  105. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_services.py +0 -0
  106. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_system.py +0 -0
  107. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_todo.py +0 -0
  108. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_traces.py +0 -0
  109. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_updates.py +0 -0
  110. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_utility.py +0 -0
  111. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
  112. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
  113. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/tools_zones.py +0 -0
  114. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/util_helpers.py +0 -0
  115. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/tools/validation_middleware.py +0 -0
  116. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/transforms/__init__.py +0 -0
  117. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/transforms/categorized_search.py +0 -0
  118. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/transforms/lite_docstrings.py +0 -0
  119. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/utils/__init__.py +0 -0
  120. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/utils/config_hash.py +0 -0
  121. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/utils/data_paths.py +0 -0
  122. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/utils/domain_handlers.py +0 -0
  123. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/utils/fuzzy_search.py +0 -0
  124. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
  125. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/utils/operation_manager.py +0 -0
  126. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/utils/python_sandbox.py +0 -0
  127. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/utils/skill_loader.py +0 -0
  128. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp/utils/usage_logger.py +0 -0
  129. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp_dev.egg-info/SOURCES.txt +0 -0
  130. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
  131. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
  132. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
  133. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
  134. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/tests/__init__.py +0 -0
  135. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/tests/test_constants.py +0 -0
  136. {ha_mcp_dev-7.6.0.dev642 → ha_mcp_dev-7.6.0.dev643}/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.6.0.dev642
3
+ Version: 7.6.0.dev643
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.6.0.dev642"
7
+ version = "7.6.0.dev643"
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"
@@ -825,6 +825,27 @@ def register_browser_landing(mcp_instance: "FastMCP | _DeferredMCP", path: str)
825
825
  )
826
826
 
827
827
 
828
+ def _log_settings_url(host: str, port: int, path: str) -> None:
829
+ """Log the web settings-UI URL at HTTP startup.
830
+
831
+ Non-add-on operators (Docker / standalone) otherwise have no easy way to
832
+ discover the settings page or its secret-path URL (issue #1458). When the
833
+ bind host is the wildcard (``0.0.0.0`` / ``::``) the process can't know its
834
+ externally reachable address, so we log a ``<host>`` placeholder.
835
+ """
836
+ is_wildcard = host in ("0.0.0.0", "::")
837
+ if is_wildcard:
838
+ display_host = "<host>"
839
+ elif ":" in host:
840
+ # IPv6 literal (e.g. ::1, 2001:db8::1) needs brackets in a URL.
841
+ display_host = f"[{host}]"
842
+ else:
843
+ display_host = host
844
+ url = f"http://{display_host}:{port}{path.rstrip('/')}/settings"
845
+ note = " (substitute this server's address for <host>)" if is_wildcard else ""
846
+ logger.info(f"Settings UI available at: {url}{note}")
847
+
848
+
828
849
  def _run_http_server(transport: str, default_port: int = 8086) -> None:
829
850
  """Common runner for HTTP-based transports.
830
851
 
@@ -837,6 +858,7 @@ def _run_http_server(transport: str, default_port: int = 8086) -> None:
837
858
  host, port, path = _get_http_runtime(default_port)
838
859
  register_browser_landing(_get_mcp(), path)
839
860
  register_settings_routes(_get_mcp(), _get_server(), secret_path=path)
861
+ _log_settings_url(host, port, path)
840
862
 
841
863
  _run_entrypoint(
842
864
  _run_http_with_graceful_shutdown(transport, host, port, path),
@@ -984,6 +1006,7 @@ async def _run_oauth_server(
984
1006
  from ha_mcp.settings_ui import register_settings_routes
985
1007
 
986
1008
  register_settings_routes(mcp, _server, secret_path=path)
1009
+ _log_settings_url(host, port, path)
987
1010
 
988
1011
  tools = await mcp.list_tools()
989
1012
  logger.info(
@@ -3017,6 +3017,25 @@ def _ingress_only(handler: _SettingsRoute) -> _SettingsRoute:
3017
3017
  return _guarded
3018
3018
 
3019
3019
 
3020
+ # Mount prefix the settings UI is served under in long-lived HTTP transports
3021
+ # (Docker / standalone ha-mcp-web / OAuth / the add-on's secret-path mount).
3022
+ # Recorded by register_settings_routes so ha_get_overview can point users at
3023
+ # the settings page in modes that have no stdio sidecar URL file to surface
3024
+ # (issue #1458). Stays None in pure stdio mode, where the sidecar writes
3025
+ # ~/.ha-mcp/ui.url instead.
3026
+ _http_settings_prefix: str | None = None
3027
+
3028
+
3029
+ def get_http_settings_prefix() -> str | None:
3030
+ """Return the settings-UI mount prefix for HTTP transports, or None.
3031
+
3032
+ Set by :func:`register_settings_routes` when the page is mounted on a
3033
+ long-lived HTTP server. ``ha_get_overview`` reads it to hint at the
3034
+ settings page when there is no stdio sidecar URL to hand the user.
3035
+ """
3036
+ return _http_settings_prefix
3037
+
3038
+
3020
3039
  def register_settings_routes(
3021
3040
  mcp: FastMCP,
3022
3041
  server: HomeAssistantSmartMCPServer,
@@ -3117,3 +3136,7 @@ def register_settings_routes(
3117
3136
  # need the same secret to reach the UI as they do for the MCP
3118
3137
  # endpoint.
3119
3138
  _mount(secret_prefix)
3139
+ # Record the mount so ha_get_overview can point users at the settings
3140
+ # page in HTTP transports that have no stdio sidecar URL file (#1458).
3141
+ global _http_settings_prefix
3142
+ _http_settings_prefix = secret_prefix
@@ -1136,10 +1136,11 @@ def register_search_tools(mcp: Any, client: Any, **kwargs: Any) -> None:
1136
1136
  "device_types, service_availability, system_info, "
1137
1137
  "notification_count, notifications, repair_count, "
1138
1138
  "dismissed_repair_count, repairs, repairs_error, "
1139
- "tool_discovery, settings_url. Note: ``settings_url`` "
1140
- "(stdio mode only, see tool description) is emitted "
1141
- "regardless of ``fields=`` projection it is always "
1142
- "included when the settings-UI sidecar is running."
1139
+ "tool_discovery, settings_url, settings_url_hint. Note: "
1140
+ "``settings_url`` (stdio mode) and ``settings_url_hint`` "
1141
+ "(HTTP/Docker/OAuth mode) are emitted regardless of "
1142
+ "``fields=`` projection so the settings page stays "
1143
+ "discoverable; see the tool description."
1143
1144
  ),
1144
1145
  ),
1145
1146
  ] = None,
@@ -1167,6 +1168,12 @@ def register_search_tools(mcp: Any, client: Any, **kwargs: Any) -> None:
1167
1168
  projection (so it stays discoverable even when callers
1168
1169
  minimize the response) but only when the sidecar URL file
1169
1170
  actually exists.
1171
+
1172
+ In HTTP / Docker / OAuth modes there is no sidecar URL file and the
1173
+ server can't know its externally reachable host, so the response
1174
+ instead carries a ``settings_url_hint`` string telling the user where
1175
+ the page is mounted and to read the full URL from the startup logs.
1176
+ Hand whichever of the two fields is present to the user.
1170
1177
  """
1171
1178
  # Validate fields= early so a malformed value returns VALIDATION_FAILED
1172
1179
  # with parameter="fields" (ha_get_overview has no outer try/except, so
@@ -1368,6 +1375,24 @@ def register_search_tools(mcp: Any, client: Any, **kwargs: Any) -> None:
1368
1375
  sidecar_url = read_sidecar_url()
1369
1376
  if sidecar_url:
1370
1377
  projected["settings_url"] = sidecar_url
1378
+ else:
1379
+ # No stdio sidecar URL file. In HTTP / Docker / OAuth modes the
1380
+ # settings page is mounted on this server, but the process binds
1381
+ # 0.0.0.0 and can't know its externally reachable host — so hint
1382
+ # at the page (and the startup-log URL) instead of guessing a
1383
+ # wrong absolute URL (issue #1458).
1384
+ from ..settings_ui import get_http_settings_prefix
1385
+
1386
+ http_prefix = get_http_settings_prefix()
1387
+ if http_prefix:
1388
+ settings_path = f"{http_prefix.rstrip('/')}/settings"
1389
+ projected["settings_url_hint"] = (
1390
+ "The settings page (enable/disable/pin tools, feature "
1391
+ "flags, advanced settings, backups, tool-approval) is "
1392
+ f"served at '{settings_path}' on this MCP server. Find the "
1393
+ "full URL in the ha-mcp startup logs, or append it to the "
1394
+ "base URL your client connects to."
1395
+ )
1371
1396
 
1372
1397
  return projected
1373
1398
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ha-mcp-dev
3
- Version: 7.6.0.dev642
3
+ Version: 7.6.0.dev643
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