ha-mcp-dev 7.6.0.dev623__tar.gz → 7.6.0.dev624__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.
- {ha_mcp_dev-7.6.0.dev623/src/ha_mcp_dev.egg-info → ha_mcp_dev-7.6.0.dev624}/PKG-INFO +1 -1
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/pyproject.toml +1 -1
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/server.py +6 -0
- ha_mcp_dev-7.6.0.dev624/src/ha_mcp/tools/validation_middleware.py +57 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624/src/ha_mcp_dev.egg-info}/PKG-INFO +1 -1
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp_dev.egg-info/SOURCES.txt +1 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/LICENSE +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/MANIFEST.in +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/README.md +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/setup.cfg +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/__main__.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/_pypi_marker +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/_version.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/auth/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/auth/consent_form.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/auth/provider.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/backup_manager.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/client/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/client/rest_client.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/client/supervisor_client.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/client/websocket_client.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/client/websocket_listener.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/config.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/errors.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/policy/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/policy/approval_queue.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/policy/evaluator.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/policy/handlers.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/policy/middleware.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/policy/model.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/policy/persistence.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/policy/value_sources.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/py.typed +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/.github/pull_request_template.md +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/evals/evals.json +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/yaml-only-integrations.md +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/settings_ui.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/smoke_test.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/stdio_settings_sidecar.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/auto_backup.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/backup.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/best_practice_checker.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/device_control.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/enhanced.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/helpers.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/reference_validator.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/registry.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/smart_search.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_addons.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_areas.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_blueprints.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_bug_report.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_calendar.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_camera.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_categories.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_code.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_config_automations.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_config_entry_flow.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_config_scenes.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_energy.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_entities.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_filesystem.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_groups.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_hacs.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_history.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_integrations.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_labels.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_mcp_component.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_registry.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_resources.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_search.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_service.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_services.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_system.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_todo.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_traces.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_updates.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_utility.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_zones.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/util_helpers.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/transforms/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/transforms/categorized_search.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/transforms/lite_docstrings.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/utils/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/utils/config_hash.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/utils/data_paths.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/utils/domain_handlers.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/utils/fuzzy_search.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/utils/operation_manager.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/utils/python_sandbox.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/utils/skill_loader.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/utils/usage_logger.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/tests/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/tests/test_constants.py +0 -0
- {ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/tests/test_env_manager.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ha-mcp-dev"
|
|
7
|
-
version = "7.6.0.
|
|
7
|
+
version = "7.6.0.dev624"
|
|
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"
|
|
@@ -190,6 +190,12 @@ class HomeAssistantSmartMCPServer(EnhancedToolsMixin):
|
|
|
190
190
|
# the skill guide tool are registered so it can wrap everything)
|
|
191
191
|
self._apply_tool_search()
|
|
192
192
|
|
|
193
|
+
# Convert Pydantic type-validation errors to structured ToolErrors so
|
|
194
|
+
# models get actionable guidance instead of raw Pydantic messages.
|
|
195
|
+
from .tools.validation_middleware import ValidationErrorMiddleware
|
|
196
|
+
|
|
197
|
+
self.mcp.add_middleware(ValidationErrorMiddleware())
|
|
198
|
+
|
|
193
199
|
# Wire tool security policies middleware (#966) — opt-in via
|
|
194
200
|
# ENABLE_TOOL_SECURITY_POLICIES. Must come last so the middleware
|
|
195
201
|
# wraps the final tool surface (including the search proxies).
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""FastMCP middleware that converts Pydantic validation errors to structured ToolErrors.
|
|
2
|
+
|
|
3
|
+
When a model passes the wrong type for a tool parameter (e.g. a JSON string where
|
|
4
|
+
a dict is required), FastMCP raises a PydanticValidationError with a raw message
|
|
5
|
+
like "Input should be a valid dictionary". This middleware intercepts those errors
|
|
6
|
+
and converts them to ha-mcp's structured format with actionable guidance.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import logging
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
from fastmcp.server.middleware.middleware import CallNext, Middleware, MiddlewareContext
|
|
15
|
+
from pydantic import ValidationError as PydanticValidationError
|
|
16
|
+
|
|
17
|
+
from ..errors import create_validation_error
|
|
18
|
+
from .helpers import raise_tool_error
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
# Maps Pydantic error types to model-readable fix hints.
|
|
23
|
+
# FastMCP uses non-strict Pydantic: scalar mismatches (bool, int) are coerced
|
|
24
|
+
# rather than rejected, so only dict_type and list_type fire in practice.
|
|
25
|
+
_TYPE_HINTS: dict[str, str] = {
|
|
26
|
+
"dict_type": (
|
|
27
|
+
"expected a JSON object. "
|
|
28
|
+
'Pass {"key": "value"} directly, not a JSON-encoded string.'
|
|
29
|
+
),
|
|
30
|
+
"list_type": (
|
|
31
|
+
"expected a JSON array. Pass [...] directly, not a JSON-encoded string."
|
|
32
|
+
),
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class ValidationErrorMiddleware(Middleware):
|
|
37
|
+
"""Convert PydanticValidationError from argument validation into ToolErrors."""
|
|
38
|
+
|
|
39
|
+
async def on_call_tool(
|
|
40
|
+
self, context: MiddlewareContext, call_next: CallNext
|
|
41
|
+
) -> Any:
|
|
42
|
+
try:
|
|
43
|
+
return await call_next(context)
|
|
44
|
+
except PydanticValidationError as exc:
|
|
45
|
+
errors = exc.errors(include_url=False)
|
|
46
|
+
parts: list[str] = []
|
|
47
|
+
for err in errors:
|
|
48
|
+
loc = err.get("loc", ())
|
|
49
|
+
param = ".".join(str(p) for p in loc if p != "__root__")
|
|
50
|
+
hint = _TYPE_HINTS.get(err["type"], err["msg"])
|
|
51
|
+
parts.append(f"`{param}`: {hint}" if param else hint)
|
|
52
|
+
raise_tool_error(
|
|
53
|
+
create_validation_error(
|
|
54
|
+
"; ".join(parts) if parts else "Invalid argument types.",
|
|
55
|
+
details=", ".join(err["type"] for err in errors),
|
|
56
|
+
)
|
|
57
|
+
)
|
|
@@ -99,6 +99,7 @@ src/ha_mcp/tools/tools_voice_assistant.py
|
|
|
99
99
|
src/ha_mcp/tools/tools_yaml_config.py
|
|
100
100
|
src/ha_mcp/tools/tools_zones.py
|
|
101
101
|
src/ha_mcp/tools/util_helpers.py
|
|
102
|
+
src/ha_mcp/tools/validation_middleware.py
|
|
102
103
|
src/ha_mcp/transforms/__init__.py
|
|
103
104
|
src/ha_mcp/transforms/categorized_search.py
|
|
104
105
|
src/ha_mcp/transforms/lite_docstrings.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/AGENTS.md
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/CLAUDE.md
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/LICENSE
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/resources/skills-vendor/README.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/best_practice_checker.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_config_automations.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_config_dashboards.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_config_entry_flow.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_config_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_config_scripts.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/tools/tools_voice_assistant.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/transforms/categorized_search.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/transforms/lite_docstrings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp/utils/kill_signal_diagnostics.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp_dev.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev623 → ha_mcp_dev-7.6.0.dev624}/src/ha_mcp_dev.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|