Skip to content

Commit 42a7026

Browse files
committed
Merge branch 'pr-854' into addon-repo
2 parents c4bc267 + 1b0db62 commit 42a7026

6 files changed

Lines changed: 995 additions & 0 deletions

File tree

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ dependencies = [
3131
"truststore==0.10.4",
3232
"websockets==16.0",
3333
"cryptography==46.0.6",
34+
"pydantic-monty==0.0.9",
3435
]
3536

3637
[project.urls]
@@ -75,6 +76,8 @@ explicit_package_bases = true
7576
module = [
7677
"fastmcp.*",
7778
"jq",
79+
"pydantic_monty",
80+
"pydantic_monty.*",
7881
]
7982
ignore_missing_imports = true
8083

src/ha_mcp/config.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,17 @@ 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+
# Code Mode — sandboxed Python execution via pydantic-monty.
116+
# Provides an "escape hatch" tool (ha_manage_custom_tool) that lets LLMs write
117+
# custom one-off Python code when no existing tool covers the request.
118+
# Disabled by default due to the inherent risk of LLM-generated code.
119+
enable_code_mode: bool = Field(False, alias="ENABLE_CODE_MODE")
120+
code_mode_max_duration: float = Field(30.0, alias="CODE_MODE_MAX_DURATION")
121+
code_mode_max_memory: int = Field(
122+
10_485_760, alias="CODE_MODE_MAX_MEMORY"
123+
) # 10 MB
124+
code_mode_max_recursion: int = Field(100, alias="CODE_MODE_MAX_RECURSION")
125+
115126
@model_validator(mode="after")
116127
def _skills_dependency(self) -> "Settings":
117128
"""Auto-enable skills (resources) when skills-as-tools is on.

src/ha_mcp/server.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,10 @@ def _apply_tool_search(self) -> None:
424424
# Build the always_visible list
425425
pinned = list(self._PINNED_TOOLS)
426426

427+
# Pin code mode tool so it gets individual permission gating
428+
if self.settings.enable_code_mode:
429+
pinned.append("ha_manage_custom_tool")
430+
427431
# Pin ResourcesAsTools and skill guidance tools if skills-as-tools is enabled
428432
if self.settings.enable_skills_as_tools:
429433
pinned.extend(["list_resources", "read_resource"])

0 commit comments

Comments
 (0)