ha-mcp-dev 7.6.0.dev640__tar.gz → 7.6.0.dev642__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.6.0.dev640/src/ha_mcp_dev.egg-info → ha_mcp_dev-7.6.0.dev642}/PKG-INFO +1 -1
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/pyproject.toml +1 -1
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_bug_report.py +28 -2
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/utils/usage_logger.py +71 -1
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642/src/ha_mcp_dev.egg-info}/PKG-INFO +1 -1
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/LICENSE +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/MANIFEST.in +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/README.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/setup.cfg +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/__main__.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/_pypi_marker +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/_version.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/auth/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/auth/consent_form.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/auth/provider.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/backup_manager.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/client/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/client/rest_client.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/client/supervisor_client.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/client/websocket_client.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/client/websocket_listener.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/config.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/errors.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/policy/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/policy/approval_queue.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/policy/evaluator.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/policy/handlers.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/policy/middleware.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/policy/model.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/policy/persistence.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/policy/value_sources.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/py.typed +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/.github/pull_request_template.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/evals/evals.json +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/yaml-only-integrations.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/server.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/settings.css +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/settings.js +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/settings_ui.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/smoke_test.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/stdio_settings_sidecar.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/auto_backup.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/backup.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/best_practice_checker.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/device_control.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/enhanced.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/helpers.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/reference_validator.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/registry.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/smart_search/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/smart_search/_base.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/smart_search/_config.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/smart_search/_deep.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/smart_search/_entities.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/smart_search/_fetch.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/smart_search/_overview.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/smart_search/_scenes.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/smart_search/_scoring.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_addons.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_areas.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_blueprints.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_calendar.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_camera.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_categories.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_code.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_config_automations.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_config_entry_flow.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_config_scenes.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_energy.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_entities.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_filesystem.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_groups.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_hacs.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_history.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_integrations.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_labels.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_mcp_component.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_registry.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_resources.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_search.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_service.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_services.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_system.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_todo.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_traces.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_updates.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_utility.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_zones.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/util_helpers.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/validation_middleware.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/transforms/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/transforms/categorized_search.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/transforms/lite_docstrings.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/utils/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/utils/config_hash.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/utils/data_paths.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/utils/domain_handlers.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/utils/fuzzy_search.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/utils/operation_manager.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/utils/python_sandbox.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/utils/skill_loader.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp_dev.egg-info/SOURCES.txt +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/tests/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/tests/test_constants.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/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.6.0.
|
|
7
|
+
version = "7.6.0.dev642"
|
|
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"
|
|
@@ -293,7 +293,8 @@ def _sanitize_log_text(text: str) -> str:
|
|
|
293
293
|
review (see ``_generate_anonymization_guide``). Rules cover the most common
|
|
294
294
|
leak shapes seen in HA add-on logs:
|
|
295
295
|
JWTs, bearer tokens, long hex tokens, ``key=value`` style credentials,
|
|
296
|
-
URL userinfo,
|
|
296
|
+
URL userinfo, IPv4 addresses with network context, and the MCP connect-URL
|
|
297
|
+
secret path (the add-on's LAN auth).
|
|
297
298
|
"""
|
|
298
299
|
# JWT tokens (header.payload.signature)
|
|
299
300
|
text = re.sub(
|
|
@@ -338,6 +339,20 @@ def _sanitize_log_text(text: str) -> str:
|
|
|
338
339
|
text = _IPV4_WITH_PORT_OR_CIDR_RE.sub("[IP]", text)
|
|
339
340
|
text = _IPV4_IN_URL_RE.sub(r"\1[IP]", text)
|
|
340
341
|
text = _IPV4_AFTER_KEYWORD_RE.sub(r"\1[IP]", text)
|
|
342
|
+
# MCP connect-URL secret path — the add-on's LAN auth. Redact by the
|
|
343
|
+
# configured value (catches custom paths) and the generated
|
|
344
|
+
# ``/private_<token>`` convention. Only bug-report output is scrubbed here;
|
|
345
|
+
# the raw logs this text is copied from are left intact.
|
|
346
|
+
configured = os.getenv("MCP_SECRET_PATH", "").rstrip("/")
|
|
347
|
+
if configured and configured != "/mcp":
|
|
348
|
+
# Anchor on a path-segment boundary so a short/substring-prone configured
|
|
349
|
+
# value (e.g. "/ha") cannot corrupt unrelated text (e.g. "/happy").
|
|
350
|
+
text = re.sub(
|
|
351
|
+
re.escape(configured) + r"(?![A-Za-z0-9_-])",
|
|
352
|
+
"[REDACTED_SECRET_PATH]",
|
|
353
|
+
text,
|
|
354
|
+
)
|
|
355
|
+
text = re.sub(r"/private_[A-Za-z0-9_-]+", "[REDACTED_SECRET_PATH]", text)
|
|
341
356
|
return text
|
|
342
357
|
|
|
343
358
|
|
|
@@ -623,7 +638,18 @@ class BugReportTools:
|
|
|
623
638
|
"success": True,
|
|
624
639
|
"diagnostic_info": diagnostic_info,
|
|
625
640
|
"recent_logs": recent_logs,
|
|
626
|
-
|
|
641
|
+
# Scrub the startup-log *messages* — they aren't sanitized at source,
|
|
642
|
+
# so the connect-URL secret path can otherwise surface here.
|
|
643
|
+
# recent_logs is also returned, but its sensitive *parameters* are
|
|
644
|
+
# key-masked at the logging chokepoint and its error_message is
|
|
645
|
+
# returned as-is to the trusted client by design (see SECURITY.md);
|
|
646
|
+
# formatted_report and addon_logs already route through
|
|
647
|
+
# _sanitize_log_text. This copies entries — the underlying log
|
|
648
|
+
# records stay raw.
|
|
649
|
+
"startup_logs": [
|
|
650
|
+
{**entry, "message": _sanitize_log_text(entry.get("message", ""))}
|
|
651
|
+
for entry in startup_logs
|
|
652
|
+
],
|
|
627
653
|
"addon_logs": addon_logs,
|
|
628
654
|
"log_count": len(recent_logs),
|
|
629
655
|
"startup_log_count": len(startup_logs),
|
|
@@ -94,6 +94,72 @@ def get_startup_logs() -> list[dict[str, Any]]:
|
|
|
94
94
|
return _startup_collector.get_logs()
|
|
95
95
|
|
|
96
96
|
|
|
97
|
+
# Parameter keys whose values are masked before a tool call is recorded to the
|
|
98
|
+
# in-memory ring buffer or persisted to disk. Tool kwargs can carry secrets
|
|
99
|
+
# (alarm/lock ``code``, tokens, passwords); these must never reach the usage
|
|
100
|
+
# log, which ``ha_report_issue`` surfaces and which is written verbatim to
|
|
101
|
+
# plaintext ``mcp_usage.jsonl``. Matching is by key name (case-insensitive) and
|
|
102
|
+
# recursive, so a secret nested under a non-sensitive key — e.g.
|
|
103
|
+
# ``ha_call_service(data={"code": ...})`` — is caught while ``data`` siblings
|
|
104
|
+
# like ``entity_id``/``brightness`` survive for debugging.
|
|
105
|
+
_SENSITIVE_PARAM_KEYS = frozenset(
|
|
106
|
+
{
|
|
107
|
+
"code",
|
|
108
|
+
"pin",
|
|
109
|
+
"password",
|
|
110
|
+
"passwd",
|
|
111
|
+
"secret",
|
|
112
|
+
"token",
|
|
113
|
+
"access_token",
|
|
114
|
+
"refresh_token",
|
|
115
|
+
"api_key",
|
|
116
|
+
"apikey",
|
|
117
|
+
"client_secret",
|
|
118
|
+
"authorization",
|
|
119
|
+
}
|
|
120
|
+
)
|
|
121
|
+
# Suffix match only for families with a low false-positive rate. Deliberately
|
|
122
|
+
# excludes ``_code``/``_key`` so ``status_code``/``cache_key`` stay readable;
|
|
123
|
+
# the exact ``code``/``pin``/``api_key`` entries above already cover the real
|
|
124
|
+
# Home Assistant service-call surface.
|
|
125
|
+
_SENSITIVE_KEY_SUFFIXES = ("_token", "_secret", "_password", "_passwd")
|
|
126
|
+
_REDACTED_VALUE = "[REDACTED]"
|
|
127
|
+
_MAX_REDACT_DEPTH = 6
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def _is_sensitive_key(key: Any) -> bool:
|
|
131
|
+
"""Return True if a parameter key's value should be masked."""
|
|
132
|
+
if not isinstance(key, str):
|
|
133
|
+
return False
|
|
134
|
+
lowered = key.lower()
|
|
135
|
+
return lowered in _SENSITIVE_PARAM_KEYS or lowered.endswith(_SENSITIVE_KEY_SUFFIXES)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def _redact_parameters(value: Any, _depth: int = 0) -> Any:
|
|
139
|
+
"""Return a copy of ``value`` with sensitive values masked by key name.
|
|
140
|
+
|
|
141
|
+
Never mutates the input: it is the live tool ``kwargs`` dict, still
|
|
142
|
+
referenced by the caller after this returns. Recurses through nested
|
|
143
|
+
dicts/lists/tuples so secrets nested under non-sensitive keys are caught
|
|
144
|
+
(a tuple is returned as a list). Fails closed past ``_MAX_REDACT_DEPTH`` —
|
|
145
|
+
a subtree too deep to walk is masked wholesale rather than returned verbatim.
|
|
146
|
+
"""
|
|
147
|
+
if _depth > _MAX_REDACT_DEPTH:
|
|
148
|
+
return _REDACTED_VALUE
|
|
149
|
+
if isinstance(value, dict):
|
|
150
|
+
return {
|
|
151
|
+
key: (
|
|
152
|
+
_REDACTED_VALUE
|
|
153
|
+
if _is_sensitive_key(key)
|
|
154
|
+
else _redact_parameters(item, _depth + 1)
|
|
155
|
+
)
|
|
156
|
+
for key, item in value.items()
|
|
157
|
+
}
|
|
158
|
+
if isinstance(value, (list, tuple)):
|
|
159
|
+
return [_redact_parameters(item, _depth + 1) for item in value]
|
|
160
|
+
return value
|
|
161
|
+
|
|
162
|
+
|
|
97
163
|
@dataclass
|
|
98
164
|
class ToolUsageLog:
|
|
99
165
|
"""Single tool usage log entry."""
|
|
@@ -201,10 +267,14 @@ class UsageLogger:
|
|
|
201
267
|
if not self._enabled:
|
|
202
268
|
return
|
|
203
269
|
try:
|
|
270
|
+
# Mask secrets (alarm/lock codes, tokens, passwords) before the entry
|
|
271
|
+
# reaches the ring buffer or disk. Returns a copy — never mutates the
|
|
272
|
+
# caller's live kwargs dict.
|
|
273
|
+
redacted_parameters = _redact_parameters(parameters)
|
|
204
274
|
log_entry = ToolUsageLog(
|
|
205
275
|
timestamp=datetime.now(UTC).isoformat(),
|
|
206
276
|
tool_name=tool_name,
|
|
207
|
-
parameters=
|
|
277
|
+
parameters=redacted_parameters,
|
|
208
278
|
execution_time_ms=execution_time_ms,
|
|
209
279
|
success=success,
|
|
210
280
|
error_message=error_message,
|
|
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
|
|
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.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/AGENTS.md
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/CLAUDE.md
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/resources/skills-vendor/LICENSE
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/best_practice_checker.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/smart_search/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/smart_search/_config.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/smart_search/_entities.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/smart_search/_overview.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/smart_search/_scenes.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/smart_search/_scoring.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
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_config_automations.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_config_dashboards.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_config_entry_flow.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_config_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_config_scripts.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
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/tools_voice_assistant.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/tools/validation_middleware.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/transforms/categorized_search.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/transforms/lite_docstrings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp/utils/kill_signal_diagnostics.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp_dev.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev642}/src/ha_mcp_dev.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|