Skip to content

Commit 157db90

Browse files
committed
Merge branch 'pr-960' into addon-repo
2 parents 8aa176e + 0089c27 commit 157db90

4 files changed

Lines changed: 617 additions & 1 deletion

File tree

src/ha_mcp/config.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,12 @@ class Settings(BaseSettings):
112112
# files. Disabled by default; only for YAML-only features with no UI/API path.
113113
enable_yaml_config_editing: bool = Field(False, alias="ENABLE_YAML_CONFIG_EDITING")
114114

115+
# Seed values for tool visibility (comma-separated tool names).
116+
# Used as initial config when no tool_config.json exists.
117+
# The web settings UI (/settings) is the primary interface for managing these.
118+
disabled_tools: str = Field("", alias="DISABLED_TOOLS")
119+
pinned_tools: str = Field("", alias="PINNED_TOOLS")
120+
115121
@model_validator(mode="after")
116122
def _skills_dependency(self) -> "Settings":
117123
"""Auto-enable skills (resources) when skills-as-tools is on.

src/ha_mcp/server.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ def _initialize_server(self) -> None:
143143
# Register bundled skills as MCP resources
144144
self._register_skills()
145145

146+
# Apply user-configured tool visibility (after all tools registered,
147+
# before tool search transform wraps them)
148+
self._apply_settings_ui()
149+
146150
# Apply tool search transform (must come after all tools and
147151
# ResourcesAsTools are registered so it can wrap everything)
148152
self._apply_tool_search()
@@ -306,6 +310,23 @@ def _build_skill_block(self, skill_name: str, main_file: Path) -> str | None:
306310

307311
return f"\n### Skill: {skill_name} ({uri})\n{description.strip()}"
308312

313+
def _apply_settings_ui(self) -> None:
314+
"""Register settings web UI and apply persisted tool visibility."""
315+
from .settings_ui import (
316+
apply_tool_visibility,
317+
load_tool_config,
318+
register_settings_routes,
319+
)
320+
321+
register_settings_routes(self.mcp, self)
322+
323+
config = load_tool_config(self.settings)
324+
if config:
325+
pinned = apply_tool_visibility(self.mcp, config, self.settings)
326+
if pinned:
327+
self._user_pinned_tools = list(pinned)
328+
logger.info("Applied persisted tool config (%d entries)", len(config.get("tools", {})))
329+
309330
# Tools pinned outside the search transform for individual permission gating.
310331
# These are always visible in list_tools() regardless of search transform.
311332
_PINNED_TOOLS: ClassVar[list[str]] = list(DEFAULT_PINNED_TOOLS)
@@ -419,8 +440,9 @@ def _apply_tool_search(self) -> None:
419440
)
420441
return
421442

422-
# Build the always_visible list
443+
# Build the always_visible list: defaults + user-configured pins
423444
pinned = list(self._PINNED_TOOLS)
445+
pinned.extend(getattr(self, "_user_pinned_tools", []))
424446

425447
# Pin ResourcesAsTools and skill guidance tools if skills-as-tools is enabled
426448
if self.settings.enable_skills_as_tools:

0 commit comments

Comments
 (0)