ha-mcp-dev 7.4.1.dev483__tar.gz → 7.4.1.dev485__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.4.1.dev483/src/ha_mcp_dev.egg-info → ha_mcp_dev-7.4.1.dev485}/PKG-INFO +1 -1
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/pyproject.toml +3 -1
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/backup.py +99 -9
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485/src/ha_mcp_dev.egg-info}/PKG-INFO +1 -1
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/LICENSE +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/MANIFEST.in +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/README.md +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/setup.cfg +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/__init__.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/__main__.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/_pypi_marker +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/_version.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/auth/__init__.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/auth/consent_form.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/auth/provider.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/client/__init__.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/client/rest_client.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/client/supervisor_client.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/client/websocket_client.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/client/websocket_listener.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/config.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/errors.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/py.typed +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/evals/evals.json +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/server.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/settings_ui.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/smoke_test.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/__init__.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/best_practice_checker.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/device_control.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/enhanced.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/helpers.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/reference_validator.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/registry.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/smart_search.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_addons.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_areas.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_blueprints.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_bug_report.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_calendar.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_camera.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_categories.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_code.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_config_automations.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_config_entry_flow.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_config_scenes.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_energy.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_entities.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_filesystem.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_groups.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_hacs.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_history.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_integrations.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_labels.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_mcp_component.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_registry.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_resources.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_search.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_service.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_services.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_system.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_todo.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_traces.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_updates.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_utility.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_zones.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/util_helpers.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/transforms/__init__.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/transforms/categorized_search.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/utils/__init__.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/utils/config_hash.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/utils/data_paths.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/utils/domain_handlers.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/utils/fuzzy_search.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/utils/operation_manager.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/utils/python_sandbox.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/utils/usage_logger.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp_dev.egg-info/SOURCES.txt +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/tests/__init__.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/tests/test_constants.py +0 -0
- {ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/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.4.1.
|
|
7
|
+
version = "7.4.1.dev485"
|
|
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"
|
|
@@ -88,6 +88,8 @@ module = [
|
|
|
88
88
|
"aiohttp",
|
|
89
89
|
"voluptuous",
|
|
90
90
|
"jsonschema",
|
|
91
|
+
"requests",
|
|
92
|
+
"requests.*",
|
|
91
93
|
]
|
|
92
94
|
ignore_missing_imports = true
|
|
93
95
|
|
|
@@ -52,6 +52,67 @@ def _get_backup_hint_text() -> str:
|
|
|
52
52
|
return hints.get(hint, hints["normal"])
|
|
53
53
|
|
|
54
54
|
|
|
55
|
+
async def _get_local_backup_agent_id(
|
|
56
|
+
ws_client: HomeAssistantWebSocketClient,
|
|
57
|
+
) -> str:
|
|
58
|
+
"""Discover the local backup agent_id at call time.
|
|
59
|
+
|
|
60
|
+
HA Supervised registers ``hassio.local`` and HA Core registers
|
|
61
|
+
``backup.local`` — both have ``name: "local"``. Hardcoding either breaks
|
|
62
|
+
the other deployment. We probe ``backup/agents/info`` and pick the agent
|
|
63
|
+
whose name is exactly ``"local"``, preferring ``hassio.local`` if both
|
|
64
|
+
happen to be registered.
|
|
65
|
+
|
|
66
|
+
Raises ToolError if no local agent is available.
|
|
67
|
+
"""
|
|
68
|
+
response = await ws_client.send_command("backup/agents/info")
|
|
69
|
+
if not response.get("success"):
|
|
70
|
+
raise_tool_error(
|
|
71
|
+
create_error_response(
|
|
72
|
+
ErrorCode.SERVICE_CALL_FAILED,
|
|
73
|
+
"Failed to enumerate backup agents",
|
|
74
|
+
context={"details": response},
|
|
75
|
+
)
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
agents = response.get("result", {}).get("agents", [])
|
|
79
|
+
if not agents:
|
|
80
|
+
raise_tool_error(
|
|
81
|
+
create_error_response(
|
|
82
|
+
ErrorCode.SERVICE_CALL_FAILED,
|
|
83
|
+
"No backup agents registered with Home Assistant",
|
|
84
|
+
suggestions=[
|
|
85
|
+
"The HA backup integration may not be fully set up; "
|
|
86
|
+
"check the backup panel in Home Assistant",
|
|
87
|
+
],
|
|
88
|
+
)
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
local_agents: list[str] = [
|
|
92
|
+
a["agent_id"]
|
|
93
|
+
for a in agents
|
|
94
|
+
if a.get("name") == "local" and a.get("agent_id")
|
|
95
|
+
]
|
|
96
|
+
# Prefer hassio.local (Supervisor) over backup.local (Core) when both exist
|
|
97
|
+
for preferred in ("hassio.local", "backup.local"):
|
|
98
|
+
if preferred in local_agents:
|
|
99
|
+
return preferred
|
|
100
|
+
if local_agents:
|
|
101
|
+
return local_agents[0]
|
|
102
|
+
|
|
103
|
+
raise_tool_error(
|
|
104
|
+
create_error_response(
|
|
105
|
+
ErrorCode.SERVICE_CALL_FAILED,
|
|
106
|
+
"No local backup agent found",
|
|
107
|
+
context={"available_agents": [a.get("agent_id") for a in agents if a.get("agent_id")]},
|
|
108
|
+
suggestions=[
|
|
109
|
+
"Backup creation requires a local agent (hassio.local on "
|
|
110
|
+
"Supervised, backup.local on Core); none is registered",
|
|
111
|
+
],
|
|
112
|
+
)
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
|
|
55
116
|
async def _get_backup_password(
|
|
56
117
|
ws_client: HomeAssistantWebSocketClient,
|
|
57
118
|
) -> str:
|
|
@@ -94,9 +155,14 @@ async def _poll_backup_completion(
|
|
|
94
155
|
backup_job_id: str,
|
|
95
156
|
max_wait_seconds: int,
|
|
96
157
|
poll_interval: int,
|
|
158
|
+
agent_id: str,
|
|
97
159
|
) -> dict[str, Any]:
|
|
98
160
|
"""Poll backup/info until the named backup completes, fails, or times out.
|
|
99
161
|
|
|
162
|
+
``agent_id`` is the local agent that owns this backup (e.g.
|
|
163
|
+
``hassio.local`` on Supervised, ``backup.local`` on Core); used to look
|
|
164
|
+
up the per-agent size in the backup-info payload.
|
|
165
|
+
|
|
100
166
|
Raises ToolError on backup failure or timeout.
|
|
101
167
|
"""
|
|
102
168
|
waited = 0
|
|
@@ -134,7 +200,7 @@ async def _poll_backup_completion(
|
|
|
134
200
|
"name": name,
|
|
135
201
|
"date": created_backup.get("date"),
|
|
136
202
|
"size_bytes": created_backup.get("agents", {})
|
|
137
|
-
.get(
|
|
203
|
+
.get(agent_id, {})
|
|
138
204
|
.get("size"),
|
|
139
205
|
"status": "Backup completed successfully",
|
|
140
206
|
"duration_seconds": waited,
|
|
@@ -192,19 +258,31 @@ async def create_backup(
|
|
|
192
258
|
# Get backup password (raises ToolError on failure)
|
|
193
259
|
password = await _get_backup_password(ws_client)
|
|
194
260
|
|
|
261
|
+
# Discover the local backup agent at call time. HA Core registers
|
|
262
|
+
# `backup.local`; HA Supervised registers `hassio.local`. Hardcoding
|
|
263
|
+
# either breaks the other deployment.
|
|
264
|
+
local_agent = await _get_local_backup_agent_id(ws_client)
|
|
265
|
+
|
|
195
266
|
# Generate backup name if not provided
|
|
196
267
|
if not name:
|
|
197
268
|
now = datetime.now()
|
|
198
269
|
name = f"MCP_Backup_{now.strftime('%Y-%m-%d_%H:%M:%S')}"
|
|
199
270
|
|
|
200
|
-
#
|
|
271
|
+
# Addons + addon folders are Supervisor concepts — HA Core errors
|
|
272
|
+
# with "Addons and folders are not supported by core backup" if we
|
|
273
|
+
# ask for them. Toggle off when we detect the Core local agent.
|
|
274
|
+
is_supervised = local_agent == "hassio.local"
|
|
275
|
+
logger.info(
|
|
276
|
+
f"Detected {'Supervised' if is_supervised else 'Core'} install "
|
|
277
|
+
f"via backup agent '{local_agent}'"
|
|
278
|
+
)
|
|
201
279
|
backup_params = {
|
|
202
280
|
"name": name,
|
|
203
281
|
"password": password,
|
|
204
|
-
"agent_ids": [
|
|
282
|
+
"agent_ids": [local_agent],
|
|
205
283
|
"include_homeassistant": True,
|
|
206
284
|
"include_database": False, # Fast backup
|
|
207
|
-
"include_all_addons":
|
|
285
|
+
"include_all_addons": is_supervised,
|
|
208
286
|
}
|
|
209
287
|
|
|
210
288
|
# Send backup request
|
|
@@ -225,6 +303,7 @@ async def create_backup(
|
|
|
225
303
|
backup_job_id,
|
|
226
304
|
max_wait_seconds=_BACKUP_MAX_WAIT_S,
|
|
227
305
|
poll_interval=_BACKUP_POLL_INTERVAL_S,
|
|
306
|
+
agent_id=local_agent,
|
|
228
307
|
)
|
|
229
308
|
|
|
230
309
|
except ToolError:
|
|
@@ -248,9 +327,13 @@ async def create_backup(
|
|
|
248
327
|
async def _create_safety_backup(
|
|
249
328
|
ws_client: HomeAssistantWebSocketClient,
|
|
250
329
|
password: str | None,
|
|
330
|
+
agent_id: str,
|
|
251
331
|
) -> str | None:
|
|
252
332
|
"""Create a pre-restore safety backup.
|
|
253
333
|
|
|
334
|
+
``agent_id`` is the local backup agent (Supervisor's ``hassio.local`` or
|
|
335
|
+
Core's ``backup.local``) discovered by the caller.
|
|
336
|
+
|
|
254
337
|
Returns the safety backup ID, or None when password is None (backup intentionally
|
|
255
338
|
skipped). Raises ToolError if backup creation fails.
|
|
256
339
|
"""
|
|
@@ -260,14 +343,16 @@ async def _create_safety_backup(
|
|
|
260
343
|
now = datetime.now()
|
|
261
344
|
safety_backup_name = f"PreRestore_Safety_{now.strftime('%Y-%m-%d_%H:%M:%S')}"
|
|
262
345
|
|
|
346
|
+
# include_all_addons is a Supervisor concept; HA Core rejects it.
|
|
347
|
+
is_supervised = agent_id == "hassio.local"
|
|
263
348
|
safety_backup = await ws_client.send_command(
|
|
264
349
|
"backup/generate",
|
|
265
350
|
name=safety_backup_name,
|
|
266
351
|
password=password,
|
|
267
|
-
agent_ids=[
|
|
352
|
+
agent_ids=[agent_id],
|
|
268
353
|
include_homeassistant=True,
|
|
269
354
|
include_database=True,
|
|
270
|
-
include_all_addons=
|
|
355
|
+
include_all_addons=is_supervised,
|
|
271
356
|
)
|
|
272
357
|
|
|
273
358
|
if not safety_backup.get("success"):
|
|
@@ -330,6 +415,11 @@ async def restore_backup(
|
|
|
330
415
|
suggestions=["Use ha_backup_list() to see available backups"],
|
|
331
416
|
))
|
|
332
417
|
|
|
418
|
+
# Discover the local backup agent (Supervisor's hassio.local on
|
|
419
|
+
# Supervised, backup.local on Core). Used for both the safety backup
|
|
420
|
+
# and the restore call below.
|
|
421
|
+
local_agent = await _get_local_backup_agent_id(ws_client)
|
|
422
|
+
|
|
333
423
|
# Create safety backup BEFORE restoring
|
|
334
424
|
logger.info("Creating safety backup before restore...")
|
|
335
425
|
try:
|
|
@@ -339,12 +429,12 @@ async def restore_backup(
|
|
|
339
429
|
logger.warning("No default password - proceeding without safety backup")
|
|
340
430
|
password = None
|
|
341
431
|
|
|
342
|
-
safety_backup_id = await _create_safety_backup(ws_client, password)
|
|
432
|
+
safety_backup_id = await _create_safety_backup(ws_client, password, local_agent)
|
|
343
433
|
|
|
344
434
|
# Perform restore
|
|
345
435
|
restore_params = {
|
|
346
436
|
"backup_id": backup_id,
|
|
347
|
-
"agent_id":
|
|
437
|
+
"agent_id": local_agent,
|
|
348
438
|
"restore_database": restore_database,
|
|
349
439
|
"restore_homeassistant": True,
|
|
350
440
|
"restore_addons": [], # Restore all addons from backup
|
|
@@ -409,7 +499,7 @@ def register_backup_tools(mcp: "FastMCP", client: HomeAssistantClient, **kwargs:
|
|
|
409
499
|
|
|
410
500
|
**Password:** Uses Home Assistant's default backup password (if configured)
|
|
411
501
|
|
|
412
|
-
**Storage:** Local only (hassio.local
|
|
502
|
+
**Storage:** Local only (the local backup agent — `hassio.local` on HA Supervised, `backup.local` on HA Core)
|
|
413
503
|
|
|
414
504
|
**Duration:** Typically takes several seconds to complete (without database)
|
|
415
505
|
|
|
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.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/resources/skills-vendor/AGENTS.md
RENAMED
|
File without changes
|
{ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/resources/skills-vendor/CLAUDE.md
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/resources/skills-vendor/LICENSE
RENAMED
|
File without changes
|
{ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/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
|
{ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/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
|
|
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.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_config_automations.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_config_dashboards.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_config_entry_flow.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_config_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/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.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/tools/tools_voice_assistant.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp/transforms/categorized_search.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/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.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/src/ha_mcp_dev.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{ha_mcp_dev-7.4.1.dev483 → ha_mcp_dev-7.4.1.dev485}/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
|