ha-mcp-dev 7.1.0.dev294__tar.gz → 7.1.0.dev296__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 (97) hide show
  1. {ha_mcp_dev-7.1.0.dev294/src/ha_mcp_dev.egg-info → ha_mcp_dev-7.1.0.dev296}/PKG-INFO +1 -1
  2. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/pyproject.toml +1 -1
  3. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/__main__.py +51 -9
  4. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296/src/ha_mcp_dev.egg-info}/PKG-INFO +1 -1
  5. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/LICENSE +0 -0
  6. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/MANIFEST.in +0 -0
  7. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/README.md +0 -0
  8. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/setup.cfg +0 -0
  9. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/__init__.py +0 -0
  10. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/_pypi_marker +0 -0
  11. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/auth/__init__.py +0 -0
  12. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/auth/consent_form.py +0 -0
  13. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/auth/provider.py +0 -0
  14. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/client/__init__.py +0 -0
  15. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/client/rest_client.py +0 -0
  16. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/client/websocket_client.py +0 -0
  17. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/client/websocket_listener.py +0 -0
  18. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/config.py +0 -0
  19. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/errors.py +0 -0
  20. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/py.typed +0 -0
  21. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/resources/card_types.json +0 -0
  22. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/resources/dashboard_guide.md +0 -0
  23. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
  24. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
  25. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
  26. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
  27. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
  28. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
  29. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
  30. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
  31. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
  32. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
  33. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
  34. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
  35. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
  36. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
  37. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
  38. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
  39. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/server.py +0 -0
  40. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/smoke_test.py +0 -0
  41. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/__init__.py +0 -0
  42. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/backup.py +0 -0
  43. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/best_practice_checker.py +0 -0
  44. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/device_control.py +0 -0
  45. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/enhanced.py +0 -0
  46. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/helpers.py +0 -0
  47. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/registry.py +0 -0
  48. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/smart_search.py +0 -0
  49. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_addons.py +0 -0
  50. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_areas.py +0 -0
  51. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_blueprints.py +0 -0
  52. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_bug_report.py +0 -0
  53. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_calendar.py +0 -0
  54. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_camera.py +0 -0
  55. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_config_automations.py +0 -0
  56. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
  57. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_config_entry_flow.py +0 -0
  58. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
  59. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_config_info.py +0 -0
  60. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
  61. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_entities.py +0 -0
  62. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_filesystem.py +0 -0
  63. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_groups.py +0 -0
  64. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_hacs.py +0 -0
  65. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_history.py +0 -0
  66. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_integrations.py +0 -0
  67. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_labels.py +0 -0
  68. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_mcp_component.py +0 -0
  69. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_registry.py +0 -0
  70. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_resources.py +0 -0
  71. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_search.py +0 -0
  72. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_service.py +0 -0
  73. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_services.py +0 -0
  74. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_system.py +0 -0
  75. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_todo.py +0 -0
  76. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_traces.py +0 -0
  77. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_updates.py +0 -0
  78. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_utility.py +0 -0
  79. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
  80. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/tools_zones.py +0 -0
  81. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/tools/util_helpers.py +0 -0
  82. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/transforms/__init__.py +0 -0
  83. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/transforms/categorized_search.py +0 -0
  84. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/utils/__init__.py +0 -0
  85. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/utils/domain_handlers.py +0 -0
  86. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/utils/fuzzy_search.py +0 -0
  87. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/utils/operation_manager.py +0 -0
  88. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/utils/python_sandbox.py +0 -0
  89. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp/utils/usage_logger.py +0 -0
  90. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp_dev.egg-info/SOURCES.txt +0 -0
  91. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
  92. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
  93. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
  94. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
  95. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/tests/__init__.py +0 -0
  96. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/tests/test_constants.py +0 -0
  97. {ha_mcp_dev-7.1.0.dev294 → ha_mcp_dev-7.1.0.dev296}/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.1.0.dev294
3
+ Version: 7.1.0.dev296
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.1.0.dev294"
7
+ version = "7.1.0.dev296"
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"
@@ -325,6 +325,27 @@ mcp = _DeferredMCP()
325
325
  _LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
326
326
 
327
327
 
328
+ class StatelessSessionLogFilter(logging.Filter):
329
+ """Downgrade 'Terminating session: None' to DEBUG to reduce user confusion.
330
+
331
+ In stateless HTTP mode every request creates and tears down a temporary
332
+ session, producing an INFO log that looks alarming but is routine.
333
+ This filter lowers the level to DEBUG so the message only appears with
334
+ verbose logging enabled.
335
+
336
+ # TODO: remove when modelcontextprotocol/python-sdk#2329 is resolved
337
+ """
338
+
339
+ def filter(self, record: logging.LogRecord) -> bool:
340
+ if (
341
+ record.name == "mcp.server.streamable_http"
342
+ and "Terminating session: None" in record.getMessage()
343
+ ):
344
+ record.levelno = logging.DEBUG
345
+ record.levelname = "DEBUG"
346
+ return True
347
+
348
+
328
349
  def _setup_logging(log_level_str: str, force: bool = False) -> None:
329
350
  """Configure root logger with consistent timestamp format."""
330
351
  logging.basicConfig(
@@ -333,6 +354,9 @@ def _setup_logging(log_level_str: str, force: bool = False) -> None:
333
354
  datefmt=_LOG_DATE_FORMAT,
334
355
  force=force,
335
356
  )
357
+ logging.getLogger("mcp.server.streamable_http").addFilter(
358
+ StatelessSessionLogFilter()
359
+ )
336
360
 
337
361
 
338
362
  def _get_timestamped_uvicorn_log_config() -> dict:
@@ -590,18 +614,36 @@ def register_browser_landing(mcp_instance: "FastMCP | _DeferredMCP", path: str)
590
614
  return
591
615
  _registered_landing_paths.add(path)
592
616
 
593
- # Safe because the MCP streamable-http transport claims only POST and DELETE.
594
- # FastMCP registers custom routes at lowest precedence (after the MCP route),
595
- # so GET requests fall through here without intercepting MCP traffic.
617
+ _landing_message = (
618
+ "HA-MCP server is up and running!\n"
619
+ "\n"
620
+ "To connect, paste the full URL (including the /private_... key) into the\n"
621
+ "connector or MCP settings of your AI/LLM client. No username or password required.\n"
622
+ "Setup instructions: https://homeassistant-ai.github.io/ha-mcp/\n"
623
+ "\n"
624
+ "--- Cloudflare Users ---\n"
625
+ "\n"
626
+ 'If your LLM cannot connect, Cloudflare\'s "Block AI training bots"\n'
627
+ "setting is the most common cause. To disable it:\n"
628
+ "\n"
629
+ "1. Log in to Cloudflare (https://dash.cloudflare.com)\n"
630
+ "2. In the left sidebar, click Domains, then click Overview\n"
631
+ "3. Click on the domain you use for connecting to Home Assistant\n"
632
+ '4. On the right side, find "Control AI Crawlers"\n'
633
+ '5. Under "Block AI training bots", open the dropdown\n'
634
+ '6. Select "do not block (allow crawlers)"\n'
635
+ "\n"
636
+ "Screenshot of the setting:\n"
637
+ "https://homeassistant-ai.github.io/ha-mcp/images/cloudflare-ai-crawlers-setting.jpg\n"
638
+ )
639
+
640
+ # Safe because FastMCP registers the MCP route with methods=["POST", "DELETE"]
641
+ # in stateless mode, so Starlette rejects GET requests before the MCP handler runs.
642
+ # Custom routes are registered at lowest precedence (after the MCP route).
596
643
  @mcp_instance.custom_route(path, methods=["GET"])
597
644
  async def _browser_landing(_: Request) -> PlainTextResponse:
598
645
  return PlainTextResponse(
599
- "HA-MCP server is up and running. To connect, please follow the "
600
- "setup instructions (https://homeassistant-ai.github.io/ha-mcp/), "
601
- "and paste the URL for this page into your LLM. If using Cloudflare "
602
- "and you're unable to connect via your LLM, make sure the "
603
- '"Block AI training bots" setting is set to '
604
- '"do not block (allow crawlers)".',
646
+ _landing_message,
605
647
  status_code=405,
606
648
  # DELETE is included per the MCP Streamable HTTP spec (used for
607
649
  # session termination), even though this deployment uses stateless mode.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ha-mcp-dev
3
- Version: 7.1.0.dev294
3
+ Version: 7.1.0.dev296
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