ha-mcp-dev 7.14.2.dev2117__tar.gz → 7.14.2.dev2120__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.
- {ha_mcp_dev-7.14.2.dev2117/src/ha_mcp_dev.egg-info → ha_mcp_dev-7.14.2.dev2120}/PKG-INFO +1 -1
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/pyproject.toml +1 -2
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/__main__.py +34 -81
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/browser_landing.py +1 -1
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/_handlers_advanced.py +1 -1
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/settings.js +1 -1
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_bug_report.py +6 -4
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120/src/ha_mcp_dev.egg-info}/PKG-INFO +1 -1
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -1
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/LICENSE +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/MANIFEST.in +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/README.md +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/setup.cfg +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/__init__.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/_pypi_marker +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/_version.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/auth/__init__.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/auth/consent_form.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/auth/provider.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/backup_manager.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/client/__init__.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/client/rest_client.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/client/supervisor_client.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/client/websocket_client.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/client/websocket_listener.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/config.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/dashboard_screenshot/__init__.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/dashboard_screenshot/capture.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/dashboard_screenshot/content.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/dashboard_screenshot/paths.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/dashboard_screenshot/provision.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/dashboard_screenshot/theme_guard.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/errors.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/llm_exposure.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/policy/__init__.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/policy/approval_queue.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/policy/evaluator.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/policy/handlers.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/policy/middleware.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/policy/model.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/policy/persistence.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/policy/value_sources.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/py.typed +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/read_only.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/.github/pull_request_template.md +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/evals/evals.json +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/appdaemon.md +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/blueprint-guide.md +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/scenes.md +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/yaml-only-integrations.md +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/server.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/__init__.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/_handlers_backups.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/_handlers_fs.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/_handlers_server.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/_handlers_theme.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/_handlers_tools.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/_i18n.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/_persistence.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/_supervisor.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/_theme.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/_tools_meta.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/locales/README.md +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/locales/de.json +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/locales/en.json +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/locales/ru.json +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/locales/zh-Hans.json +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/settings.css +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/settings.html +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/smoke_test.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/stdio_settings_sidecar.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/strict_bps.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/__init__.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/auto_backup.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/backup.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/best_practice_checker.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/component_api.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/component_config_reads.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/component_devices.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/component_registries.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/component_registry_lookup.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/config_entry_flow.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/device_control.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/enhanced.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/helpers.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/radio/__init__.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/radio/base.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/radio/matter.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/radio/thread.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/radio/zigbee.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/radio/zwave.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/reference_validator.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/registry.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/smart_search/__init__.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/smart_search/_base.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/smart_search/_config.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/smart_search/_deep.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/smart_search/_entities.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/smart_search/_fetch.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/smart_search/_overview.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/smart_search/_scenes.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/smart_search/_scoring.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tool_search_hint_middleware.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_addons.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_areas.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_blueprints.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_calendar.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_camera.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_categories.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_code.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_config_automations.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_config_scenes.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_dashboard_screenshot.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_dev.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_energy.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_entities.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_filesystem.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_groups.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_hacs.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_history.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_integrations.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_labels.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_radio.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_registry.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_resources.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_search.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_service.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_services.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_system.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_themes.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_todo.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_traces.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_updates.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_utility.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_yaml_read.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_zones.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/util_helpers.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/validation_middleware.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/transforms/__init__.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/transforms/categorized_search.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/transforms/lite_docstrings.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/transport_security.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/update_check.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/utils/__init__.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/utils/config_hash.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/utils/config_write_lock.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/utils/data_paths.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/utils/domain_handlers.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/utils/fuzzy_search.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/utils/operation_manager.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/utils/python_sandbox.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/utils/skill_loader.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/utils/usage_logger.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/visibility/__init__.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/visibility/enforcement.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/visibility/model.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/visibility/persistence.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/visibility/resolver.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp_dev.egg-info/SOURCES.txt +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/tests/__init__.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/tests/test_constants.py +0 -0
- {ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/tests/test_env_manager.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ha-mcp-dev"
|
|
7
|
-
version = "7.14.2.
|
|
7
|
+
version = "7.14.2.dev2120"
|
|
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
|
|
@@ -57,7 +57,6 @@ ha-mcp-dev = "ha_mcp.__main__:main_dev"
|
|
|
57
57
|
ha-mcp-smoke-test = "ha_mcp.smoke_test:main"
|
|
58
58
|
hamcp-test-env = "tests.test_env_manager:main"
|
|
59
59
|
ha-mcp-web = "ha_mcp.__main__:main_web"
|
|
60
|
-
ha-mcp-sse = "ha_mcp.__main__:main_sse"
|
|
61
60
|
ha-mcp-oauth = "ha_mcp.__main__:main_oauth"
|
|
62
61
|
ha-mcp-oidc = "ha_mcp.__main__:main_oidc"
|
|
63
62
|
|
|
@@ -306,28 +306,21 @@ def _setup_standard_mode() -> None:
|
|
|
306
306
|
_log_startup_version()
|
|
307
307
|
|
|
308
308
|
|
|
309
|
-
def _http_run_kwargs(
|
|
310
|
-
"""Build common run_async kwargs for HTTP
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
``
|
|
314
|
-
``transport="sse"`` makes fastmcp's ``run_async`` raise
|
|
315
|
-
``ValueError("SSE transport does not support stateless mode")``. Gating it to
|
|
316
|
-
non-SSE transports keeps SSE startup working. (Before this fix that raise was
|
|
317
|
-
also swallowed into a silent exit 0; ``_run_with_shutdown`` now surfaces a
|
|
318
|
-
self-terminating server task's exception instead.) See #1544.
|
|
309
|
+
def _http_run_kwargs(host: str, port: int, path: str) -> dict[str, Any]:
|
|
310
|
+
"""Build common run_async kwargs for the Streamable HTTP transport.
|
|
311
|
+
|
|
312
|
+
Every HTTP entry point (``ha-mcp-web``, OAuth, OIDC) runs Streamable HTTP,
|
|
313
|
+
so ``stateless_http`` — a Streamable-HTTP-only concept — always applies.
|
|
319
314
|
"""
|
|
320
|
-
|
|
321
|
-
"transport":
|
|
315
|
+
return {
|
|
316
|
+
"transport": "http",
|
|
322
317
|
"host": host,
|
|
323
318
|
"port": port,
|
|
324
319
|
"path": path,
|
|
320
|
+
"stateless_http": True,
|
|
325
321
|
"show_banner": _get_show_banner(),
|
|
326
322
|
"uvicorn_config": {"log_config": _get_timestamped_uvicorn_log_config()},
|
|
327
323
|
}
|
|
328
|
-
if transport != "sse":
|
|
329
|
-
kwargs["stateless_http"] = True
|
|
330
|
-
return kwargs
|
|
331
324
|
|
|
332
325
|
|
|
333
326
|
def _create_server() -> "HomeAssistantSmartMCPServer":
|
|
@@ -458,14 +451,12 @@ class ProbeAccessLogFilter(logging.Filter):
|
|
|
458
451
|
health check, reverse proxy, or a connector's SSE-style pre-flight) hit a
|
|
459
452
|
POST-only Streamable HTTP endpoint. The raw access line is dropped and the
|
|
460
453
|
landing handler logs one annotated "(NORMAL for most non-SSE connections)"
|
|
461
|
-
line in its place.
|
|
462
|
-
pass False, since there a GET answers 200 and a GET-405 is a genuine fault.
|
|
454
|
+
line in its place.
|
|
463
455
|
"""
|
|
464
456
|
|
|
465
|
-
def __init__(self, mcp_path: str
|
|
457
|
+
def __init__(self, mcp_path: str) -> None:
|
|
466
458
|
super().__init__()
|
|
467
459
|
self._mcp_path = mcp_path.rstrip("/") or "/"
|
|
468
|
-
self._drop_mcp_405 = drop_mcp_405
|
|
469
460
|
|
|
470
461
|
def filter(self, record: logging.LogRecord) -> bool:
|
|
471
462
|
# uvicorn.access records carry structured args: (client, method, path,
|
|
@@ -483,12 +474,8 @@ class ProbeAccessLogFilter(logging.Filter):
|
|
|
483
474
|
return False # opt-in liveness probe (register_healthz) — pure noise
|
|
484
475
|
# By-design probe 405 on the MCP path; the handler logs an annotated line
|
|
485
476
|
# instead. This trusts that the landing route is the only GET/HEAD responder
|
|
486
|
-
# on the MCP path (true today).
|
|
487
|
-
|
|
488
|
-
is_dropped_probe = (
|
|
489
|
-
status == 405 and path == self._mcp_path and self._drop_mcp_405
|
|
490
|
-
)
|
|
491
|
-
return not is_dropped_probe
|
|
477
|
+
# on the MCP path (true today).
|
|
478
|
+
return not (status == 405 and path == self._mcp_path)
|
|
492
479
|
|
|
493
480
|
|
|
494
481
|
def _setup_logging(log_level_str: str, force: bool = False) -> None:
|
|
@@ -967,7 +954,7 @@ def main_dev() -> None:
|
|
|
967
954
|
|
|
968
955
|
# HTTP entry point for web clients
|
|
969
956
|
def _get_http_runtime(default_port: int = 8086) -> tuple[str, int, str]:
|
|
970
|
-
"""Return runtime configuration shared by HTTP
|
|
957
|
+
"""Return runtime configuration shared by the HTTP entry points.
|
|
971
958
|
|
|
972
959
|
Args:
|
|
973
960
|
default_port: Default port to use if MCP_PORT env var is not set.
|
|
@@ -1048,12 +1035,12 @@ def _is_running_in_container() -> bool:
|
|
|
1048
1035
|
def _warn_if_default_path_exposed(host: str, port: int, path: str) -> None:
|
|
1049
1036
|
"""Warn on a direct run that leaves the default path on a LAN bind.
|
|
1050
1037
|
|
|
1051
|
-
Standard-mode HTTP
|
|
1038
|
+
Standard-mode HTTP authenticates by URL-path secrecy (see
|
|
1052
1039
|
SECURITY.md → Threat Model). The default ``/mcp`` is not the
|
|
1053
1040
|
high-entropy secret that model assumes once the bind leaves loopback.
|
|
1054
1041
|
|
|
1055
|
-
Fires only for a direct ``ha-mcp-web``
|
|
1056
|
-
|
|
1042
|
+
Fires only for a direct ``ha-mcp-web`` start (uvx, pip, source) that uses
|
|
1043
|
+
the default path on a non-loopback host. Operators
|
|
1057
1044
|
silence it the same way they harden — bind ``MCP_HOST=127.0.0.1`` or set
|
|
1058
1045
|
a high-entropy ``MCP_SECRET_PATH``. Containers are skipped: an
|
|
1059
1046
|
in-container ``0.0.0.0`` bind says nothing about real exposure, which is
|
|
@@ -1068,7 +1055,7 @@ def _warn_if_default_path_exposed(host: str, port: int, path: str) -> None:
|
|
|
1068
1055
|
return
|
|
1069
1056
|
logger.warning(
|
|
1070
1057
|
"ha-mcp listening on %s:%s%s with default MCP_SECRET_PATH. "
|
|
1071
|
-
"Standard-mode HTTP
|
|
1058
|
+
"Standard-mode HTTP authenticates by URL-path secrecy and assumes "
|
|
1072
1059
|
"a high-entropy MCP_SECRET_PATH for non-loopback binds "
|
|
1073
1060
|
"(see SECURITY.md → Threat Model). "
|
|
1074
1061
|
"Either bind loopback (MCP_HOST=127.0.0.1) or set MCP_SECRET_PATH "
|
|
@@ -1080,15 +1067,12 @@ def _warn_if_default_path_exposed(host: str, port: int, path: str) -> None:
|
|
|
1080
1067
|
|
|
1081
1068
|
|
|
1082
1069
|
async def _run_http_with_graceful_shutdown(
|
|
1083
|
-
transport: str,
|
|
1084
1070
|
host: str,
|
|
1085
1071
|
port: int,
|
|
1086
1072
|
path: str,
|
|
1087
1073
|
) -> None:
|
|
1088
1074
|
"""Run HTTP server with graceful shutdown support."""
|
|
1089
|
-
await _run_with_shutdown(
|
|
1090
|
-
_get_mcp().run_async(**_http_run_kwargs(transport, host, port, path))
|
|
1091
|
-
)
|
|
1075
|
+
await _run_with_shutdown(_get_mcp().run_async(**_http_run_kwargs(host, port, path)))
|
|
1092
1076
|
|
|
1093
1077
|
|
|
1094
1078
|
def _healthz_enabled() -> bool:
|
|
@@ -1137,8 +1121,6 @@ def _oidc_allowed_client_redirect_uris() -> list[str] | None:
|
|
|
1137
1121
|
def register_browser_landing(
|
|
1138
1122
|
mcp_instance: "FastMCP | _DeferredMCP",
|
|
1139
1123
|
path: str,
|
|
1140
|
-
*,
|
|
1141
|
-
quiet_probe_log: bool = True,
|
|
1142
1124
|
) -> None:
|
|
1143
1125
|
"""Register the friendly browser landing page and tidy the uvicorn access log.
|
|
1144
1126
|
|
|
@@ -1152,24 +1134,16 @@ def register_browser_landing(
|
|
|
1152
1134
|
Args:
|
|
1153
1135
|
mcp_instance: The FastMCP server to register the route on.
|
|
1154
1136
|
path: The MCP endpoint path (e.g. "/mcp" or a secret path).
|
|
1155
|
-
quiet_probe_log: When True (default, for Streamable HTTP), drop the
|
|
1156
|
-
by-design GET/HEAD-405 probe line on the MCP path from the uvicorn
|
|
1157
|
-
access log (the handler logs an annotated replacement). Pass False
|
|
1158
|
-
for SSE, where a GET answers 200 and a 405 is a genuine fault.
|
|
1159
1137
|
"""
|
|
1160
1138
|
if not _register_landing_route(mcp_instance, path):
|
|
1161
1139
|
# Already registered for this path — don't double-attach the log filter.
|
|
1162
1140
|
return
|
|
1163
1141
|
|
|
1164
|
-
# Tidy uvicorn's access log:
|
|
1165
|
-
#
|
|
1166
|
-
#
|
|
1167
|
-
#
|
|
1168
|
-
|
|
1169
|
-
# filter would miss it.
|
|
1170
|
-
logging.getLogger("uvicorn.access").addFilter(
|
|
1171
|
-
ProbeAccessLogFilter(path, drop_mcp_405=quiet_probe_log)
|
|
1172
|
-
)
|
|
1142
|
+
# Tidy uvicorn's access log: drop browser favicon 404s and the raw by-design
|
|
1143
|
+
# GET/HEAD-405 probe line on the MCP path (the landing handler logs an
|
|
1144
|
+
# annotated replacement). Attach to uvicorn.access directly — it has
|
|
1145
|
+
# propagate=False, so a root-logger filter would miss it.
|
|
1146
|
+
logging.getLogger("uvicorn.access").addFilter(ProbeAccessLogFilter(path))
|
|
1173
1147
|
|
|
1174
1148
|
|
|
1175
1149
|
def _log_settings_url(
|
|
@@ -1229,7 +1203,7 @@ def _log_settings_url(
|
|
|
1229
1203
|
|
|
1230
1204
|
# Truthy / falsy env-var spellings for HA_MCP_DISABLE_SETTINGS_UI, matching the
|
|
1231
1205
|
# parsing in stdio_settings_sidecar.py so the toggle behaves the same across
|
|
1232
|
-
#
|
|
1206
|
+
# entry points. A value in neither set is unrecognized: fail closed (disable) with
|
|
1233
1207
|
# a warning, since this is a security kill switch and failing open on a typo
|
|
1234
1208
|
# would leave an unauthenticated surface up.
|
|
1235
1209
|
_SETTINGS_TRUTHY = {"1", "true", "yes", "on"}
|
|
@@ -1239,9 +1213,9 @@ _SETTINGS_FALSY = {"0", "false", "no", "off", ""}
|
|
|
1239
1213
|
def _settings_ui_disabled() -> bool:
|
|
1240
1214
|
"""Return True when ``HA_MCP_DISABLE_SETTINGS_UI`` turns the settings UI off.
|
|
1241
1215
|
|
|
1242
|
-
Honored by every long-lived HTTP transport (standard ``ha-mcp-web``
|
|
1243
|
-
|
|
1244
|
-
|
|
1216
|
+
Honored by every long-lived HTTP transport (standard ``ha-mcp-web`` as well
|
|
1217
|
+
as OAuth/OIDC) and, with matching semantics, by the stdio sidecar. As a
|
|
1218
|
+
security kill switch it fails **closed**: any value that
|
|
1245
1219
|
is neither a recognized truthy nor falsy spelling disables the UI and warns
|
|
1246
1220
|
(so the operator learns why it vanished), rather than leaving an
|
|
1247
1221
|
unauthenticated surface up on a typo. Unset — or an explicit falsy value —
|
|
@@ -1373,11 +1347,10 @@ def _register_settings_ui_secret_path(
|
|
|
1373
1347
|
)
|
|
1374
1348
|
|
|
1375
1349
|
|
|
1376
|
-
def _run_http_server(
|
|
1377
|
-
"""Common runner for
|
|
1350
|
+
def _run_http_server(default_port: int = 8086) -> None:
|
|
1351
|
+
"""Common runner for the standard-mode Streamable HTTP server.
|
|
1378
1352
|
|
|
1379
1353
|
Args:
|
|
1380
|
-
transport: Transport type (http or sse).
|
|
1381
1354
|
default_port: Default port to use if MCP_PORT env var is not set.
|
|
1382
1355
|
"""
|
|
1383
1356
|
from ha_mcp.settings_ui import register_settings_routes
|
|
@@ -1386,9 +1359,7 @@ def _run_http_server(transport: str, default_port: int = 8086) -> None:
|
|
|
1386
1359
|
# _get_mcp below, before the app is built) -- see transport_security.
|
|
1387
1360
|
host, port, path = _get_http_runtime(default_port)
|
|
1388
1361
|
_warn_if_default_path_exposed(host, port, path)
|
|
1389
|
-
|
|
1390
|
-
# would be a real fault, not a benign probe — keep its access log intact.
|
|
1391
|
-
register_browser_landing(_get_mcp(), path, quiet_probe_log=transport != "sse")
|
|
1362
|
+
register_browser_landing(_get_mcp(), path)
|
|
1392
1363
|
if _healthz_enabled():
|
|
1393
1364
|
_register_healthz_route(_get_mcp())
|
|
1394
1365
|
if _settings_ui_disabled():
|
|
@@ -1400,7 +1371,7 @@ def _run_http_server(transport: str, default_port: int = 8086) -> None:
|
|
|
1400
1371
|
_log_settings_url(host, port, path)
|
|
1401
1372
|
|
|
1402
1373
|
_run_entrypoint(
|
|
1403
|
-
_run_http_with_graceful_shutdown(
|
|
1374
|
+
_run_http_with_graceful_shutdown(host, port, path),
|
|
1404
1375
|
"HTTP server",
|
|
1405
1376
|
)
|
|
1406
1377
|
|
|
@@ -1418,23 +1389,7 @@ def main_web() -> None:
|
|
|
1418
1389
|
settings UI at all
|
|
1419
1390
|
"""
|
|
1420
1391
|
_setup_standard_mode()
|
|
1421
|
-
_run_http_server(
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
def main_sse() -> None:
|
|
1425
|
-
"""Run server using Server-Sent Events transport for MCP clients.
|
|
1426
|
-
|
|
1427
|
-
Environment:
|
|
1428
|
-
- HOMEASSISTANT_URL (required)
|
|
1429
|
-
- HOMEASSISTANT_TOKEN (required)
|
|
1430
|
-
- MCP_HOST (optional, default: "0.0.0.0"; set 127.0.0.1 to restrict to loopback)
|
|
1431
|
-
- MCP_PORT (optional, default: 8087)
|
|
1432
|
-
- MCP_SECRET_PATH (optional, default: "/mcp")
|
|
1433
|
-
- HA_MCP_DISABLE_SETTINGS_UI (optional): set truthy to not serve the web
|
|
1434
|
-
settings UI at all
|
|
1435
|
-
"""
|
|
1436
|
-
_setup_standard_mode()
|
|
1437
|
-
_run_http_server("sse", default_port=8087)
|
|
1392
|
+
_run_http_server(default_port=8086)
|
|
1438
1393
|
|
|
1439
1394
|
|
|
1440
1395
|
def main_oauth() -> None:
|
|
@@ -1568,9 +1523,7 @@ async def _run_oauth_server(
|
|
|
1568
1523
|
f"Starting OAuth-enabled MCP server with {len(tools)} tools on {base_url}{path}"
|
|
1569
1524
|
)
|
|
1570
1525
|
|
|
1571
|
-
await _run_with_shutdown(
|
|
1572
|
-
mcp.run_async(**_http_run_kwargs("http", host, port, path))
|
|
1573
|
-
)
|
|
1526
|
+
await _run_with_shutdown(mcp.run_async(**_http_run_kwargs(host, port, path)))
|
|
1574
1527
|
|
|
1575
1528
|
|
|
1576
1529
|
def main_oidc() -> None:
|
|
@@ -1763,7 +1716,7 @@ async def _run_oidc_server(
|
|
|
1763
1716
|
logger.info(f"Starting OIDC-enabled MCP server at {base_url}{path}")
|
|
1764
1717
|
|
|
1765
1718
|
await _run_with_shutdown(
|
|
1766
|
-
mcp_instance.run_async(**_http_run_kwargs(
|
|
1719
|
+
mcp_instance.run_async(**_http_run_kwargs(host, port, path))
|
|
1767
1720
|
)
|
|
1768
1721
|
|
|
1769
1722
|
|
|
@@ -150,7 +150,7 @@ def register_healthz(mcp_instance: CustomRouteServer) -> bool:
|
|
|
150
150
|
"""Register a GET ``/healthz`` liveness route answering 200 with JSON.
|
|
151
151
|
|
|
152
152
|
Lets uptime monitors, blackbox probes, and load balancers confirm the HTTP
|
|
153
|
-
server is alive without knowing the MCP path. Standard-mode HTTP
|
|
153
|
+
server is alive without knowing the MCP path. Standard-mode HTTP
|
|
154
154
|
authenticates by URL-path secrecy (SECURITY.md -> Threat Model), so this
|
|
155
155
|
route is opt-in (``MCP_HEALTHZ`` env var, checked by the caller) and the
|
|
156
156
|
response body deliberately does not echo the MCP path.
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/_handlers_advanced.py
RENAMED
|
@@ -166,7 +166,7 @@ async def _get_advanced_settings(
|
|
|
166
166
|
)
|
|
167
167
|
]
|
|
168
168
|
# is_stdio: the sidecar-port field only applies when this settings page
|
|
169
|
-
# is served by the stdio settings-UI sidecar. In HTTP/
|
|
169
|
+
# is served by the stdio settings-UI sidecar. In HTTP/OAuth/addon
|
|
170
170
|
# deployments there is no sidecar, so the UI greys the section.
|
|
171
171
|
return JSONResponse(
|
|
172
172
|
{
|
|
@@ -3619,7 +3619,7 @@ async function loadAdvancedSettings() {
|
|
|
3619
3619
|
|
|
3620
3620
|
function applySidecarAvailability(isStdio) {
|
|
3621
3621
|
// The sidecar-port setting only applies when this settings page is served
|
|
3622
|
-
// by the stdio settings-UI sidecar. In HTTP/
|
|
3622
|
+
// by the stdio settings-UI sidecar. In HTTP/OAuth/addon deployments
|
|
3623
3623
|
// there is no sidecar, so dim + disable the section and explain why, rather
|
|
3624
3624
|
// than letting a user save a value that does nothing.
|
|
3625
3625
|
// Remove any note from a prior load first, so the <h2> title is once again
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_bug_report.py
RENAMED
|
@@ -343,15 +343,17 @@ def _detect_mcp_transport() -> str:
|
|
|
343
343
|
transport perfectly from a tool call, so we look at the entrypoint name
|
|
344
344
|
and well-known env hints. The result is informational — the bug template
|
|
345
345
|
surfaces it as an auto-detect that the agent or user can override.
|
|
346
|
+
|
|
347
|
+
ha-mcp ships no SSE entry point, so ``sse`` only appears when an operator
|
|
348
|
+
drives fastmcp's own deprecated SSE transport via ``FASTMCP_TRANSPORT`` —
|
|
349
|
+
worth surfacing in a report, since that run shape is unsupported.
|
|
346
350
|
"""
|
|
347
|
-
# Entry-point script name (e.g. ``ha-mcp-web`` for HTTP
|
|
348
|
-
#
|
|
351
|
+
# Entry-point script name (e.g. ``ha-mcp-web`` for HTTP;
|
|
352
|
+
# pyproject.toml's [project.scripts] is the source of truth).
|
|
349
353
|
argv0 = (sys.argv[0] if sys.argv else "").lower()
|
|
350
354
|
basename = os.path.basename(argv0)
|
|
351
355
|
if basename.endswith("-web"):
|
|
352
356
|
return "http"
|
|
353
|
-
if basename.endswith("-sse"):
|
|
354
|
-
return "sse"
|
|
355
357
|
|
|
356
358
|
# Env hints set by HTTP wrappers / supervisors. ``streamable-http`` is the
|
|
357
359
|
# documented FastMCP variant; collapse it to ``http`` since the
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp_dev.egg-info/entry_points.txt
RENAMED
|
@@ -4,6 +4,5 @@ ha-mcp-dev = ha_mcp.__main__:main_dev
|
|
|
4
4
|
ha-mcp-oauth = ha_mcp.__main__:main_oauth
|
|
5
5
|
ha-mcp-oidc = ha_mcp.__main__:main_oidc
|
|
6
6
|
ha-mcp-smoke-test = ha_mcp.smoke_test:main
|
|
7
|
-
ha-mcp-sse = ha_mcp.__main__:main_sse
|
|
8
7
|
ha-mcp-web = ha_mcp.__main__:main_web
|
|
9
8
|
hamcp-test-env = tests.test_env_manager:main
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/client/supervisor_client.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/client/websocket_client.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/client/websocket_listener.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/dashboard_screenshot/__init__.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/dashboard_screenshot/capture.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/dashboard_screenshot/content.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/dashboard_screenshot/paths.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/dashboard_screenshot/provision.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/AGENTS.md
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/CLAUDE.md
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/LICENSE
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/resources/skills-vendor/README.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/_handlers_backups.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/_handlers_fs.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/_handlers_server.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/_handlers_theme.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/_handlers_tools.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/_persistence.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/_supervisor.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/_tools_meta.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/locales/README.md
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/locales/de.json
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/locales/en.json
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/locales/ru.json
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/locales/zh-Hans.json
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/settings_ui/settings.html
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/stdio_settings_sidecar.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/best_practice_checker.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/component_config_reads.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/component_devices.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/component_registries.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/config_entry_flow.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/reference_validator.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/smart_search/__init__.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/smart_search/_base.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/smart_search/_config.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/smart_search/_deep.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/smart_search/_entities.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/smart_search/_fetch.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/smart_search/_overview.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/smart_search/_scenes.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/smart_search/_scoring.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_blueprints.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_categories.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_config_automations.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_config_dashboards.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_config_helpers.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_config_scenes.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_config_scripts.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_filesystem.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_integrations.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_voice_assistant.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/tools_yaml_config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/tools/validation_middleware.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/transforms/categorized_search.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/transforms/lite_docstrings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/utils/config_write_lock.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/utils/kill_signal_diagnostics.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/utils/operation_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/visibility/enforcement.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp/visibility/persistence.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp_dev.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp_dev.egg-info/requires.txt
RENAMED
|
File without changes
|
{ha_mcp_dev-7.14.2.dev2117 → ha_mcp_dev-7.14.2.dev2120}/src/ha_mcp_dev.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|