Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: CoplayDev/unity-mcp
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v8.7.1
Choose a base ref
...
head repository: CoplayDev/unity-mcp
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v9.0.0
Choose a head ref
  • 15 commits
  • 985 files changed
  • 12 contributors

Commits on Jan 5, 2026

  1. Configuration menu
    Copy the full SHA
    d6a1a9b View commit details
    Browse the repository at this point in the history

Commits on Jan 6, 2026

  1. fix: Multi-session UI improvements and HTTP instance recognition (#517)

    * fix: Multi-session UI improvements and HTTP instance recognition
    
    - Separate server and session lifecycle in HTTP Local mode
      - Show 'Start Server' / 'Stop Server' button for server control
      - Show 'Start Session' / 'End Session' button when server is running
      - No auto-join on server start (requires manual session start)
    - Show instance name instead of port in session status (e.g. 'Session Active (ramble)')
    - Use native project_hash for HTTP instance recognition instead of computed SHA256
    - Fix test expectations for manage_asset JSON parsing error messages
    
    * fix: Multi-session UI improvements and HTTP instance recognition
    
    - Separate server and session lifecycle in HTTP Local mode
      - Show 'Start Server' / 'Stop Server' button for server control
      - Show 'Start Session' / 'End Session' button when server is running
      - Auto-start session when THIS instance starts the server
      - Require manual session start when connecting to external server
      - Auto-detect and end orphaned sessions when server stops
    - Show instance name instead of port in session status
    - Use native project_hash for HTTP instance recognition
      - Guard against empty hash with warning log
    - Remove dead code (duplicate _safe_response)
    - Add defensive path handling for instance name extraction
    dsarno authored Jan 6, 2026
    Configuration menu
    Copy the full SHA
    2a1e56a View commit details
    Browse the repository at this point in the history
  2. feat: Add tool annotations for improved LLM tool understanding (#480)

    * feat: Add tool annotations for improved LLM tool understanding
    
    Add readOnlyHint and destructiveHint annotations to all 23 tools
    to help LLMs better understand tool behavior and make safer decisions.
    
    Changes:
    - Added readOnlyHint: true to 5 read-only tools:
      - debug_request_context, find_in_file, validate_script,
        manage_script_capabilities, get_sha
    - Added destructiveHint: true to 18 tools that modify data:
      - All CRUD tools, execution tools, and state-modifying tools
    - Added title annotations for human-readable display
    - Imported ToolAnnotations from mcp.types in all tool files
    
    This improves tool safety metadata for MCP clients.
    
    🤖 Generated with [Claude Code](https://claude.com/claude-code)
    
    Co-Authored-By: Claude <noreply@anthropic.com>
    
    * docs: Clarify dual-purpose tool behavior in annotations
    
    Address Sourcery AI review feedback by updating descriptions for
    batch_execute and manage_* tools to clarify their safety characteristics
    depend on the specific actions/operations being performed.
    
    Updated tools:
    - batch_execute: clarifies safety depends on contained tools
    - read_console: clarifies 'get' is read-only, 'clear' is destructive
    - manage_asset: lists read-only vs destructive actions
    - manage_gameobject: lists read-only vs destructive actions
    - manage_scene: lists read-only vs destructive actions
    - manage_editor: lists read-only vs destructive actions
    - manage_material: lists read-only vs destructive actions
    - manage_shader: lists read-only vs destructive actions
    - manage_script: lists read-only vs destructive actions
    
    🤖 Generated with [Claude Code](https://claude.com/claude-code)
    
    Co-Authored-By: Claude <noreply@anthropic.com>
    
    * fix: Remove destructiveHint from mixed-behavior tools
    
    Address maintainer feedback on annotation semantics. Tools that
    have both read-only and modifying actions based on the 'action'
    parameter should not be marked as destructive.
    
    Changed to title-only annotations:
    - manage_gameobject (find/get vs create/modify/delete)
    - manage_scene (get_hierarchy vs create/load/save)
    - manage_prefabs (open_stage vs save/create)
    - manage_material (ping/get vs create/set)
    - manage_shader (read vs create/update/delete)
    - manage_editor (telemetry_status vs play/pause)
    - manage_script router (read vs create/delete)
    - batch_execute (depends on contained operations)
    - execute_menu_item (behavior varies by menu item)
    - execute_custom_tool (behavior varies by custom tool)
    - read_console (get vs clear - ephemeral UI state)
    
    Kept destructiveHint=True for always-destructive tools:
    - apply_text_edits (always writes files)
    - create_script (always creates files)
    - delete_script (always deletes files)
    - script_apply_edits (always writes files)
    - run_tests (always executes tests)
    - set_active_instance (always modifies session)
    
    * fix: Remove destructiveHint from set_active_instance
    
    set_active_instance is a session-scoped operation that switches which
    Unity instance is active. It doesn't persist data and is easily reversible,
    so it should not be marked as destructive.
    
    * fix: Re-apply destructiveHint per maintainer guidance on MCP spec
    
    Per maintainer feedback referencing MCP docs, tools should have
    destructiveHint=True if they MAY perform a destructive action,
    even if they also support read-only operations.
    
    Re-applied to tools that can destroy Unity resources:
    - manage_gameobject, manage_scene, manage_prefabs
    - manage_material, manage_shader, manage_script
    - manage_asset, batch_execute
    - execute_menu_item, execute_custom_tool
    
    Kept as-is (no destructiveHint):
    - read_console (clearing is ephemeral UI state)
    - set_active_instance (session toggle, not destructive)
    - manage_editor (no destructive actions)
    
    🤖 Generated with [Claude Code](https://claude.com/claude-code)
    
    * feat: Add tool annotations to manage_scriptable_object
    
    Per reviewer request (@dsarno), add ToolAnnotations with destructiveHint=True
    to manage_scriptable_object tool since it can create/modify ScriptableObject assets.
    
    🤖 Generated with [Claude Code](https://claude.com/claude-code)
    
    * feat: Add tool annotations to new async test and refresh tools
    
    Add readOnlyHint and destructiveHint annotations to tools added
    since the last commit:
    
    - refresh_unity: destructiveHint=True (triggers asset DB refresh)
    - run_tests_async: destructiveHint=True (starts test execution)
    - get_test_job: readOnlyHint=True (queries job status only)
    
    Also regenerate uv.lock after rebase.
    
    ---------
    
    Co-authored-by: triepod-ai <noreply@github.com>
    Co-authored-by: Claude <noreply@anthropic.com>
    Co-authored-by: triepod-ai <199543909+triepod-ai@users.noreply.github.com>
    4 people authored Jan 6, 2026
    Configuration menu
    Copy the full SHA
    9d5a817 View commit details
    Browse the repository at this point in the history
  3. 🎮 GameObject Toolset Redesign and Streamlining (#518)

    * feat: Redesign GameObject API for better LLM ergonomics
    
    ## New Tools
    - find_gameobjects: Search GameObjects, returns paginated instance IDs only
    - manage_components: Component lifecycle (add, remove, set_property)
    
    ## New Resources
    - unity://scene/gameobject/{id}: Single GameObject data (no component serialization)
    - unity://scene/gameobject/{id}/components: All components (paginated)
    - unity://scene/gameobject/{id}/component/{name}: Single component by type
    
    ## Updated
    - manage_scene get_hierarchy: Now includes componentTypes array
    - manage_gameobject: Slimmed to lifecycle only (create, modify, delete)
      - Legacy actions (find, get_components, etc.) log deprecation warnings
    
    ## Extracted Utilities
    - ParamCoercion: Centralized int/bool/float/string coercion
    - VectorParsing: Vector3/Vector2/Quaternion/Color parsing
    - GameObjectLookup: Centralized GameObject search logic
    
    ## Test Coverage
    - 76 new Unity EditMode tests for ManageGameObject actions
    - 21 new pytest tests for Python tools/resources
    - New NL/T CI suite for GameObject API (GO-0 to GO-5)
    
    Addresses LLM confusion with parameter overload by splitting into
    focused tools and read-only resources.
    
    * feat: Add static gameobject_api helper resource for UI discoverability
    
    Adds unity://scene/gameobject-api resource that:
    - Shows in Cursor's resource list UI (no parameters needed)
    - Documents the parameterized gameobject resources
    - Explains the workflow: find_gameobjects → read resource
    - Lists examples and related tools
    
    * feat: Add GO tests to main NL/T CI workflow
    
    - Adds GO pass (GO-0 to GO-5) after T pass in claude-nl-suite.yml
    - Includes retry logic for incomplete GO tests
    - Updates all regex patterns to recognize GO-* test IDs
    - Updates DESIRED lists to include all 21 tests (NL-0..4, T-A..J, GO-0..5)
    - Updates default_titles for GO tests in markdown summary
    - Keeps separate claude-gameobject-suite.yml for standalone runs
    
    * feat: Add GameObject API stress tests and NL/T suite updates
    
    Stress Tests (12 new tests):
    - BulkCreate small/medium batches
    - FindGameObjects pagination with by_component search
    - AddComponents to single object
    - GetComponents with full serialization
    - SetComponentProperties (complex Rigidbody)
    - Deep hierarchy creation and path lookup
    - GetHierarchy with large scenes
    - Resource read performance tests
    - RapidFire create-modify-delete cycles
    
    NL/T Suite Updates:
    - Added GO-0..GO-10 tests in nl-gameobject-suite.md
    - Fixed tool naming: mcp__unity__ → mcp__UnityMCP__
    
    Other:
    - Fixed LongUnityScriptClaudeTest.cs compilation errors
    - Added reports/, .claude/local/, scripts/local-test/ to .gitignore
    
    All 254 EditMode tests pass (250 run, 4 explicit skips)
    
    * fix: Address code review feedback
    
    - ParamCoercion: Use CultureInfo.InvariantCulture for float parsing
    - ManageComponents: Move Transform removal check before GetComponent
    - ManageGameObjectFindTests: Use try-finally for LogAssert.ignoreFailingMessages
    - VectorParsing: Document that quaternions are not auto-normalized
    - gameobject.py: Prefix unused ctx parameter with underscore
    
    * fix: Address additional code review feedback
    
    - ManageComponents: Reuse GameObjectLookup.FindComponentType instead of duplicate
    - ManageComponents: Log warnings when SetPropertiesOnComponent fails
    - GameObjectLookup: Make FindComponentType public for reuse
    - gameobject.py: Extract _normalize_response helper to reduce duplication
    - gameobject.py: Add TODO comment for unused typed response classes
    
    * fix: Address more code review feedback
    
    NL/T Prompt Fixes:
    - nl-gameobject-suite.md: Remove non-existent list_resources/read_resource from AllowedTools
    - nl-gameobject-suite.md: Fix parameter names (component_type, properties)
    - nl-unity-suite-nl.md: Remove unused manage_editor from AllowedTools
    
    Test Fixes:
    - GameObjectAPIStressTests: Add null check to ToJObject helper
    - GameObjectAPIStressTests: Clarify AudioSource usage comment
    - ManageGameObjectFindTests: Use built-in 'UI' layer instead of 'Water'
    - LongUnityScriptClaudeTest: Clean up NL/T test artifacts (Counte42 typo, HasTarget)
    
    * docs: Add documentation for API limitations and behaviors
    
    - GameObjectLookup.SearchByPath: Document and warn that includeInactive
      has no effect (Unity API limitation)
    - ManageComponents.TrySetProperty: Document case-insensitive lookup behavior
    
    * More test fixes and tighten parameters on python tools
    
    * fix: Align test expectation with implementation error message case
    
    * docs: update README tools and resources lists
    
    - Add missing tools: manage_components, batch_execute, find_gameobjects, refresh_unity
    - Add missing resources: gameobject_api, editor_state_v2
    - Make descriptions more concise across all tools and resources
    - Ensure documentation matches current MCP server functionality
    
    * fix: Address code review feedback
    
    - ParamCoercion: Use InvariantCulture for int/double parsing consistency
    - ManageComponents: Remove redundant Undo.RecordObject (AddComponent handles undo)
    - ManageScene: Replace deprecated FindObjectsOfType with FindObjectsByType
    - GameObjectLookup: Add explanatory comment to empty catch block
    - gameobject.py: Extract _validate_instance_id helper to reduce duplication
    - Tests: Fix assertion for instanceID (Unity IDs can be negative)
    
    * chore: Remove accidentally committed test artifacts
    
    - Remove Materials folder (40 .mat files from interactive testing)
    - Remove Shaders folder (5 noise shaders from testing)
    - Remove test scripts (Bounce*, CylinderBounce* from testing)
    - Remove Temp.meta and commit.sh
    
    * test: Improve delete tests to verify actual deletion
    
    - Delete_ByTag_DeletesMatchingObjects: Verify objects are actually destroyed
    - Delete_ByLayer_DeletesMatchingObjects: Assert deletion using Unity null check
    - Delete_MultipleObjectsSameName_DeletesCorrectly: Document first-match behavior
    - Delete_Success_ReturnsDeletedCount: Verify count value if present
    
    All tests now verify deletion occurred rather than just checking for a result.
    
    * refactor: remove deprecated manage_gameobject actions
    
    - Remove deprecated switch cases: find, get_components, get_component, add_component, remove_component, set_component_property
    - Remove deprecated wrapper methods (423 lines deleted from ManageGameObject.cs)
    - Delete ManageGameObjectFindTests.cs (tests deprecated 'find' action)
    - Remove deprecated test methods from ManageGameObjectTests.cs
    - Add GameObject resource URIs to README documentation
    - Add batch_execute performance tips to README, tool description, and gameobject_api resource
    - Enhance batch_execute description to emphasize 10-100x performance gains
    
    Total: ~1200 lines removed. New API (find_gameobjects, manage_components, resources) is the recommended path forward.
    
    * fix: Remove starlette stubs from conftest.py
    
    Starlette is now a proper dependency via the mcp package, so we don't need
    to stub it anymore. The real package handles all HTTP transport needs.
    dsarno authored Jan 6, 2026
    Configuration menu
    Copy the full SHA
    dbdaa54 View commit details
    Browse the repository at this point in the history
  4. 🔧 Clean up & Consolidate Shared Services Across MCP Tools (#519)

    * feat: Redesign GameObject API for better LLM ergonomics
    
    - find_gameobjects: Search GameObjects, returns paginated instance IDs only
    - manage_components: Component lifecycle (add, remove, set_property)
    
    - unity://scene/gameobject/{id}: Single GameObject data (no component serialization)
    - unity://scene/gameobject/{id}/components: All components (paginated)
    - unity://scene/gameobject/{id}/component/{name}: Single component by type
    
    - manage_scene get_hierarchy: Now includes componentTypes array
    - manage_gameobject: Slimmed to lifecycle only (create, modify, delete)
      - Legacy actions (find, get_components, etc.) log deprecation warnings
    
    - ParamCoercion: Centralized int/bool/float/string coercion
    - VectorParsing: Vector3/Vector2/Quaternion/Color parsing
    - GameObjectLookup: Centralized GameObject search logic
    
    - 76 new Unity EditMode tests for ManageGameObject actions
    - 21 new pytest tests for Python tools/resources
    - New NL/T CI suite for GameObject API (GO-0 to GO-5)
    
    Addresses LLM confusion with parameter overload by splitting into
    focused tools and read-only resources.
    
    * feat: Add GameObject API stress tests and NL/T suite updates
    
    Stress Tests (12 new tests):
    - BulkCreate small/medium batches
    - FindGameObjects pagination with by_component search
    - AddComponents to single object
    - GetComponents with full serialization
    - SetComponentProperties (complex Rigidbody)
    - Deep hierarchy creation and path lookup
    - GetHierarchy with large scenes
    - Resource read performance tests
    - RapidFire create-modify-delete cycles
    
    NL/T Suite Updates:
    - Added GO-0..GO-10 tests in nl-gameobject-suite.md
    - Fixed tool naming: mcp__unity__ → mcp__UnityMCP__
    
    Other:
    - Fixed LongUnityScriptClaudeTest.cs compilation errors
    - Added reports/, .claude/local/, scripts/local-test/ to .gitignore
    
    All 254 EditMode tests pass (250 run, 4 explicit skips)
    
    * fix: Address code review feedback
    
    - ParamCoercion: Use CultureInfo.InvariantCulture for float parsing
    - ManageComponents: Move Transform removal check before GetComponent
    - ManageGameObjectFindTests: Use try-finally for LogAssert.ignoreFailingMessages
    - VectorParsing: Document that quaternions are not auto-normalized
    - gameobject.py: Prefix unused ctx parameter with underscore
    
    * fix: Address more code review feedback
    
    NL/T Prompt Fixes:
    - nl-gameobject-suite.md: Remove non-existent list_resources/read_resource from AllowedTools
    - nl-gameobject-suite.md: Fix parameter names (component_type, properties)
    - nl-unity-suite-nl.md: Remove unused manage_editor from AllowedTools
    
    Test Fixes:
    - GameObjectAPIStressTests: Add null check to ToJObject helper
    - GameObjectAPIStressTests: Clarify AudioSource usage comment
    - ManageGameObjectFindTests: Use built-in 'UI' layer instead of 'Water'
    - LongUnityScriptClaudeTest: Clean up NL/T test artifacts (Counte42 typo, HasTarget)
    
    * docs: update README tools and resources lists
    
    - Add missing tools: manage_components, batch_execute, find_gameobjects, refresh_unity
    - Add missing resources: gameobject_api, editor_state_v2
    - Make descriptions more concise across all tools and resources
    - Ensure documentation matches current MCP server functionality
    
    * chore: Remove accidentally committed test artifacts
    
    - Remove Materials folder (40 .mat files from interactive testing)
    - Remove Shaders folder (5 noise shaders from testing)
    - Remove test scripts (Bounce*, CylinderBounce* from testing)
    - Remove Temp.meta and commit.sh
    
    * refactor: remove deprecated manage_gameobject actions
    
    - Remove deprecated switch cases: find, get_components, get_component, add_component, remove_component, set_component_property
    - Remove deprecated wrapper methods (423 lines deleted from ManageGameObject.cs)
    - Delete ManageGameObjectFindTests.cs (tests deprecated 'find' action)
    - Remove deprecated test methods from ManageGameObjectTests.cs
    - Add GameObject resource URIs to README documentation
    - Add batch_execute performance tips to README, tool description, and gameobject_api resource
    - Enhance batch_execute description to emphasize 10-100x performance gains
    
    Total: ~1200 lines removed. New API (find_gameobjects, manage_components, resources) is the recommended path forward.
    
    * refactor: consolidate shared services across MCP tools
    
    Major architectural improvements:
    - Create UnityJsonSerializer for shared JSON/Unity type conversion
    - Create ObjectResolver for unified object resolution (GameObjects, Components, Assets)
    - Create UnityTypeResolver for consolidated type resolution with caching
    - Create PropertyConversion for unified JSON→Unity property conversion
    - Create ComponentOps for low-level component operations
    - Create Pagination helpers for standardized pagination across tools
    
    Tool simplifications:
    - ManageGameObject: Remove 68-line prefab redirect anti-pattern, delegate to helpers
    - ManageAsset: Remove ~80 lines duplicate ConvertJTokenToType
    - ManageScriptableObject: Remove ~40 lines duplicate ResolveType
    - ManageComponents: Use ComponentOps, UnityTypeResolver (~90 lines saved)
    - ManageMaterial: Standardize to SuccessResponse/ErrorResponse patterns
    - FindGameObjects: Use PaginationRequest/PaginationResponse
    - GameObjectLookup: FindComponentType delegates to UnityTypeResolver
    
    Tests: 242/246 passed, 4 skipped (expected)
    
    * Apply code review feedback: consolidate utilities and improve compatibility
    
    Python Server:
    - Extract normalize_properties() to shared utils.py (removes duplication)
    - Move search_term validation before preflight() for fail-fast
    - Fix manage_script.py documentation (remove incorrect 'update' reference)
    - Remove stale comments in execute_menu_item.py, manage_editor.py
    - Remove misleading destructiveHint from manage_shader.py
    
    C# Unity:
    - Add Vector4Converter (commonly used, was missing)
    - Fix Unity 2021 compatibility: replace FindObjectsByType with FindObjectsOfType
    - Add path normalization in ObjectResolver before StartsWith check
    - Improve ComponentOps.SetProperty conversion error detection
    - Add Undo.RecordObject in ManageComponents before property modifications
    - Improve error message clarity in ManageMaterial.cs
    - Add defensive error handling to stress test ToJObject helper
    - Increase CI timeout thresholds for test stability
    
    GitHub Workflows:
    - Fix GO test sorting in markdown output (GO-10 now sorts after GO-9)
    - Add warning logging for fragment parsing errors
    
    * Fix animator hash names in test fixture to match parameter names
    
    BlendXHash/BlendYHash now use 'reachX'/'reachY' to match the
    actual animator parameter names.
    
    * fix(windows): improve HTTP server detection and auto-start reliability
    
    - Fix netstat detection on Windows by running netstat.exe directly instead
      of piping through findstr (findstr returns exit code 1 when no matches,
      causing false detection failures)
    - Increase auto-start retry attempts (20→30) and delays (2s→3s) to handle
      slow server starts during first install, version upgrades, and dev mode
    - Only attempt blind connection after 20 failed detection attempts to reduce
      connection error spam during server startup
    - Remove verbose debug logs that were spamming the console every frame
    
    * fix: auto-create tags and remove deprecated manage_gameobject actions
    
    - ManageGameObject.cs: Check tag existence before setting; auto-create
      undefined tags using InternalEditorUtility.AddTag() instead of relying
      on exception handling (Unity logs warning, doesn't throw)
    - manage_gameobject.py: Remove deprecated actions (find, get_components,
      add_component, remove_component, set_component_property, get_component)
      from Literal type - these are now handled by find_gameobjects and
      manage_components tools
    - Update test suite and unit tests to reflect new auto-create behavior
    
    * fix: address code review feedback
    
    Bug fixes:
    - Fix searchInactive flag ignored in FindObjectsOfType (use includeInactive overload)
    - Fix property lookup to try both original and normalized names for backwards compat
    - Remove dead code for deprecated 'find' action validation
    - Update error message to list only valid actions
    
    Improvements:
    - Add destructiveHint=True to manage_shader tool
    - Limit fallback connection attempts (every 3rd attempt) to avoid spamming errors
    - Consolidate PropertyConversion exception handlers to single catch block
    - Add tag existence assertion and cleanup in tag auto-creation tests
    
    Test fixes:
    - Update SetComponentProperties_ContinuesAfterException log regex for new error format
    - Update test_manage_gameobject_param_coercion to test valid actions only
    dsarno authored Jan 6, 2026
    Configuration menu
    Copy the full SHA
    5511a2b View commit details
    Browse the repository at this point in the history

Commits on Jan 7, 2026

  1. Asset store helper script + updated README (#521)

    * Remove stray .meta file
    
    * Add a new project that will do asset uploads
    
    * Add asset store uploader
    
    * refactor: Replace Debug.Log calls with McpLog helper across codebase
    
    Standardize logging by replacing direct Debug.Log/LogWarning/LogError calls
    with McpLog.Info/Warn/Error throughout helper classes and client registry.
    Affected files:
    - McpClientRegistry.cs
    - GameObjectLookup.cs
    - GameObjectSerializer.cs
    - MaterialOps.cs
    - McpConfigurationHelper.cs
    - ObjectResolver.cs
    - PropertyConversion.cs
    - UnityJsonSerializer.cs
    - UnityTypeResolver.cs
    
    * feat: Add Asset Store release preparation script
    
    Add prepare_unity_asset_store_release.py tool to automate Asset Store packaging:
    - Stages temporary copy of MCPForUnity with Asset Store-specific edits
    - Removes auto-popup setup window ([InitializeOnLoad] attribute)
    - Renames menu entry to "Local Setup Window" for clarity
    - Sets default HTTP base URL to hosted endpoint
    - Defaults transport to HTTPRemote instead of HTTPLocal
    - Supports dry-run mode and optional backup of existing Assets/MCPForUnity
    
    * Show gif of MCP for Unity in Action
    
    * Add shield with asset store link
    
    * Update README to have asset store page unders installation section
    msanatan authored Jan 7, 2026
    1 Configuration menu
    Copy the full SHA
    22e5266 View commit details
    Browse the repository at this point in the history
  2. [FEATURE]: Manage VFX function (#520)

    Feature: Add ManageVFX
    
    Add ManageVFX to the current function, support:
    1. Modify LineRender, TrailRender properties
    2. Modify particle system (legacy) properties
    3. Modify VisualEffectGraph and use templates (does not support edit graph yet)
    
    * Update Server/src/services/tools/utils.py
    
    Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
    
    * Update Server/src/services/tools/manage_vfx.py
    
    Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
    
    * Update ManageVFX.cs
    
    Added 6 helper methods :
    ApplyCommonRendererProperties - Handles shadows, lighting, probes, sorting, rendering layer (used by ParticleSetRenderer, LineSetProperties, TrailSetProperties)
    GetCommonRendererInfo - Returns common renderer info for GetInfo methods
    ApplyWidthProperties - Generic width handling (used by LineSetWidth, TrailSetWidth)
    ApplyColorProperties - Generic color handling with fadeEndAlpha option (used by LineSetColor, TrailSetColor)
    SetRendererMaterial - Generic material assignment (used by LineSetMaterial, TrailSetMaterial)
    ApplyLineTrailProperties - Shared Line/Trail properties like alignment, textureMode, numCornerVertices (used by LineSetProperties, TrailSetProperties)
    
    * Optimize the code structure
    
    Declutter the redundant files by adding RendererHelpers and VectorParsing.cs
    
    * Minor Fixes
    
    Minor Fixes based on AI-feedback
    
    * Fixes
    
    ---------
    
    Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
    Scriptwonder and sourcery-ai[bot] authored Jan 7, 2026
    Configuration menu
    Copy the full SHA
    d285c8d View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    3090a01 View commit details
    Browse the repository at this point in the history
  4. Harden manage_scriptable_object Tool (#522)

    * feat(manage_scriptable_object): harden tool with path normalization, auto-resize, bulk mapping
    
    Phase 1: Path Syntax & Auto-Resizing
    - Add NormalizePropertyPath() to convert field[index] to Array.data format
    - Add EnsureArrayCapacity() to auto-grow arrays when targeting out-of-bounds indices
    
    Phase 2: Consolidation
    - Replace duplicate TryGet* helpers with ParamCoercion/VectorParsing shared utilities
    - Add Vector4 parsing support to VectorParsing.cs
    
    Phase 3: Bulk Data Mapping
    - Handle JArray values for list/array properties (recursive element setting)
    - Handle JObject values for nested struct/class properties
    
    Phase 4: Enhanced Reference Resolution
    - Support plain 32-char GUID strings for ObjectReference fields
    
    Phase 5: Validation & Dry-Run
    - Add ValidatePatches() for pre-validation of all patches
    - Add dry_run parameter to validate without mutating
    
    Includes comprehensive stress test suite covering:
    - Big Bang (large nested arrays), Out of Bounds, Friendly Path Syntax
    - Deep Nesting, Mixed References, Rapid Fire, Type Mismatch
    - Bulk Array Mapping, GUID Shorthand, Dry Run validation
    
    * feat: Add AnimationCurve and Quaternion support to manage_scriptable_object tool
    
    - Implement TrySetAnimationCurve() supporting both {'keys': [...]} and direct [...] formats
      * Support keyframe properties: time, value, inSlope, outSlope, weightedMode, inWeight, outWeight
      * Gracefully default missing optional fields to 0
      * Clear error messages for malformed structures
    
    - Implement TrySetQuaternion() with 4 input formats:
      * Euler array [x, y, z] - 3 elements interpreted as degrees
      * Raw array [x, y, z, w] - 4 components
      * Object format {x, y, z, w} - explicit components
      * Explicit euler {euler: [x, y, z]} - labeled format
    
    - Improve error handling:
      * Null values: AnimationCurve→empty, Quaternion→identity
      * Invalid inputs rejected with specific, actionable error messages
      * Validate keyframe objects and array sizes
    
    - Add comprehensive test coverage in ManageScriptableObjectStressTests.cs:
      * AnimationCurve with keyframe array format
      * AnimationCurve with direct array (no wrapper)
      * Quaternion via Euler angles
      * Quaternion via raw components
      * Quaternion via object format
      * Quaternion via explicit euler property
    
    - Fix test file compilation issues:
      * Replace undefined TestFolder with _runRoot
      * Add System.IO using statement
    
    * refactor: consolidate test utilities to eliminate duplication
    
    - Add TestUtilities.cs with shared helpers:
      - ToJObject() - consolidates 11 duplicates across test files
      - EnsureFolder() - consolidates 2 duplicates
      - WaitForUnityReady() - consolidates 2 duplicates
      - FindFallbackShader() - consolidates shader chain duplicates
      - SafeDeleteAsset() - helper for asset cleanup
      - CleanupEmptyParentFolders() - standardizes TearDown cleanup
    
    - Update 11 test files to use shared TestUtilities via 'using static'
    - Standardize TearDown cleanup patterns across all test files
    - Net reduction of ~40 lines while improving maintainability
    
    * fix: add missing animCurve and rotation fields to ComplexStressSO
    
    Add AnimationCurve and Quaternion fields required by Phase 6 stress tests.
    dsarno authored Jan 7, 2026
    Configuration menu
    Copy the full SHA
    552b2d3 View commit details
    Browse the repository at this point in the history
  5. Configuration menu
    Copy the full SHA
    7de4d0f View commit details
    Browse the repository at this point in the history
  6. v9 pre-release pruning (#528)

    * refactor: Split ParseColorOrDefault into two overloads and change default to Color.white
    
    * Auto-format Python code
    
    * Remove unused Python module
    
    * Refactored VFX functionality into multiple files
    
    Tested everything, works like a charm
    
    * Rename ManageVfx folder to just Vfx
    
    We know what it's managing
    
    * Clean up whitespace on plugin tools and resources
    
    * Make ManageGameObject less of a monolith by splitting it out into different files
    
    * Remove obsolete FindObjectByInstruction method
    
    We also update the namespace for ManageVFX
    
    * refactor: Consolidate editor state resources into single canonical implementation
    
    Merged EditorStateV2 into EditorState, making get_editor_state the canonical resource. Updated Unity C# to use EditorStateCache directly. Enhanced Python implementation with advice/staleness enrichment, external changes detection, and instance ID inference. Removed duplicate EditorStateV2 resource and legacy fallback mapping.
    
    * Validate editor state with Pydantic models in both C# and Python
    
    Added strongly-typed Pydantic models for EditorStateV2 schema in Python and corresponding C# classes with JsonProperty attributes. Updated C# to serialize using typed classes instead of anonymous objects. Python now validates the editor state payload before returning it, catching schema mismatches early.
    
    * Consolidate run_tests and run_tests_async into single async implementation
    
    Merged run_tests_async into run_tests, making async job-based execution the default behavior. Removed synchronous blocking test execution. Updated RunTests.cs to start test jobs immediately and return job_id for polling. Changed TestJobManager methods to internal visibility. Updated README to reflect single run_tests_async tool. Python implementation now uses async job pattern exclusively.
    
    * Validate test job responses with Pydantic models in Python
    
    * Change resources URI from unity:// to mcpforunity://
    
    It should reduce conflicts with other Unity MCPs that users try, and to comply with Unity's requests regarding use of their company and product name
    
    * Update README with all tools + better listing for resources
    
    * Update other references to resources
    
    * Updated translated doc - unfortunately I cannot verify
    
    * Update the Chinese translation of the dev docks
    
    * Change menu item from Setup Window to Local Setup Window
    
    We now differentiate whether it's HTTP local or remote
    
    * Fix URIs for menu items and tests
    
    * Shouldn't have removed it
    
    * Minor edits from CodeRabbit feedback
    
    * Don't use reflection which takes longer
    
    * Fix failing python tests
    
    * Add serialization helpers for ParticleSystem curves and MinMaxCurve types
    
    Added SerializeAnimationCurve and SerializeMinMaxCurve helper methods to properly serialize Unity's curve types. Updated GetInfo to use these helpers for startLifetime, startSpeed, startSize, gravityModifier, and rateOverTime instead of only reading constant values.
    
    * Use ctx param
    
    * Update Server/src/services/tools/run_tests.py
    
    Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
    
    * Minor fixes
    
    * Rename anything EditorStateV2 to just EditorState
    
    It's the default, there's no old version
    
    * Make infer_single_instance_id public by removing underscore prefix
    
    * Fix Python tests, again
    
    * Replace AI generated .meta files with actual Unity ones
    
    * ## Pre-Launch Enhancements: Testing Infrastructure & Tool Improvements (#8)
    
    * Add local test harness for fast developer iteration
    
    Scripts for running the NL/T/GO test suites locally against a GUI Unity
    Editor, complementing the CI workflows in .github/workflows/.
    
    Benefits:
    - 10-100x faster than CI (no Docker startup)
    - Real-time Unity console debugging
    - Single test execution for rapid iteration
    - Auto-detects HTTP vs stdio transport
    
    Usage:
      ./scripts/local-test/setup.sh           # One-time setup
      ./scripts/local-test/quick-test.sh NL-0 # Run single test
      ./scripts/local-test/run-nl-suite-local.sh  # Full suite
    
    See scripts/local-test/README.md for details.
    
    Also updated .gitignore to:
    - Allow scripts/local-test/ to be tracked
    - Ignore generated artifacts (reports/*.xml, .claude/local/, .unity-mcp/)
    
    * Fix issue #525: Save dirty scenes for all test modes
    
    Move SaveDirtyScenesIfNeeded() call outside the PlayMode conditional
    so EditMode tests don't get blocked by Unity's "Save Scene" modal dialog.
    
    This prevents MCP from timing out when running EditMode tests with unsaved
    scene changes.
    
    * fix: add missing FAST_FAIL_TIMEOUT constant in PluginHub
    
    The FAST_FAIL_TIMEOUT class attribute was referenced on line 149 but never
    defined, causing AttributeError on every ping attempt. This error was silently
    caught by the broad 'except Exception' handler, causing all fast-fail commands
    (read_console, get_editor_state, ping) to fail after 6 seconds of retries with
    'ping not answered' error.
    
    Added FAST_FAIL_TIMEOUT = 10 to define a 10-second timeout for fast-fail
    commands, matching the intent of the existing fast-fail infrastructure.
    
    * feat(ScriptableObject): enhance dry-run validation for AnimationCurve and Quaternion
    
    Dry-run validation now validates value formats, not just property existence:
    
    - AnimationCurve: Validates structure ({keys:[...]} or direct array), checks
      each keyframe is an object, validates numeric fields (time, value, inSlope,
      outSlope, inWeight, outWeight) and integer fields (weightedMode)
    - Quaternion: Validates array length (3 for Euler, 4 for raw) or object
      structure ({x,y,z,w} or {euler:[x,y,z]}), ensures all components are numeric
    
    Refactored shared validation helpers into appropriate locations:
    - ParamCoercion: IsNumericToken, ValidateNumericField, ValidateIntegerField
    - VectorParsing: ValidateAnimationCurveFormat, ValidateQuaternionFormat
    
    Added comprehensive XML documentation clarifying keyframe field defaults
    (all default to 0 except as noted).
    
    Added 5 new dry-run validation tests covering valid and invalid formats
    for both AnimationCurve and Quaternion properties.
    
    * test: fix integration tests after merge
    
    - test_refresh_unity_retry_recovery: Mock now handles both refresh_unity and
      get_editor_state commands (refresh_unity internally calls get_editor_state
      when wait_for_ready=True)
    - test_run_tests_async_forwards_params: Mock response now includes required
      'mode' field for RunTestsStartResponse Pydantic validation
    - test_get_test_job_forwards_job_id: Updated to handle GetTestJobResponse as
      Pydantic model instead of dict (use model_dump() for assertions)
    
    * Update warning message to apply to all test modes
    
    Follow-up to PR #527: Since SaveDirtyScenesIfNeeded() now runs for all test modes, update the warning message to say 'tests' instead of 'PlayMode tests'.
    
    * feat(run_tests): add wait_timeout to get_test_job to avoid client loop detection
    
    When polling for test completion, MCP clients like Cursor can detect the
    repeated get_test_job calls as 'looping' and terminate the agent.
    
    Added wait_timeout parameter that makes the server wait internally for tests
    to complete (polling Unity every 2s) before returning. This dramatically
    reduces client-side tool calls from 10-20 down to 1-2, avoiding loop detection.
    
    Usage: get_test_job(job_id='xxx', wait_timeout=30)
    - Returns immediately if tests complete within timeout
    - Returns current status if timeout expires (client can call again)
    - Recommended: 30-60 seconds
    
    * fix: use Pydantic attribute access in test_run_tests_async for merge compatibility
    
    * revert: remove local test harness - will be submitted in separate PR
    
    ---------
    
    Co-authored-by: Scott Jennings <scott.jennings+CIGINT@cloudimperiumgames.com>
    
    ---------
    
    Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
    Co-authored-by: dsarno <david@lighthaus.us>
    Co-authored-by: Scott Jennings <scott.jennings+CIGINT@cloudimperiumgames.com>
    4 people authored Jan 7, 2026
    Configuration menu
    Copy the full SHA
    c0fd7d5 View commit details
    Browse the repository at this point in the history
  7. Fix issue #525: Save dirty scenes for all test modes (#527)

    Move SaveDirtyScenesIfNeeded() call outside the PlayMode conditional
    so EditMode tests don't get blocked by Unity's "Save Scene" modal dialog.
    
    This prevents MCP from timing out when running EditMode tests with unsaved
    scene changes.
    
    Co-authored-by: Scott Jennings <scott.jennings+CIGINT@cloudimperiumgames.com>
    sjennings and Scott Jennings authored Jan 7, 2026
    Configuration menu
    Copy the full SHA
    5e21f12 View commit details
    Browse the repository at this point in the history
  8. Configuration menu
    Copy the full SHA
    34b6a11 View commit details
    Browse the repository at this point in the history

Commits on Jan 8, 2026

  1. Fix HTTP/Stdio Transport UX and Test Bug (#530)

    * refactor: Split ParseColorOrDefault into two overloads and change default to Color.white
    
    * Auto-format Python code
    
    * Remove unused Python module
    
    * Refactored VFX functionality into multiple files
    
    Tested everything, works like a charm
    
    * Rename ManageVfx folder to just Vfx
    
    We know what it's managing
    
    * Clean up whitespace on plugin tools and resources
    
    * Make ManageGameObject less of a monolith by splitting it out into different files
    
    * Remove obsolete FindObjectByInstruction method
    
    We also update the namespace for ManageVFX
    
    * Add local test harness for fast developer iteration
    
    Scripts for running the NL/T/GO test suites locally against a GUI Unity
    Editor, complementing the CI workflows in .github/workflows/.
    
    Benefits:
    - 10-100x faster than CI (no Docker startup)
    - Real-time Unity console debugging
    - Single test execution for rapid iteration
    - Auto-detects HTTP vs stdio transport
    
    Usage:
      ./scripts/local-test/setup.sh           # One-time setup
      ./scripts/local-test/quick-test.sh NL-0 # Run single test
      ./scripts/local-test/run-nl-suite-local.sh  # Full suite
    
    See scripts/local-test/README.md for details.
    
    Also updated .gitignore to:
    - Allow scripts/local-test/ to be tracked
    - Ignore generated artifacts (reports/*.xml, .claude/local/, .unity-mcp/)
    
    * Fix issue #525: Save dirty scenes for all test modes
    
    Move SaveDirtyScenesIfNeeded() call outside the PlayMode conditional
    so EditMode tests don't get blocked by Unity's "Save Scene" modal dialog.
    
    This prevents MCP from timing out when running EditMode tests with unsaved
    scene changes.
    
    * refactor: Consolidate editor state resources into single canonical implementation
    
    Merged EditorStateV2 into EditorState, making get_editor_state the canonical resource. Updated Unity C# to use EditorStateCache directly. Enhanced Python implementation with advice/staleness enrichment, external changes detection, and instance ID inference. Removed duplicate EditorStateV2 resource and legacy fallback mapping.
    
    * Validate editor state with Pydantic models in both C# and Python
    
    Added strongly-typed Pydantic models for EditorStateV2 schema in Python and corresponding C# classes with JsonProperty attributes. Updated C# to serialize using typed classes instead of anonymous objects. Python now validates the editor state payload before returning it, catching schema mismatches early.
    
    * Consolidate run_tests and run_tests_async into single async implementation
    
    Merged run_tests_async into run_tests, making async job-based execution the default behavior. Removed synchronous blocking test execution. Updated RunTests.cs to start test jobs immediately and return job_id for polling. Changed TestJobManager methods to internal visibility. Updated README to reflect single run_tests_async tool. Python implementation now uses async job pattern exclusively.
    
    * Validate test job responses with Pydantic models in Python
    
    * Change resources URI from unity:// to mcpforunity://
    
    It should reduce conflicts with other Unity MCPs that users try, and to comply with Unity's requests regarding use of their company and product name
    
    * Update README with all tools + better listing for resources
    
    * Update other references to resources
    
    * Updated translated doc - unfortunately I cannot verify
    
    * Update the Chinese translation of the dev docks
    
    * Change menu item from Setup Window to Local Setup Window
    
    We now differentiate whether it's HTTP local or remote
    
    * Fix URIs for menu items and tests
    
    * Shouldn't have removed it
    
    * fix: add missing FAST_FAIL_TIMEOUT constant in PluginHub
    
    The FAST_FAIL_TIMEOUT class attribute was referenced on line 149 but never
    defined, causing AttributeError on every ping attempt. This error was silently
    caught by the broad 'except Exception' handler, causing all fast-fail commands
    (read_console, get_editor_state, ping) to fail after 6 seconds of retries with
    'ping not answered' error.
    
    Added FAST_FAIL_TIMEOUT = 10 to define a 10-second timeout for fast-fail
    commands, matching the intent of the existing fast-fail infrastructure.
    
    * feat(ScriptableObject): enhance dry-run validation for AnimationCurve and Quaternion
    
    Dry-run validation now validates value formats, not just property existence:
    
    - AnimationCurve: Validates structure ({keys:[...]} or direct array), checks
      each keyframe is an object, validates numeric fields (time, value, inSlope,
      outSlope, inWeight, outWeight) and integer fields (weightedMode)
    - Quaternion: Validates array length (3 for Euler, 4 for raw) or object
      structure ({x,y,z,w} or {euler:[x,y,z]}), ensures all components are numeric
    
    Refactored shared validation helpers into appropriate locations:
    - ParamCoercion: IsNumericToken, ValidateNumericField, ValidateIntegerField
    - VectorParsing: ValidateAnimationCurveFormat, ValidateQuaternionFormat
    
    Added comprehensive XML documentation clarifying keyframe field defaults
    (all default to 0 except as noted).
    
    Added 5 new dry-run validation tests covering valid and invalid formats
    for both AnimationCurve and Quaternion properties.
    
    * test: fix integration tests after merge
    
    - test_refresh_unity_retry_recovery: Mock now handles both refresh_unity and
      get_editor_state commands (refresh_unity internally calls get_editor_state
      when wait_for_ready=True)
    - test_run_tests_async_forwards_params: Mock response now includes required
      'mode' field for RunTestsStartResponse Pydantic validation
    - test_get_test_job_forwards_job_id: Updated to handle GetTestJobResponse as
      Pydantic model instead of dict (use model_dump() for assertions)
    
    * Update warning message to apply to all test modes
    
    Follow-up to PR #527: Since SaveDirtyScenesIfNeeded() now runs for all test modes, update the warning message to say 'tests' instead of 'PlayMode tests'.
    
    * feat(run_tests): add wait_timeout to get_test_job to avoid client loop detection
    
    When polling for test completion, MCP clients like Cursor can detect the
    repeated get_test_job calls as 'looping' and terminate the agent.
    
    Added wait_timeout parameter that makes the server wait internally for tests
    to complete (polling Unity every 2s) before returning. This dramatically
    reduces client-side tool calls from 10-20 down to 1-2, avoiding loop detection.
    
    Usage: get_test_job(job_id='xxx', wait_timeout=30)
    - Returns immediately if tests complete within timeout
    - Returns current status if timeout expires (client can call again)
    - Recommended: 30-60 seconds
    
    * fix: use Pydantic attribute access in test_run_tests_async for merge compatibility
    
    * revert: remove local test harness - will be submitted in separate PR
    
    * fix: stdio transport survives test runs without UI flicker
    
    Root cause: WriteToConfigTests.TearDown() was unconditionally deleting
    UseHttpTransport EditorPref even when tests were skipped on Windows
    (NUnit runs TearDown even after Assert.Ignore).
    
    Changes:
    - Fix WriteToConfigTests to save/restore prefs instead of deleting
    - Add centralized ShouldForceUvxRefresh() for local dev path detection
    - Clean stale Python build/ artifacts before client configuration
    - Improve reload handler flag management to prevent stuck Resuming state
    - Show Resuming status during stdio bridge restart
    - Initialize client config display on window open
    - Add DevModeForceServerRefresh to EditorPrefs window known types
    
    ---------
    
    Co-authored-by: Marcus Sanatan <msanatan@gmail.com>
    Co-authored-by: Scott Jennings <scott.jennings+CIGINT@cloudimperiumgames.com>
    3 people authored Jan 8, 2026
    Configuration menu
    Copy the full SHA
    cb4e2c9 View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    ea55c44 View commit details
    Browse the repository at this point in the history
Loading