Commit Graph

15 Commits (15bf79391f47c24e96f009ecdad6fa7bcff1e4a7)

Author SHA1 Message Date
dsarno 15bf79391f
Fix port discovery protocol mismatch (#341)
- Update _try_probe_unity_mcp to recognize Unity bridge welcome message
- Unity bridge sends 'WELCOME UNITY-MCP' instead of JSON pong response
- Maintains backward compatibility with JSON pong format
- Fixes MCP server connection to Unity Editor
2025-10-23 16:51:58 -07:00
GitHub Actions 26eafbfe11 chore: bump version to 6.2.4 2025-10-23 01:43:22 +00:00
dsarno c866e0625b
Harden MCP tool parameter handling to eliminate “invalid param” errors (#339)
* feat: migrate to FastMCP 2.0 (v2.12.5)

- Update pyproject.toml to use fastmcp>=2.12.5 instead of mcp[cli]
- Replace all imports from mcp.server.fastmcp to fastmcp
- Maintain MCP protocol compliance with mcp>=1.16.0
- All 15 files updated with new import statements
- Server and tools registration working with FastMCP 2.0

* chore: bump MCP for Unity to 6.2.2 and widen numeric tool params (asset search/read_resource/run_tests) for better LLM compatibility

* chore: bump installed server_version.txt to 6.2.2 so Unity installer logs correct version

* fix(parameters): apply parameter hardening to read_console, manage_editor, and manage_gameobject

- read_console: accept int|str for count parameter with coercion
- manage_editor: accept bool|str for wait_for_completion with coercion
- manage_gameobject: accept bool|str for all boolean parameters with coercion
- All tools now handle string parameters gracefully and convert to proper types internally

* chore(deps): drop fastmcp, use mcp>=1.18.0; update imports to mcp.server.fastmcp

* chore(deps): re-add fastmcp>=2.12.5, relax mcp to >=1.16.0

Adds fastmcp as explicit dependency for FastMCP 2.0 migration.
Relaxes mcp version constraint to support broader compatibility.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* test: remove obsolete mcp stubs for FastMCP 2.0 compatibility

Removes stub mcp modules from test files that were conflicting with
the real mcp and fastmcp packages now installed as dependencies.
Adds tests/__init__.py to make tests a proper Python package.

This fixes test collection errors after migrating to FastMCP 2.0.

Test results: 40 passed, 7 xpassed, 5 skipped, 1 failed (pre-existing)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* fix: complete FastMCP 2.0 migration with correct import paths

Updates all remaining files to use `from fastmcp import` instead of
the old `from mcp.server.fastmcp import` path.

Changes:
- server.py: Update FastMCP import
- tools/__init__.py: Update FastMCP import
- resources/__init__.py: Update FastMCP import
- tools/manage_script.py, read_console.py, resource_tools.py: Update imports
- test stubs: Update to stub `fastmcp` instead of `mcp.server.fastmcp`

Addresses PR review feedback about incomplete migration.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* fix: harden parameter type handling and resolve PR feedback

Parameter Type Improvements:
- Broaden count in read_console.py to accept int | str
- Broaden build_index in manage_scene.py to accept int | str
- Harden vector parsing in manage_gameobject.py with NaN/Inf checks
- Add whitespace-delimited vector support (e.g., "1 2 3")
- Narrow exception handling from Exception to (ValueError, TypeError)

Test Improvements:
- Harden _load_module in test files with spec/loader validation
- Fix test_manage_gameobject_boolean_and_tag_mapping by mapping tag→search_term

Bug Fixes:
- Fix syntax error in manage_shader.py (remove stray 'x')

Version: Bump to 6.2.3

All tests pass: 41 passed, 5 skipped, 7 xpassed

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-22 18:42:46 -07:00
Marcus Sanatan 558f9232d3
Allow the MCP server to be run by `uvx` remotely (#336)
* feat: add entry point script and additional Python modules to server package

Now we can run this server with `uvx`

* refactor: improve package version detection to support both installed and development environments

* refactor: simplify release workflow by removing server packaging step
2025-10-22 17:36:24 -04:00
dsarno e3e5485d39
Fix/replace pytest anyio with pytest asyncio (#333)
* mcp_source.py: use MCPForUnity path and show branch in options

* dev(deps): replace pytest-anyio (stub) with pytest-asyncio for tests
2025-10-21 13:56:59 -07:00
dsarno 0397887204
test: Consolidate pytest suite to MCPForUnity and improve test infrastructure (#332)
* Update github-repo-stats.yml

* pytest: make harness MCPForUnity-only; remove UnityMcpBridge paths from tests; route tools.manage_script via unity_connection for reliable monkeypatching; fix ctx usage; all tests green (39 pass, 5 skip, 7 xpass)

* Add missing meta for MaterialMeshInstantiationTests.cs (Assets)

* bridge/tools/manage_script: fix missing unity_connection prefix in validate_script; tests: tidy manage_script_uri unused symbols and arg names

* tests: rename to script_apply_edits_module; extract DummyContext to tests/test_helpers and import; add telemetry stubs in tests to avoid pyproject I/O

* tests: import cleanup and helper extraction; telemetry: prefer plain config and opt-in env override; test stubs and CWD fixes; exclude Bridge from pytest discovery

* chore: remove unintended .wt-origin-main gitlink and ignore folder

* tests: nit fixes (unused-arg stubs, import order, path-normalized ignore hook); telemetry: validate config endpoint; read_console: action optional

* Add development dependencies to pyproject.toml

- Add [project.optional-dependencies] section with dev group
- Include pytest>=8.0.0 and pytest-anyio>=0.6.0
- Add Development Setup section to README-DEV.md with installation and testing instructions

* Revert "Update github-repo-stats.yml"

This reverts commit 8ae595d2f4f2525b0e44ece948883ea37138add4.

* test: improve test clarity and modernize asyncio usage

- Add explanation for 200ms timeout in backpressure test
- Replace manual event loop creation with asyncio.run()
- Add assertion message with actual elapsed time for easier debugging

* refactor: remove duplicate DummyContext definitions across test files

Replace 7 duplicate DummyContext class definitions with imports from tests.test_helpers.
This follows DRY principles and ensures consistency across the test suite.

* chore: remove unused _load function from test_edit_strict_and_warnings.py

Dead code cleanup - function was no longer used after refactoring to dynamic tool registration.

* docs: add comment explaining CWD manipulation in telemetry test

Clarify why os.chdir() is necessary: telemetry.py calls get_package_version()
at module load time, which reads pyproject.toml using a relative path.
Acknowledges the fragility while explaining why it's currently required.
2025-10-21 10:42:55 -07:00
GitHub Actions a81e130a6b chore: bump version to 6.2.1 2025-10-21 16:30:17 +00:00
GitHub Actions fdf8482323 chore: bump version to 6.2.0 2025-10-19 00:47:51 +00:00
Marcus Sanatan 85cc93f33c
Allow users to easily add tools in the Asset folder (#324)
* Fix issue #308: Find py files in MCPForUnityTools and version.txt

This allows for auto finding new tools. A good dir on a custom tool would look like this:
CustomTool/
├── CustomTool.MCPEnabler.asmdef
├── CustomTool.MCPEnabler.asmdef.meta
├── ExternalAssetToolFunction.cs
├── ExternalAssetToolFunction.cs.meta
├── external_asset_tool_function.py
├── external_asset_tool_function.py.meta
├── version.txt
└── version.txt.meta

CS files are left in the tools folder. The asmdef is recommended to allow for dependency on MCPForUnity when MCP For Unity is installed:

asmdef example
{
    "name": "CustomTool.MCPEnabler",
    "rootNamespace": "MCPForUnity.Editor.Tools",
    "references": [
        "CustomTool",
        "MCPForUnity.Editor"
    ],
    "includePlatforms": [
        "Editor"
    ],
    "excludePlatforms": [],
    "allowUnsafeCode": false,
    "overrideReferences": false,
    "precompiledReferences": [],
    "autoReferenced": true,
    "defineConstraints": [],
    "versionDefines": [],
    "noEngineReferences": false
}

* Follow-up: address CodeRabbit feedback for #308 (<GetToolsFolderIdentifier was duplicated>)

* Follow-up: address CodeRabbit feedback for #308 – centralize GetToolsFolderIdentifier, fix tools copy dir, and limit scan scope

* Fixing so the MCP don't removes _skipDirs e.g. __pycache__

* skip empty folders with no py files

* Rabbit: "Fix identifier collision between different package roots."

* Update MCPForUnity/Editor/Helpers/ServerInstaller.cs

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

* Rabbbit: Cleanup may delete server’s built-in tool subfolders — restrict to managed names.

* Fixed minor + missed onadding rabit change

* Revert "Fixed minor + missed onadding rabit change"

This reverts commit 571ca8c5de3d07da3791dad558677909a07e886d.

* refactor: remove Unity project tools copying and version tracking functionality

* refactor: consolidate module discovery logic into shared utility function

* Remove unused imports

* feat: add Python tool registry and sync system for MCP server integration

* feat: add auto-sync processor for Python tools with Unity editor integration

* feat: add menu item to reimport all Python files in project

Good to give users a manual option

* Fix infinite loop error

Don't react to PythonToolAsset changes - it only needs to react to Python file changes.
And we also batch asset edits to minimise the DB refreshes

* refactor: move Python tool sync menu items under Window/MCP For Unity/Tool Sync

* Update docs

* Remove duplicate header

* feat: add OnValidate handler to sync Python tools when asset is modified

This fixes the issue with deletions in the asset, now file removals are synced

* test: add unit tests for Python tools asset and sync services

* Update MCPForUnity/Editor/Helpers/PythonToolSyncProcessor.cs

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

* style: remove trailing whitespace from Python tool sync files

* test: remove incomplete unit tests from ToolSyncServiceTests

* perf: optimize Python file reimport by using AssetDatabase.FindAssets instead of GetAllAssetPaths

---------

Co-authored-by: Johan Holtby <72528418+JohanHoltby@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-10-18 00:18:25 -04:00
GitHub Actions 3d82cb26b0 chore: bump version to 6.1.0 2025-10-13 15:27:36 +00:00
Marcus Sanatan f2c57ca91e
Add testing and move menu items to resources (#316)
* deps: add tomli>=2.3.0 dependency to UnityMcpServer package

* feat: dynamically fetch package version from pyproject.toml for telemetry

* Add pydantic

* feat: add resource registry for MCP resource auto-discovery

* feat: add telemetry decorator for tracking MCP resource usage

* feat: add auto-discovery and registration system for MCP resources

* feat: add resource registration to MCP server initialization

* feat: add MCPResponse model class for standardized API responses

* refactor: replace Debug.Log calls with McpLog wrapper for consistent logging

* feat: add test discovery endpoints for Unity Test Framework integration

We haven't connected them as yet, still thinking about how to do this neatly

* Fix server setup

* refactor: reduce log verbosity by changing individual resource/tool registration logs to debug level

* chore: bump mcp[cli] dependency from 1.15.0 to 1.17.0

* refactor: remove Context parameter and add uri keyword argument in resource decorator

The Context parameter doesn't work on our version of FastMCP

* chore: upgrade Python base image to 3.13 and simplify Dockerfile setup

* fix: apply telemetry decorator before mcp.tool to ensure proper wrapping order

* fix: swap order of telemetry and resource decorators to properly wrap handlers

* fix: update log prefixes for consistency in logging methods

* Fix compile errors

* feat: extend command registry to support both tools and resources

* Run get tests as a coroutine because it doesn't return results immediately

This works but it spams logs like crazy, maybe there's a better/simpler way

* refactor: migrate from coroutines to async/await for test retrieval and command execution

* feat: add optional error field to MCPResponse model

* Increased timeout because loading tests can take some time

* Make message optional so error responses that only have success and error don't cause Pydantic errors

* Set max_retries to 5

This connection module needs a lookover. The retries should be an exponential backoff and we could structure why it's failing so much

* Use pydantic model to structure the error output

* fix: initialize data field in GetTestsResponse to avoid potential errors

* Don't return path parameter

* feat: add Unity test runner execution with structured results and Python bindings

* refactor: simplify GetTests by removing mode filtering and related parsing logic

* refactor: move test runner functionality into dedicated service interface

* feat: add resource retrieval telemetry tracking with new record type and helper function

* fix: convert tool functions to async and await ctx.info calls

* refactor: reorganize menu item functionality into separate execute and get commands

An MCP resource for retrieval, and a simple command to execute. Because it's a resource, it's easier for the user to see what's in the menu items

* refactor: rename manage_menu_item to execute_menu_item and update tool examples to use async/await

We'll eventually put a section for resources

* Revert "fix: convert tool functions to async and await ctx.info calls"

This reverts commit 012ea6b7439bd1f2593864d98d03d9d95d7bdd03.

* fix: replace tomllib with tomli for Python 3.10 compatibility in telemetry module

* Remove confusing comment

* refactor: improve error handling and simplify test retrieval logic in GetTests commands

* No cache by default

* docs: remove redundant comment for HandleCommand method in ExecuteMenuItem
2025-10-13 11:16:43 -04:00
Marcus Sanatan 3a9ec4f1a6
docs: replace "Unity MCP" with "MCP for Unity" in all text strings (#314) 2025-10-11 04:01:51 -04:00
GitHub Actions 32cb8137cc chore: bump version to 6.0.0 2025-10-11 07:12:26 +00:00
GitHub Actions ba1e488f32 chore: bump version to 5.0.0 2025-10-04 01:01:06 +00:00
Marcus Sanatan e9b1ae44c5
Rename plugin folder to MCPForUnity (#303)
* Copy UnityMcpBridge into a new MCPForUnity folder

This is to close #284

* refactor: rename UnityMcpBridge directory to MCPForUnity in docs

* chore: rename UnityMcpBridge directory to MCPForUnity across workflow files

* chore: rename UnityMcpBridge directory to MCPForUnity across all files

* refactor: update import paths from UnityMcpBridge to MCPForUnity across test files

* fix: update module import paths to use MCPForUnity instead of UnityMcpBridge

* chore: update unity-mcp package path to MCPForUnity directory

* feat: add OneTimeSetUp to initialize CommandRegistry before tests run

Hopefully fix the CI failures

* Apply recent fix to new folder

* Temporarily trigger tests to see if CI works

* Revert "Temporarily trigger tests to see if CI works"

It works!

This reverts commit 8c6eaaad07545cef047769f2c52fe506545a8161.
2025-10-03 20:23:28 -04:00