Skip to content

Commit 853b153

Browse files
committed
feat: replace custom boolean coercion logic with shared utility function
1 parent 993ca32 commit 853b153

File tree

4 files changed

+37
-50
lines changed

4 files changed

+37
-50
lines changed

Server/src/services/tools/manage_editor.py

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from services.tools import get_unity_instance_from_context
77
from transport.unity_transport import send_with_unity_instance
88
from transport.legacy.unity_connection import async_send_command_with_retry
9+
from Server.src.services.tools.utils import coerce_bool
910

1011

1112
@mcp_for_unity_tool(
@@ -26,21 +27,7 @@ async def manage_editor(
2627
# Get active instance from request state (injected by middleware)
2728
unity_instance = get_unity_instance_from_context(ctx)
2829

29-
# Coerce boolean parameters defensively to tolerate 'true'/'false' strings
30-
def _coerce_bool(value, default=None):
31-
if value is None:
32-
return default
33-
if isinstance(value, bool):
34-
return value
35-
if isinstance(value, str):
36-
v = value.strip().lower()
37-
if v in ("true", "1", "yes", "on"): # common truthy strings
38-
return True
39-
if v in ("false", "0", "no", "off"):
40-
return False
41-
return bool(value)
42-
43-
wait_for_completion = _coerce_bool(wait_for_completion)
30+
wait_for_completion = coerce_bool(wait_for_completion)
4431

4532
try:
4633
# Diagnostics: quick telemetry checks

Server/src/services/tools/manage_gameobject.py

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from services.tools import get_unity_instance_from_context
77
from transport.unity_transport import send_with_unity_instance
88
from transport.legacy.unity_connection import async_send_command_with_retry
9+
from Server.src.services.tools.utils import coerce_bool
910

1011

1112
@mcp_for_unity_tool(
@@ -72,19 +73,6 @@ async def manage_gameobject(
7273
unity_instance = get_unity_instance_from_context(ctx)
7374

7475
# Coercers to tolerate stringified booleans and vectors
75-
def _coerce_bool(value, default=None):
76-
if value is None:
77-
return default
78-
if isinstance(value, bool):
79-
return value
80-
if isinstance(value, str):
81-
v = value.strip().lower()
82-
if v in ("true", "1", "yes", "on"):
83-
return True
84-
if v in ("false", "0", "no", "off"):
85-
return False
86-
return bool(value)
87-
8876
def _coerce_vec(value, default=None):
8977
if value is None:
9078
return default
@@ -113,12 +101,12 @@ def _to_vec3(parts):
113101
position = _coerce_vec(position, default=position)
114102
rotation = _coerce_vec(rotation, default=rotation)
115103
scale = _coerce_vec(scale, default=scale)
116-
save_as_prefab = _coerce_bool(save_as_prefab)
117-
set_active = _coerce_bool(set_active)
118-
find_all = _coerce_bool(find_all)
119-
search_in_children = _coerce_bool(search_in_children)
120-
search_inactive = _coerce_bool(search_inactive)
121-
includeNonPublicSerialized = _coerce_bool(includeNonPublicSerialized)
104+
save_as_prefab = coerce_bool(save_as_prefab)
105+
set_active = coerce_bool(set_active)
106+
find_all = coerce_bool(find_all)
107+
search_in_children = coerce_bool(search_in_children)
108+
search_inactive = coerce_bool(search_inactive)
109+
includeNonPublicSerialized = coerce_bool(includeNonPublicSerialized)
122110

123111
# Coerce 'component_properties' from JSON string to dict for client compatibility
124112
if isinstance(component_properties, str):

Server/src/services/tools/manage_prefabs.py

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from services.tools import get_unity_instance_from_context
66
from transport.unity_transport import send_with_unity_instance
77
from transport.legacy.unity_connection import async_send_command_with_retry
8+
from Server.src.services.tools.utils import coerce_bool
89

910

1011
@mcp_for_unity_tool(
@@ -30,35 +31,22 @@ async def manage_prefabs(
3031
# Removed session_state import
3132
unity_instance = get_unity_instance_from_context(ctx)
3233

33-
def _coerce_bool(value, default=None):
34-
if value is None:
35-
return default
36-
if isinstance(value, bool):
37-
return value
38-
if isinstance(value, str):
39-
v = value.strip().lower()
40-
if v in ("true", "1", "yes", "on"):
41-
return True
42-
if v in ("false", "0", "no", "off"):
43-
return False
44-
return bool(value)
45-
4634
try:
4735
params: dict[str, Any] = {"action": action}
4836

4937
if prefab_path:
5038
params["prefabPath"] = prefab_path
5139
if mode:
5240
params["mode"] = mode
53-
save_before_close_val = _coerce_bool(save_before_close)
41+
save_before_close_val = coerce_bool(save_before_close)
5442
if save_before_close_val is not None:
5543
params["saveBeforeClose"] = save_before_close_val
5644
if target:
5745
params["target"] = target
58-
allow_overwrite_val = _coerce_bool(allow_overwrite)
46+
allow_overwrite_val = coerce_bool(allow_overwrite)
5947
if allow_overwrite_val is not None:
6048
params["allowOverwrite"] = allow_overwrite_val
61-
search_inactive_val = _coerce_bool(search_inactive)
49+
search_inactive_val = coerce_bool(search_inactive)
6250
if search_inactive_val is not None:
6351
params["searchInactive"] = search_inactive_val
6452
response = await send_with_unity_instance(async_send_command_with_retry, unity_instance, "manage_prefabs", params)

Server/src/services/tools/utils.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
"""Shared helper utilities for MCP server tools."""
2+
3+
from __future__ import annotations
4+
5+
from typing import Any
6+
7+
8+
_TRUTHY = {"true", "1", "yes", "on"}
9+
_FALSY = {"false", "0", "no", "off"}
10+
11+
12+
def coerce_bool(value: Any, default: bool | None = None) -> bool | None:
13+
"""Attempt to coerce a loosely-typed value to a boolean."""
14+
if value is None:
15+
return default
16+
if isinstance(value, bool):
17+
return value
18+
if isinstance(value, str):
19+
lowered = value.strip().lower()
20+
if lowered in _TRUTHY:
21+
return True
22+
if lowered in _FALSY:
23+
return False
24+
return bool(value)

0 commit comments

Comments
 (0)