Commit Graph

10 Commits (6f3b869f3d1f00a78028275fa44c53bd5b30bb24)

Author SHA1 Message Date
dsarno 74236b6f66
fix: Beta mode status validation and EditorPrefs Manager improvements (#671)
* fix: Use beta server args for Claude Code registration

Claude Code registration was still using gitUrl directly instead of
GetBetaServerFromArgs(), meaning the beta server toggle had no effect
on registration. Now uses GetBetaServerFromArgs(quoteFromPath: true)
to properly generate --prerelease args for beta users.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: EditorPrefs Manager shows 'Unset' for keys that haven't been set

- Show "Unset. Default: [value]" for EditorPrefs that haven't been explicitly set
- Disable value field and save button for unset items (grayed out at 60% opacity)
- Fix search filter bug where reloading window showed filtered results with empty search field

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Claude Code status check now accounts for beta server mode

The version validation was comparing the registered package source
(mcpforunityserver>=0.0.0a0 for beta) against the exact package version
(mcpforunityserver==9.4.0-beta.1), causing false "Incorrect Path" status.

Now both CheckStatus paths (main thread and background thread) use the
same logic that considers:
- Explicit GitUrlOverride
- UseBetaServer setting (with dynamic default for prerelease packages)
- Standard pinned version as fallback

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 23:16:30 -08:00
Marcus Sanatan 140a7e5c55
Asset store updates (#660)
* Add resource discovery service and UI for managing MCP resources

* Consolidate duplicate IsBuiltIn logic into StringCaseUtility.IsBuiltInMcpType

* Add resource enable/disable enforcement and improve error response handling

- Block execution of disabled resources in TransportCommandDispatcher with clear error message
- Add parse_resource_response() utility to handle error responses without Pydantic validation failures
- Replace inline response parsing with parse_resource_response() across all resource handlers
- Export parse_resource_response from models/__init__.py for consistent usage

* Block execution of disabled built-in tools in TransportCommandDispatcher with clear error message

Add tool enable/disable enforcement before command execution. Check tool metadata and enabled state, returning error response if tool is disabled. Prevents execution of disabled tools with user-friendly error message.

* Fire warning in the rare chance there are duplicate names

* Add Asset Store version checking with separate cache from Git installations

To make this work I've added a publicly available JSON that's updated after every release.
We can get the info from the asset store page that's against Unity's terms of service, so we want to avoid trouble.

The release approval is manual, so this method suffices

* Change LastUpdateCheck from Int to String type and add Asset Store version check EditorPrefs

* Add EditorPrefs keys for local HTTP server state tracking

* Add remote URL configuration parameter for Asset Store release preparation

Needed to update this to set the default scope to "remote" because now it's a separate transport mode
2026-01-30 21:31:23 -04:00
Marcus Sanatan 664a43b76c
Remote server auth (#644)
* Disable the gloabl default to first session when hosting remotely

* Remove calls to /plugin/sessions

The newer /api/instances covers that data, and we want to remove these "expose all" endpoints

* Disable CLI routes when running in remote hosted mode

* Update server README

* feat: add API key authentication support for remote-hosted HTTP transport

- Add API key field to connection UI (visible only in HTTP Remote mode)
- Add "Get API Key" and "Clear" buttons with login URL retrieval
- Include X-API-Key header in WebSocket connections when configured
- Add API key to CLI commands (mcp add, claude mcp add) when set
- Update config.json generation to include headers with API key
- Add API key validation service with caching and configurable endpoints
- Add /api/auth/login-url endpoint

* feat: add environment variable support for HTTP remote hosted mode

- Add UNITY_MCP_HTTP_REMOTE_HOSTED environment variable as alternative to --http-remote-hosted flag
- Accept "true", "1", or "yes" values (case-insensitive)
- Update CLI help text to document environment variable option

* feat: add user isolation enforcement for remote-hosted mode session listing

- Raise ValueError when list_sessions() called without user_id in remote-hosted mode
- Add comprehensive integration tests for multi-user session isolation
- Add unit tests for PluginRegistry user-scoped session filtering
- Verify cross-user isolation with same project hash
- Test unity_instances resource and set_active_instance user filtering

* feat: add comprehensive integration tests for API key authentication

- Add ApiKeyService tests covering validation, caching, retries, and singleton lifecycle
- Add startup config validation tests for remote-hosted mode requirements
- Test cache hit/miss scenarios, TTL expiration, and manual invalidation
- Test transient failure handling (5xx, timeouts, connection errors) with retry logic
- Test service token header injection and empty key fast-path validation
- Test startup validation requiring

* test: add autouse fixture to restore config state after startup validation tests

Ensures test isolation for config-dependent integration tests

* feat: skip user_id resolution in non-remote-hosted mode

Prevents unnecessary API key validation when not in remote-hosted mode

* test: add missing mock attributes to instance routing tests

- Add client_id to test context mock in set_active_instance test
- Add get_state mock to context in global instance routing test

* Fix broken telemetry test

* Add comprehensive API key authentication documentation

- Add user guide covering configuration, setup, and troubleshooting
- Add architecture reference documenting internal design and request flows

* Add remote-hosted mode and API key authentication documentation to server README

* Update reference doc for Docker Hub

* Specify exception being caught

* Ensure caplog handler cleanup in telemetry queue worker test

* Use NoUnitySessionError instead of RuntimeError in session isolation test

* Remove unusued monkeypatch arg

* Use more obviously fake API keys

* Reject connections when ApiKeyService is not initialized in remote-hosted mode

- Validate that user_id is present after successful key validation
- Expand transient error detection to include timeout and service errors
- Use consistent 1013 status code for retryable auth failures

* Accept "on" for UNITY_MCP_HTTP_REMOTE_HOSTED env var

Consistent with repo

* Invalidate cached login URL when HTTP base URL changes

* Pass API key as parameter instead of reading from EditorPrefs in RegisterWithCapturedValues

* Cache API key in field instead of reading from EditorPrefs on each reconnection

* Align markdown table formatting in remote server auth documentation

* Minor fixes

* security: Sanitize API key values in shell commands and fix minor issues

Add SanitizeShellHeaderValue() method to escape special shell characters (", \, `, $, !) in API keys before including them in shell command arguments. Apply sanitization to all three locations where API keys are embedded in shell commands (two in RegisterWithCapturedValues, one in GetManualInstructions).

Also fix deprecated passwordCharacter property (now maskChar) and improve exception logging in _resolve_user_id_from_request

* Consolidate duplicate instance selection error messages into InstanceSelectionRequiredError class

Add InstanceSelectionRequiredError exception class with centralized error messages (_SELECTION_REQUIRED and _MULTIPLE_INSTANCES). Replace 4 duplicate RuntimeError raises with new exception type. Update tests to catch InstanceSelectionRequiredError instead of RuntimeError.

* Replace hardcoded "X-API-Key" strings with AuthConstants.ApiKeyHeader constant across C# and Python codebases

Add AuthConstants class in C# and API_KEY_HEADER constant in Python to centralize the API key header name definition. Update all 8 locations where "X-API-Key" was hardcoded (4 in C#, 4 in Python) to use the new constants instead.

* Fix imports

* Filter session listing by user_id in all code paths to prevent cross-user session access

Remove conditional logic that only filtered sessions by user_id in remote-hosted mode. Now all session listings are filtered by user_id regardless of hosting mode, ensuring users can only see and interact with their own sessions.

* Consolidate get_session_id_by_hash methods into single method with optional user_id parameter

Merge get_session_id_by_hash and get_session_id_by_user_hash into a single method that accepts an optional user_id parameter. Update all call sites to use the unified method signature with user_id as the second parameter. Update tests and documentation to reflect the simplified API.

* Add environment variable support for project-scoped-tools flag [skip ci]

Support UNITY_MCP_PROJECT_SCOPED_TOOLS environment variable as alternative to --project-scoped-tools command line flag. Accept "true", "1", "yes", or "on" as truthy values (case-insensitive). Update help text to document the environment variable option.

* Fix Python tests

* Update validation logic to only require API key validation URL when both http_remote_hosted is enabled AND transport mode is "http", preventing false validation errors in stdio mode.

* Update Server/src/main.py

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Refactor HTTP transport configuration to support separate local and remote URLs

Split HTTP transport into HttpLocal and HttpRemote modes with separate EditorPrefs storage (HttpBaseUrl and HttpRemoteBaseUrl).

Add HttpEndpointUtility methods to get/save local and remote URLs independently, and introduce IsRemoteScope() and GetCurrentServerTransport() helpers to centralize 3-way transport determination (Stdio/Http/HttpRemote). Update all client configuration code to distinguish between local and remote HTTP

* Only include API key headers in HTTP/WebSocket configuration when in remote-hosted mode

Update all locations where API key headers are added to HTTP/WebSocket configurations to check HttpEndpointUtility.IsRemoteScope() or serverTransport == HttpRemote before including the API key. This prevents local HTTP mode from unnecessarily including API key headers in shell commands, config JSON, and WebSocket connections.

* Hide Manual Server Launch foldout when not in HTTP Local mode

* Fix failing test

* Improve error messaging and API key validation for HTTP Remote transport

Add detailed error messages to WebSocket connection failures that guide users to check server URL, server status, and API key validity. Store error state in TransportState for propagation to UI. Disable "Start Session" button when HTTP Remote mode is selected without an API key, with tooltip explaining requirement. Display error dialog on connection failure with specific error message from transport state. Update connection

* Add missing .meta file

* Store transport mode in ServerConfig instead of environment variable

* Add autouse fixture to restore global config state between tests

Add restore_global_config fixture in conftest.py that automatically saves and restores global config attributes and UNITY_MCP_TRANSPORT environment variable between tests. Update integration tests to use monkeypatch.setattr on config.transport_mode instead of monkeypatch.setenv to prevent test pollution and ensure clean state isolation.

* Fix startup

* Replace _current_transport() calls with direct config.transport_mode access

* Minor cleanup

* Add integration tests for HTTP transport authentication behavior

Verify that HTTP local mode allows requests without user_id while HTTP remote-hosted mode rejects them with auth_required error.

* Add smoke tests for transport routing paths across HTTP local, HTTP remote, and stdio modes

Verify that HTTP local routes through PluginHub without user_id, HTTP remote routes through PluginHub with user_id, and stdio calls legacy send function with instance_id. Each test uses monkeypatch to configure transport mode and mock appropriate transport layer functions.

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-01-30 18:39:21 -04:00
dsarno 17c6a36c8d
feat: Add beta server mode with PyPI pre-release support (#640)
* feat: add TestPyPI toggle for pre-release server package testing

- Add UseTestPyPI editor preference key
- Add TestPyPI toggle to Advanced settings UI with tooltip
- Configure uvx to use test.pypi.org when TestPyPI mode enabled
- Skip version pinning in TestPyPI mode to get latest pre-release
- Update ConfigJsonBuilder to handle TestPyPI index URL

* Update .meta file

* fix: Use PyPI pre-release versions instead of TestPyPI for beta server

TestPyPI has polluted packages (broken httpx, mcp, fastapi) that cause
server startup failures. Switch to publishing beta versions directly to
PyPI as pre-releases (e.g., 9.3.0b20260127).

Key changes:
- beta-release.yml: Publish to PyPI instead of TestPyPI, use beta suffix
- Use --prerelease explicit with version specifier (>=0.0.0a0) to only
  get prereleases of our package, not broken dependency prereleases
- Default "Use Beta Server" toggle to true on beta branch
- Rename UI label from "Use TestPyPI" to "Use Beta Server"
- Add UseTestPyPI to EditorPrefsWindow known prefs
- Add search field and refresh button to EditorPrefsWindow

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: Add beta mode indicator to UI badge and server version logging

- Show "β" suffix on version badge when beta server mode is enabled
- Badge updates dynamically when toggle changes
- Add server version to startup log: "MCP for Unity Server v9.2.0 starting up"
- Add version field to /health endpoint response

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* refactor: Rename UseTestPyPI to UseBetaServer and fix EditorPrefs margin

- Rename EditorPref key from UseTestPyPI to UseBetaServer for clarity
- Rename all related variables and UXML element names
- Increase bottom margin on EditorPrefs search bar to prevent clipping first entry

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* refactor: Address code review feedback

- Centralize beta server uvx args in AssetPathUtility.GetBetaServerFromArgs()
  to avoid duplication between HTTP and stdio transports
- Cache server version at startup instead of calling get_package_version()
  on every /health request
- Add robustness to beta version parsing in workflow: strip existing
  pre-release suffix and validate X.Y.Z format before parsing

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* Prioritize explicit fromUrl override and optimize search filter

- GetBetaServerFromArgs/GetBetaServerFromArgsList now check for explicit
  GitUrlOverride before applying beta server mode, ensuring local dev
  paths and custom URLs are honored
- EditorPrefsWindow search filter uses IndexOf with OrdinalIgnoreCase
  instead of ToLowerInvariant().Contains() for fewer allocations

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Marcus Sanatan <msanatan@gmail.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 11:34:11 -08:00
Marcus Sanatan b69ee80da9
Project scoped tools (#596)
* feat: Add project-scoped tools flag to control custom tool registration behavior

Add `--project-scoped-tools` CLI flag and `UNITY_MCP_PROJECT_SCOPED_TOOLS` environment variable to control whether custom tools are registered globally or scoped to specific Unity projects.

Closes #416

* Add .meta file

* feat: Add project-scoped tools toggle for local HTTP transport

Add UI toggle in Connection section to control project-scoped tools flag when using HTTP Local transport. The toggle:
- Defaults to enabled (true)
- Persists state in EditorPrefs
- Only displays when HTTP Local transport is selected
- Automatically appends `--project-scoped-tools` flag to uvx server command
- Updates manual config display when toggled

* Update Server/src/services/custom_tool_service.py

Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>

* Pass project_scoped_tools flag directly without environment variable conversion

Remove unnecessary environment variable conversion for project_scoped_tools flag.

* fix: Improve error handling and logging in global custom tool registration

Split exception handling to distinguish between expected RuntimeError (service not initialized) and unexpected errors.

---------

Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
2026-01-21 13:07:52 -04:00
dsarno cb4e2c9ef7
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>
2026-01-07 23:33:22 -04:00
Marcus Sanatan 22e52664cd
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
2026-01-07 01:33:20 -04:00
dsarno c2a6b0ac7a
HTTP setup overhaul: transport selection (HTTP local/remote vs stdio), safer lifecycle, cleaner UI, better Claude Code integration (#499)
* Avoid blocking Claude CLI status checks on focus

* Fix Claude Code registration to remove existing server before re-registering

When registering with Claude Code, if a UnityMCP server already exists,
remove it first before adding the new registration. This ensures the
transport mode (HTTP vs stdio) is always updated to match the current
UseHttpTransport EditorPref setting.

Previously, if a stdio registration existed and the user tried to register
with HTTP, the command would fail with 'already exists' and the old stdio
configuration would remain unchanged.

* Fix Claude Code transport validation to parse CLI output format correctly

The validation code was incorrectly parsing the output of 'claude mcp get UnityMCP' by looking for JSON format ("transport": "http"), but the CLI actually returns human-readable text format ("Type: http"). This caused the transport mismatch detection to never trigger, allowing stdio to be selected in the UI while HTTP was registered with Claude Code.

Changes:
- Fix parsing logic to check for "Type: http" or "Type: stdio" in CLI output
- Add OnTransportChanged event to refresh client status when transport changes
- Wire up event handler to trigger client status refresh on transport dropdown change

This ensures that when the transport mode in Unity doesn't match what's registered with Claude Code, the UI will correctly show an error status with instructions to re-register.

* Fix Claude Code registration UI blocking and thread safety issues

This commit resolves three issues with Claude Code registration:

1. UI blocking: Removed synchronous CheckStatus() call after registration
   that was blocking the editor. Status is now set immediately with async
   verification happening in the background.

2. Thread safety: Fixed "can only be called from the main thread" errors
   by capturing Application.dataPath and EditorPrefs.GetBool() on the main
   thread before spawning async status check tasks.

3. Transport mismatch detection: Transport mode changes now trigger immediate
   status checks to detect HTTP/stdio mismatches, instead of waiting for the
   45-second refresh interval.

The registration button now turns green immediately after successful
registration without blocking, and properly detects transport mismatches
when switching between HTTP and stdio modes.

* Enforce thread safety for Claude Code status checks at compile time

Address code review feedback by making CheckStatusWithProjectDir thread-safe
by design rather than by convention:

1. Made projectDir and useHttpTransport parameters non-nullable to prevent
   accidental background thread calls without captured values

2. Removed nullable fallback to EditorPrefs.GetBool() which would cause
   thread safety violations if called from background threads

3. Added ArgumentNullException for null projectDir instead of falling back
   to Application.dataPath (which is main-thread only)

4. Added XML documentation clearly stating threading contracts:
   - CheckStatus() must be called from main thread
   - CheckStatusWithProjectDir() is safe for background threads

5. Removed unreachable else branch in async status check code

These changes make it impossible to misuse the API from background threads,
with compile-time enforcement instead of runtime errors.

* Consolidate local HTTP Start/Stop and auto-start session

* HTTP improvements: Unity-owned server lifecycle + UI polish

* Deterministic HTTP stop via pidfile+token; spawn server in terminal

* Fix review feedback: token validation, host normalization, safer casts

* Fix stop heuristics edge cases; remove dead pid capture

* Fix unity substring guard in stop heuristics

* Fix local server cleanup and connection checks

* Fix read_console default limits; cleanup Unity-managed server vestiges

* Fix unfocused reconnect stalls; fast-fail retryable Unity commands

* Simplify PluginHub reload handling; honor run_tests timeout

* Fix Windows Claude CLI status check threading
2026-01-01 17:08:51 -08:00
Marcus Sanatan 6f080f5390
Edit editor configs (#493)
* Add EditorPrefs management window for MCP configuration debugging

Meant to help with dev and testing, not so much the average user

* Update MCPForUnity/Editor/Windows/EditorPrefs/EditorPrefsWindow.cs

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Revert "Update MCPForUnity/Editor/Windows/EditorPrefs/EditorPrefsWindow.cs"

This reverts commit 09bb4e1d2582678bc87d0ace45f9d8c3c88c3203.

* Reapply "Update MCPForUnity/Editor/Windows/EditorPrefs/EditorPrefsWindow.cs"

This reverts commit 6ccbc5e478f0bd2b61c992ae60db0ca367d651ae.

* Fix EditorPrefs type detection using sentinel values and null handling

* Simplify EditorPrefs type detection using known type mapping and basic parsing

Replace complex sentinel-based type detection with a dictionary of known pref types and simple TryParse fallback for unknown keys. Remove null handling and HasKey checks for known keys since they're defined in EditorPrefKeys.

* Make the menu item more clear

* Remove rounded borders and spacing from EditorPrefs list items

Minor visual tweak [skip ci]

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-12-29 13:40:50 -04:00
Marcus Sanatan c770a8c713
Add EditorPrefs management window for MCP configuration debugging (#491)
* Add EditorPrefs management window for MCP configuration debugging

Meant to help with dev and testing, not so much the average user

* Update MCPForUnity/Editor/Windows/EditorPrefs/EditorPrefsWindow.cs

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Revert "Update MCPForUnity/Editor/Windows/EditorPrefs/EditorPrefsWindow.cs"

This reverts commit 09bb4e1d2582678bc87d0ace45f9d8c3c88c3203.

* Reapply "Update MCPForUnity/Editor/Windows/EditorPrefs/EditorPrefsWindow.cs"

This reverts commit 6ccbc5e478f0bd2b61c992ae60db0ca367d651ae.

* Fix EditorPrefs type detection using sentinel values and null handling

* Simplify EditorPrefs type detection using known type mapping and basic parsing

Replace complex sentinel-based type detection with a dictionary of known pref types and simple TryParse fallback for unknown keys. Remove null handling and HasKey checks for known keys since they're defined in EditorPrefKeys.

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-12-29 13:30:45 -04:00