ha-mcp-dev 7.5.0.dev538__tar.gz → 7.5.0.dev539__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 (111) hide show
  1. {ha_mcp_dev-7.5.0.dev538/src/ha_mcp_dev.egg-info → ha_mcp_dev-7.5.0.dev539}/PKG-INFO +1 -1
  2. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/pyproject.toml +1 -1
  3. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_system.py +81 -12
  4. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539/src/ha_mcp_dev.egg-info}/PKG-INFO +1 -1
  5. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/LICENSE +0 -0
  6. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/MANIFEST.in +0 -0
  7. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/README.md +0 -0
  8. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/setup.cfg +0 -0
  9. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/__init__.py +0 -0
  10. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/__main__.py +0 -0
  11. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/_pypi_marker +0 -0
  12. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/_version.py +0 -0
  13. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/auth/__init__.py +0 -0
  14. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/auth/consent_form.py +0 -0
  15. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/auth/provider.py +0 -0
  16. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/client/__init__.py +0 -0
  17. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/client/rest_client.py +0 -0
  18. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/client/supervisor_client.py +0 -0
  19. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/client/websocket_client.py +0 -0
  20. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/client/websocket_listener.py +0 -0
  21. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/config.py +0 -0
  22. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/errors.py +0 -0
  23. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/py.typed +0 -0
  24. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
  25. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
  26. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
  27. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
  28. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
  29. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
  30. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
  31. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
  32. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
  33. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
  34. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/evals/evals.json +0 -0
  35. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
  36. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +0 -0
  37. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +0 -0
  38. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
  39. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +0 -0
  40. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
  41. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
  42. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
  43. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
  44. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/server.py +0 -0
  45. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/settings_ui.py +0 -0
  46. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/smoke_test.py +0 -0
  47. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/__init__.py +0 -0
  48. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/backup.py +0 -0
  49. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/best_practice_checker.py +0 -0
  50. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/device_control.py +0 -0
  51. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/enhanced.py +0 -0
  52. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/helpers.py +0 -0
  53. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/reference_validator.py +0 -0
  54. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/registry.py +0 -0
  55. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/smart_search.py +0 -0
  56. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_addons.py +0 -0
  57. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_areas.py +0 -0
  58. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_blueprints.py +0 -0
  59. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_bug_report.py +0 -0
  60. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_calendar.py +0 -0
  61. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_camera.py +0 -0
  62. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_categories.py +0 -0
  63. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_code.py +0 -0
  64. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_config_automations.py +0 -0
  65. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
  66. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_config_entry_flow.py +0 -0
  67. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
  68. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_config_scenes.py +0 -0
  69. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
  70. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_energy.py +0 -0
  71. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_entities.py +0 -0
  72. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_filesystem.py +0 -0
  73. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_groups.py +0 -0
  74. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_hacs.py +0 -0
  75. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_history.py +0 -0
  76. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_integrations.py +0 -0
  77. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_labels.py +0 -0
  78. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_mcp_component.py +0 -0
  79. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_registry.py +0 -0
  80. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_resources.py +0 -0
  81. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_search.py +0 -0
  82. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_service.py +0 -0
  83. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_services.py +0 -0
  84. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_todo.py +0 -0
  85. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_traces.py +0 -0
  86. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_updates.py +0 -0
  87. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_utility.py +0 -0
  88. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
  89. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
  90. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/tools_zones.py +0 -0
  91. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/tools/util_helpers.py +0 -0
  92. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/transforms/__init__.py +0 -0
  93. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/transforms/categorized_search.py +0 -0
  94. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/transforms/lite_docstrings.py +0 -0
  95. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/utils/__init__.py +0 -0
  96. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/utils/config_hash.py +0 -0
  97. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/utils/data_paths.py +0 -0
  98. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/utils/domain_handlers.py +0 -0
  99. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/utils/fuzzy_search.py +0 -0
  100. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
  101. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/utils/operation_manager.py +0 -0
  102. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/utils/python_sandbox.py +0 -0
  103. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp/utils/usage_logger.py +0 -0
  104. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp_dev.egg-info/SOURCES.txt +0 -0
  105. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
  106. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
  107. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
  108. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
  109. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/tests/__init__.py +0 -0
  110. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/tests/test_constants.py +0 -0
  111. {ha_mcp_dev-7.5.0.dev538 → ha_mcp_dev-7.5.0.dev539}/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: 7.5.0.dev538
3
+ Version: 7.5.0.dev539
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 = "7.5.0.dev538"
7
+ version = "7.5.0.dev539"
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"
@@ -7,7 +7,9 @@ This module provides tools for Home Assistant system administration including:
7
7
  - System health monitoring
8
8
  """
9
9
 
10
+ import asyncio
10
11
  import logging
12
+ from collections.abc import Coroutine
11
13
  from typing import Any
12
14
 
13
15
  from fastmcp.exceptions import ToolError
@@ -376,22 +378,89 @@ class SystemTools:
376
378
  if unknown:
377
379
  result["warning"] = f"Unknown include sections ignored: {', '.join(sorted(unknown))}"
378
380
 
379
- # Fetch optional sections
380
- if "repairs" in includes:
381
- result["repairs"] = await self._fetch_repairs(
382
- ws_client,
383
- include_dismissed=include_dismissed_repairs_bool,
384
- )
385
-
381
+ # Fetch optional sections concurrently. The ws_client serialises
382
+ # outgoing writes via its internal `_send_lock`, but per-message
383
+ # futures keyed by message_id let response waits overlap — so this
384
+ # gives request pipelining instead of head-of-line blocking.
385
+ #
386
+ # Each ``_fetch_*`` helper already returns an embeddable sub-dict
387
+ # with an ``error`` field on backend failure (it never raises);
388
+ # ``return_exceptions=True`` is belt-and-suspenders against a future
389
+ # helper edit that lets an exception escape.
386
390
  zha_full = "zha_network_full" in includes
387
391
  zha_summary = "zha_network" in includes
388
- if zha_full or zha_summary:
389
- result["zha_network"] = await self._fetch_zha_network(
390
- ws_client, full=zha_full
392
+ want_repairs = "repairs" in includes
393
+ want_zha = zha_full or zha_summary
394
+ want_zwave = "zwave_network" in includes
395
+
396
+ sections: list[tuple[str, Coroutine[Any, Any, dict[str, Any]]]] = []
397
+ if want_repairs:
398
+ sections.append(
399
+ (
400
+ "repairs",
401
+ self._fetch_repairs(
402
+ ws_client,
403
+ include_dismissed=include_dismissed_repairs_bool,
404
+ ),
405
+ )
406
+ )
407
+ if want_zha:
408
+ sections.append(
409
+ ("zha_network", self._fetch_zha_network(ws_client, full=zha_full))
410
+ )
411
+ if want_zwave:
412
+ sections.append(
413
+ ("zwave_network", self._fetch_zwave_network(ws_client))
391
414
  )
392
415
 
393
- if "zwave_network" in includes:
394
- result["zwave_network"] = await self._fetch_zwave_network(ws_client)
416
+ if sections:
417
+ gathered = await asyncio.gather(
418
+ *[coro for _, coro in sections], return_exceptions=True
419
+ )
420
+ # Pre-pass: re-raise anything that must unwind the request
421
+ # rather than land as an embedded section error. ``gather``
422
+ # with ``return_exceptions=True`` returns ``CancelledError``
423
+ # (and any other ``BaseException``) as a result element
424
+ # instead of propagating, and a ``ToolError`` raised from
425
+ # inside a helper would otherwise be silently demoted to
426
+ # ``{"error": "ToolError: …"}`` and break the MCP
427
+ # ``isError=true`` contract for the whole tool.
428
+ for section_result in gathered:
429
+ if isinstance(section_result, asyncio.CancelledError):
430
+ raise section_result
431
+ if isinstance(section_result, ToolError):
432
+ raise section_result
433
+ if isinstance(section_result, BaseException) and not isinstance(
434
+ section_result, Exception
435
+ ):
436
+ # ``KeyboardInterrupt`` / ``SystemExit`` — never demote
437
+ # these to a section-level error string.
438
+ raise section_result
439
+ for (section_name, _), section_result in zip(
440
+ sections, gathered, strict=True
441
+ ):
442
+ if isinstance(section_result, Exception):
443
+ # Last-resort fallback: emit a minimal ``{error: ...}``
444
+ # dict so an unexpected exception attributes to its
445
+ # section instead of bubbling out and dropping siblings.
446
+ # The helpers themselves return richer
447
+ # ``{<key>: <baseline>, ..., error: ...}`` shapes on
448
+ # their own (caught) failures; this branch is the
449
+ # belt-and-suspenders path that fires only on a
450
+ # helper-edit regression that lets an exception escape.
451
+ logger.warning(
452
+ "Concurrent fetch for section %r raised: %s: %s",
453
+ section_name,
454
+ type(section_result).__name__,
455
+ section_result,
456
+ )
457
+ result[section_name] = {
458
+ "error": (
459
+ f"{type(section_result).__name__}: {section_result}"
460
+ )
461
+ }
462
+ else:
463
+ result[section_name] = section_result
395
464
 
396
465
  return result
397
466
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ha-mcp-dev
3
- Version: 7.5.0.dev538
3
+ Version: 7.5.0.dev539
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