-
Notifications
You must be signed in to change notification settings - Fork 0
FastMCP 2.0 migration and dependency updates #88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
* mcp_source.py: use MCPForUnity path and show branch in options * dev(deps): replace pytest-anyio (stub) with pytest-asyncio for tests
- 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
…et search/read_resource/run_tests) for better LLM compatibility
…logs correct version
…itor, 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
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>
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>
|
Warning Rate limit exceeded@dsarno has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 2 minutes and 35 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (9)
WalkthroughThis PR updates MCP dependencies by replacing Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Tool
participant Coercer
participant Command
Client->>Tool: Call with string param<br/>(e.g., "50", "true", "[1,2,3]")
activate Tool
Tool->>Coercer: Defensive coercion<br/>(_coerce_int, _coerce_bool, _coerce_vec)
activate Coercer
Coercer->>Coercer: Parse/convert to native type
Coercer-->>Tool: Typed value or None
deactivate Coercer
Tool->>Command: send_command_with_retry<br/>with native types
activate Command
Command-->>Tool: Response
deactivate Command
Tool-->>Client: Standardized result
deactivate Tool
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Rationale: Mix of routine import migrations (homogeneous pattern across multiple files, low effort), parameter type broadening (consistent pattern with coercion helpers), and new tests. While individual changes are straightforward, the scope spans 20+ files with subtle type/coercion logic changes that require verification. New Possibly related PRs
Suggested labels
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Greptile Overview
Summary
This PR migrates unity-mcp to FastMCP 2.0 with dependency updates and extensive parameter hardening for better client compatibility.
Key Changes:
- Added
fastmcp>=2.12.5as explicit dependency and relaxedmcpto>=1.16.0 - Updated tool file imports from
mcp.server.fastmcptofastmcp(FastMCP 2.0 pattern) - Added comprehensive parameter hardening across tools to accept string/int/float/bool variations for broader client compatibility
- Removed obsolete test stubs from 6 test files; added 2 new parameter coercion tests
- Switched test framework from pytest-anyio to pytest-asyncio
Issues Found:
- Critical: Three core files (
server.py,tools/__init__.py,resources/__init__.py) still use the oldmcp.server.fastmcpimport path instead offastmcp, creating an inconsistent migration. These are the main entry points and must be updated for proper FastMCP 2.0 compatibility.
Positive Aspects:
- Thorough parameter hardening with defensive type coercion improves robustness
- New tests verify parameter coercion logic works correctly
- Test suite shows good results (40 pass, 7 xpass, 5 skip)
- Code quality is maintained throughout the changes
Confidence Score: 3/5
- This PR requires fixes before merging due to incomplete FastMCP 2.0 import migration in core files
- Score reflects incomplete migration: while tool files correctly use new FastMCP 2.0 imports, the three most critical files (server.py, tools/init.py, resources/init.py) still use deprecated import paths. This inconsistency could cause runtime issues when FastMCP 2.0 removes backward compatibility. The parameter hardening and test improvements are solid, but the incomplete migration is a blocking issue.
- Pay close attention to
server.py,tools/__init__.py, andresources/__init__.py- these core files need import path updates to complete the FastMCP 2.0 migration
Important Files Changed
File Analysis
| Filename | Score | Overview |
|---|---|---|
| MCPForUnity/UnityMcpServer~/src/pyproject.toml | 4/5 | Added fastmcp>=2.12.5 dependency, relaxed mcp to >=1.16.0, and switched pytest-anyio to pytest-asyncio; version bumped to 6.2.2 |
| MCPForUnity/UnityMcpServer~/src/tools/manage_editor.py | 5/5 | Updated FastMCP 2.0 import; added boolean parameter hardening for wait_for_completion with defensive string coercion ('true'/'false' support) |
| MCPForUnity/UnityMcpServer~/src/tools/manage_gameobject.py | 5/5 | Updated FastMCP 2.0 import; extensive parameter hardening for booleans and vectors with string coercion support for broader client compatibility |
| tests/test_manage_asset_param_coercion.py | 5/5 | New test file to verify pagination parameter coercion (page_size/page_number string-to-int conversion) |
| tests/test_manage_gameobject_param_coercion.py | 5/5 | New test file to verify boolean parameter coercion and tag-to-searchTerm mapping |
| MCPForUnity/UnityMcpServer~/src/server.py | 2/5 | NOT updated in this PR - still uses deprecated mcp.server.fastmcp import instead of fastmcp (incomplete migration, critical issue) |
| MCPForUnity/UnityMcpServer~/src/tools/init.py | 2/5 | NOT updated in this PR - still uses deprecated mcp.server.fastmcp import instead of fastmcp (incomplete migration, critical issue) |
| MCPForUnity/UnityMcpServer~/src/resources/init.py | 2/5 | NOT updated in this PR - still uses deprecated mcp.server.fastmcp import instead of fastmcp (incomplete migration, critical issue) |
Sequence Diagram
sequenceDiagram
participant Dev as Developer
participant Deps as pyproject.toml
participant Server as server.py
participant Tools as Tool Files
participant Tests as Test Suite
Dev->>Deps: Update to FastMCP 2.0
Deps->>Deps: Add fastmcp>=2.12.5
Deps->>Deps: Relax mcp to >=1.16.0
Deps->>Deps: Switch to pytest-asyncio
Dev->>Tools: Migrate imports
Tools->>Tools: Update from mcp.server.fastmcp
Tools->>Tools: to fastmcp (FastMCP 2.0)
Note over Server: server.py NOT updated<br/>(still uses old import)
Dev->>Tools: Add parameter hardening
Tools->>Tools: Support string/int/float coercion
Tools->>Tools: Support boolean string coercion
Tools->>Tools: Support vector string parsing
Dev->>Tests: Remove obsolete stubs
Tests->>Tests: Remove mcp stub modules
Tests->>Tests: Add tests/__init__.py
Tests->>Tests: Add new param coercion tests
Tests->>Tools: Test with real fastmcp
Tools-->>Tests: 40 pass, 7 xpass, 5 skip, 1 fail
Additional Comments (3)
-
MCPForUnity/UnityMcpServer~/src/server.py, line 2 (link)syntax: Incomplete FastMCP 2.0 migration - this file still uses the old import path
mcp.server.fastmcpinstead offastmcp -
MCPForUnity/UnityMcpServer~/src/tools/__init__.py, line 7 (link)syntax: Incomplete FastMCP 2.0 migration - uses old import path
-
MCPForUnity/UnityMcpServer~/src/resources/__init__.py, line 7 (link)syntax: Incomplete FastMCP 2.0 migration - uses old import path
26 files reviewed, 3 comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (8)
tests/test_manage_gameobject_param_coercion.py (1)
52-54: Minor: Unused parameter in test fixture.The
cmdparameter is unused but acceptable for test fixtures that need to match the signature being mocked.Optionally prefix with underscore to signal intent:
- def fake_send(cmd, params): + def fake_send(_cmd, params):tests/test_manage_asset_param_coercion.py (1)
53-55: Minor: Unused parameters in test fixture.The
cmdandloopparameters are unused but acceptable for test fixtures that need to match the signature being mocked.Optionally prefix with underscores to signal intent:
- async def fake_async_send(cmd, params, loop=None): + async def fake_async_send(_cmd, params, _loop=None):MCPForUnity/UnityMcpServer~/src/tools/run_tests.py (1)
46-70: Consider broadening the type hint and extracting the coercion helper.The parameter type is restricted to
strbut the coercion logic handlesint | float | str. Consider usingint | float | strfor consistency with other tools in this PR (e.g.,manage_asset.py).Additionally,
_coerce_intis duplicated across multiple files (manage_asset.py,read_console.py,resource_tools.py). Consider extracting it to a shared utility module.For immediate consistency, apply this diff to align the type hint with the coercion capability:
- timeout_seconds: Annotated[str, Field( - description="Optional timeout in seconds for the Unity test run (string, e.g. '30')")] | None = None, + timeout_seconds: Annotated[int | float | str, Field( + description="Optional timeout in seconds for the Unity test run")] | None = None,For the longer term, consider extracting
_coerce_int(and similar helpers like_coerce_bool) to a sharedcoercion_utils.pymodule to eliminate duplication.MCPForUnity/UnityMcpServer~/src/tools/manage_editor.py (1)
16-41: LGTM: Type broadening with boolean coercion.The changes correctly handle string representations of booleans for improved client compatibility.
Note:
_coerce_boolis also defined inmanage_gameobject.py(lines 69-80 per relevant snippets). Consider extracting to a shared utility module to reduce duplication.MCPForUnity/UnityMcpServer~/src/tools/read_console.py (1)
19-55: Consider broadening the type hint for flexibility.The parameter type is restricted to
strbut the coercion logic handlesint | float | str. Consider usingint | float | strfor consistency with other tools in this PR (e.g.,manage_asset.py,resource_tools.py).Apply this diff to align the type hint with the coercion capability:
- count: Annotated[str, "Max messages to return (pass as quoted string, e.g., '5')"] | None = None, + count: Annotated[int | float | str, "Max messages to return"] | None = None,Also consider extracting
_coerce_intto a shared utility module, as it's duplicated across multiple files.MCPForUnity/UnityMcpServer~/src/tools/resource_tools.py (1)
193-315: LGTM: Type broadening with coercion.The parameter types now accept
int | float | str, and the module-level_coerce_inthelper properly normalizes these inputs. This is the preferred pattern over inline helper definitions.Note:
_coerce_intand similar helpers are duplicated across multiple files (manage_asset.py,read_console.py,run_tests.py). Consider consolidating these into a sharedcoercion_utils.pymodule for maintainability.MCPForUnity/UnityMcpServer~/src/tools/manage_scene.py (1)
22-35: Consider extracting coercion helpers to a shared utility module.The
_coerce_intfunction is well-implemented for defensive input handling. However, similar coercion patterns (_coerce_bool,_coerce_vec,_coerce_int) appear across multiple tool modules, includingmanage_gameobject.pyandmanage_editor.py. Extracting these to a shared utility module (e.g.,src/utils/type_coercion.py) would eliminate duplication and ensure consistency.Example structure:
# src/utils/type_coercion.py def coerce_int(value, default=None): """Convert value to int, handling strings, floats, and edge cases.""" # ... current implementation ... def coerce_bool(value, default=None): """Convert value to bool, handling string representations.""" # ... implementation ... def coerce_vec(value, default=None): """Convert value to [float, float, float], handling string representations.""" # ... implementation ...Then import and use across tool modules:
from utils.type_coercion import coerce_int, coerce_bool, coerce_vecMCPForUnity/UnityMcpServer~/src/tools/manage_gameobject.py (1)
70-81: Code duplication detected.The
_coerce_boolfunction is duplicated frommanage_editor.py(lines 27-38, shown in relevant snippets). This reinforces the suggestion from themanage_scene.pyreview to extract these coercion helpers into a shared utility module to maintain DRY principles and ensure consistency across the codebase.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (25)
MCPForUnity/UnityMcpServer~/src/pyproject.toml(1 hunks)MCPForUnity/UnityMcpServer~/src/server_version.txt(1 hunks)MCPForUnity/UnityMcpServer~/src/tools/execute_menu_item.py(1 hunks)MCPForUnity/UnityMcpServer~/src/tools/manage_asset.py(2 hunks)MCPForUnity/UnityMcpServer~/src/tools/manage_editor.py(2 hunks)MCPForUnity/UnityMcpServer~/src/tools/manage_gameobject.py(3 hunks)MCPForUnity/UnityMcpServer~/src/tools/manage_prefabs.py(1 hunks)MCPForUnity/UnityMcpServer~/src/tools/manage_scene.py(1 hunks)MCPForUnity/UnityMcpServer~/src/tools/manage_script.py(1 hunks)MCPForUnity/UnityMcpServer~/src/tools/manage_shader.py(1 hunks)MCPForUnity/UnityMcpServer~/src/tools/read_console.py(1 hunks)MCPForUnity/UnityMcpServer~/src/tools/resource_tools.py(2 hunks)MCPForUnity/UnityMcpServer~/src/tools/run_tests.py(2 hunks)MCPForUnity/UnityMcpServer~/src/tools/script_apply_edits.py(1 hunks)MCPForUnity/package.json(1 hunks)mcp_source.py(2 hunks)tests/__init__.py(1 hunks)tests/test_edit_normalization_and_noop.py(0 hunks)tests/test_get_sha.py(0 hunks)tests/test_improved_anchor_matching.py(0 hunks)tests/test_manage_asset_param_coercion.py(1 hunks)tests/test_manage_gameobject_param_coercion.py(1 hunks)tests/test_read_console_truncate.py(0 hunks)tests/test_script_tools.py(0 hunks)tests/test_validate_script_summary.py(0 hunks)
💤 Files with no reviewable changes (6)
- tests/test_read_console_truncate.py
- tests/test_script_tools.py
- tests/test_edit_normalization_and_noop.py
- tests/test_improved_anchor_matching.py
- tests/test_get_sha.py
- tests/test_validate_script_summary.py
🧰 Additional context used
🧬 Code graph analysis (5)
tests/test_manage_gameobject_param_coercion.py (2)
tests/test_helpers.py (1)
DummyContext(1-10)MCPForUnity/UnityMcpServer~/src/tools/manage_gameobject.py (1)
manage_gameobject(11-191)
MCPForUnity/UnityMcpServer~/src/tools/run_tests.py (1)
MCPForUnity/UnityMcpServer~/src/tools/resource_tools.py (1)
_coerce_int(20-42)
MCPForUnity/UnityMcpServer~/src/tools/manage_editor.py (1)
MCPForUnity/UnityMcpServer~/src/tools/manage_gameobject.py (1)
_coerce_bool(70-81)
tests/test_manage_asset_param_coercion.py (2)
tests/test_helpers.py (1)
DummyContext(1-10)MCPForUnity/UnityMcpServer~/src/tools/manage_asset.py (1)
manage_asset(15-83)
MCPForUnity/UnityMcpServer~/src/tools/manage_gameobject.py (1)
MCPForUnity/UnityMcpServer~/src/tools/manage_editor.py (1)
_coerce_bool(28-39)
🪛 Ruff (0.14.1)
tests/test_manage_gameobject_param_coercion.py
52-52: Unused function argument: cmd
(ARG001)
MCPForUnity/UnityMcpServer~/src/tools/run_tests.py
64-64: Do not catch blind exception: Exception
(BLE001)
tests/test_manage_asset_param_coercion.py
53-53: Unused function argument: cmd
(ARG001)
53-53: Unused function argument: loop
(ARG001)
MCPForUnity/UnityMcpServer~/src/tools/manage_gameobject.py
89-89: Do not catch blind exception: Exception
(BLE001)
100-100: Do not catch blind exception: Exception
(BLE001)
🔇 Additional comments (28)
mcp_source.py (2)
95-95: LGTM! URL format corrected for Unity Package Manager.The removal of the
git+prefix aligns with Unity's package manager git URL format, which useshttps://directly without the prefix.
106-109: LGTM! Dynamic labels improve user experience.Including the branch name in the labels makes it clearer which branch the user is selecting for both remote and local options.
MCPForUnity/UnityMcpServer~/src/server_version.txt (1)
1-1: LGTM! Version bump is consistent with the migration.The version bump from 6.2.1 to 6.2.2 aligns with the FastMCP 2.0 migration and is consistent across all version-tracking files in the PR.
MCPForUnity/package.json (1)
3-3: LGTM! Version bump is consistent.The version bump to 6.2.2 aligns with the server version file and pyproject.toml, maintaining version consistency across the Unity package.
MCPForUnity/UnityMcpServer~/src/pyproject.toml (4)
3-3: LGTM! Version bump is consistent.The version bump to 6.2.2 aligns with the other version files in the PR.
15-19: Good migration from pytest-anyio to pytest-asyncio.Replacing
pytest-anyio>=0.6.0withpytest-asyncio>=0.23is a sensible choice for async test support, as pytest-asyncio is the more standard and actively maintained option for pytest async testing.
21-27: Build system configuration improves packaging.The explicit build-system configuration and setuptools settings provide better control over the package structure and make the build process more reproducible.
7-13: Dependency versions verified and compatible — no issues found.FastMCP 2.12.5 is the latest stable release (Oct 17, 2025) and exists on PyPI. The specified mcp version 1.16.0 is compatible with fastmcp 2.12.5, which declares a dependency on mcp>=1.10.0, so version 1.16.0 satisfies that requirement. The relaxed constraint from mcp>=1.17.0 to mcp>=1.16.0 maintains compatibility with fastmcp while broadening the acceptable version range.
tests/__init__.py (1)
1-1: Good addition for test package structure.Adding
__init__.pyproperly establishes the tests directory as a Python package, enabling test modules to import from each other. This is a standard best practice.MCPForUnity/UnityMcpServer~/src/tools/execute_menu_item.py (1)
6-6: LGTM! Import path updated for FastMCP 2.0.The import migration from
mcp.server.fastmcp.Contexttofastmcp.Contextis consistent with the FastMCP 2.0 upgrade. No functional changes to the tool.MCPForUnity/UnityMcpServer~/src/tools/manage_script.py (1)
6-6: LGTM! Import path updated for FastMCP 2.0.The import migration from
mcp.server.fastmcptofastmcpis consistent with the FastMCP 2.0 upgrade. No functional changes to the tool.MCPForUnity/UnityMcpServer~/src/tools/manage_prefabs.py (1)
3-3: LGTM! Import path updated for FastMCP 2.0.The import migration from
mcp.server.fastmcp.Contexttofastmcp.Contextis consistent with the FastMCP 2.0 upgrade. No functional changes to the tool.MCPForUnity/UnityMcpServer~/src/tools/manage_shader.py (1)
4-4: LGTM! Import path updated for FastMCP 2.0.The import migration from
mcp.server.fastmcp.Contexttofastmcp.Contextis consistent with the FastMCP 2.0 upgrade. No functional changes to the tool.MCPForUnity/UnityMcpServer~/src/tools/script_apply_edits.py (1)
6-6: LGTM: Import path updated for FastMCP 2.0.The import path migration from
mcp.server.fastmcptofastmcpis correct and consistent with the PR objectives.MCPForUnity/UnityMcpServer~/src/tools/manage_asset.py (2)
7-7: LGTM: Import path updated for FastMCP 2.0.The import path migration is correct and consistent with the PR objectives.
32-57: LGTM: Type broadening with defensive coercion.The parameter types now accept
int | float | str, and the_coerce_inthelper properly normalizes these inputs to integers before sending to Unity.MCPForUnity/UnityMcpServer~/src/tools/run_tests.py (1)
4-4: LGTM: Import path updated for FastMCP 2.0.MCPForUnity/UnityMcpServer~/src/tools/manage_editor.py (1)
3-3: LGTM: Import path updated for FastMCP 2.0.MCPForUnity/UnityMcpServer~/src/tools/read_console.py (1)
6-6: LGTM: Import path updated for FastMCP 2.0.MCPForUnity/UnityMcpServer~/src/tools/resource_tools.py (1)
14-14: LGTM: Import path updated for FastMCP 2.0.MCPForUnity/UnityMcpServer~/src/tools/manage_scene.py (3)
3-3: LGTM! FastMCP 2.0 import migration.The import update from
mcp.server.fastmcptofastmcpcorrectly reflects the FastMCP 2.0 migration.
8-8: Well-documented API broadening for client compatibility.The parameter type change from
inttostrforbuild_indexbroadens the API surface for better client compatibility. The updated description clearly documents this change, and the internal coercion logic maintains backward compatibility with numeric inputs.Also applies to: 16-17
37-37: LGTM! Clean coercion application.The coercion is applied correctly, and the coerced value is properly validated before being added to the parameters dictionary. This ensures that
Nonevalues are not passed to the Unity side.Also applies to: 44-45
MCPForUnity/UnityMcpServer~/src/tools/manage_gameobject.py (5)
3-3: Excellent client compatibility improvements.The API has been thoughtfully broadened to accept string representations alongside native types for booleans and vectors. The expanded description clearly documents these capabilities, making the API more accessible to clients that may have limited type support. The import migration to
fastmcpis correct.Also applies to: 9-9, 24-29, 34-35, 40-41, 54-59, 64-65
45-50: Well-documented new parameter.The
component_propertiesparameter is a valuable addition that enables bulk component property updates. The detailed description with multiple examples clearly explains the expected structure and use cases.
83-102: Acceptable defensive exception handling.The
_coerce_vecfunction uses broad exception handling (lines 89, 100) as flagged by Ruff. While this is generally discouraged, it's acceptable in this coercion context where the function's purpose is to defensively parse various input formats and fall back to a default on any parsing failure. The broad catch prevents coercion failures from breaking the tool invocation, which is appropriate for optional parameter handling.
104-112: LGTM! Systematic coercion application.All parameters that accept string alternatives are properly coerced using the appropriate helper functions. The implementation is clean and ensures consistent handling of various input formats.
164-179: LGTM! Sound prefab path handling.The prefab path logic correctly:
- Constructs a default path when
saveAsPrefabis True but noprefabPathis provided- Validates the path ends with
.prefab- Normalizes path separators for Unity compatibility
- Removes the intermediate
prefabFolderparameter before sending to the C# sideThe error handling for missing name is appropriate.
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>
Migrates unity-mcp to FastMCP 2.0 (v2.12.5) with updated dependencies and test compatibility
fixes.
Changes
Testing
✅ 40 tests passing, 7 xpassed, 5 skipped
❌ 1 pre-existing test failure (unrelated to migration)
Summary by CodeRabbit
Release Notes
New Features
component_propertiesparameter for enhanced game object configuration.Improvements
Chores