ha-mcp-dev 6.7.2.dev248__tar.gz → 6.7.2.dev250__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.dev250}/PKG-INFO +1 -1
  2. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/pyproject.toml +1 -1
  3. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/client/rest_client.py +55 -12
  4. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_search.py +35 -1
  5. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250/src/ha_mcp_dev.egg-info}/PKG-INFO +1 -1
  6. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/LICENSE +0 -0
  7. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/MANIFEST.in +0 -0
  8. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/README.md +0 -0
  9. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/setup.cfg +0 -0
  10. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/__init__.py +0 -0
  11. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/__main__.py +0 -0
  12. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/_pypi_marker +0 -0
  13. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/auth/__init__.py +0 -0
  14. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/auth/consent_form.py +0 -0
  15. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/auth/provider.py +0 -0
  16. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/client/__init__.py +0 -0
  17. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/client/websocket_client.py +0 -0
  18. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/client/websocket_listener.py +0 -0
  19. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/config.py +0 -0
  20. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/errors.py +0 -0
  21. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/py.typed +0 -0
  22. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/resources/card_types.json +0 -0
  23. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/resources/dashboard_guide.md +0 -0
  24. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
  25. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
  26. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
  27. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
  28. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
  29. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
  30. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
  31. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
  32. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
  33. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
  34. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
  35. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
  36. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
  37. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
  38. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
  39. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
  40. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/server.py +0 -0
  41. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/smoke_test.py +0 -0
  42. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/__init__.py +0 -0
  43. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/backup.py +0 -0
  44. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/device_control.py +0 -0
  45. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/enhanced.py +0 -0
  46. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/helpers.py +0 -0
  47. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/registry.py +0 -0
  48. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/smart_search.py +0 -0
  49. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_addons.py +0 -0
  50. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_areas.py +0 -0
  51. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_blueprints.py +0 -0
  52. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_bug_report.py +0 -0
  53. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_calendar.py +0 -0
  54. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_camera.py +0 -0
  55. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_config_automations.py +0 -0
  56. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
  57. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_config_entry_flow.py +0 -0
  58. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
  59. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_config_info.py +0 -0
  60. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
  61. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_entities.py +0 -0
  62. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_filesystem.py +0 -0
  63. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_groups.py +0 -0
  64. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_hacs.py +0 -0
  65. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_history.py +0 -0
  66. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_integrations.py +0 -0
  67. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_labels.py +0 -0
  68. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_mcp_component.py +0 -0
  69. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_registry.py +0 -0
  70. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_resources.py +0 -0
  71. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_service.py +0 -0
  72. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_services.py +0 -0
  73. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_system.py +0 -0
  74. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_todo.py +0 -0
  75. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_traces.py +0 -0
  76. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_updates.py +0 -0
  77. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_utility.py +0 -0
  78. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
  79. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/tools_zones.py +0 -0
  80. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/tools/util_helpers.py +0 -0
  81. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/utils/__init__.py +0 -0
  82. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/utils/domain_handlers.py +0 -0
  83. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/utils/fuzzy_search.py +0 -0
  84. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/utils/operation_manager.py +0 -0
  85. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/utils/python_sandbox.py +0 -0
  86. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp/utils/usage_logger.py +0 -0
  87. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/src/ha_mcp_dev.egg-info/SOURCES.txt +0 -0
  88. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/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.dev250}/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.dev250}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
  91. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/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.dev250}/tests/__init__.py +0 -0
  93. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/tests/test_constants.py +0 -0
  94. {ha_mcp_dev-6.7.2.dev248 → ha_mcp_dev-6.7.2.dev250}/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.dev250
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.dev250"
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. "
@@ -492,11 +492,19 @@ def register_search_tools(mcp: Any, client: Any, **kwargs: Any) -> None:
492
492
  description="Include entity_id field for entities (None = auto based on level). Full defaults to True.",
493
493
  ),
494
494
  ] = None,
495
+ include_notifications: Annotated[
496
+ bool | str | None,
497
+ Field(
498
+ default=True,
499
+ description="Include active persistent notifications (default: True). Set False to skip.",
500
+ ),
501
+ ] = True,
495
502
  ) -> dict[str, Any]:
496
503
  """Get AI-friendly system overview with intelligent categorization.
497
504
 
498
505
  Returns comprehensive system information at the requested detail level,
499
- including Home Assistant base_url, version, location, timezone, and entity overview.
506
+ including Home Assistant base_url, version, location, timezone, entity overview,
507
+ and active persistent notifications (if any).
500
508
  Use 'standard' (default) for most queries. Optionally customize entity fields and limits.
501
509
  """
502
510
  # Coerce boolean parameters that may come as strings from XML-style calls
@@ -506,6 +514,9 @@ def register_search_tools(mcp: Any, client: Any, **kwargs: Any) -> None:
506
514
  include_entity_id_bool = coerce_bool_param(
507
515
  include_entity_id, "include_entity_id", default=None
508
516
  )
517
+ include_notifications_bool = coerce_bool_param(
518
+ include_notifications, "include_notifications", default=True
519
+ )
509
520
 
510
521
  result = await smart_tools.get_system_overview(
511
522
  detail_level,
@@ -544,6 +555,29 @@ def register_search_tools(mcp: Any, client: Any, **kwargs: Any) -> None:
544
555
  except Exception as e:
545
556
  logger.warning(f"Failed to fetch system info for overview: {e}")
546
557
 
558
+ # Include active persistent notifications
559
+ if include_notifications_bool:
560
+ result["notification_count"] = 0
561
+ try:
562
+ ws_result = await client.send_websocket_message(
563
+ {"type": "persistent_notification/get"}
564
+ )
565
+ if ws_result.get("success"):
566
+ notifications = ws_result.get("result", [])
567
+ result["notification_count"] = len(notifications)
568
+ if notifications:
569
+ result["notifications"] = [
570
+ {
571
+ "notification_id": n.get("notification_id"),
572
+ "title": n.get("title"),
573
+ "message": n.get("message"),
574
+ "created_at": n.get("created_at"),
575
+ }
576
+ for n in notifications
577
+ ]
578
+ except Exception as e:
579
+ logger.debug(f"Failed to fetch notifications for overview: {e}")
580
+
547
581
  return result
548
582
 
549
583
  @mcp.tool(
@@ -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.dev250
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