mcpforunityserver 8.5.0__py3-none-any.whl → 9.1.0__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.
Files changed (79) hide show
  1. cli/__init__.py +3 -0
  2. cli/commands/__init__.py +3 -0
  3. cli/commands/animation.py +87 -0
  4. cli/commands/asset.py +310 -0
  5. cli/commands/audio.py +133 -0
  6. cli/commands/batch.py +184 -0
  7. cli/commands/code.py +189 -0
  8. cli/commands/component.py +212 -0
  9. cli/commands/editor.py +487 -0
  10. cli/commands/gameobject.py +510 -0
  11. cli/commands/instance.py +101 -0
  12. cli/commands/lighting.py +128 -0
  13. cli/commands/material.py +268 -0
  14. cli/commands/prefab.py +144 -0
  15. cli/commands/scene.py +255 -0
  16. cli/commands/script.py +240 -0
  17. cli/commands/shader.py +238 -0
  18. cli/commands/ui.py +263 -0
  19. cli/commands/vfx.py +439 -0
  20. cli/main.py +248 -0
  21. cli/utils/__init__.py +31 -0
  22. cli/utils/config.py +58 -0
  23. cli/utils/connection.py +191 -0
  24. cli/utils/output.py +195 -0
  25. main.py +207 -62
  26. {mcpforunityserver-8.5.0.dist-info → mcpforunityserver-9.1.0.dist-info}/METADATA +4 -2
  27. mcpforunityserver-9.1.0.dist-info/RECORD +96 -0
  28. {mcpforunityserver-8.5.0.dist-info → mcpforunityserver-9.1.0.dist-info}/WHEEL +1 -1
  29. {mcpforunityserver-8.5.0.dist-info → mcpforunityserver-9.1.0.dist-info}/entry_points.txt +1 -0
  30. {mcpforunityserver-8.5.0.dist-info → mcpforunityserver-9.1.0.dist-info}/top_level.txt +1 -2
  31. services/custom_tool_service.py +179 -19
  32. services/resources/__init__.py +6 -1
  33. services/resources/active_tool.py +1 -1
  34. services/resources/custom_tools.py +2 -2
  35. services/resources/editor_state.py +283 -21
  36. services/resources/gameobject.py +243 -0
  37. services/resources/layers.py +1 -1
  38. services/resources/prefab_stage.py +1 -1
  39. services/resources/project_info.py +1 -1
  40. services/resources/selection.py +1 -1
  41. services/resources/tags.py +1 -1
  42. services/resources/unity_instances.py +1 -1
  43. services/resources/windows.py +1 -1
  44. services/state/external_changes_scanner.py +245 -0
  45. services/tools/__init__.py +6 -1
  46. services/tools/batch_execute.py +24 -9
  47. services/tools/debug_request_context.py +8 -2
  48. services/tools/execute_custom_tool.py +6 -1
  49. services/tools/execute_menu_item.py +6 -3
  50. services/tools/find_gameobjects.py +89 -0
  51. services/tools/find_in_file.py +26 -19
  52. services/tools/manage_asset.py +19 -43
  53. services/tools/manage_components.py +131 -0
  54. services/tools/manage_editor.py +9 -8
  55. services/tools/manage_gameobject.py +120 -79
  56. services/tools/manage_material.py +80 -31
  57. services/tools/manage_prefabs.py +7 -1
  58. services/tools/manage_scene.py +34 -13
  59. services/tools/manage_script.py +62 -19
  60. services/tools/manage_scriptable_object.py +22 -10
  61. services/tools/manage_shader.py +8 -1
  62. services/tools/manage_vfx.py +738 -0
  63. services/tools/preflight.py +110 -0
  64. services/tools/read_console.py +81 -18
  65. services/tools/refresh_unity.py +153 -0
  66. services/tools/run_tests.py +202 -41
  67. services/tools/script_apply_edits.py +15 -7
  68. services/tools/set_active_instance.py +12 -7
  69. services/tools/utils.py +60 -6
  70. transport/legacy/port_discovery.py +2 -2
  71. transport/legacy/unity_connection.py +129 -26
  72. transport/plugin_hub.py +191 -19
  73. transport/unity_instance_middleware.py +93 -2
  74. transport/unity_transport.py +17 -6
  75. utils/focus_nudge.py +321 -0
  76. __init__.py +0 -0
  77. mcpforunityserver-8.5.0.dist-info/RECORD +0 -66
  78. routes/__init__.py +0 -0
  79. {mcpforunityserver-8.5.0.dist-info → mcpforunityserver-9.1.0.dist-info}/licenses/LICENSE +0 -0
main.py CHANGED
@@ -1,3 +1,18 @@
1
+ from starlette.requests import Request
2
+ from transport.unity_instance_middleware import (
3
+ UnityInstanceMiddleware,
4
+ get_unity_instance_middleware
5
+ )
6
+ from transport.legacy.unity_connection import get_unity_connection_pool, UnityConnectionPool
7
+ from services.tools import register_all_tools
8
+ from core.telemetry import record_milestone, record_telemetry, MilestoneType, RecordType, get_package_version
9
+ from services.resources import register_all_resources
10
+ from transport.plugin_registry import PluginRegistry
11
+ from transport.plugin_hub import PluginHub
12
+ from services.custom_tool_service import CustomToolService
13
+ from core.config import config
14
+ from starlette.routing import WebSocketRoute
15
+ from starlette.responses import JSONResponse
1
16
  import argparse
2
17
  import asyncio
3
18
  import logging
@@ -30,28 +45,27 @@ try: # pragma: no cover - startup safety guard
30
45
  )
31
46
  for _name in _typing_names:
32
47
  if not hasattr(builtins, _name) and hasattr(_typing, _name):
33
- setattr(builtins, _name, getattr(_typing, _name)) # type: ignore[attr-defined]
48
+ # type: ignore[attr-defined]
49
+ setattr(builtins, _name, getattr(_typing, _name))
34
50
  except Exception:
35
51
  pass
36
52
 
37
53
  from fastmcp import FastMCP
38
54
  from logging.handlers import RotatingFileHandler
39
- from starlette.requests import Request
40
- from starlette.responses import JSONResponse
41
- from starlette.routing import WebSocketRoute
42
55
 
43
- from core.config import config
44
- from services.custom_tool_service import CustomToolService
45
- from transport.plugin_hub import PluginHub
46
- from transport.plugin_registry import PluginRegistry
47
- from services.resources import register_all_resources
48
- from core.telemetry import record_milestone, record_telemetry, MilestoneType, RecordType, get_package_version
49
- from services.tools import register_all_tools
50
- from transport.legacy.unity_connection import get_unity_connection_pool, UnityConnectionPool
51
- from transport.unity_instance_middleware import (
52
- UnityInstanceMiddleware,
53
- get_unity_instance_middleware
54
- )
56
+
57
+ class WindowsSafeRotatingFileHandler(RotatingFileHandler):
58
+ """RotatingFileHandler that gracefully handles Windows file locking during rotation."""
59
+
60
+ def doRollover(self):
61
+ """Override to catch PermissionError on Windows when log file is locked."""
62
+ try:
63
+ super().doRollover()
64
+ except PermissionError:
65
+ # On Windows, another process may have the log file open.
66
+ # Skip rotation this time - we'll try again on the next rollover.
67
+ pass
68
+
55
69
 
56
70
  # Configure logging using settings from config
57
71
  logging.basicConfig(
@@ -68,7 +82,7 @@ try:
68
82
  "~/Library/Application Support/UnityMCP"), "Logs")
69
83
  os.makedirs(_log_dir, exist_ok=True)
70
84
  _file_path = os.path.join(_log_dir, "unity_mcp_server.log")
71
- _fh = RotatingFileHandler(
85
+ _fh = WindowsSafeRotatingFileHandler(
72
86
  _file_path, maxBytes=512*1024, backupCount=2, encoding="utf-8")
73
87
  _fh.setFormatter(logging.Formatter(config.log_format))
74
88
  _fh.setLevel(getattr(logging, config.log_level))
@@ -227,17 +241,26 @@ async def server_lifespan(server: FastMCP) -> AsyncIterator[dict[str, Any]]:
227
241
  _unity_connection_pool.disconnect_all()
228
242
  logger.info("MCP for Unity Server shut down")
229
243
 
230
- # Initialize MCP server
231
- mcp = FastMCP(
232
- name="mcp-for-unity-server",
233
- lifespan=server_lifespan,
234
- instructions="""
244
+
245
+ def _build_instructions(project_scoped_tools: bool) -> str:
246
+ if project_scoped_tools:
247
+ custom_tools_note = (
248
+ "I have a dynamic tool system. Always check the mcpforunity://custom-tools resource first "
249
+ "to see what special capabilities are available for the current project."
250
+ )
251
+ else:
252
+ custom_tools_note = (
253
+ "Custom tools are registered as standard tools when Unity connects. "
254
+ "No project-scoped custom tools resource is available."
255
+ )
256
+
257
+ return f"""
235
258
  This server provides tools to interact with the Unity Game Engine Editor.
236
259
 
237
- I have a dynamic tool system. Always check the unity://custom-tools resource first to see what special capabilities are available for the current project.
260
+ {custom_tools_note}
238
261
 
239
262
  Targeting Unity instances:
240
- - Use the resource unity://instances to list active Unity sessions (Name@hash).
263
+ - Use the resource mcpforunity://instances to list active Unity sessions (Name@hash).
241
264
  - When multiple instances are connected, call set_active_instance with the exact Name@hash before using tools/resources. The server will error if multiple are connected and no active instance is set.
242
265
 
243
266
  Important Workflows:
@@ -281,46 +304,123 @@ Payload sizing & paging (important):
281
304
  - Use paging (`page_size`, `page_number`) and keep `page_size` modest (e.g. **25-50**) to avoid token-heavy responses.
282
305
  - Keep `generate_preview=false` unless you explicitly need thumbnails (previews may include large base64 payloads).
283
306
  """
284
- )
285
-
286
- custom_tool_service = CustomToolService(mcp)
287
-
288
307
 
289
- @mcp.custom_route("/health", methods=["GET"])
290
- async def health_http(_: Request) -> JSONResponse:
291
- return JSONResponse({
292
- "status": "healthy",
293
- "timestamp": time.time(),
294
- "message": "MCP for Unity server is running"
295
- })
296
-
297
-
298
- @mcp.custom_route("/plugin/sessions", methods=["GET"])
299
- async def plugin_sessions_route(_: Request) -> JSONResponse:
300
- data = await PluginHub.get_sessions()
301
- return JSONResponse(data.model_dump())
302
308
 
309
+ def create_mcp_server(project_scoped_tools: bool) -> FastMCP:
310
+ mcp = FastMCP(
311
+ name="mcp-for-unity-server",
312
+ lifespan=server_lifespan,
313
+ instructions=_build_instructions(project_scoped_tools),
314
+ )
303
315
 
304
- # Initialize and register middleware for session-based Unity instance routing
305
- # Using the singleton getter ensures we use the same instance everywhere
306
- unity_middleware = get_unity_instance_middleware()
307
- mcp.add_middleware(unity_middleware)
308
- logger.info("Registered Unity instance middleware for session-based routing")
316
+ global custom_tool_service
317
+ custom_tool_service = CustomToolService(
318
+ mcp, project_scoped_tools=project_scoped_tools)
319
+
320
+ @mcp.custom_route("/health", methods=["GET"])
321
+ async def health_http(_: Request) -> JSONResponse:
322
+ return JSONResponse({
323
+ "status": "healthy",
324
+ "timestamp": time.time(),
325
+ "message": "MCP for Unity server is running"
326
+ })
327
+
328
+ @mcp.custom_route("/api/command", methods=["POST"])
329
+ async def cli_command_route(request: Request) -> JSONResponse:
330
+ """REST endpoint for CLI commands to Unity."""
331
+ try:
332
+ body = await request.json()
333
+
334
+ command_type = body.get("type")
335
+ params = body.get("params", {})
336
+ unity_instance = body.get("unity_instance")
337
+
338
+ if not command_type:
339
+ return JSONResponse({"success": False, "error": "Missing 'type' field"}, status_code=400)
340
+
341
+ # Get available sessions
342
+ sessions = await PluginHub.get_sessions()
343
+ if not sessions.sessions:
344
+ return JSONResponse({
345
+ "success": False,
346
+ "error": "No Unity instances connected. Make sure Unity is running with MCP plugin."
347
+ }, status_code=503)
348
+
349
+ # Find target session
350
+ session_id = None
351
+ if unity_instance:
352
+ # Try to match by hash or project name
353
+ for sid, details in sessions.sessions.items():
354
+ if details.hash == unity_instance or details.project == unity_instance:
355
+ session_id = sid
356
+ break
357
+
358
+ # If a specific unity_instance was requested but not found, return an error
359
+ if not session_id:
360
+ return JSONResponse(
361
+ {
362
+ "success": False,
363
+ "error": f"Unity instance '{unity_instance}' not found",
364
+ },
365
+ status_code=404,
366
+ )
367
+ else:
368
+ # No specific unity_instance requested: use first available session
369
+ session_id = next(iter(sessions.sessions.keys()))
309
370
 
310
- # Mount plugin websocket hub at /hub/plugin when HTTP transport is active
311
- existing_routes = [
312
- route for route in mcp._get_additional_http_routes()
313
- if isinstance(route, WebSocketRoute) and route.path == "/hub/plugin"
314
- ]
315
- if not existing_routes:
316
- mcp._additional_http_routes.append(
317
- WebSocketRoute("/hub/plugin", PluginHub))
371
+ # Send command to Unity
372
+ result = await PluginHub.send_command(session_id, command_type, params)
373
+ return JSONResponse(result)
318
374
 
319
- # Register all tools
320
- register_all_tools(mcp)
375
+ except Exception as e:
376
+ logger.error(f"CLI command error: {e}")
377
+ return JSONResponse({"success": False, "error": str(e)}, status_code=500)
321
378
 
322
- # Register all resources
323
- register_all_resources(mcp)
379
+ @mcp.custom_route("/api/instances", methods=["GET"])
380
+ async def cli_instances_route(_: Request) -> JSONResponse:
381
+ """REST endpoint to list connected Unity instances."""
382
+ try:
383
+ sessions = await PluginHub.get_sessions()
384
+ instances = []
385
+ for session_id, details in sessions.sessions.items():
386
+ instances.append({
387
+ "session_id": session_id,
388
+ "project": details.project,
389
+ "hash": details.hash,
390
+ "unity_version": details.unity_version,
391
+ "connected_at": details.connected_at,
392
+ })
393
+ return JSONResponse({"success": True, "instances": instances})
394
+ except Exception as e:
395
+ return JSONResponse({"success": False, "error": str(e)}, status_code=500)
396
+
397
+ @mcp.custom_route("/plugin/sessions", methods=["GET"])
398
+ async def plugin_sessions_route(_: Request) -> JSONResponse:
399
+ data = await PluginHub.get_sessions()
400
+ return JSONResponse(data.model_dump())
401
+
402
+ # Initialize and register middleware for session-based Unity instance routing
403
+ # Using the singleton getter ensures we use the same instance everywhere
404
+ unity_middleware = get_unity_instance_middleware()
405
+ mcp.add_middleware(unity_middleware)
406
+ logger.info("Registered Unity instance middleware for session-based routing")
407
+
408
+ # Mount plugin websocket hub at /hub/plugin when HTTP transport is active
409
+ existing_routes = [
410
+ route for route in mcp._get_additional_http_routes()
411
+ if isinstance(route, WebSocketRoute) and route.path == "/hub/plugin"
412
+ ]
413
+ if not existing_routes:
414
+ mcp._additional_http_routes.append(
415
+ WebSocketRoute("/hub/plugin", PluginHub))
416
+
417
+ # Register all tools
418
+ register_all_tools(mcp, project_scoped_tools=project_scoped_tools)
419
+
420
+ # Register all resources
421
+ register_all_resources(mcp, project_scoped_tools=project_scoped_tools)
422
+
423
+ return mcp
324
424
 
325
425
 
326
426
  def main():
@@ -391,6 +491,27 @@ Examples:
391
491
  help="HTTP server port (overrides URL port). "
392
492
  "Overrides UNITY_MCP_HTTP_PORT environment variable."
393
493
  )
494
+ parser.add_argument(
495
+ "--unity-instance-token",
496
+ type=str,
497
+ default=None,
498
+ metavar="TOKEN",
499
+ help="Optional per-launch token set by Unity for deterministic lifecycle management. "
500
+ "Used by Unity to validate it is stopping the correct process."
501
+ )
502
+ parser.add_argument(
503
+ "--pidfile",
504
+ type=str,
505
+ default=None,
506
+ metavar="PATH",
507
+ help="Optional path where the server will write its PID on startup. "
508
+ "Used by Unity to stop the exact process it launched when running in a terminal."
509
+ )
510
+ parser.add_argument(
511
+ "--project-scoped-tools",
512
+ action="store_true",
513
+ help="Keep custom tools scoped to the active Unity project and enable the custom tools resource."
514
+ )
394
515
 
395
516
  args = parser.parse_args()
396
517
 
@@ -412,12 +533,35 @@ Examples:
412
533
  # Allow individual host/port to override URL components
413
534
  http_host = args.http_host or os.environ.get(
414
535
  "UNITY_MCP_HTTP_HOST") or parsed_url.hostname or "localhost"
415
- http_port = args.http_port or (int(os.environ.get("UNITY_MCP_HTTP_PORT")) if os.environ.get(
416
- "UNITY_MCP_HTTP_PORT") else None) or parsed_url.port or 8080
536
+
537
+ # Safely parse optional environment port (may be None or non-numeric)
538
+ _env_port_str = os.environ.get("UNITY_MCP_HTTP_PORT")
539
+ try:
540
+ _env_port = int(_env_port_str) if _env_port_str is not None else None
541
+ except ValueError:
542
+ logger.warning(
543
+ "Invalid UNITY_MCP_HTTP_PORT value '%s', ignoring", _env_port_str)
544
+ _env_port = None
545
+
546
+ http_port = args.http_port or _env_port or parsed_url.port or 8080
417
547
 
418
548
  os.environ["UNITY_MCP_HTTP_HOST"] = http_host
419
549
  os.environ["UNITY_MCP_HTTP_PORT"] = str(http_port)
420
550
 
551
+ # Optional lifecycle handshake for Unity-managed terminal launches
552
+ if args.unity_instance_token:
553
+ os.environ["UNITY_MCP_INSTANCE_TOKEN"] = args.unity_instance_token
554
+ if args.pidfile:
555
+ try:
556
+ pid_dir = os.path.dirname(args.pidfile)
557
+ if pid_dir:
558
+ os.makedirs(pid_dir, exist_ok=True)
559
+ with open(args.pidfile, "w", encoding="ascii") as f:
560
+ f.write(str(os.getpid()))
561
+ except Exception as exc:
562
+ logger.warning(
563
+ "Failed to write pidfile '%s': %s", args.pidfile, exc)
564
+
421
565
  if args.http_url != "http://localhost:8080":
422
566
  logger.info(f"HTTP URL set to: {http_url}")
423
567
  if args.http_host:
@@ -425,6 +569,8 @@ Examples:
425
569
  if args.http_port:
426
570
  logger.info(f"HTTP port override: {http_port}")
427
571
 
572
+ mcp = create_mcp_server(args.project_scoped_tools)
573
+
428
574
  # Determine transport mode
429
575
  if transport_mode == 'http':
430
576
  # Use HTTP transport for FastMCP
@@ -434,8 +580,7 @@ Examples:
434
580
  parsed_url = urlparse(http_url)
435
581
  host = args.http_host or os.environ.get(
436
582
  "UNITY_MCP_HTTP_HOST") or parsed_url.hostname or "localhost"
437
- port = args.http_port or (int(os.environ.get("UNITY_MCP_HTTP_PORT")) if os.environ.get(
438
- "UNITY_MCP_HTTP_PORT") else None) or parsed_url.port or 8080
583
+ port = args.http_port or _env_port or parsed_url.port or 8080
439
584
  logger.info(f"Starting FastMCP with HTTP transport on {host}:{port}")
440
585
  mcp.run(transport=transport, host=host, port=port)
441
586
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcpforunityserver
3
- Version: 8.5.0
3
+ Version: 9.1.0
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
@@ -32,9 +32,11 @@ Requires-Dist: pydantic>=2.12.5
32
32
  Requires-Dist: tomli>=2.3.0
33
33
  Requires-Dist: fastapi>=0.104.0
34
34
  Requires-Dist: uvicorn>=0.35.0
35
+ Requires-Dist: click>=8.1.0
35
36
  Provides-Extra: dev
36
37
  Requires-Dist: pytest>=8.0.0; extra == "dev"
37
38
  Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
39
+ Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
38
40
  Dynamic: license-file
39
41
 
40
42
  # MCP for Unity Server
@@ -108,7 +110,7 @@ Use this to run the latest released version from the repository. Change the vers
108
110
  "command": "uvx",
109
111
  "args": [
110
112
  "--from",
111
- "git+https://github.com/CoplayDev/unity-mcp@v8.5.0#subdirectory=Server",
113
+ "git+https://github.com/CoplayDev/unity-mcp@v9.1.0#subdirectory=Server",
112
114
  "mcp-for-unity",
113
115
  "--transport",
114
116
  "stdio"
@@ -0,0 +1,96 @@
1
+ main.py,sha256=iscQv6VBCK-kHFDmu-Cgskc_S3-kWlF-2AuF-vMr0MI,23952
2
+ cli/__init__.py,sha256=f2HjXqR9d8Uhibru211t9HPpdrb_1vdDC2v_NwF_eqA,63
3
+ cli/main.py,sha256=LFrHFWxiUlX7Ttc-YxqHeXxIcEzhNndpvUJT_LQ28mw,7101
4
+ cli/commands/__init__.py,sha256=xQHf6o0afDV2HsU9gwSxjcrzS41cMCSGZyWYWxblPIk,69
5
+ cli/commands/animation.py,sha256=emBE5oKhFQNU8V2ENm9E5N4Grj0Tah9H0X7fF6grQdk,2442
6
+ cli/commands/asset.py,sha256=V1xzLgBPhdRzXsnj9Wt2HnJYo_8hT3RqoVnR2WrLP5w,7988
7
+ cli/commands/audio.py,sha256=qJ-Whc8aH7oUgT79O_RRRo-lAVktFqtC5pgbyG2bRNo,3333
8
+ cli/commands/batch.py,sha256=rMe8BDsthZ0AwaDrFoj6Kxl4xAVNRIlKSCcJ5eSagyY,5732
9
+ cli/commands/code.py,sha256=FGV8IDx6eFhcEmc6jREQwHwoOdiUyhY8d6Hy7KN4cTw,5624
10
+ cli/commands/component.py,sha256=uIOtno1T2mPF3rnW2OymetggScqtWrs_Th06FI7FISQ,6327
11
+ cli/commands/editor.py,sha256=mlfCQjw1PtA6V4ZY7HlbQ7ICDvvxu5EH7y6JOYMj0yU,13219
12
+ cli/commands/gameobject.py,sha256=b7ZxHXyIgUOvjYhHmKavigs-wfxGB6NhDMqqRyEGtNY,13643
13
+ cli/commands/instance.py,sha256=J6uQrNIEWbnJT-Y09ICTA9R11lgtPQflBbmTrBr5bg8,3041
14
+ cli/commands/lighting.py,sha256=eBvSDhQ5jkoUJJ4sito0yFxXwJv0JlpT4iD-D6Q2Pak,3869
15
+ cli/commands/material.py,sha256=51uxeoTgqnnMuUQUbhBTdMdI70kU4pOCH6GUIy2OjQI,7847
16
+ cli/commands/prefab.py,sha256=1t0fnGdDWD_a3yok02QI74YYmS1M92LDYfWvv_8iz90,3607
17
+ cli/commands/scene.py,sha256=P08rud-6FZaO8Tw9jnP0xcS043Bf5IAooGbEDZPVBqw,6274
18
+ cli/commands/script.py,sha256=Yf9o00irn4wf0cbsE665mxJehwtiIr0y3IHKLyvYhgY,6434
19
+ cli/commands/shader.py,sha256=CwIIgyrU9OosVmidD6E9Txmn6Yyo4rDJBubrBchAlVw,6380
20
+ cli/commands/ui.py,sha256=JDfAXE3ba45r41Svfop-fiy4p8C0gxE4ekJ8aFRG7aI,7627
21
+ cli/commands/vfx.py,sha256=5wKypI-QWa8Jd-Fp6bLGBiQw8wuIg6fynL6WiOJy36c,15199
22
+ cli/utils/__init__.py,sha256=Gbm9hYC7UqwloFwdirXgo6z1iBktR9Y96o3bQcrYudc,613
23
+ cli/utils/config.py,sha256=_k3XAFmXG22sv8tYIb5JmO46kNl3T1sGqFptySAayfc,1550
24
+ cli/utils/connection.py,sha256=T1xKA3Vr98Oj9b0RvFKQLAh2stvHwCdOiq3GIc58ZvE,6150
25
+ cli/utils/output.py,sha256=96daU55ta_hl7UeOhNh5Iy7OJ4psbdR9Nfx1-q2k3xA,6370
26
+ core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
+ core/config.py,sha256=czkTtNji1crQcQbUvmdx4OL7f-RBqkVhj_PtHh-w7rs,1623
28
+ core/logging_decorator.py,sha256=D9CD7rFvQz-MBG-G4inizQj0Ivr6dfc9RBmTrw7q8mI,1383
29
+ core/telemetry.py,sha256=eHjYgzd8f7eTwSwF2Kbi8D4TtJIcdaDjKLeo1c-0hVA,19829
30
+ core/telemetry_decorator.py,sha256=ycSTrzVNCDQHSd-xmIWOpVfKFURPxpiZe_XkOQAGDAo,6705
31
+ mcpforunityserver-9.1.0.dist-info/licenses/LICENSE,sha256=bv5lDJZQEqxBgjjc1rkRbkEwpSIHF-8N-1Od0VnEJFw,1066
32
+ models/__init__.py,sha256=JlscZkGWE9TRmSoBi99v_LSl8OAFNGmr8463PYkXin4,179
33
+ models/models.py,sha256=heXuvdBtdats1SGwW8wKFFHM0qR4hA6A7qETn5s9BZ0,1827
34
+ models/unity_response.py,sha256=oJ1PTsnNc5VBC-9OgM59C0C-R9N-GdmEdmz_yph4GSU,1454
35
+ services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
+ services/custom_tool_service.py,sha256=WJxljL-hdJE5GMlAhVimHVhQwwnWHCd0StgWhWEFgaI,18592
37
+ services/registry/__init__.py,sha256=QCwcYThvGF0kBt3WR6DBskdyxkegJC7NymEChgJA-YM,470
38
+ services/registry/resource_registry.py,sha256=T_Kznqgvt5kKgV7mU85nb0LlFuB4rg-Tm4Cjhxt-IcI,1467
39
+ services/registry/tool_registry.py,sha256=9tMwOP07JE92QFYUS4KvoysO0qC9pkBD5B79kjRsSPw,1304
40
+ services/resources/__init__.py,sha256=G8uSEYJtiyX3yg0QsfoeGdDXOdbU89l5m0B5Anay1Fc,3054
41
+ services/resources/active_tool.py,sha256=zDuWRK1uz853TrMNv0w8vhZVOxemDPoI4QAkXSIezN8,1480
42
+ services/resources/custom_tools.py,sha256=3t0mKAL9PkJbv8S4DpRFU8D-NlRWkCd2geO6QnlQo7I,1716
43
+ services/resources/editor_state.py,sha256=pQdcsWGcKV7-6icpcVXtFD35CHUXodANc0jXkljVdLs,10823
44
+ services/resources/gameobject.py,sha256=RM28kfsV208zdTy-549U2_nwSPiAHYo6SqXy22k4tC8,9116
45
+ services/resources/layers.py,sha256=wE-mSgZsknGrXKu-0Cppv6NeijszD7beFf88dizT0ZI,1086
46
+ services/resources/menu_items.py,sha256=9SNycjwTXoeS1ZHra0Y1fTyCjSEdPCo34JyxtuqauG8,1021
47
+ services/resources/prefab_stage.py,sha256=RyVskG-P9lb4szbsTDhPpyDMb0ptLskr0BnoYJylhw0,1388
48
+ services/resources/project_info.py,sha256=ggiUj9rJUvIddxorKu9yqJiHTWOnxyywkjjsKXhIyqA,1329
49
+ services/resources/selection.py,sha256=MALwKkM9xsKing2bALNVTVLWzDTE_b26EVbnVUGZivU,1845
50
+ services/resources/tags.py,sha256=IKZWiZhBO_HkJqFXqBvWeIcMxhGN_QXkonzuAEFsEfg,1055
51
+ services/resources/tests.py,sha256=xDvvgesPSU93nLD_ERQopOpkpq69pbMEqmFsJd0jekI,2063
52
+ services/resources/unity_instances.py,sha256=XRR5YCDe8v_FXG45VlSdEPaqu7Qlbnm4NYIRzK5brjc,4354
53
+ services/resources/windows.py,sha256=FyzPEtEmfKiXYh1lviemZ7-bFyjkAR61_seSTXQA9rk,1433
54
+ services/state/external_changes_scanner.py,sha256=ZiXu8ZcK5B-hv7CaJLmnEIa9JxzgOBpdmrsRDY2eK5I,9052
55
+ services/tools/__init__.py,sha256=mS9EpbPWchYj6gNW1eu0REv-SLPsQkY8xTkk7u-DeMU,2607
56
+ services/tools/batch_execute.py,sha256=hjh67kgWvQDHyGd2N-Tfezv9WAj5x_pWTt_Vybmmq7s,3501
57
+ services/tools/debug_request_context.py,sha256=Duq5xiuSmRO5GdvWAlZhCfOfmrwvK7gGkRC4wYnXmXk,2907
58
+ services/tools/execute_custom_tool.py,sha256=hiZbm2A9t84f92jitzvkE2G4CMOIUiDVm7u5B8K-RbU,1527
59
+ services/tools/execute_menu_item.py,sha256=k4J89LlXmEGyo9z3NK8Q0vREIzr11ucF_9tN_JeQq9M,1248
60
+ services/tools/find_gameobjects.py,sha256=Qpfd_oQG0fluz8S1CfriGh1FmLnZ080-ZEZOrAsij8U,3602
61
+ services/tools/find_in_file.py,sha256=SxhMeo8lRrt0OiGApGZSFUnq671bxVfK8qgAsHxLua8,6493
62
+ services/tools/manage_asset.py,sha256=St_iWQWg9icztnRthU78t6JNhJN0AlC6ELiZhn-SNZU,5990
63
+ services/tools/manage_components.py,sha256=Z74QWrOdJyvQBRqIk3ZNYhUxyyH-R0Er1cEkt-70Hcg,5025
64
+ 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
68
+ services/tools/manage_scene.py,sha256=-ARtRuj7ZNk_14lmMSORnQs0qTAYKBTPtUfk0sNDo6A,5370
69
+ services/tools/manage_script.py,sha256=MzPw0xXjtbdjEyjvUfLem9fa3GVE-WGvCr4WEVfW9Cs,28461
70
+ services/tools/manage_scriptable_object.py,sha256=tezG_mbGzPLNpL3F7l5JJLyyjJN3rJi1thGMU8cpOC4,3659
71
+ services/tools/manage_shader.py,sha256=bucRKzQww7opy6DK5nf6isVaEECWWqJ-DVkFulp8CV8,3185
72
+ services/tools/manage_vfx.py,sha256=eeqf4xUYw_yT2rALIGHrHLJCpemx9H__S3zCjj_GZsI,34054
73
+ services/tools/preflight.py,sha256=0nvo0BmZMdIGop1Ha_vypkjn2VLiRvskF0uxh_SlZgE,4162
74
+ services/tools/read_console.py,sha256=ps23debJcQkj3Ap-MqTYVhopYnKGspJs9QHLJHZAAkE,6826
75
+ services/tools/refresh_unity.py,sha256=KrRA8bmLkDLFO1XBv2NmagQAp1dmyaXdUAap567Hcv4,7100
76
+ services/tools/run_tests.py,sha256=wg8Ke8vpKHxyz0kqFaJC5feXTL3e6Cxzi0QKNitLDRE,9176
77
+ services/tools/script_apply_edits.py,sha256=0f-SaP5NUYGuivl4CWHjR8F-CXUpt3-5qkHpf_edn1U,47677
78
+ services/tools/set_active_instance.py,sha256=pdmC1SxFijyzzjeEyC2N1bXk-GNMu_iXsbCieIpa-R4,4242
79
+ services/tools/utils.py,sha256=uk--6w_-O0eVAxczackXbgKde2ONmsgci43G3wY7dfA,4258
80
+ transport/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
81
+ transport/models.py,sha256=6wp7wsmSaeeJEvUGXPF1m6zuJnxJ1NJlCC4YZ9oQIq0,1226
82
+ transport/plugin_hub.py,sha256=X6tAnJU0s1LQtgIgiK_YHBhSWMRD5bRjbkGjOl8eLFQ,23725
83
+ transport/plugin_registry.py,sha256=nW-7O7PN0QUgSWivZTkpAVKKq9ZOe2b2yeIdpaNt_3I,4359
84
+ transport/unity_instance_middleware.py,sha256=DD8gs-peMRmRJz9CYwaHEh4m75LTYPDjVuKuw9sArBw,10438
85
+ transport/unity_transport.py,sha256=G6aMC1qR31YZOBZs4fxQbSQBHuXBP1d5Qn0MJaB3yGs,3908
86
+ transport/legacy/port_discovery.py,sha256=JDSCqXLodfTT7fOsE0DFC1jJ3QsU6hVaYQb7x7FgdxY,12728
87
+ transport/legacy/stdio_port_registry.py,sha256=j4iARuP6wetppNDG8qKeuvo1bJKcSlgEhZvSyl_uf0A,2313
88
+ transport/legacy/unity_connection.py,sha256=FE9ZQfYMhHvIxBycr_DjI3BKvuEdORXuABnCE5Q2tjQ,36733
89
+ utils/focus_nudge.py,sha256=HaTOSI7wzDmdRviodUHx2oQFPIL_jSwubai3YkDJbH0,9910
90
+ utils/module_discovery.py,sha256=My48ofB1BUqxiBoAZAGbEaLQYdsrDhMm8MayBP_bUSQ,2005
91
+ utils/reload_sentinel.py,sha256=s1xMWhl-r2XwN0OUbiUv_VGUy8TvLtV5bkql-5n2DT0,373
92
+ mcpforunityserver-9.1.0.dist-info/METADATA,sha256=PACNq7XroxW8GgaCiY6HYFoBy8hR-9ykPJadwFVeGEU,5789
93
+ mcpforunityserver-9.1.0.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
94
+ mcpforunityserver-9.1.0.dist-info/entry_points.txt,sha256=pPm70RXQvkt3uBhPOtViDa47ZTA03RaQ6rwXvyi8oiI,70
95
+ mcpforunityserver-9.1.0.dist-info/top_level.txt,sha256=3-A65WsmBO6UZYH8O5mINdyhhZ63SDssr8LncRd1PSQ,46
96
+ mcpforunityserver-9.1.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,2 +1,3 @@
1
1
  [console_scripts]
2
2
  mcp-for-unity = main:main
3
+ unity-mcp = cli.main:main
@@ -1,8 +1,7 @@
1
- __init__
1
+ cli
2
2
  core
3
3
  main
4
4
  models
5
- routes
6
5
  services
7
6
  transport
8
7
  utils