ha-mcp-dev 7.13.0.dev1975__tar.gz → 7.13.0.dev1977__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 (185) hide show
  1. {ha_mcp_dev-7.13.0.dev1975/src/ha_mcp_dev.egg-info → ha_mcp_dev-7.13.0.dev1977}/PKG-INFO +2 -1
  2. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/README.md +1 -0
  3. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/pyproject.toml +2 -1
  4. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/__main__.py +220 -0
  5. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977/src/ha_mcp_dev.egg-info}/PKG-INFO +2 -1
  6. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp_dev.egg-info/entry_points.txt +1 -0
  7. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/LICENSE +0 -0
  8. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/MANIFEST.in +0 -0
  9. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/setup.cfg +0 -0
  10. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/__init__.py +0 -0
  11. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/_pypi_marker +0 -0
  12. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/_version.py +0 -0
  13. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/auth/__init__.py +0 -0
  14. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/auth/consent_form.py +0 -0
  15. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/auth/provider.py +0 -0
  16. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/backup_manager.py +0 -0
  17. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/browser_landing.py +0 -0
  18. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/client/__init__.py +0 -0
  19. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/client/rest_client.py +0 -0
  20. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/client/supervisor_client.py +0 -0
  21. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/client/websocket_client.py +0 -0
  22. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/client/websocket_listener.py +0 -0
  23. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/config.py +0 -0
  24. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/dashboard_screenshot/__init__.py +0 -0
  25. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/dashboard_screenshot/capture.py +0 -0
  26. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/dashboard_screenshot/content.py +0 -0
  27. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/dashboard_screenshot/paths.py +0 -0
  28. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/dashboard_screenshot/provision.py +0 -0
  29. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/errors.py +0 -0
  30. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/llm_exposure.py +0 -0
  31. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/policy/__init__.py +0 -0
  32. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/policy/approval_queue.py +0 -0
  33. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/policy/evaluator.py +0 -0
  34. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/policy/handlers.py +0 -0
  35. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/policy/middleware.py +0 -0
  36. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/policy/model.py +0 -0
  37. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/policy/persistence.py +0 -0
  38. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/policy/value_sources.py +0 -0
  39. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/py.typed +0 -0
  40. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/read_only.py +0 -0
  41. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
  42. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
  43. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
  44. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
  45. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/.github/pull_request_template.md +0 -0
  46. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
  47. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
  48. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
  49. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
  50. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
  51. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
  52. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/evals/evals.json +0 -0
  53. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/appdaemon.md +0 -0
  54. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
  55. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/blueprint-guide.md +0 -0
  56. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +0 -0
  57. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +0 -0
  58. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
  59. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +0 -0
  60. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
  61. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
  62. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
  63. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/scenes.md +0 -0
  64. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
  65. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/yaml-only-integrations.md +0 -0
  66. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/server.py +0 -0
  67. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/settings_ui/__init__.py +0 -0
  68. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/settings_ui/_handlers_advanced.py +0 -0
  69. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/settings_ui/_handlers_backups.py +0 -0
  70. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/settings_ui/_handlers_fs.py +0 -0
  71. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/settings_ui/_handlers_server.py +0 -0
  72. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/settings_ui/_handlers_theme.py +0 -0
  73. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/settings_ui/_handlers_tools.py +0 -0
  74. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/settings_ui/_i18n.py +0 -0
  75. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/settings_ui/_persistence.py +0 -0
  76. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/settings_ui/_supervisor.py +0 -0
  77. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/settings_ui/_theme.py +0 -0
  78. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/settings_ui/_tools_meta.py +0 -0
  79. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/settings_ui/locales/README.md +0 -0
  80. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/settings_ui/locales/en.json +0 -0
  81. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/settings_ui/locales/ru.json +0 -0
  82. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/settings_ui/settings.css +0 -0
  83. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/settings_ui/settings.html +0 -0
  84. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/settings_ui/settings.js +0 -0
  85. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/smoke_test.py +0 -0
  86. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/stdio_settings_sidecar.py +0 -0
  87. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/strict_bps.py +0 -0
  88. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/__init__.py +0 -0
  89. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/auto_backup.py +0 -0
  90. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/backup.py +0 -0
  91. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/best_practice_checker.py +0 -0
  92. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/component_api.py +0 -0
  93. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/component_config_reads.py +0 -0
  94. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/component_devices.py +0 -0
  95. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/component_registries.py +0 -0
  96. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/component_registry_lookup.py +0 -0
  97. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/config_entry_flow.py +0 -0
  98. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/device_control.py +0 -0
  99. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/enhanced.py +0 -0
  100. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/helpers.py +0 -0
  101. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/radio/__init__.py +0 -0
  102. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/radio/base.py +0 -0
  103. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/radio/matter.py +0 -0
  104. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/radio/thread.py +0 -0
  105. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/radio/zigbee.py +0 -0
  106. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/radio/zwave.py +0 -0
  107. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/reference_validator.py +0 -0
  108. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/registry.py +0 -0
  109. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/smart_search/__init__.py +0 -0
  110. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/smart_search/_base.py +0 -0
  111. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/smart_search/_config.py +0 -0
  112. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/smart_search/_deep.py +0 -0
  113. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/smart_search/_entities.py +0 -0
  114. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/smart_search/_fetch.py +0 -0
  115. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/smart_search/_overview.py +0 -0
  116. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/smart_search/_scenes.py +0 -0
  117. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/smart_search/_scoring.py +0 -0
  118. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tool_search_hint_middleware.py +0 -0
  119. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_addons.py +0 -0
  120. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_areas.py +0 -0
  121. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_blueprints.py +0 -0
  122. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_bug_report.py +0 -0
  123. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_calendar.py +0 -0
  124. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_camera.py +0 -0
  125. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_categories.py +0 -0
  126. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_code.py +0 -0
  127. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_config_automations.py +0 -0
  128. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
  129. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
  130. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_config_scenes.py +0 -0
  131. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
  132. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_dashboard_screenshot.py +0 -0
  133. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_dev.py +0 -0
  134. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_energy.py +0 -0
  135. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_entities.py +0 -0
  136. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_filesystem.py +0 -0
  137. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_groups.py +0 -0
  138. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_hacs.py +0 -0
  139. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_history.py +0 -0
  140. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_integrations.py +0 -0
  141. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_labels.py +0 -0
  142. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_radio.py +0 -0
  143. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_registry.py +0 -0
  144. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_resources.py +0 -0
  145. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_search.py +0 -0
  146. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_service.py +0 -0
  147. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_services.py +0 -0
  148. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_system.py +0 -0
  149. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_themes.py +0 -0
  150. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_todo.py +0 -0
  151. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_traces.py +0 -0
  152. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_updates.py +0 -0
  153. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_utility.py +0 -0
  154. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
  155. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
  156. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_yaml_read.py +0 -0
  157. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/tools_zones.py +0 -0
  158. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/util_helpers.py +0 -0
  159. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/tools/validation_middleware.py +0 -0
  160. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/transforms/__init__.py +0 -0
  161. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/transforms/categorized_search.py +0 -0
  162. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/transforms/lite_docstrings.py +0 -0
  163. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/transport_security.py +0 -0
  164. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/update_check.py +0 -0
  165. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/utils/__init__.py +0 -0
  166. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/utils/config_hash.py +0 -0
  167. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/utils/data_paths.py +0 -0
  168. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/utils/domain_handlers.py +0 -0
  169. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/utils/fuzzy_search.py +0 -0
  170. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
  171. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/utils/operation_manager.py +0 -0
  172. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/utils/python_sandbox.py +0 -0
  173. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/utils/skill_loader.py +0 -0
  174. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/utils/usage_logger.py +0 -0
  175. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/visibility/__init__.py +0 -0
  176. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/visibility/model.py +0 -0
  177. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/visibility/persistence.py +0 -0
  178. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp/visibility/resolver.py +0 -0
  179. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp_dev.egg-info/SOURCES.txt +0 -0
  180. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
  181. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
  182. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
  183. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/tests/__init__.py +0 -0
  184. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/tests/test_constants.py +0 -0
  185. {ha_mcp_dev-7.13.0.dev1975 → ha_mcp_dev-7.13.0.dev1977}/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.13.0.dev1975
3
+ Version: 7.13.0.dev1977
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
@@ -118,6 +118,7 @@ These run the server outside Home Assistant — useful for **Container** / **Cor
118
118
  - **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.
119
119
  - **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/).
120
120
  - **Local stdio (not recommended):** runs ha-mcp on your own machine over stdio. The one-command installers in the **Demo server** section below use this path; the [Setup Wizard](https://homeassistant-ai.github.io/ha-mcp/setup/) covers connecting it to your own Home Assistant.
121
+ - **OIDC authentication:** gate remote access behind an external identity provider (Authentik, Keycloak, Auth0, Google, etc.) instead of a secret URL — all authenticated users share the server's Home Assistant credentials. See [OIDC Mode](docs/oidc.md).
121
122
 
122
123
  > ⚠️ **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
124
 
@@ -85,6 +85,7 @@ These run the server outside Home Assistant — useful for **Container** / **Cor
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/).
87
87
  - **Local stdio (not recommended):** runs ha-mcp on your own machine over stdio. The one-command installers in the **Demo server** section below use this path; the [Setup Wizard](https://homeassistant-ai.github.io/ha-mcp/setup/) covers connecting it to your own Home Assistant.
88
+ - **OIDC authentication:** gate remote access behind an external identity provider (Authentik, Keycloak, Auth0, Google, etc.) instead of a secret URL — all authenticated users share the server's Home Assistant credentials. See [OIDC Mode](docs/oidc.md).
88
89
 
89
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.
90
91
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ha-mcp-dev"
7
- version = "7.13.0.dev1975"
7
+ version = "7.13.0.dev1977"
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
@@ -59,6 +59,7 @@ hamcp-test-env = "tests.test_env_manager:main"
59
59
  ha-mcp-web = "ha_mcp.__main__:main_web"
60
60
  ha-mcp-sse = "ha_mcp.__main__:main_sse"
61
61
  ha-mcp-oauth = "ha_mcp.__main__:main_oauth"
62
+ ha-mcp-oidc = "ha_mcp.__main__:main_oidc"
62
63
 
63
64
  [tool.setuptools]
64
65
  package-dir = {"" = "src", "tests" = "tests"}
@@ -979,6 +979,39 @@ def _healthz_enabled() -> bool:
979
979
  return os.getenv("MCP_HEALTHZ", "").strip().lower() in ("1", "true", "yes", "on")
980
980
 
981
981
 
982
+ def _oidc_verify_id_token_enabled() -> bool:
983
+ """True when OIDC_VERIFY_ID_TOKEN opts in to ID-token verification.
984
+
985
+ Off by default: FastMCP's OIDCProxy verifies the access token as a JWT,
986
+ which works for providers like Authentik and Keycloak. Providers that
987
+ issue opaque access tokens (Google always; Auth0 without an API
988
+ audience) need ``verify_id_token=True`` so FastMCP verifies the ID token
989
+ instead.
990
+ """
991
+ return os.getenv("OIDC_VERIFY_ID_TOKEN", "").strip().lower() in (
992
+ "1",
993
+ "true",
994
+ "yes",
995
+ "on",
996
+ )
997
+
998
+
999
+ def _oidc_allowed_client_redirect_uris() -> list[str] | None:
1000
+ """Parse OIDC_ALLOWED_CLIENT_REDIRECT_URIS into a list, or None if unset.
1001
+
1002
+ Comma-separated list of redirect URI patterns FastMCP's OIDCProxy will
1003
+ accept from dynamically-registered clients. With no allow-list set,
1004
+ FastMCP still validates a client's redirect URI against that same
1005
+ client's own registered redirect URIs — the exposure is that open DCR
1006
+ lets an attacker register their own client with their own redirect URI;
1007
+ internet-facing deployments should set this to constrain what any
1008
+ dynamically-registered client may register in the first place.
1009
+ """
1010
+ raw = os.getenv("OIDC_ALLOWED_CLIENT_REDIRECT_URIS", "")
1011
+ uris = [uri.strip() for uri in raw.split(",") if uri.strip()]
1012
+ return uris or None
1013
+
1014
+
982
1015
  def register_browser_landing(
983
1016
  mcp_instance: "FastMCP | _DeferredMCP",
984
1017
  path: str,
@@ -1225,5 +1258,192 @@ async def _run_oauth_server(
1225
1258
  )
1226
1259
 
1227
1260
 
1261
+ def main_oidc() -> None:
1262
+ """Run server with OIDC authentication over HTTP.
1263
+
1264
+ This mode enables authentication via an external OIDC provider
1265
+ (Authentik, Keycloak, Auth0, Google, etc.). All authenticated users
1266
+ share the same Home Assistant instance via the configured credentials.
1267
+
1268
+ Unlike OAuth mode which collects per-user HA credentials via a consent form,
1269
+ OIDC mode is purely an access gate — users authenticate through the OIDC provider,
1270
+ then all requests use the shared HA credentials from environment variables.
1271
+
1272
+ Environment:
1273
+ - OIDC_CONFIG_URL (required): OIDC discovery URL (.well-known/openid-configuration)
1274
+ - OIDC_CLIENT_ID (required): OAuth client ID registered with your OIDC provider
1275
+ - OIDC_CLIENT_SECRET (required): OAuth client secret from your OIDC provider
1276
+ - MCP_BASE_URL (required): Public HTTPS URL where this server is accessible
1277
+ - HOMEASSISTANT_URL (required): Home Assistant instance URL
1278
+ - HOMEASSISTANT_TOKEN (required): Home Assistant long-lived access token or supervisor token
1279
+ - OIDC_JWT_SIGNING_KEY (optional): Secret key for signing FastMCP JWTs. Sessions
1280
+ persist across restarts by default (the key is derived from OIDC_CLIENT_SECRET);
1281
+ set this to decouple the signing key from the client secret. Generate with:
1282
+ python -c "import secrets; print(secrets.token_urlsafe(32))"
1283
+ - OIDC_ALLOWED_CLIENT_REDIRECT_URIS (optional): Comma-separated list of redirect URI
1284
+ patterns accepted from dynamically-registered clients. Strongly recommended for
1285
+ internet-facing deployments.
1286
+ - OIDC_VERIFY_ID_TOKEN (optional, default: false): Set true for providers that issue
1287
+ opaque access tokens (e.g. Google, or Auth0 without an API audience).
1288
+ - OIDC_AUDIENCE (optional): Expected `aud` claim for IdP-issued access tokens.
1289
+ Without it (and with OIDC_VERIFY_ID_TOKEN off), FastMCP's JWT verifier checks
1290
+ issuer, signature, and expiry but not audience. With OIDC_VERIFY_ID_TOKEN=true,
1291
+ verification pins `aud` to OIDC_CLIENT_ID instead and this value is only
1292
+ forwarded to the IdP's authorize/token endpoints (it is what makes Auth0
1293
+ issue JWT rather than opaque access tokens).
1294
+ - MCP_HOST (optional, default: "0.0.0.0"; set 127.0.0.1 to restrict to loopback
1295
+ behind a same-host reverse proxy)
1296
+ - MCP_PORT (optional, default: 8086)
1297
+ - MCP_SECRET_PATH (optional, default: "/mcp")
1298
+ - LOG_LEVEL (optional, default: INFO)
1299
+ """
1300
+ # Configure logging for OIDC mode (force=True needed since logging may already be configured)
1301
+ log_level = os.getenv("LOG_LEVEL", "INFO").upper()
1302
+ _setup_logging(log_level, force=True)
1303
+ for logger_name in ["ha_mcp", "ha_mcp.auth", "ha_mcp.auth.provider"]:
1304
+ logging.getLogger(logger_name).setLevel(getattr(logging, log_level))
1305
+ logger.info(f"OIDC mode logging configured at {log_level} level")
1306
+ _log_startup_version()
1307
+
1308
+ # Validate HA credentials (OIDC mode needs them — unlike OAuth mode)
1309
+ from ha_mcp.config import get_settings
1310
+
1311
+ settings = get_settings()
1312
+ _validate_standard_credentials(settings)
1313
+
1314
+ # Validate OIDC-specific env vars
1315
+ oidc_config_url = os.getenv("OIDC_CONFIG_URL")
1316
+ oidc_client_id = os.getenv("OIDC_CLIENT_ID")
1317
+ oidc_client_secret = os.getenv("OIDC_CLIENT_SECRET")
1318
+ base_url = os.getenv("MCP_BASE_URL")
1319
+
1320
+ missing = []
1321
+ if not oidc_config_url:
1322
+ missing.append("OIDC_CONFIG_URL")
1323
+ if not oidc_client_id:
1324
+ missing.append("OIDC_CLIENT_ID")
1325
+ if not oidc_client_secret:
1326
+ missing.append("OIDC_CLIENT_SECRET")
1327
+ if not base_url:
1328
+ missing.append("MCP_BASE_URL")
1329
+
1330
+ if missing:
1331
+ logger.error(
1332
+ f"Missing required environment variables for OIDC mode: {', '.join(missing)}"
1333
+ )
1334
+ logger.error(
1335
+ "OIDC mode requires an external OIDC provider (Authentik, Keycloak, Auth0, etc.)"
1336
+ )
1337
+ sys.exit(1)
1338
+
1339
+ assert oidc_config_url is not None
1340
+ assert oidc_client_id is not None
1341
+ assert oidc_client_secret is not None
1342
+ assert base_url is not None
1343
+
1344
+ host, port, path = _get_http_runtime(default_port=8086)
1345
+
1346
+ _run_entrypoint(
1347
+ _run_oidc_server(
1348
+ config_url=oidc_config_url,
1349
+ client_id=oidc_client_id,
1350
+ client_secret=oidc_client_secret,
1351
+ base_url=base_url,
1352
+ host=host,
1353
+ port=port,
1354
+ path=path,
1355
+ ),
1356
+ "OIDC server",
1357
+ )
1358
+
1359
+
1360
+ async def _run_oidc_server(
1361
+ config_url: str,
1362
+ client_id: str,
1363
+ client_secret: str,
1364
+ base_url: str,
1365
+ host: str,
1366
+ port: int,
1367
+ path: str,
1368
+ ) -> None:
1369
+ """Run the OIDC-authenticated MCP server.
1370
+
1371
+ Unlike OAuth mode which uses OAuthProxyClient for per-user credential routing,
1372
+ OIDC mode uses the standard HomeAssistantClient with shared credentials.
1373
+ OIDC is purely an access gate — all authenticated users share the same HA instance.
1374
+
1375
+ Args:
1376
+ config_url: OIDC discovery URL (.well-known/openid-configuration)
1377
+ client_id: OAuth client ID from the OIDC provider
1378
+ client_secret: OAuth client secret from the OIDC provider
1379
+ base_url: Public HTTPS URL where this server is accessible
1380
+ host: Bind host (typically 0.0.0.0; override via MCP_HOST)
1381
+ port: Port to listen on
1382
+ path: MCP endpoint path
1383
+ """
1384
+ from fastmcp.server.auth.oidc_proxy import OIDCProxy
1385
+
1386
+ from ha_mcp.server import HomeAssistantSmartMCPServer
1387
+ from ha_mcp.transport_security import ensure_host_origin_guard_default_off
1388
+
1389
+ # OIDC mode is deployed behind a public reverse proxy or LAN hostname;
1390
+ # disable FastMCP's Host/Origin rebinding guard so proxied requests are
1391
+ # not rejected with 421/403 before OIDC auth runs.
1392
+ ensure_host_origin_guard_default_off()
1393
+
1394
+ proxy_kwargs: dict[str, Any] = {
1395
+ "config_url": config_url,
1396
+ "client_id": client_id,
1397
+ "client_secret": client_secret,
1398
+ "base_url": base_url,
1399
+ # "external" tells FastMCP that consent is handled by the upstream
1400
+ # IdP (Authentik, Keycloak, etc.) -- unlike `False`, this does not
1401
+ # log a security warning at startup that consent is disabled.
1402
+ "require_authorization_consent": "external",
1403
+ # Preserve `or None`: an empty-but-set env var must not bypass
1404
+ # FastMCP's derive-from-client-secret default for jwt_signing_key.
1405
+ "jwt_signing_key": os.getenv("OIDC_JWT_SIGNING_KEY") or None,
1406
+ }
1407
+
1408
+ allowed_redirect_uris = _oidc_allowed_client_redirect_uris()
1409
+ if allowed_redirect_uris:
1410
+ proxy_kwargs["allowed_client_redirect_uris"] = allowed_redirect_uris
1411
+ else:
1412
+ logger.warning(
1413
+ "OIDC_ALLOWED_CLIENT_REDIRECT_URIS is not set: any dynamically-registered "
1414
+ "(DCR) client's own redirect URIs are accepted. Internet-facing "
1415
+ "deployments should set it."
1416
+ )
1417
+
1418
+ if _oidc_verify_id_token_enabled():
1419
+ proxy_kwargs["verify_id_token"] = True
1420
+
1421
+ audience = os.getenv("OIDC_AUDIENCE", "").strip()
1422
+ if audience:
1423
+ proxy_kwargs["audience"] = audience
1424
+
1425
+ # Create OIDC auth provider — auto-discovers endpoints from config_url
1426
+ auth = OIDCProxy(**proxy_kwargs)
1427
+
1428
+ # Standard server with shared credentials (no proxy client needed)
1429
+ global _server
1430
+ _server = HomeAssistantSmartMCPServer()
1431
+ mcp_instance = _server.mcp
1432
+ mcp_instance.auth = auth
1433
+
1434
+ logger.info("Server created with OIDC authentication")
1435
+ # Unlike standard/OAuth HTTP modes, OIDC mode intentionally registers no
1436
+ # browser landing page and no settings-UI sidecar: an unauthenticated
1437
+ # browser GET gets a bare 405 rather than a friendly page, and there is
1438
+ # no settings UI surface here.
1439
+ if _healthz_enabled():
1440
+ _register_healthz_route(mcp_instance)
1441
+ logger.info(f"Starting OIDC-enabled MCP server at {base_url}{path}")
1442
+
1443
+ await _run_with_shutdown(
1444
+ mcp_instance.run_async(**_http_run_kwargs("http", host, port, path))
1445
+ )
1446
+
1447
+
1228
1448
  if __name__ == "__main__":
1229
1449
  main()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ha-mcp-dev
3
- Version: 7.13.0.dev1975
3
+ Version: 7.13.0.dev1977
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
@@ -118,6 +118,7 @@ These run the server outside Home Assistant — useful for **Container** / **Cor
118
118
  - **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.
119
119
  - **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/).
120
120
  - **Local stdio (not recommended):** runs ha-mcp on your own machine over stdio. The one-command installers in the **Demo server** section below use this path; the [Setup Wizard](https://homeassistant-ai.github.io/ha-mcp/setup/) covers connecting it to your own Home Assistant.
121
+ - **OIDC authentication:** gate remote access behind an external identity provider (Authentik, Keycloak, Auth0, Google, etc.) instead of a secret URL — all authenticated users share the server's Home Assistant credentials. See [OIDC Mode](docs/oidc.md).
121
122
 
122
123
  > ⚠️ **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
124
 
@@ -2,6 +2,7 @@
2
2
  ha-mcp = ha_mcp.__main__:main
3
3
  ha-mcp-dev = ha_mcp.__main__:main_dev
4
4
  ha-mcp-oauth = ha_mcp.__main__:main_oauth
5
+ ha-mcp-oidc = ha_mcp.__main__:main_oidc
5
6
  ha-mcp-smoke-test = ha_mcp.smoke_test:main
6
7
  ha-mcp-sse = ha_mcp.__main__:main_sse
7
8
  ha-mcp-web = ha_mcp.__main__:main_web