ha-mcp-dev 6.7.1.dev230__tar.gz → 6.7.1.dev232__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 (78) hide show
  1. {ha_mcp_dev-6.7.1.dev230/src/ha_mcp_dev.egg-info → ha_mcp_dev-6.7.1.dev232}/PKG-INFO +1 -1
  2. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/pyproject.toml +2 -4
  3. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_config_helpers.py +214 -35
  4. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232/src/ha_mcp_dev.egg-info}/PKG-INFO +1 -1
  5. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/LICENSE +0 -0
  6. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/MANIFEST.in +0 -0
  7. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/README.md +0 -0
  8. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/setup.cfg +0 -0
  9. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/__init__.py +0 -0
  10. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/__main__.py +0 -0
  11. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/_pypi_marker +0 -0
  12. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/auth/__init__.py +0 -0
  13. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/auth/consent_form.py +0 -0
  14. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/auth/provider.py +0 -0
  15. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/client/__init__.py +0 -0
  16. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/client/rest_client.py +0 -0
  17. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/client/websocket_client.py +0 -0
  18. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/client/websocket_listener.py +0 -0
  19. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/config.py +0 -0
  20. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/errors.py +0 -0
  21. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/py.typed +0 -0
  22. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/resources/card_types.json +0 -0
  23. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/resources/dashboard_guide.md +0 -0
  24. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/server.py +0 -0
  25. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/smoke_test.py +0 -0
  26. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/__init__.py +0 -0
  27. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/backup.py +0 -0
  28. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/device_control.py +0 -0
  29. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/enhanced.py +0 -0
  30. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/helpers.py +0 -0
  31. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/registry.py +0 -0
  32. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/smart_search.py +0 -0
  33. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_addons.py +0 -0
  34. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_areas.py +0 -0
  35. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_blueprints.py +0 -0
  36. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_bug_report.py +0 -0
  37. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_calendar.py +0 -0
  38. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_camera.py +0 -0
  39. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_config_automations.py +0 -0
  40. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
  41. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_config_entry_flow.py +0 -0
  42. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_config_info.py +0 -0
  43. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
  44. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_entities.py +0 -0
  45. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_filesystem.py +0 -0
  46. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_groups.py +0 -0
  47. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_hacs.py +0 -0
  48. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_history.py +0 -0
  49. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_integrations.py +0 -0
  50. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_labels.py +0 -0
  51. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_mcp_component.py +0 -0
  52. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_registry.py +0 -0
  53. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_resources.py +0 -0
  54. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_search.py +0 -0
  55. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_service.py +0 -0
  56. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_services.py +0 -0
  57. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_system.py +0 -0
  58. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_todo.py +0 -0
  59. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_traces.py +0 -0
  60. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_updates.py +0 -0
  61. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_utility.py +0 -0
  62. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
  63. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/tools_zones.py +0 -0
  64. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/tools/util_helpers.py +0 -0
  65. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/utils/__init__.py +0 -0
  66. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/utils/domain_handlers.py +0 -0
  67. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/utils/fuzzy_search.py +0 -0
  68. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/utils/operation_manager.py +0 -0
  69. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/utils/python_sandbox.py +0 -0
  70. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp/utils/usage_logger.py +0 -0
  71. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp_dev.egg-info/SOURCES.txt +0 -0
  72. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
  73. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
  74. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
  75. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
  76. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/tests/__init__.py +0 -0
  77. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/tests/test_constants.py +0 -0
  78. {ha_mcp_dev-6.7.1.dev230 → ha_mcp_dev-6.7.1.dev232}/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.1.dev230
3
+ Version: 6.7.1.dev232
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.1.dev230"
7
+ version = "6.7.1.dev232"
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"
@@ -174,10 +174,8 @@ version_variables = [
174
174
  "src/ha_mcp/__init__.py:__version__",
175
175
  ]
176
176
  build_command = """
177
- VERSION=$(grep '^version = ' pyproject.toml | sed 's/version = \"\\(.*\\)\"/\\1/')
178
- sed -i "s/^version: \\\".*\\\"/version: \\\"$VERSION\\\"/" homeassistant-addon/config.yaml
179
177
  pip install uv && uv lock
180
- git add homeassistant-addon/config.yaml uv.lock
178
+ git add uv.lock
181
179
  """
182
180
  dist_path = "dist/"
183
181
  upload_to_PyPI = true
@@ -656,56 +656,235 @@ def register_config_helper_tools(mcp: Any, client: Any, **kwargs: Any) -> None:
656
656
  context={"helper_type": helper_type},
657
657
  ))
658
658
 
659
- # For updates, we primarily use entity registry update
660
659
  entity_id = (
661
660
  helper_id
662
661
  if helper_id.startswith(helper_type)
663
662
  else f"{helper_type}.{helper_id}"
664
663
  )
665
664
 
666
- update_msg: dict[str, Any] = {
667
- "type": "config/entity_registry/update",
668
- "entity_id": entity_id,
669
- }
670
-
671
- if name:
672
- update_msg["name"] = name
673
- if icon:
674
- update_msg["icon"] = icon
675
- if area_id:
676
- update_msg["area_id"] = area_id
677
- if labels:
678
- update_msg["labels"] = labels
679
-
680
- result = await client.send_websocket_message(update_msg)
665
+ # Person, zone, and tag store config in separate config stores
666
+ # (not just the entity registry). Route updates accordingly.
667
+ # Person and zone have entity registry entries with unique_id
668
+ # used as the config store identifier. Tags use their own tag
669
+ # registry and don't have entity registry entries.
670
+ config_store_types = {"person", "zone"}
671
+
672
+ updated_data: dict[str, Any] = {}
673
+
674
+ if helper_type == "tag":
675
+ # Tags use their own registry — no entity registry entries.
676
+ # The helper_id IS the tag_id (strip "tag." prefix if present).
677
+ tag_update_id = (
678
+ helper_id.removeprefix("tag.")
679
+ if helper_id.startswith("tag.")
680
+ else helper_id
681
+ )
682
+ update_msg: dict[str, Any] = {
683
+ "type": "tag/update",
684
+ "tag_id": tag_update_id,
685
+ }
686
+ if name is not None:
687
+ update_msg["name"] = name
688
+ if description is not None:
689
+ update_msg["description"] = description
681
690
 
682
- if result.get("success"):
683
- entity_data = result.get("result", {}).get("entity_entry", {})
691
+ result = await client.send_websocket_message(update_msg)
692
+ if not result.get("success"):
693
+ raise_tool_error(create_error_response(
694
+ ErrorCode.SERVICE_CALL_FAILED,
695
+ f"Failed to update tag config: {result.get('error', 'Unknown error')}",
696
+ context={"helper_type": helper_type, "entity_id": entity_id},
697
+ ))
698
+ updated_data = result.get("result", {})
684
699
 
685
- # Wait for entity to reflect the update
686
- wait_bool = coerce_bool_param(wait, "wait", default=True)
687
- response: dict[str, Any] = {
700
+ # Tags don't have entity registry entries, so return directly
701
+ # without wait_for_entity_registered (they're not entities).
702
+ return {
688
703
  "success": True,
689
704
  "action": "update",
690
705
  "helper_type": helper_type,
691
706
  "entity_id": entity_id,
692
- "updated_data": entity_data,
707
+ "updated_data": updated_data,
693
708
  "message": f"Successfully updated {helper_type}: {entity_id}",
694
709
  }
695
- if wait_bool:
696
- try:
697
- registered = await wait_for_entity_registered(client, entity_id)
698
- if not registered:
699
- response["warning"] = f"Update applied but {entity_id} not yet queryable."
700
- except Exception as e:
701
- response["warning"] = f"Update applied but verification failed: {e}"
702
- return response
710
+
711
+ elif helper_type in config_store_types:
712
+ # Person and zone: look up unique_id from entity registry
713
+ registry_msg: dict[str, Any] = {
714
+ "type": "config/entity_registry/get",
715
+ "entity_id": entity_id,
716
+ }
717
+ registry_result = await client.send_websocket_message(
718
+ registry_msg
719
+ )
720
+ if not registry_result.get("success"):
721
+ raise_tool_error(create_error_response(
722
+ ErrorCode.ENTITY_NOT_FOUND,
723
+ f"Could not find {helper_type} entity: {entity_id}",
724
+ context={"helper_type": helper_type, "entity_id": entity_id},
725
+ ))
726
+ registry_entry = registry_result.get("result", {})
727
+ if not isinstance(registry_entry, dict):
728
+ raise_tool_error(create_error_response(
729
+ ErrorCode.INTERNAL_ERROR,
730
+ f"Unexpected registry response for {entity_id}",
731
+ context={"helper_type": helper_type, "entity_id": entity_id},
732
+ ))
733
+ unique_id = registry_entry.get("unique_id")
734
+ if not unique_id:
735
+ raise_tool_error(create_error_response(
736
+ ErrorCode.CONFIG_NOT_FOUND,
737
+ f"No unique_id found in entity registry for {entity_id}",
738
+ context={"helper_type": helper_type, "entity_id": entity_id},
739
+ ))
740
+
741
+ if helper_type == "person":
742
+ # Person config API is full-replace (not patch):
743
+ # fetch current config, merge with new values, then send.
744
+ list_result = await client.send_websocket_message(
745
+ {"type": "person/list"}
746
+ )
747
+ if not list_result.get("success"):
748
+ raise_tool_error(create_error_response(
749
+ ErrorCode.SERVICE_CALL_FAILED,
750
+ f"Failed to fetch person config list: {list_result.get('error', 'Unknown')}",
751
+ context={"helper_type": helper_type, "entity_id": entity_id},
752
+ ))
753
+
754
+ # person/list returns {"storage": [...], "config": [...]}
755
+ # "storage" contains UI-managed (editable) persons
756
+ person_result = list_result.get("result", {})
757
+ person_list = (
758
+ person_result.get("storage", [])
759
+ if isinstance(person_result, dict)
760
+ else person_result
761
+ )
762
+
763
+ current_config = next(
764
+ (
765
+ p for p in person_list
766
+ if isinstance(p, dict) and p.get("id") == unique_id
767
+ ),
768
+ None,
769
+ )
770
+
771
+ if not current_config:
772
+ raise_tool_error(create_error_response(
773
+ ErrorCode.CONFIG_NOT_FOUND,
774
+ f"Person config not found for id: {unique_id}",
775
+ context={"helper_type": helper_type, "entity_id": entity_id},
776
+ ))
777
+
778
+ # Merge: use new values if provided, else keep current
779
+ update_msg = {
780
+ "type": "person/update",
781
+ "person_id": unique_id,
782
+ "name": name if name is not None else current_config.get("name"),
783
+ "user_id": user_id
784
+ if user_id is not None
785
+ else current_config.get("user_id"),
786
+ "device_trackers": device_trackers
787
+ if device_trackers is not None
788
+ else current_config.get("device_trackers", []),
789
+ }
790
+ if picture is not None:
791
+ update_msg["picture"] = picture
792
+ elif current_config.get("picture"):
793
+ update_msg["picture"] = current_config["picture"]
794
+
795
+ result = await client.send_websocket_message(update_msg)
796
+ if not result.get("success"):
797
+ raise_tool_error(create_error_response(
798
+ ErrorCode.SERVICE_CALL_FAILED,
799
+ f"Failed to update person config: {result.get('error', 'Unknown error')}",
800
+ context={"helper_type": helper_type, "entity_id": entity_id},
801
+ ))
802
+ updated_data = result.get("result", {})
803
+
804
+ elif helper_type == "zone":
805
+ update_msg = {
806
+ "type": "zone/update",
807
+ "zone_id": unique_id,
808
+ }
809
+ if name is not None:
810
+ update_msg["name"] = name
811
+ if latitude is not None:
812
+ update_msg["latitude"] = latitude
813
+ if longitude is not None:
814
+ update_msg["longitude"] = longitude
815
+ if radius is not None:
816
+ update_msg["radius"] = radius
817
+ if passive is not None:
818
+ update_msg["passive"] = passive
819
+
820
+ result = await client.send_websocket_message(update_msg)
821
+ if not result.get("success"):
822
+ raise_tool_error(create_error_response(
823
+ ErrorCode.SERVICE_CALL_FAILED,
824
+ f"Failed to update zone config: {result.get('error', 'Unknown error')}",
825
+ context={"helper_type": helper_type, "entity_id": entity_id},
826
+ ))
827
+ updated_data = result.get("result", {})
828
+
829
+ # Also update entity registry for icon, area, and labels
830
+ if icon or area_id or labels:
831
+ registry_update: dict[str, Any] = {
832
+ "type": "config/entity_registry/update",
833
+ "entity_id": entity_id,
834
+ }
835
+ if icon:
836
+ registry_update["icon"] = icon
837
+ if area_id:
838
+ registry_update["area_id"] = area_id
839
+ if labels:
840
+ registry_update["labels"] = labels
841
+ await client.send_websocket_message(registry_update)
842
+
703
843
  else:
704
- raise_tool_error(create_error_response(
705
- ErrorCode.SERVICE_CALL_FAILED,
706
- f"Failed to update helper: {result.get('error', 'Unknown error')}",
707
- context={"helper_type": helper_type, "entity_id": entity_id},
708
- ))
844
+ # Standard helpers: entity registry update only
845
+ update_msg = {
846
+ "type": "config/entity_registry/update",
847
+ "entity_id": entity_id,
848
+ }
849
+
850
+ if name is not None:
851
+ update_msg["name"] = name
852
+ if icon:
853
+ update_msg["icon"] = icon
854
+ if area_id:
855
+ update_msg["area_id"] = area_id
856
+ if labels:
857
+ update_msg["labels"] = labels
858
+
859
+ result = await client.send_websocket_message(update_msg)
860
+
861
+ if result.get("success"):
862
+ updated_data = result.get("result", {}).get("entity_entry", {})
863
+ else:
864
+ raise_tool_error(create_error_response(
865
+ ErrorCode.SERVICE_CALL_FAILED,
866
+ f"Failed to update helper: {result.get('error', 'Unknown error')}",
867
+ context={"helper_type": helper_type, "entity_id": entity_id},
868
+ ))
869
+
870
+ # Wait for entity to reflect the update
871
+ wait_bool = coerce_bool_param(wait, "wait", default=True)
872
+ response: dict[str, Any] = {
873
+ "success": True,
874
+ "action": "update",
875
+ "helper_type": helper_type,
876
+ "entity_id": entity_id,
877
+ "updated_data": updated_data,
878
+ "message": f"Successfully updated {helper_type}: {entity_id}",
879
+ }
880
+ if wait_bool:
881
+ try:
882
+ registered = await wait_for_entity_registered(client, entity_id)
883
+ if not registered:
884
+ response["warning"] = f"Update applied but {entity_id} not yet queryable."
885
+ except Exception as e:
886
+ response["warning"] = f"Update applied but verification failed: {e}"
887
+ return response
709
888
 
710
889
  # This should never be reached since action is either "create" or "update"
711
890
  raise_tool_error(create_error_response(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ha-mcp-dev
3
- Version: 6.7.1.dev230
3
+ Version: 6.7.1.dev232
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