mcpforunityserver 9.3.0__py3-none-any.whl → 9.3.0b20260128055651__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/commands/vfx.py CHANGED
@@ -10,6 +10,27 @@ from cli.utils.output import format_output, print_error, print_success
10
10
  from cli.utils.connection import run_command, UnityConnectionError
11
11
 
12
12
 
13
+ _VFX_TOP_LEVEL_KEYS = {"action", "target", "searchMethod", "properties"}
14
+
15
+
16
+ def _normalize_vfx_params(params: dict[str, Any]) -> dict[str, Any]:
17
+ params = dict(params)
18
+ properties: dict[str, Any] = {}
19
+ for key in list(params.keys()):
20
+ if key in _VFX_TOP_LEVEL_KEYS:
21
+ continue
22
+ properties[key] = params.pop(key)
23
+
24
+ if properties:
25
+ existing = params.get("properties")
26
+ if isinstance(existing, dict):
27
+ params["properties"] = {**properties, **existing}
28
+ else:
29
+ params["properties"] = properties
30
+
31
+ return {k: v for k, v in params.items() if v is not None}
32
+
33
+
13
34
  @click.group()
14
35
  def vfx():
15
36
  """VFX operations - particle systems, line renderers, trails."""
@@ -43,7 +64,8 @@ def particle_info(target: str, search_method: Optional[str]):
43
64
  params["searchMethod"] = search_method
44
65
 
45
66
  try:
46
- result = run_command("manage_vfx", params, config)
67
+ result = run_command(
68
+ "manage_vfx", _normalize_vfx_params(params), config)
47
69
  click.echo(format_output(result, config.format))
48
70
  except UnityConnectionError as e:
49
71
  print_error(str(e))
@@ -70,7 +92,8 @@ def particle_play(target: str, with_children: bool, search_method: Optional[str]
70
92
  params["searchMethod"] = search_method
71
93
 
72
94
  try:
73
- result = run_command("manage_vfx", params, config)
95
+ result = run_command(
96
+ "manage_vfx", _normalize_vfx_params(params), config)
74
97
  click.echo(format_output(result, config.format))
75
98
  if result.get("success"):
76
99
  print_success(f"Playing particle system: {target}")
@@ -93,7 +116,8 @@ def particle_stop(target: str, with_children: bool, search_method: Optional[str]
93
116
  params["searchMethod"] = search_method
94
117
 
95
118
  try:
96
- result = run_command("manage_vfx", params, config)
119
+ result = run_command(
120
+ "manage_vfx", _normalize_vfx_params(params), config)
97
121
  click.echo(format_output(result, config.format))
98
122
  if result.get("success"):
99
123
  print_success(f"Stopped particle system: {target}")
@@ -113,7 +137,8 @@ def particle_pause(target: str, search_method: Optional[str]):
113
137
  params["searchMethod"] = search_method
114
138
 
115
139
  try:
116
- result = run_command("manage_vfx", params, config)
140
+ result = run_command(
141
+ "manage_vfx", _normalize_vfx_params(params), config)
117
142
  click.echo(format_output(result, config.format))
118
143
  except UnityConnectionError as e:
119
144
  print_error(str(e))
@@ -134,7 +159,8 @@ def particle_restart(target: str, with_children: bool, search_method: Optional[s
134
159
  params["searchMethod"] = search_method
135
160
 
136
161
  try:
137
- result = run_command("manage_vfx", params, config)
162
+ result = run_command(
163
+ "manage_vfx", _normalize_vfx_params(params), config)
138
164
  click.echo(format_output(result, config.format))
139
165
  except UnityConnectionError as e:
140
166
  print_error(str(e))
@@ -155,7 +181,8 @@ def particle_clear(target: str, with_children: bool, search_method: Optional[str
155
181
  params["searchMethod"] = search_method
156
182
 
157
183
  try:
158
- result = run_command("manage_vfx", params, config)
184
+ result = run_command(
185
+ "manage_vfx", _normalize_vfx_params(params), config)
159
186
  click.echo(format_output(result, config.format))
160
187
  except UnityConnectionError as e:
161
188
  print_error(str(e))
@@ -188,7 +215,8 @@ def line_info(target: str, search_method: Optional[str]):
188
215
  params["searchMethod"] = search_method
189
216
 
190
217
  try:
191
- result = run_command("manage_vfx", params, config)
218
+ result = run_command(
219
+ "manage_vfx", _normalize_vfx_params(params), config)
192
220
  click.echo(format_output(result, config.format))
193
221
  except UnityConnectionError as e:
194
222
  print_error(str(e))
@@ -223,7 +251,8 @@ def line_set_positions(target: str, positions: str, search_method: Optional[str]
223
251
  params["searchMethod"] = search_method
224
252
 
225
253
  try:
226
- result = run_command("manage_vfx", params, config)
254
+ result = run_command(
255
+ "manage_vfx", _normalize_vfx_params(params), config)
227
256
  click.echo(format_output(result, config.format))
228
257
  except UnityConnectionError as e:
229
258
  print_error(str(e))
@@ -253,7 +282,8 @@ def line_create_line(target: str, start: Tuple[float, float, float], end: Tuple[
253
282
  params["searchMethod"] = search_method
254
283
 
255
284
  try:
256
- result = run_command("manage_vfx", params, config)
285
+ result = run_command(
286
+ "manage_vfx", _normalize_vfx_params(params), config)
257
287
  click.echo(format_output(result, config.format))
258
288
  except UnityConnectionError as e:
259
289
  print_error(str(e))
@@ -286,7 +316,8 @@ def line_create_circle(target: str, center: Tuple[float, float, float], radius:
286
316
  params["searchMethod"] = search_method
287
317
 
288
318
  try:
289
- result = run_command("manage_vfx", params, config)
319
+ result = run_command(
320
+ "manage_vfx", _normalize_vfx_params(params), config)
290
321
  click.echo(format_output(result, config.format))
291
322
  except UnityConnectionError as e:
292
323
  print_error(str(e))
@@ -304,7 +335,8 @@ def line_clear(target: str, search_method: Optional[str]):
304
335
  params["searchMethod"] = search_method
305
336
 
306
337
  try:
307
- result = run_command("manage_vfx", params, config)
338
+ result = run_command(
339
+ "manage_vfx", _normalize_vfx_params(params), config)
308
340
  click.echo(format_output(result, config.format))
309
341
  except UnityConnectionError as e:
310
342
  print_error(str(e))
@@ -332,7 +364,8 @@ def trail_info(target: str, search_method: Optional[str]):
332
364
  params["searchMethod"] = search_method
333
365
 
334
366
  try:
335
- result = run_command("manage_vfx", params, config)
367
+ result = run_command(
368
+ "manage_vfx", _normalize_vfx_params(params), config)
336
369
  click.echo(format_output(result, config.format))
337
370
  except UnityConnectionError as e:
338
371
  print_error(str(e))
@@ -360,7 +393,8 @@ def trail_set_time(target: str, duration: float, search_method: Optional[str]):
360
393
  params["searchMethod"] = search_method
361
394
 
362
395
  try:
363
- result = run_command("manage_vfx", params, config)
396
+ result = run_command(
397
+ "manage_vfx", _normalize_vfx_params(params), config)
364
398
  click.echo(format_output(result, config.format))
365
399
  except UnityConnectionError as e:
366
400
  print_error(str(e))
@@ -378,7 +412,8 @@ def trail_clear(target: str, search_method: Optional[str]):
378
412
  params["searchMethod"] = search_method
379
413
 
380
414
  try:
381
- result = run_command("manage_vfx", params, config)
415
+ result = run_command(
416
+ "manage_vfx", _normalize_vfx_params(params), config)
382
417
  click.echo(format_output(result, config.format))
383
418
  except UnityConnectionError as e:
384
419
  print_error(str(e))
@@ -432,7 +467,8 @@ def vfx_raw(action: str, target: Optional[str], params: str, search_method: Opti
432
467
  # Merge extra params
433
468
  request_params.update(extra_params)
434
469
  try:
435
- result = run_command("manage_vfx", request_params, config)
470
+ result = run_command(
471
+ "manage_vfx", _normalize_vfx_params(request_params), config)
436
472
  click.echo(format_output(result, config.format))
437
473
  except UnityConnectionError as e:
438
474
  print_error(str(e))
cli/main.py CHANGED
@@ -8,6 +8,7 @@ from typing import Optional
8
8
 
9
9
  from cli import __version__
10
10
  from cli.utils.config import CLIConfig, set_config, get_config
11
+ from cli.utils.suggestions import suggest_matches, format_suggestions
11
12
  from cli.utils.output import format_output, print_error, print_success, print_info
12
13
  from cli.utils.connection import (
13
14
  run_command,
@@ -28,6 +29,35 @@ class Context:
28
29
  pass_context = click.make_pass_decorator(Context, ensure=True)
29
30
 
30
31
 
32
+ _ORIGINAL_RESOLVE_COMMAND = click.Group.resolve_command
33
+
34
+
35
+ def _resolve_command_with_suggestions(self: click.Group, ctx: click.Context, args: list[str]):
36
+ try:
37
+ return _ORIGINAL_RESOLVE_COMMAND(self, ctx, args)
38
+ except click.exceptions.NoSuchCommand as e:
39
+ if not args or args[0].startswith("-"):
40
+ raise
41
+ matches = suggest_matches(args[0], self.list_commands(ctx))
42
+ suggestion = format_suggestions(matches)
43
+ if suggestion:
44
+ message = f"{e}\n{suggestion}"
45
+ raise click.exceptions.UsageError(message, ctx=ctx)
46
+ raise
47
+ except click.exceptions.UsageError as e:
48
+ if args and not args[0].startswith("-") and "No such command" in str(e):
49
+ matches = suggest_matches(args[0], self.list_commands(ctx))
50
+ suggestion = format_suggestions(matches)
51
+ if suggestion:
52
+ message = f"{e}\n{suggestion}"
53
+ raise click.exceptions.UsageError(message, ctx=ctx)
54
+ raise
55
+
56
+
57
+ # Install suggestion handling for all CLI command groups.
58
+ click.Group.resolve_command = _resolve_command_with_suggestions # type: ignore[assignment]
59
+
60
+
31
61
  @click.group()
32
62
  @click.version_option(version=__version__, prog_name="unity-mcp")
33
63
  @click.option(
@@ -212,6 +242,8 @@ def register_commands():
212
242
  cli.add_command(command)
213
243
 
214
244
  optional_commands = [
245
+ ("cli.commands.tool", "tool"),
246
+ ("cli.commands.tool", "custom_tool"),
215
247
  ("cli.commands.gameobject", "gameobject"),
216
248
  ("cli.commands.component", "component"),
217
249
  ("cli.commands.scene", "scene"),
@@ -229,6 +261,7 @@ def register_commands():
229
261
  ("cli.commands.shader", "shader"),
230
262
  ("cli.commands.vfx", "vfx"),
231
263
  ("cli.commands.batch", "batch"),
264
+ ("cli.commands.texture", "texture"),
232
265
  ]
233
266
 
234
267
  for module_name, command_name in optional_commands:
cli/utils/connection.py CHANGED
@@ -189,3 +189,40 @@ async def list_unity_instances(config: Optional[CLIConfig] = None) -> Dict[str,
189
189
  def run_list_instances(config: Optional[CLIConfig] = None) -> Dict[str, Any]:
190
190
  """Synchronous wrapper for list_unity_instances."""
191
191
  return asyncio.run(list_unity_instances(config))
192
+
193
+
194
+ async def list_custom_tools(config: Optional[CLIConfig] = None) -> Dict[str, Any]:
195
+ """List custom tools registered for the active Unity project."""
196
+ cfg = config or get_config()
197
+ url = f"http://{cfg.host}:{cfg.port}/api/custom-tools"
198
+ params: Dict[str, Any] = {}
199
+ if cfg.unity_instance:
200
+ params["instance"] = cfg.unity_instance
201
+
202
+ try:
203
+ async with httpx.AsyncClient() as client:
204
+ response = await client.get(url, params=params, timeout=cfg.timeout)
205
+ response.raise_for_status()
206
+ return response.json()
207
+ except httpx.ConnectError as e:
208
+ raise UnityConnectionError(
209
+ f"Cannot connect to Unity MCP server at {cfg.host}:{cfg.port}. "
210
+ f"Make sure the server is running and Unity is connected.\n"
211
+ f"Error: {e}"
212
+ )
213
+ except httpx.TimeoutException:
214
+ raise UnityConnectionError(
215
+ f"Connection to Unity timed out after {cfg.timeout}s. "
216
+ f"Unity may be busy or unresponsive."
217
+ )
218
+ except httpx.HTTPStatusError as e:
219
+ raise UnityConnectionError(
220
+ f"HTTP error from server: {e.response.status_code} - {e.response.text}"
221
+ )
222
+ except Exception as e:
223
+ raise UnityConnectionError(f"Unexpected error: {e}")
224
+
225
+
226
+ def run_list_custom_tools(config: Optional[CLIConfig] = None) -> Dict[str, Any]:
227
+ """Synchronous wrapper for list_custom_tools."""
228
+ return asyncio.run(list_custom_tools(config))
@@ -0,0 +1,34 @@
1
+ """Helpers for CLI suggestion messages."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import difflib
6
+ from typing import Iterable, List
7
+
8
+
9
+ def suggest_matches(
10
+ value: str,
11
+ choices: Iterable[str],
12
+ *,
13
+ limit: int = 3,
14
+ cutoff: float = 0.6,
15
+ ) -> List[str]:
16
+ """Return close matches for a value from a list of choices."""
17
+ try:
18
+ normalized = [c for c in choices if isinstance(c, str)]
19
+ except Exception:
20
+ normalized = []
21
+ if not value or not normalized:
22
+ return []
23
+ return difflib.get_close_matches(value, normalized, n=limit, cutoff=cutoff)
24
+
25
+
26
+ def format_suggestions(matches: Iterable[str]) -> str | None:
27
+ """Format matches into a CLI-friendly suggestion string."""
28
+ items = [m for m in matches if m]
29
+ if not items:
30
+ return None
31
+ if len(items) == 1:
32
+ return f"Did you mean: {items[0]}"
33
+ joined = ", ".join(items)
34
+ return f"Did you mean one of: {joined}"
main.py CHANGED
@@ -9,7 +9,10 @@ from core.telemetry import record_milestone, record_telemetry, MilestoneType, Re
9
9
  from services.resources import register_all_resources
10
10
  from transport.plugin_registry import PluginRegistry
11
11
  from transport.plugin_hub import PluginHub
12
- from services.custom_tool_service import CustomToolService
12
+ from services.custom_tool_service import (
13
+ CustomToolService,
14
+ resolve_project_id_for_unity_instance,
15
+ )
13
16
  from core.config import config
14
17
  from starlette.routing import WebSocketRoute
15
18
  from starlette.responses import JSONResponse
@@ -123,6 +126,9 @@ except Exception:
123
126
  _unity_connection_pool: UnityConnectionPool | None = None
124
127
  _plugin_registry: PluginRegistry | None = None
125
128
 
129
+ # Cached server version (set at startup to avoid repeated I/O)
130
+ _server_version: str | None = None
131
+
126
132
  # In-memory custom tool service initialized after MCP construction
127
133
  custom_tool_service: CustomToolService | None = None
128
134
 
@@ -130,8 +136,9 @@ custom_tool_service: CustomToolService | None = None
130
136
  @asynccontextmanager
131
137
  async def server_lifespan(server: FastMCP) -> AsyncIterator[dict[str, Any]]:
132
138
  """Handle server startup and shutdown."""
133
- global _unity_connection_pool
134
- logger.info("MCP for Unity Server starting up")
139
+ global _unity_connection_pool, _server_version
140
+ _server_version = get_package_version()
141
+ logger.info(f"MCP for Unity Server v{_server_version} starting up")
135
142
 
136
143
  # Register custom tool management endpoints with FastMCP
137
144
  # Routes are declared globally below after FastMCP initialization
@@ -155,13 +162,12 @@ async def server_lifespan(server: FastMCP) -> AsyncIterator[dict[str, Any]]:
155
162
  # Record server startup telemetry
156
163
  start_time = time.time()
157
164
  start_clk = time.perf_counter()
158
- server_version = get_package_version()
159
165
  # Defer initial telemetry by 1s to avoid stdio handshake interference
160
166
 
161
167
  def _emit_startup():
162
168
  try:
163
169
  record_telemetry(RecordType.STARTUP, {
164
- "server_version": server_version,
170
+ "server_version": _server_version,
165
171
  "startup_time": start_time,
166
172
  })
167
173
  record_milestone(MilestoneType.FIRST_STARTUP)
@@ -322,9 +328,18 @@ def create_mcp_server(project_scoped_tools: bool) -> FastMCP:
322
328
  return JSONResponse({
323
329
  "status": "healthy",
324
330
  "timestamp": time.time(),
331
+ "version": _server_version or "unknown",
325
332
  "message": "MCP for Unity server is running"
326
333
  })
327
334
 
335
+ def _normalize_instance_token(instance_token: str | None) -> tuple[str | None, str | None]:
336
+ if not instance_token:
337
+ return None, None
338
+ if "@" in instance_token:
339
+ name_part, _, hash_part = instance_token.partition("@")
340
+ return (name_part or None), (hash_part or None)
341
+ return None, instance_token
342
+
328
343
  @mcp.custom_route("/api/command", methods=["POST"])
329
344
  async def cli_command_route(request: Request) -> JSONResponse:
330
345
  """REST endpoint for CLI commands to Unity."""
@@ -348,11 +363,14 @@ def create_mcp_server(project_scoped_tools: bool) -> FastMCP:
348
363
 
349
364
  # Find target session
350
365
  session_id = None
366
+ session_details = None
367
+ instance_name, instance_hash = _normalize_instance_token(unity_instance)
351
368
  if unity_instance:
352
369
  # Try to match by hash or project name
353
370
  for sid, details in sessions.sessions.items():
354
- if details.hash == unity_instance or details.project == unity_instance:
371
+ if details.hash == instance_hash or details.project in (instance_name, unity_instance):
355
372
  session_id = sid
373
+ session_details = details
356
374
  break
357
375
 
358
376
  # If a specific unity_instance was requested but not found, return an error
@@ -367,6 +385,46 @@ def create_mcp_server(project_scoped_tools: bool) -> FastMCP:
367
385
  else:
368
386
  # No specific unity_instance requested: use first available session
369
387
  session_id = next(iter(sessions.sessions.keys()))
388
+ session_details = sessions.sessions.get(session_id)
389
+
390
+ if command_type == "execute_custom_tool":
391
+ tool_name = None
392
+ tool_params = {}
393
+ if isinstance(params, dict):
394
+ tool_name = params.get("tool_name") or params.get("name")
395
+ tool_params = params.get("parameters") or params.get("params") or {}
396
+
397
+ if not tool_name:
398
+ return JSONResponse(
399
+ {"success": False, "error": "Missing 'tool_name' for execute_custom_tool"},
400
+ status_code=400,
401
+ )
402
+ if tool_params is None:
403
+ tool_params = {}
404
+ if not isinstance(tool_params, dict):
405
+ return JSONResponse(
406
+ {"success": False, "error": "Tool parameters must be an object/dict"},
407
+ status_code=400,
408
+ )
409
+
410
+ # Prefer a concrete hash for project-scoped tools.
411
+ unity_instance_hint = unity_instance
412
+ if session_details and session_details.hash:
413
+ unity_instance_hint = session_details.hash
414
+
415
+ project_id = resolve_project_id_for_unity_instance(
416
+ unity_instance_hint)
417
+ if not project_id:
418
+ return JSONResponse(
419
+ {"success": False, "error": "Could not resolve project id for custom tool"},
420
+ status_code=400,
421
+ )
422
+
423
+ service = CustomToolService.get_instance()
424
+ result = await service.execute_tool(
425
+ project_id, tool_name, unity_instance_hint, tool_params
426
+ )
427
+ return JSONResponse(result.model_dump())
370
428
 
371
429
  # Send command to Unity
372
430
  result = await PluginHub.send_command(session_id, command_type, params)
@@ -376,6 +434,67 @@ def create_mcp_server(project_scoped_tools: bool) -> FastMCP:
376
434
  logger.error(f"CLI command error: {e}")
377
435
  return JSONResponse({"success": False, "error": str(e)}, status_code=500)
378
436
 
437
+ @mcp.custom_route("/api/custom-tools", methods=["GET"])
438
+ async def cli_custom_tools_route(request: Request) -> JSONResponse:
439
+ """REST endpoint to list custom tools for the active Unity project."""
440
+ try:
441
+ unity_instance = request.query_params.get("instance")
442
+ instance_name, instance_hash = _normalize_instance_token(unity_instance)
443
+
444
+ sessions = await PluginHub.get_sessions()
445
+ if not sessions.sessions:
446
+ return JSONResponse({
447
+ "success": False,
448
+ "error": "No Unity instances connected. Make sure Unity is running with MCP plugin."
449
+ }, status_code=503)
450
+
451
+ session_details = None
452
+ if unity_instance:
453
+ # Try to match by hash or project name
454
+ for _, details in sessions.sessions.items():
455
+ if details.hash == instance_hash or details.project in (instance_name, unity_instance):
456
+ session_details = details
457
+ break
458
+ if not session_details:
459
+ return JSONResponse(
460
+ {
461
+ "success": False,
462
+ "error": f"Unity instance '{unity_instance}' not found",
463
+ },
464
+ status_code=404,
465
+ )
466
+ else:
467
+ # No specific unity_instance requested: use first available session
468
+ session_details = next(iter(sessions.sessions.values()))
469
+
470
+ unity_instance_hint = unity_instance
471
+ if session_details and session_details.hash:
472
+ unity_instance_hint = session_details.hash
473
+
474
+ project_id = resolve_project_id_for_unity_instance(
475
+ unity_instance_hint)
476
+ if not project_id:
477
+ return JSONResponse(
478
+ {"success": False, "error": "Could not resolve project id for custom tools"},
479
+ status_code=400,
480
+ )
481
+
482
+ service = CustomToolService.get_instance()
483
+ tools = await service.list_registered_tools(project_id)
484
+ tools_payload = [
485
+ tool.model_dump() if hasattr(tool, "model_dump") else tool for tool in tools
486
+ ]
487
+
488
+ return JSONResponse({
489
+ "success": True,
490
+ "project_id": project_id,
491
+ "tool_count": len(tools_payload),
492
+ "tools": tools_payload,
493
+ })
494
+ except Exception as e:
495
+ logger.error(f"CLI custom tools error: {e}")
496
+ return JSONResponse({"success": False, "error": str(e)}, status_code=500)
497
+
379
498
  @mcp.custom_route("/api/instances", methods=["GET"])
380
499
  async def cli_instances_route(_: Request) -> JSONResponse:
381
500
  """REST endpoint to list connected Unity instances."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcpforunityserver
3
- Version: 9.3.0
3
+ Version: 9.3.0b20260128055651
4
4
  Summary: MCP for Unity Server: A Unity package for Unity Editor integration via the Model Context Protocol (MCP).
5
5
  Author-email: Marcus Sanatan <msanatan@gmail.com>, David Sarno <david.sarno@gmail.com>, Wu Shutong <martinwfire@gmail.com>
6
6
  License-Expression: MIT
@@ -110,7 +110,7 @@ Use this to run the latest released version from the repository. Change the vers
110
110
  "command": "uvx",
111
111
  "args": [
112
112
  "--from",
113
- "git+https://github.com/CoplayDev/unity-mcp@v9.3.0#subdirectory=Server",
113
+ "git+https://github.com/CoplayDev/unity-mcp@v9.2.0#subdirectory=Server",
114
114
  "mcp-for-unity",
115
115
  "--transport",
116
116
  "stdio"
@@ -1,6 +1,6 @@
1
- main.py,sha256=iscQv6VBCK-kHFDmu-Cgskc_S3-kWlF-2AuF-vMr0MI,23952
1
+ main.py,sha256=EoHA0upWjtQzuoOgN5BfNmGL6bIVnFQjRW5PHO5EmjY,29265
2
2
  cli/__init__.py,sha256=f2HjXqR9d8Uhibru211t9HPpdrb_1vdDC2v_NwF_eqA,63
3
- cli/main.py,sha256=LFrHFWxiUlX7Ttc-YxqHeXxIcEzhNndpvUJT_LQ28mw,7101
3
+ cli/main.py,sha256=V_VFa8tA-CDHNv9J5NzNSLxRuEGjRVZWDe4xn6rYdog,8457
4
4
  cli/commands/__init__.py,sha256=xQHf6o0afDV2HsU9gwSxjcrzS41cMCSGZyWYWxblPIk,69
5
5
  cli/commands/animation.py,sha256=emBE5oKhFQNU8V2ENm9E5N4Grj0Tah9H0X7fF6grQdk,2442
6
6
  cli/commands/asset.py,sha256=V1xzLgBPhdRzXsnj9Wt2HnJYo_8hT3RqoVnR2WrLP5w,7988
@@ -8,27 +8,30 @@ cli/commands/audio.py,sha256=qJ-Whc8aH7oUgT79O_RRRo-lAVktFqtC5pgbyG2bRNo,3333
8
8
  cli/commands/batch.py,sha256=rMe8BDsthZ0AwaDrFoj6Kxl4xAVNRIlKSCcJ5eSagyY,5732
9
9
  cli/commands/code.py,sha256=FGV8IDx6eFhcEmc6jREQwHwoOdiUyhY8d6Hy7KN4cTw,5624
10
10
  cli/commands/component.py,sha256=uIOtno1T2mPF3rnW2OymetggScqtWrs_Th06FI7FISQ,6327
11
- cli/commands/editor.py,sha256=mlfCQjw1PtA6V4ZY7HlbQ7ICDvvxu5EH7y6JOYMj0yU,13219
11
+ cli/commands/editor.py,sha256=oM1g8DNoJZ6slOSfNJYbLN02rQVmIX_a2QLhecc_Qog,14586
12
12
  cli/commands/gameobject.py,sha256=b7ZxHXyIgUOvjYhHmKavigs-wfxGB6NhDMqqRyEGtNY,13643
13
13
  cli/commands/instance.py,sha256=J6uQrNIEWbnJT-Y09ICTA9R11lgtPQflBbmTrBr5bg8,3041
14
14
  cli/commands/lighting.py,sha256=eBvSDhQ5jkoUJJ4sito0yFxXwJv0JlpT4iD-D6Q2Pak,3869
15
15
  cli/commands/material.py,sha256=51uxeoTgqnnMuUQUbhBTdMdI70kU4pOCH6GUIy2OjQI,7847
16
- cli/commands/prefab.py,sha256=1t0fnGdDWD_a3yok02QI74YYmS1M92LDYfWvv_8iz90,3607
16
+ cli/commands/prefab.py,sha256=E6aWXKyosJH0pJPK8krsRYUrZhHjnCm3iUpIAy4dkes,8177
17
17
  cli/commands/scene.py,sha256=P08rud-6FZaO8Tw9jnP0xcS043Bf5IAooGbEDZPVBqw,6274
18
18
  cli/commands/script.py,sha256=Yf9o00irn4wf0cbsE665mxJehwtiIr0y3IHKLyvYhgY,6434
19
19
  cli/commands/shader.py,sha256=CwIIgyrU9OosVmidD6E9Txmn6Yyo4rDJBubrBchAlVw,6380
20
+ cli/commands/texture.py,sha256=qkvxb94W2B4oqyCi0WI0Cvwvvch5sp-UenBH5xMHnNY,18251
21
+ cli/commands/tool.py,sha256=9JQSUNPinLoDfP1T-STjcrn9A_UdIbGBr_c5G7X4r7k,1754
20
22
  cli/commands/ui.py,sha256=JDfAXE3ba45r41Svfop-fiy4p8C0gxE4ekJ8aFRG7aI,7627
21
- cli/commands/vfx.py,sha256=5wKypI-QWa8Jd-Fp6bLGBiQw8wuIg6fynL6WiOJy36c,15199
23
+ cli/commands/vfx.py,sha256=tmHdaGDUABJ339Ia2Y4MTqr72UnoUOf_LxY69qUnAPg,16373
22
24
  cli/utils/__init__.py,sha256=Gbm9hYC7UqwloFwdirXgo6z1iBktR9Y96o3bQcrYudc,613
23
25
  cli/utils/config.py,sha256=_k3XAFmXG22sv8tYIb5JmO46kNl3T1sGqFptySAayfc,1550
24
- cli/utils/connection.py,sha256=T1xKA3Vr98Oj9b0RvFKQLAh2stvHwCdOiq3GIc58ZvE,6150
26
+ cli/utils/connection.py,sha256=T9xmjfil0TAYJg5ZAbeqTtnmIhv5angQNG5vw40Ines,7619
25
27
  cli/utils/output.py,sha256=96daU55ta_hl7UeOhNh5Iy7OJ4psbdR9Nfx1-q2k3xA,6370
28
+ cli/utils/suggestions.py,sha256=n6KG3Mrvub28X9rPFYFLRTtZ6HePp3PhhAeojG2WOJw,929
26
29
  core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
30
  core/config.py,sha256=czkTtNji1crQcQbUvmdx4OL7f-RBqkVhj_PtHh-w7rs,1623
28
31
  core/logging_decorator.py,sha256=D9CD7rFvQz-MBG-G4inizQj0Ivr6dfc9RBmTrw7q8mI,1383
29
32
  core/telemetry.py,sha256=eHjYgzd8f7eTwSwF2Kbi8D4TtJIcdaDjKLeo1c-0hVA,19829
30
33
  core/telemetry_decorator.py,sha256=ycSTrzVNCDQHSd-xmIWOpVfKFURPxpiZe_XkOQAGDAo,6705
31
- mcpforunityserver-9.3.0.dist-info/licenses/LICENSE,sha256=bv5lDJZQEqxBgjjc1rkRbkEwpSIHF-8N-1Od0VnEJFw,1066
34
+ mcpforunityserver-9.3.0b20260128055651.dist-info/licenses/LICENSE,sha256=bv5lDJZQEqxBgjjc1rkRbkEwpSIHF-8N-1Od0VnEJFw,1066
32
35
  models/__init__.py,sha256=JlscZkGWE9TRmSoBi99v_LSl8OAFNGmr8463PYkXin4,179
33
36
  models/models.py,sha256=heXuvdBtdats1SGwW8wKFFHM0qR4hA6A7qETn5s9BZ0,1827
34
37
  models/unity_response.py,sha256=oJ1PTsnNc5VBC-9OgM59C0C-R9N-GdmEdmz_yph4GSU,1454
@@ -44,6 +47,7 @@ services/resources/editor_state.py,sha256=pQdcsWGcKV7-6icpcVXtFD35CHUXodANc0jXkl
44
47
  services/resources/gameobject.py,sha256=RM28kfsV208zdTy-549U2_nwSPiAHYo6SqXy22k4tC8,9116
45
48
  services/resources/layers.py,sha256=wE-mSgZsknGrXKu-0Cppv6NeijszD7beFf88dizT0ZI,1086
46
49
  services/resources/menu_items.py,sha256=9SNycjwTXoeS1ZHra0Y1fTyCjSEdPCo34JyxtuqauG8,1021
50
+ services/resources/prefab.py,sha256=z5mTWNke5MQauovbgdNa3HRe5-5B6K7FBspp-OtfGHM,7303
47
51
  services/resources/prefab_stage.py,sha256=RyVskG-P9lb4szbsTDhPpyDMb0ptLskr0BnoYJylhw0,1388
48
52
  services/resources/project_info.py,sha256=ggiUj9rJUvIddxorKu9yqJiHTWOnxyywkjjsKXhIyqA,1329
49
53
  services/resources/selection.py,sha256=MALwKkM9xsKing2bALNVTVLWzDTE_b26EVbnVUGZivU,1845
@@ -60,16 +64,17 @@ services/tools/execute_menu_item.py,sha256=k4J89LlXmEGyo9z3NK8Q0vREIzr11ucF_9tN_
60
64
  services/tools/find_gameobjects.py,sha256=Qpfd_oQG0fluz8S1CfriGh1FmLnZ080-ZEZOrAsij8U,3602
61
65
  services/tools/find_in_file.py,sha256=SxhMeo8lRrt0OiGApGZSFUnq671bxVfK8qgAsHxLua8,6493
62
66
  services/tools/manage_asset.py,sha256=St_iWQWg9icztnRthU78t6JNhJN0AlC6ELiZhn-SNZU,5990
63
- services/tools/manage_components.py,sha256=Z74QWrOdJyvQBRqIk3ZNYhUxyyH-R0Er1cEkt-70Hcg,5025
67
+ services/tools/manage_components.py,sha256=2_nKPk9iPAf5VyYiXuRxSkN8U76VNQbMtE68UTPngrw,5061
64
68
  services/tools/manage_editor.py,sha256=ShvlSBQRfoNQ0DvqBWak_Hi3MB7tv2WkMKEhrKQipk0,3279
65
- services/tools/manage_gameobject.py,sha256=fOuaYoQAZ1OgCnfSMZboqISRUr6bIuaBcG6XV-iVN_M,15092
66
- services/tools/manage_material.py,sha256=0i5gsTXkahzq_5qEByXvsMHxMpWuMBJH3HzbEr8GQns,5520
67
- services/tools/manage_prefabs.py,sha256=5waHRvxbdVA9N60tvf9m1f9NTRPspyxZOh4GZfuCfII,3179
69
+ services/tools/manage_gameobject.py,sha256=AXHT4fcrxvsaX53bypKoz3egY2uFI5kf7JCn2SizfB4,16604
70
+ services/tools/manage_material.py,sha256=Zt-tqGRCmOKTmttsu5yeudFNWzkDBkeuf44av06g-w0,5548
71
+ services/tools/manage_prefabs.py,sha256=mGGuYYpB2b9OV0fxNOtI8WnTZj9KjF7A3Isdzx8GGuI,6973
68
72
  services/tools/manage_scene.py,sha256=-ARtRuj7ZNk_14lmMSORnQs0qTAYKBTPtUfk0sNDo6A,5370
69
73
  services/tools/manage_script.py,sha256=MzPw0xXjtbdjEyjvUfLem9fa3GVE-WGvCr4WEVfW9Cs,28461
70
74
  services/tools/manage_scriptable_object.py,sha256=tezG_mbGzPLNpL3F7l5JJLyyjJN3rJi1thGMU8cpOC4,3659
71
75
  services/tools/manage_shader.py,sha256=bucRKzQww7opy6DK5nf6isVaEECWWqJ-DVkFulp8CV8,3185
72
- services/tools/manage_vfx.py,sha256=eeqf4xUYw_yT2rALIGHrHLJCpemx9H__S3zCjj_GZsI,34054
76
+ services/tools/manage_texture.py,sha256=ap2WolIJw2iVnLyAHhY6WahiGNLmtejJX7k0kq1zWrc,25932
77
+ services/tools/manage_vfx.py,sha256=7KFbRohF8EzaD0m7vVIEwjUz-QwC7NEXS5cVcU6Die0,4710
73
78
  services/tools/preflight.py,sha256=0nvo0BmZMdIGop1Ha_vypkjn2VLiRvskF0uxh_SlZgE,4162
74
79
  services/tools/read_console.py,sha256=ps23debJcQkj3Ap-MqTYVhopYnKGspJs9QHLJHZAAkE,6826
75
80
  services/tools/refresh_unity.py,sha256=KrRA8bmLkDLFO1XBv2NmagQAp1dmyaXdUAap567Hcv4,7100
@@ -89,8 +94,8 @@ transport/legacy/unity_connection.py,sha256=FE9ZQfYMhHvIxBycr_DjI3BKvuEdORXuABnC
89
94
  utils/focus_nudge.py,sha256=HaTOSI7wzDmdRviodUHx2oQFPIL_jSwubai3YkDJbH0,9910
90
95
  utils/module_discovery.py,sha256=My48ofB1BUqxiBoAZAGbEaLQYdsrDhMm8MayBP_bUSQ,2005
91
96
  utils/reload_sentinel.py,sha256=s1xMWhl-r2XwN0OUbiUv_VGUy8TvLtV5bkql-5n2DT0,373
92
- mcpforunityserver-9.3.0.dist-info/METADATA,sha256=7V0VW-sIvRdsK5pTHfomqPUmf-1UmITHOzMxSN8wf1c,5789
93
- mcpforunityserver-9.3.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
94
- mcpforunityserver-9.3.0.dist-info/entry_points.txt,sha256=pPm70RXQvkt3uBhPOtViDa47ZTA03RaQ6rwXvyi8oiI,70
95
- mcpforunityserver-9.3.0.dist-info/top_level.txt,sha256=3-A65WsmBO6UZYH8O5mINdyhhZ63SDssr8LncRd1PSQ,46
96
- mcpforunityserver-9.3.0.dist-info/RECORD,,
97
+ mcpforunityserver-9.3.0b20260128055651.dist-info/METADATA,sha256=oYHDprvEMpsJnYVleQbe99kXV7CRCOoPY32jTDkZ7Jc,5804
98
+ mcpforunityserver-9.3.0b20260128055651.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
99
+ mcpforunityserver-9.3.0b20260128055651.dist-info/entry_points.txt,sha256=pPm70RXQvkt3uBhPOtViDa47ZTA03RaQ6rwXvyi8oiI,70
100
+ mcpforunityserver-9.3.0b20260128055651.dist-info/top_level.txt,sha256=3-A65WsmBO6UZYH8O5mINdyhhZ63SDssr8LncRd1PSQ,46
101
+ mcpforunityserver-9.3.0b20260128055651.dist-info/RECORD,,