mcpforunityserver 9.4.0b20260203025228__py3-none-any.whl
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.
- cli/__init__.py +3 -0
- cli/commands/__init__.py +3 -0
- cli/commands/animation.py +84 -0
- cli/commands/asset.py +280 -0
- cli/commands/audio.py +125 -0
- cli/commands/batch.py +171 -0
- cli/commands/code.py +182 -0
- cli/commands/component.py +190 -0
- cli/commands/editor.py +447 -0
- cli/commands/gameobject.py +487 -0
- cli/commands/instance.py +93 -0
- cli/commands/lighting.py +123 -0
- cli/commands/material.py +239 -0
- cli/commands/prefab.py +248 -0
- cli/commands/scene.py +231 -0
- cli/commands/script.py +222 -0
- cli/commands/shader.py +226 -0
- cli/commands/texture.py +540 -0
- cli/commands/tool.py +58 -0
- cli/commands/ui.py +258 -0
- cli/commands/vfx.py +421 -0
- cli/main.py +281 -0
- cli/utils/__init__.py +31 -0
- cli/utils/config.py +58 -0
- cli/utils/confirmation.py +37 -0
- cli/utils/connection.py +254 -0
- cli/utils/constants.py +23 -0
- cli/utils/output.py +195 -0
- cli/utils/parsers.py +112 -0
- cli/utils/suggestions.py +34 -0
- core/__init__.py +0 -0
- core/config.py +67 -0
- core/constants.py +4 -0
- core/logging_decorator.py +37 -0
- core/telemetry.py +551 -0
- core/telemetry_decorator.py +164 -0
- main.py +845 -0
- mcpforunityserver-9.4.0b20260203025228.dist-info/METADATA +328 -0
- mcpforunityserver-9.4.0b20260203025228.dist-info/RECORD +105 -0
- mcpforunityserver-9.4.0b20260203025228.dist-info/WHEEL +5 -0
- mcpforunityserver-9.4.0b20260203025228.dist-info/entry_points.txt +3 -0
- mcpforunityserver-9.4.0b20260203025228.dist-info/licenses/LICENSE +21 -0
- mcpforunityserver-9.4.0b20260203025228.dist-info/top_level.txt +7 -0
- models/__init__.py +4 -0
- models/models.py +56 -0
- models/unity_response.py +70 -0
- services/__init__.py +0 -0
- services/api_key_service.py +235 -0
- services/custom_tool_service.py +499 -0
- services/registry/__init__.py +22 -0
- services/registry/resource_registry.py +53 -0
- services/registry/tool_registry.py +51 -0
- services/resources/__init__.py +86 -0
- services/resources/active_tool.py +48 -0
- services/resources/custom_tools.py +57 -0
- services/resources/editor_state.py +304 -0
- services/resources/gameobject.py +243 -0
- services/resources/layers.py +30 -0
- services/resources/menu_items.py +35 -0
- services/resources/prefab.py +191 -0
- services/resources/prefab_stage.py +40 -0
- services/resources/project_info.py +40 -0
- services/resources/selection.py +56 -0
- services/resources/tags.py +31 -0
- services/resources/tests.py +88 -0
- services/resources/unity_instances.py +125 -0
- services/resources/windows.py +48 -0
- services/state/external_changes_scanner.py +245 -0
- services/tools/__init__.py +83 -0
- services/tools/batch_execute.py +93 -0
- services/tools/debug_request_context.py +86 -0
- services/tools/execute_custom_tool.py +43 -0
- services/tools/execute_menu_item.py +32 -0
- services/tools/find_gameobjects.py +110 -0
- services/tools/find_in_file.py +181 -0
- services/tools/manage_asset.py +119 -0
- services/tools/manage_components.py +131 -0
- services/tools/manage_editor.py +64 -0
- services/tools/manage_gameobject.py +260 -0
- services/tools/manage_material.py +111 -0
- services/tools/manage_prefabs.py +209 -0
- services/tools/manage_scene.py +111 -0
- services/tools/manage_script.py +645 -0
- services/tools/manage_scriptable_object.py +87 -0
- services/tools/manage_shader.py +71 -0
- services/tools/manage_texture.py +581 -0
- services/tools/manage_vfx.py +120 -0
- services/tools/preflight.py +110 -0
- services/tools/read_console.py +151 -0
- services/tools/refresh_unity.py +153 -0
- services/tools/run_tests.py +317 -0
- services/tools/script_apply_edits.py +1006 -0
- services/tools/set_active_instance.py +120 -0
- services/tools/utils.py +348 -0
- transport/__init__.py +0 -0
- transport/legacy/port_discovery.py +329 -0
- transport/legacy/stdio_port_registry.py +65 -0
- transport/legacy/unity_connection.py +910 -0
- transport/models.py +68 -0
- transport/plugin_hub.py +787 -0
- transport/plugin_registry.py +182 -0
- transport/unity_instance_middleware.py +262 -0
- transport/unity_transport.py +94 -0
- utils/focus_nudge.py +589 -0
- utils/module_discovery.py +55 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Telemetry decorator for MCP for Unity tools
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import functools
|
|
6
|
+
import inspect
|
|
7
|
+
import logging
|
|
8
|
+
import time
|
|
9
|
+
from typing import Callable, Any
|
|
10
|
+
|
|
11
|
+
from core.telemetry import record_resource_usage, record_tool_usage, record_milestone, MilestoneType
|
|
12
|
+
|
|
13
|
+
_log = logging.getLogger("unity-mcp-telemetry")
|
|
14
|
+
_decorator_log_count = 0
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def telemetry_tool(tool_name: str):
|
|
18
|
+
"""Decorator to add telemetry tracking to MCP tools"""
|
|
19
|
+
def decorator(func: Callable) -> Callable:
|
|
20
|
+
@functools.wraps(func)
|
|
21
|
+
def _sync_wrapper(*args, **kwargs) -> Any:
|
|
22
|
+
start_time = time.time()
|
|
23
|
+
success = False
|
|
24
|
+
error = None
|
|
25
|
+
# Extract sub-action (e.g., 'get_hierarchy') from bound args when available
|
|
26
|
+
sub_action = None
|
|
27
|
+
try:
|
|
28
|
+
sig = inspect.signature(func)
|
|
29
|
+
bound = sig.bind_partial(*args, **kwargs)
|
|
30
|
+
bound.apply_defaults()
|
|
31
|
+
sub_action = bound.arguments.get("action")
|
|
32
|
+
except Exception:
|
|
33
|
+
sub_action = None
|
|
34
|
+
try:
|
|
35
|
+
global _decorator_log_count
|
|
36
|
+
if _decorator_log_count < 10:
|
|
37
|
+
_log.info(f"telemetry_decorator sync: tool={tool_name}")
|
|
38
|
+
_decorator_log_count += 1
|
|
39
|
+
result = func(*args, **kwargs)
|
|
40
|
+
success = True
|
|
41
|
+
action_val = sub_action or kwargs.get("action")
|
|
42
|
+
try:
|
|
43
|
+
if tool_name == "manage_script" and action_val == "create":
|
|
44
|
+
record_milestone(MilestoneType.FIRST_SCRIPT_CREATION)
|
|
45
|
+
elif tool_name.startswith("manage_scene"):
|
|
46
|
+
record_milestone(
|
|
47
|
+
MilestoneType.FIRST_SCENE_MODIFICATION)
|
|
48
|
+
record_milestone(MilestoneType.FIRST_TOOL_USAGE)
|
|
49
|
+
except Exception:
|
|
50
|
+
_log.debug("milestone emit failed", exc_info=True)
|
|
51
|
+
return result
|
|
52
|
+
except Exception as e:
|
|
53
|
+
error = str(e)
|
|
54
|
+
raise
|
|
55
|
+
finally:
|
|
56
|
+
duration_ms = (time.time() - start_time) * 1000
|
|
57
|
+
try:
|
|
58
|
+
record_tool_usage(tool_name, success,
|
|
59
|
+
duration_ms, error, sub_action=sub_action)
|
|
60
|
+
except Exception:
|
|
61
|
+
_log.debug("record_tool_usage failed", exc_info=True)
|
|
62
|
+
|
|
63
|
+
@functools.wraps(func)
|
|
64
|
+
async def _async_wrapper(*args, **kwargs) -> Any:
|
|
65
|
+
start_time = time.time()
|
|
66
|
+
success = False
|
|
67
|
+
error = None
|
|
68
|
+
# Extract sub-action (e.g., 'get_hierarchy') from bound args when available
|
|
69
|
+
sub_action = None
|
|
70
|
+
try:
|
|
71
|
+
sig = inspect.signature(func)
|
|
72
|
+
bound = sig.bind_partial(*args, **kwargs)
|
|
73
|
+
bound.apply_defaults()
|
|
74
|
+
sub_action = bound.arguments.get("action")
|
|
75
|
+
except Exception:
|
|
76
|
+
sub_action = None
|
|
77
|
+
try:
|
|
78
|
+
global _decorator_log_count
|
|
79
|
+
if _decorator_log_count < 10:
|
|
80
|
+
_log.info(f"telemetry_decorator async: tool={tool_name}")
|
|
81
|
+
_decorator_log_count += 1
|
|
82
|
+
result = await func(*args, **kwargs)
|
|
83
|
+
success = True
|
|
84
|
+
action_val = sub_action or kwargs.get("action")
|
|
85
|
+
try:
|
|
86
|
+
if tool_name == "manage_script" and action_val == "create":
|
|
87
|
+
record_milestone(MilestoneType.FIRST_SCRIPT_CREATION)
|
|
88
|
+
elif tool_name.startswith("manage_scene"):
|
|
89
|
+
record_milestone(
|
|
90
|
+
MilestoneType.FIRST_SCENE_MODIFICATION)
|
|
91
|
+
record_milestone(MilestoneType.FIRST_TOOL_USAGE)
|
|
92
|
+
except Exception:
|
|
93
|
+
_log.debug("milestone emit failed", exc_info=True)
|
|
94
|
+
return result
|
|
95
|
+
except Exception as e:
|
|
96
|
+
error = str(e)
|
|
97
|
+
raise
|
|
98
|
+
finally:
|
|
99
|
+
duration_ms = (time.time() - start_time) * 1000
|
|
100
|
+
try:
|
|
101
|
+
record_tool_usage(tool_name, success,
|
|
102
|
+
duration_ms, error, sub_action=sub_action)
|
|
103
|
+
except Exception:
|
|
104
|
+
_log.debug("record_tool_usage failed", exc_info=True)
|
|
105
|
+
|
|
106
|
+
return _async_wrapper if inspect.iscoroutinefunction(func) else _sync_wrapper
|
|
107
|
+
return decorator
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def telemetry_resource(resource_name: str):
|
|
111
|
+
"""Decorator to add telemetry tracking to MCP resources"""
|
|
112
|
+
def decorator(func: Callable) -> Callable:
|
|
113
|
+
@functools.wraps(func)
|
|
114
|
+
def _sync_wrapper(*args, **kwargs) -> Any:
|
|
115
|
+
start_time = time.time()
|
|
116
|
+
success = False
|
|
117
|
+
error = None
|
|
118
|
+
try:
|
|
119
|
+
global _decorator_log_count
|
|
120
|
+
if _decorator_log_count < 10:
|
|
121
|
+
_log.info(
|
|
122
|
+
f"telemetry_decorator sync: resource={resource_name}")
|
|
123
|
+
_decorator_log_count += 1
|
|
124
|
+
result = func(*args, **kwargs)
|
|
125
|
+
success = True
|
|
126
|
+
return result
|
|
127
|
+
except Exception as e:
|
|
128
|
+
error = str(e)
|
|
129
|
+
raise
|
|
130
|
+
finally:
|
|
131
|
+
duration_ms = (time.time() - start_time) * 1000
|
|
132
|
+
try:
|
|
133
|
+
record_resource_usage(resource_name, success,
|
|
134
|
+
duration_ms, error)
|
|
135
|
+
except Exception:
|
|
136
|
+
_log.debug("record_resource_usage failed", exc_info=True)
|
|
137
|
+
|
|
138
|
+
@functools.wraps(func)
|
|
139
|
+
async def _async_wrapper(*args, **kwargs) -> Any:
|
|
140
|
+
start_time = time.time()
|
|
141
|
+
success = False
|
|
142
|
+
error = None
|
|
143
|
+
try:
|
|
144
|
+
global _decorator_log_count
|
|
145
|
+
if _decorator_log_count < 10:
|
|
146
|
+
_log.info(
|
|
147
|
+
f"telemetry_decorator async: resource={resource_name}")
|
|
148
|
+
_decorator_log_count += 1
|
|
149
|
+
result = await func(*args, **kwargs)
|
|
150
|
+
success = True
|
|
151
|
+
return result
|
|
152
|
+
except Exception as e:
|
|
153
|
+
error = str(e)
|
|
154
|
+
raise
|
|
155
|
+
finally:
|
|
156
|
+
duration_ms = (time.time() - start_time) * 1000
|
|
157
|
+
try:
|
|
158
|
+
record_resource_usage(resource_name, success,
|
|
159
|
+
duration_ms, error)
|
|
160
|
+
except Exception:
|
|
161
|
+
_log.debug("record_resource_usage failed", exc_info=True)
|
|
162
|
+
|
|
163
|
+
return _async_wrapper if inspect.iscoroutinefunction(func) else _sync_wrapper
|
|
164
|
+
return decorator
|