ha-mcp-dev 6.7.2.dev248__tar.gz → 6.7.2.dev249__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. {ha_mcp_dev-6.7.2.dev248/src/ha_mcp_dev.egg-info → ha_mcp_dev-6.7.2.dev249}/PKG-INFO +1 -1
  2. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/pyproject.toml +1 -1
  3. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/client/rest_client.py +55 -12
  4. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249/src/ha_mcp_dev.egg-info}/PKG-INFO +1 -1
  5. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/LICENSE +0 -0
  6. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/MANIFEST.in +0 -0
  7. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/README.md +0 -0
  8. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/setup.cfg +0 -0
  9. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/__init__.py +0 -0
  10. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/__main__.py +0 -0
  11. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/_pypi_marker +0 -0
  12. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/auth/__init__.py +0 -0
  13. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/auth/consent_form.py +0 -0
  14. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/auth/provider.py +0 -0
  15. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/client/__init__.py +0 -0
  16. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/client/websocket_client.py +0 -0
  17. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/client/websocket_listener.py +0 -0
  18. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/config.py +0 -0
  19. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/errors.py +0 -0
  20. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/py.typed +0 -0
  21. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/resources/card_types.json +0 -0
  22. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/resources/dashboard_guide.md +0 -0
  23. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
  24. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
  25. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
  26. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
  27. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
  28. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
  29. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
  30. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
  31. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
  32. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
  33. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
  34. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
  35. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
  36. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
  37. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
  38. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
  39. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/server.py +0 -0
  40. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/smoke_test.py +0 -0
  41. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/__init__.py +0 -0
  42. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/backup.py +0 -0
  43. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/device_control.py +0 -0
  44. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/enhanced.py +0 -0
  45. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/helpers.py +0 -0
  46. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/registry.py +0 -0
  47. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/smart_search.py +0 -0
  48. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_addons.py +0 -0
  49. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_areas.py +0 -0
  50. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_blueprints.py +0 -0
  51. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_bug_report.py +0 -0
  52. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_calendar.py +0 -0
  53. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_camera.py +0 -0
  54. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_config_automations.py +0 -0
  55. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
  56. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_config_entry_flow.py +0 -0
  57. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
  58. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_config_info.py +0 -0
  59. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
  60. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_entities.py +0 -0
  61. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_filesystem.py +0 -0
  62. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_groups.py +0 -0
  63. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_hacs.py +0 -0
  64. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_history.py +0 -0
  65. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_integrations.py +0 -0
  66. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_labels.py +0 -0
  67. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_mcp_component.py +0 -0
  68. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_registry.py +0 -0
  69. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_resources.py +0 -0
  70. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_search.py +0 -0
  71. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_service.py +0 -0
  72. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_services.py +0 -0
  73. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_system.py +0 -0
  74. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_todo.py +0 -0
  75. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_traces.py +0 -0
  76. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_updates.py +0 -0
  77. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_utility.py +0 -0
  78. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
  79. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/tools_zones.py +0 -0
  80. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/tools/util_helpers.py +0 -0
  81. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/utils/__init__.py +0 -0
  82. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/utils/domain_handlers.py +0 -0
  83. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/utils/fuzzy_search.py +0 -0
  84. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/utils/operation_manager.py +0 -0
  85. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/utils/python_sandbox.py +0 -0
  86. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp/utils/usage_logger.py +0 -0
  87. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp_dev.egg-info/SOURCES.txt +0 -0
  88. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
  89. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
  90. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
  91. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
  92. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/tests/__init__.py +0 -0
  93. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/tests/test_constants.py +0 -0
  94. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev249}/tests/test_env_manager.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ha-mcp-dev
3
- Version: 6.7.2.dev248
3
+ Version: 6.7.2.dev249
4
4
  Summary: Home Assistant MCP Server - Complete control of Home Assistant through MCP
5
5
  Author-email: Julien <github@qc-h.net>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ha-mcp-dev"
7
- version = "6.7.2.dev248"
7
+ version = "6.7.2.dev249"
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"
@@ -831,18 +831,58 @@ class HomeAssistantClient:
831
831
  "template": message.get("template"),
832
832
  }
833
833
 
834
+ async def _resolve_script_id(self, identifier: str) -> str:
835
+ """
836
+ Resolve a script identifier to its storage key via the entity registry.
837
+
838
+ Scripts may be renamed in the HA UI, changing the entity_id but keeping
839
+ the original storage key. This method looks up the entity registry via
840
+ WebSocket to find the actual storage key (unique_id).
841
+
842
+ Unlike automations (which expose their storage key in state attributes),
843
+ scripts require a WebSocket entity registry lookup.
844
+
845
+ Args:
846
+ identifier: Script ID (with or without 'script.' prefix)
847
+
848
+ Returns:
849
+ The storage key for the configuration API
850
+ """
851
+ bare_id = identifier.removeprefix("script.")
852
+ entity_id = f"script.{bare_id}"
853
+ try:
854
+ result = await self.send_websocket_message(
855
+ {"type": "config/entity_registry/get", "entity_id": entity_id}
856
+ )
857
+ if result.get("success") is not False:
858
+ unique_id = result.get("result", {}).get("unique_id")
859
+ if unique_id:
860
+ if unique_id != bare_id:
861
+ logger.debug(
862
+ f"Resolved script entity_id {entity_id} to storage key {unique_id}"
863
+ )
864
+ return str(unique_id)
865
+ except Exception:
866
+ logger.debug(
867
+ f"Entity registry lookup failed for {entity_id}, using bare id: {bare_id}",
868
+ exc_info=True # Log full traceback for better debugging
869
+ )
870
+ return bare_id
871
+
834
872
  async def get_script_config(self, script_id: str) -> dict[str, Any]:
835
873
  """Get Home Assistant script configuration by script_id."""
874
+ resolved_id = await self._resolve_script_id(script_id)
836
875
  try:
837
- endpoint = f"config/script/config/{script_id}"
876
+ endpoint = f"config/script/config/{resolved_id}"
838
877
  response = await self._request("GET", endpoint)
839
878
 
840
- return {"success": True, "script_id": script_id, "config": response}
879
+ return {"success": True, "script_id": resolved_id, "config": response}
841
880
  except HomeAssistantAPIError as e:
842
881
  if e.status_code == 404:
843
- raise HomeAssistantAPIError(
844
- f"Script not found: {script_id}", status_code=404
845
- ) from e
882
+ msg = f"Script not found: {script_id}"
883
+ if resolved_id != script_id:
884
+ msg += f" (resolved storage key: {resolved_id})"
885
+ raise HomeAssistantAPIError(msg, status_code=404) from e
846
886
  raise
847
887
  except Exception as e:
848
888
  logger.error(f"Failed to get script config for {script_id}: {e}")
@@ -852,8 +892,9 @@ class HomeAssistantClient:
852
892
  self, config: dict[str, Any], script_id: str
853
893
  ) -> dict[str, Any]:
854
894
  """Create or update Home Assistant script configuration."""
895
+ resolved_id = await self._resolve_script_id(script_id)
855
896
  try:
856
- endpoint = f"config/script/config/{script_id}"
897
+ endpoint = f"config/script/config/{resolved_id}"
857
898
 
858
899
  # Validate required fields
859
900
  if "alias" not in config:
@@ -870,7 +911,7 @@ class HomeAssistantClient:
870
911
 
871
912
  return {
872
913
  "success": True,
873
- "script_id": script_id,
914
+ "script_id": resolved_id,
874
915
  "result": response.get("result", "ok"),
875
916
  "operation": "created" if response.get("result") == "ok" else "updated",
876
917
  }
@@ -880,21 +921,23 @@ class HomeAssistantClient:
880
921
 
881
922
  async def delete_script_config(self, script_id: str) -> dict[str, Any]:
882
923
  """Delete Home Assistant script configuration."""
924
+ resolved_id = await self._resolve_script_id(script_id)
883
925
  try:
884
- endpoint = f"config/script/config/{script_id}"
926
+ endpoint = f"config/script/config/{resolved_id}"
885
927
  response = await self._request("DELETE", endpoint)
886
928
 
887
929
  return {
888
930
  "success": True,
889
- "script_id": script_id,
931
+ "script_id": resolved_id,
890
932
  "result": response.get("result", "ok"),
891
933
  "operation": "deleted",
892
934
  }
893
935
  except HomeAssistantAPIError as e:
894
936
  if e.status_code == 404:
895
- raise HomeAssistantAPIError(
896
- f"Script not found: {script_id}", status_code=404
897
- ) from e
937
+ msg = f"Script not found: {script_id}"
938
+ if resolved_id != script_id:
939
+ msg += f" (resolved storage key: {resolved_id})"
940
+ raise HomeAssistantAPIError(msg, status_code=404) from e
898
941
  elif e.status_code == 405:
899
942
  raise HomeAssistantAPIError(
900
943
  f"Cannot delete script '{script_id}': The HTTP DELETE method is blocked. "
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ha-mcp-dev
3
- Version: 6.7.2.dev248
3
+ Version: 6.7.2.dev249
4
4
  Summary: Home Assistant MCP Server - Complete control of Home Assistant through MCP
5
5
  Author-email: Julien <github@qc-h.net>
6
6
  License: MIT