Skip to content

Conversation

@dsarno
Copy link
Owner

@dsarno dsarno commented Nov 20, 2025

Note

Adds HTTP transport with WebSocket plugin hub, refactors server/Unity transport (keeping stdio), switches to uvx, and makes tools/resources async with new custom-tool registration; updates docs, tests, and packaging.

  • Networking/Transport:
    • Add HTTP transport for MCP server with health and plugin endpoints; retain stdio.
    • Introduce WebSocket-based PluginHub/Registry for Unity communication.
    • New transport layer (unity_transport, IMcpTransportClient, stdio/websocket clients) and manager on Unity side.
  • Server Refactor:
    • Move server to Server/; switch runtime to uvx (remote git package) and add Dockerfile + docker-compose.
    • Unify calls to async; add response normalization; port discovery cache.
  • Custom Tools:
    • Support dynamic tool registration via HTTP (/register-tools), with C# attributes for metadata.
  • Config/Migrations:
    • Add stdio version and legacy server migrations; support HTTP/stdio config generation.
  • Tests/Docs:
    • Convert tests to async and update paths; expand docs (HTTP-first setup, networking, custom tools); README updates.
  • Misc:
    • Clean up Unity test assets and temp handling; minor telemetry/config tweaks.

Written by Cursor Bugbot for commit 9af504c. This will update automatically on new commits. Configure here.

We'll reference the remote server in GitHub and configure clients to use `uvx`
- Replaced local server execution with uvx package-based configuration for improved reliability
- Added GetUvxCommand helper to generate correct package version command string
- Updated config generation to use `uvx mcp-for-unity` instead of local Python server
- Modified Codex and client configuration validation to support uvx-based setup
- Removed unused server source directory handling and related preferences
- Updated tests to verify uvx command generation
We don't commit temp folders, tests are expected to clean up after themselves
- Replaced local server path detection with uvx-based package installation from git repository
- Updated all configuration generators to use structured uvx command parts (command, --from URL, package)
- Renamed UV path references to UVX for clarity and consistency
- Added GetUvxCommandParts() helper to centralize uvx command generation
- Added GetMcpServerGitUrl() to handle git repository URL construction
- Updated client configuration validation
- Added GetUvxPackageSourcePath method to locate unity-mcp package in uv cache by traversing git checkouts
- Replaced hardcoded "Dummy" path in PythonToolSyncProcessor with dynamic path resolution
- Added validation for Server directory structure and pyproject.toml to ensure correct package location
Key thing is that MCPForUnity/UnityMcpServer/src is still deleted
…ystem

- Removed PythonToolsAsset and file-based sync processor in favor of attribute-based tool discovery
- Implemented CustomToolRegistrationProcessor with automatic registration on startup and script reload
- Added registration enable/disable preference and force re-registration capability
- Implemented HTTP transport option with configurable URL/port alongside existing stdio mode
- Added cache management service with menu item to clear uvx package cache
- Updated config builder to generate transport-specific arguments and VSCode type field based on selected mode
- Replaced separate host/port arguments with single --http-url parameter for cleaner configuration
- Updated server to parse URL and allow individual host/port overrides when needed
- Consolidated HTTP client implementation with connection testing and tool execution support
…rt flag

- Replaced --enable-http-server flag with --transport choice parameter (stdio/http) for clearer intent
- Removed redundant HTTP port field from UI since HTTP mode uses the same URL/port as MCP client
- Simplified server startup logic by consolidating transport mode determination
- Changed HTTP mode to use URL-based configuration instead of command-line arguments
- Added proper cleanup of incompatible fields when switching between stdio and HTTP transports
- Moved uvx command parsing inside stdio-specific block to avoid unnecessary processing in HTTP mode
- Implemented server management service with menu item to start local HTTP server in new terminal window
- Added Git URL override setting in advanced configuration to allow custom server source for uvx --from
- Integrated server management into service locator with validation for local-only server startup
- Removed auto-prefixing logic that added "http://" to URLs without protocol
- Added placeholder text to guide users on expected URL format
- Created dedicated url-field style class for better URL input styling
- Added initialize, ping, and disconnect methods to HttpMcpClient for proper MCP protocol session management
- Implemented session ID tracking and header management for stateful HTTP connections
- Added cross-platform terminal launcher support for Windows and Linux (previously macOS-only)
- Added proper JSON-RPC 2.0 request/response handling with request ID tracking
- Included MCP protocol headers (version, session ID) for standard compliance
- Added error handling for JSON-RPC error responses
- Added white-space: normal and flex-shrink properties to section headers and override labels to prevent text overflow
- Created new help-text style class for consistent formatting of help text elements
- Added flex-wrap to setting rows to prevent overflow on narrow windows
- Set flex-shrink: 0 on labels to maintain consistent width
- Replaced max-width and margin-left with flex-basis for better flex behavior
- Capture Unity API calls on main thread before async operations to prevent threading issues
- Update RegisterAllTools to use Task.Run pattern instead of GetAwaiter().GetResult() to avoid potential deadlocks
- Add optional projectId parameter to RegisterAllToolsAsync for pre-captured values
…registration

- Removed synchronous registration method and unused MCP bridge logic from CustomToolRegistrationService
- Changed tool registration to use direct HTTP POST to /register-tools endpoint instead of MCP protocol
- Added FastAPI HTTP routes alongside existing MCP tools for more flexible tool management access
- Created HttpEndpointUtility to normalize and manage base URLs consistently
- Replaced scattered EditorPrefs calls with utility methods that handle URL normalization
- Ensured base URL storage excludes trailing paths like "/mcp" for cleaner configuration
msanatan and others added 19 commits November 16, 2025 01:17
Clean up import organization by moving imports to the top of the file, removing duplicate imports scattered throughout the code, and sorting imports alphabetically within their groups (standard library, third-party, local). Remove unnecessary import aliases and consolidate duplicate urlparse and time imports.
…ing Unity focus

- Add immediate restart attempt in OnAfterAssemblyReload() when Unity is not compiling
- Enhanced compile detection to check both EditorApplication.isCompiling and CompilationPipeline.isCompiling
- Add brief port release wait in StdioBridgeHost before switching ports to reduce port thrash
- Fallback to delayCall/update loop only when Unity is actively compiling

This fixes the issue where domain reloads (e.g., script edits) would cause connection loss until Unity window was refocused, as EditorApplication.update only fires when Unity has focus.
We use HTTP mode by default in docker, this is what will be hosted remotely if one chooses to.
We needed to update the uvicorn package to a version with websockets, at least so the right version is explicitly retrieved
Add static constructor with [InitializeOnLoad] attribute to cache project hash and name at startup. Introduce volatile _identityCached flag and cached values (_cachedProjectName, _cachedProjectHash) to store computed identity. Schedule cache refresh on initialization and when project changes via EditorApplication.projectChanged event. Extract ComputeProjectHash and ComputeProjectName as private methods that perform the actual computation. Update public
Fix: Automatic bridge reconnection after domain reload without requir…
Replace Foldout with VisualElement for http-server-command-section to display HTTP server command directly without collapsible wrapper. Remove unused manualConfigFoldout field and associated CSS styles. Remove unused _identityCached volatile flag from ProjectIdentityUtility as caching logic no longer requires it.
Trying to avoid to monolithic files, this is easier to work, for humans and LLMs
We also fix the Python/uv detectors. Instead of searching for binaries, we just test that they're available in the PATH
…d stdio

These only work for JSON configs, we'll have to handle Codex and Claude Code separately
It's better than checking the JSON and it can verify both HTTP and stdio setups
@greptile-apps
Copy link

greptile-apps bot commented Nov 20, 2025

Skipped: This PR changes more files than the configured file change limit: (308 files found, 100 file limit)

@coderabbitai
Copy link

coderabbitai bot commented Nov 20, 2025

Important

Review skipped

More than 25% of the files skipped due to max files limit. The review is being skipped to prevent a low-quality review.

103 files out of 298 files are above the max files limit of 100. Please upgrade to Pro plan to get higher limits.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch use-uvx

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


Comment @coderabbitai help to get the list of available commands and usage tips.

@dsarno dsarno closed this Nov 20, 2025
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is being reviewed by Cursor Bugbot

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

string output = process.StandardOutput.ReadToEnd().Trim();
process.WaitForExit(5000);

if (process.ExitCode == 0 && output.StartsWith("uv "))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Incorrect uvx version string validation

The validation logic checks if output starts with uv (including a space), but uvx --version typically outputs uvx followed by the version. This mismatch causes valid uvx installations to be rejected, forcing fallbacks or failures.

Fix in Cursor Fix in Web

if (!string.IsNullOrEmpty(fromUrl))
{
args.Insert(0, fromUrl);
args.Insert(0, "--from");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Incompatible arguments used for uv binary fallback

If the detector falls back to the uv binary (instead of uvx), the generator still applies uvx-specific arguments like --from. The uv command does not support --from directly (it requires tool run), which will cause the server launch to fail.

Fix in Cursor Fix in Web

// Stdio mode: Use uvx command
var (uvxPath, fromUrl, packageName) = AssetPathUtility.GetUvxCommandParts();

unity["command"] = uvxPath;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Config builder ignores verified uv path argument

The PopulateUnityNode method ignores its uvPath argument, instead re-fetching the path via AssetPathUtility.GetUvxCommandParts. This discards the verified path from McpConfigurationHelper and may result in writing an unverified or default command to the config.

Fix in Cursor Fix in Web

{
unity["env"] = new JObject();
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Missing UNITY_PROJECT_ROOT in stdio configuration

The generated stdio configuration for uvx does not include the UNITY_PROJECT_ROOT environment variable. Without this variable, the isolated MCP server (running via uvx) cannot detect or access the Unity project path, breaking server functionality.

Fix in Cursor Fix in Web

string output = process.StandardOutput.ReadToEnd().Trim();
process.WaitForExit(5000);

if (process.ExitCode == 0 && output.StartsWith("uv "))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Incorrect uvx version string validation

The code validates the uvx binary by checking if the version output starts with "uv " (note the space). However, uvx --version typically outputs "uvx x.y.z". This mismatch causes the validation to fail for valid uvx installations, forcing a fallback to uv or failing detection entirely.

Fix in Cursor Fix in Web

if (!string.IsNullOrEmpty(fromUrl))
{
args.Insert(0, fromUrl);
args.Insert(0, "--from");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Invalid arguments generated for uv binary fallback

When the detector falls back to the uv binary (e.g., if uvx detection fails), the configuration builder incorrectly applies uvx-specific arguments (like --from) to the uv command. The uv binary does not support --from directly (it requires tool run), which will cause the generated command to fail.

Fix in Cursor Fix in Web

// Stdio mode: Use uvx command
var (uvxPath, fromUrl, packageName) = AssetPathUtility.GetUvxCommandParts();

unity["command"] = uvxPath;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Config builder ignores verified uv path argument

The PopulateUnityNode method accepts a uvPath argument (likely verified by the caller), but ignores it completely. It instead calls AssetPathUtility.GetUvxCommandParts() which performs a fresh, potentially unverified or defaulted lookup (e.g., returning "uvx" string literal), discarding the robust path resolution performed earlier.

Fix in Cursor Fix in Web

{
unity["env"] = new JObject();
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Missing project root environment variable in config

The generated configuration for stdio/uvx mode does not include the UNITY_PROJECT_ROOT environment variable (unlike the CI configuration). Without this variable, the isolated MCP server process may fail to locate or interact with the correct Unity project instance.

Fix in Cursor Fix in Web

dsarno added a commit that referenced this pull request Jan 26, 2026
- Mark prefab stage scene as dirty when manage_components adds/removes/
  modifies components, ensuring save_open_stage correctly detects changes

- When renaming the root GameObject of an open prefab stage, also rename
  the prefab asset file to match, preventing Unity's "file name must
  match" dialog from interrupting automated workflows

- Fix ManagePrefabsCrudTests cleanup order: delete NestedContainer.prefab
  before ChildPrefab.prefab to avoid missing prefab reference errors

- Remove incorrect LogAssert.Expect that expected an error that doesn't
  occur in the test scenario

Addresses #97 (Prefab Editor Inspection & Modification Support)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
dsarno added a commit that referenced this pull request Jan 26, 2026
…rces

- Mark prefab stage scene as dirty when manage_components adds/removes/
  modifies components, ensuring save_open_stage correctly detects changes

- When renaming the root GameObject of an open prefab stage, also rename
  the prefab asset file to match, preventing Unity's "file name must
  match" dialog from interrupting automated workflows

- Fix ManagePrefabsCrudTests cleanup order: delete NestedContainer.prefab
  before ChildPrefab.prefab to avoid missing prefab reference errors

- Remove incorrect LogAssert.Expect that expected an error that doesn't
  occur in the test scenario

- Add new prefab MCP resources for inspecting prefabs:
  - mcpforunity://prefab-api: Documentation for prefab resources
  - mcpforunity://prefab/{path}: Get prefab asset info
  - mcpforunity://prefab/{path}/hierarchy: Get full prefab hierarchy

Addresses #97 (Prefab Editor Inspection & Modification Support)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
dsarno added a commit that referenced this pull request Jan 26, 2026
…rces

- Mark prefab stage scene as dirty when manage_components adds/removes/
  modifies components, ensuring save_open_stage correctly detects changes

- When renaming the root GameObject of an open prefab stage, also rename
  the prefab asset file to match, preventing Unity's "file name must
  match" dialog from interrupting automated workflows

- Fix ManagePrefabsCrudTests cleanup order: delete NestedContainer.prefab
  before ChildPrefab.prefab to avoid missing prefab reference errors

- Remove incorrect LogAssert.Expect that expected an error that doesn't
  occur in the test scenario

- Add new prefab MCP resources for inspecting prefabs:
  - mcpforunity://prefab-api: Documentation for prefab resources
  - mcpforunity://prefab/{path}: Get prefab asset info
  - mcpforunity://prefab/{path}/hierarchy: Get full prefab hierarchy

Addresses #97 (Prefab Editor Inspection & Modification Support)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
dsarno added a commit that referenced this pull request Jan 26, 2026
…rces

- Mark prefab stage scene as dirty when manage_components adds/removes/
  modifies components, ensuring save_open_stage correctly detects changes

- When renaming the root GameObject of an open prefab stage, also rename
  the prefab asset file to match, preventing Unity's "file name must
  match" dialog from interrupting automated workflows

- Fix ManagePrefabsCrudTests cleanup order: delete NestedContainer.prefab
  before ChildPrefab.prefab to avoid missing prefab reference errors

- Remove incorrect LogAssert.Expect that expected an error that doesn't
  occur in the test scenario

- Add new prefab MCP resources for inspecting prefabs:
  - mcpforunity://prefab-api: Documentation for prefab resources
  - mcpforunity://prefab/{path}: Get prefab asset info
  - mcpforunity://prefab/{path}/hierarchy: Get full prefab hierarchy

Addresses #97 (Prefab Editor Inspection & Modification Support)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
dsarno added a commit that referenced this pull request Jan 26, 2026
…rces

- Mark prefab stage scene as dirty when manage_components adds/removes/
  modifies components, ensuring save_open_stage correctly detects changes

- When renaming the root GameObject of an open prefab stage, also rename
  the prefab asset file to match, preventing Unity's "file name must
  match" dialog from interrupting automated workflows

- Fix ManagePrefabsCrudTests cleanup order: delete NestedContainer.prefab
  before ChildPrefab.prefab to avoid missing prefab reference errors

- Remove incorrect LogAssert.Expect that expected an error that doesn't
  occur in the test scenario

- Add new prefab MCP resources for inspecting prefabs:
  - mcpforunity://prefab-api: Documentation for prefab resources
  - mcpforunity://prefab/{path}: Get prefab asset info
  - mcpforunity://prefab/{path}/hierarchy: Get full prefab hierarchy

Addresses #97 (Prefab Editor Inspection & Modification Support)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
dsarno added a commit that referenced this pull request Jan 26, 2026
…rces

- Mark prefab stage scene as dirty when manage_components adds/removes/
  modifies components, ensuring save_open_stage correctly detects changes

- When renaming the root GameObject of an open prefab stage, also rename
  the prefab asset file to match, preventing Unity's "file name must
  match" dialog from interrupting automated workflows

- Fix ManagePrefabsCrudTests cleanup order: delete NestedContainer.prefab
  before ChildPrefab.prefab to avoid missing prefab reference errors

- Remove incorrect LogAssert.Expect that expected an error that doesn't
  occur in the test scenario

- Add new prefab MCP resources for inspecting prefabs:
  - mcpforunity://prefab-api: Documentation for prefab resources
  - mcpforunity://prefab/{path}: Get prefab asset info
  - mcpforunity://prefab/{path}/hierarchy: Get full prefab hierarchy

Addresses #97 (Prefab Editor Inspection & Modification Support)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
dsarno added a commit that referenced this pull request Jan 26, 2026
…rces (CoplayDev#627)

- Mark prefab stage scene as dirty when manage_components adds/removes/
  modifies components, ensuring save_open_stage correctly detects changes

- When renaming the root GameObject of an open prefab stage, also rename
  the prefab asset file to match, preventing Unity's "file name must
  match" dialog from interrupting automated workflows

- Fix ManagePrefabsCrudTests cleanup order: delete NestedContainer.prefab
  before ChildPrefab.prefab to avoid missing prefab reference errors

- Remove incorrect LogAssert.Expect that expected an error that doesn't
  occur in the test scenario

- Add new prefab MCP resources for inspecting prefabs:
  - mcpforunity://prefab-api: Documentation for prefab resources
  - mcpforunity://prefab/{path}: Get prefab asset info
  - mcpforunity://prefab/{path}/hierarchy: Get full prefab hierarchy

Addresses #97 (Prefab Editor Inspection & Modification Support)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants