diff --git a/.claude/skills/unity-mcp-skill/references/tools-reference.md b/.claude/skills/unity-mcp-skill/references/tools-reference.md
index bc100e25a..601e533a9 100644
--- a/.claude/skills/unity-mcp-skill/references/tools-reference.md
+++ b/.claude/skills/unity-mcp-skill/references/tools-reference.md
@@ -18,7 +18,9 @@ Complete reference for all MCP tools. Each tool includes parameters, types, and
- [Camera Tools](#camera-tools)
- [Graphics Tools](#graphics-tools)
- [Package Tools](#package-tools)
+- [Physics Tools](#physics-tools)
- [ProBuilder Tools](#probuilder-tools)
+- [Profiler Tools](#profiler-tools)
- [Docs Tools](#docs-tools)
---
@@ -175,26 +177,6 @@ manage_scene(action="get_build_settings") # Build settings
manage_scene(action="create", name="NewScene", path="Assets/Scenes/")
manage_scene(action="load", path="Assets/Scenes/Main.unity")
manage_scene(action="save")
-
-# Scene templates — create with preset objects
-manage_scene(action="create", name="Level1", template="3d_basic") # Camera + Light + Ground
-manage_scene(action="create", name="Level2", template="2d_basic") # Camera (ortho) + Light
-manage_scene(action="create", name="Empty", template="empty") # No default objects
-manage_scene(action="create", name="Default", template="default") # Camera + Light (Unity default)
-
-# Multi-scene editing
-manage_scene(action="load", path="Assets/Scenes/Level2.unity", additive=True) # Keep current scene
-manage_scene(action="get_loaded_scenes") # List all loaded scenes
-manage_scene(action="set_active_scene", scene_name="Level2") # Set active scene
-manage_scene(action="close_scene", scene_name="Level2") # Unload scene
-manage_scene(action="close_scene", scene_name="Level2", remove_scene=True) # Fully remove
-manage_scene(action="move_to_scene", target="Player", scene_name="Level2") # Move root GO
-
-# Build settings — use manage_build(action="scenes") instead
-
-# Scene validation
-manage_scene(action="validate") # Detect missing scripts, broken prefabs
-manage_scene(action="validate", auto_repair=True) # Also auto-fix missing scripts (undoable)
```
### find_gameobjects
@@ -352,11 +334,6 @@ manage_components(
# - "Assets/Prefabs/My.prefab" → String shorthand for asset paths
# - "ObjectName" → String shorthand for scene name lookup
# - 12345 → Integer shorthand for instanceID
-#
-# Sprite sub-asset references (for SpriteRenderer.sprite, Image.sprite, etc.):
-# - {"guid": "...", "spriteName": "SubSprite"} → Sprite sub-asset from atlas
-# - {"guid": "...", "fileID": 12345} → Sub-asset by fileID
-# Single-sprite textures auto-resolve from guid/path alone.
```
---
@@ -549,23 +526,27 @@ manage_prefabs(
components_to_add=["AudioSource"]
)
-# Add child GameObjects to a prefab (single or batch)
+# Delete child GameObjects from prefab
manage_prefabs(
action="modify_contents",
prefab_path="Assets/Prefabs/Player.prefab",
- create_child=[
- {"name": "Child1", "primitive_type": "Sphere", "position": [1, 0, 0]},
- {"name": "Child2", "primitive_type": "Cube", "parent": "Child1"}
- ]
+ delete_child=["OldChild", "Turret/Barrel"] # single string or list
+)
+
+# Create child GameObject in prefab
+manage_prefabs(
+ action="modify_contents",
+ prefab_path="Assets/Prefabs/Player.prefab",
+ create_child={"name": "SpawnPoint", "primitive_type": "Sphere", "position": [0, 2, 0]}
)
-# Add a nested prefab instance inside a prefab
+# Set component properties on prefab contents
manage_prefabs(
action="modify_contents",
prefab_path="Assets/Prefabs/Player.prefab",
- create_child={"name": "Bullet", "source_prefab_path": "Assets/Prefabs/Bullet.prefab", "position": [0, 2, 0]}
+ target="ChildObject",
+ component_properties={"Rigidbody": {"mass": 5.0}, "MyScript": {"health": 100}}
)
-# source_prefab_path and primitive_type are mutually exclusive
```
---
@@ -734,7 +715,7 @@ manage_ui(
### manage_editor
-Control Unity Editor state, undo/redo.
+Control Unity Editor state.
```python
manage_editor(action="play") # Enter play mode
@@ -749,12 +730,10 @@ manage_editor(action="remove_tag", tag_name="OldTag")
manage_editor(action="add_layer", layer_name="Projectiles")
manage_editor(action="remove_layer", layer_name="OldLayer")
+manage_editor(action="open_prefab_stage", prefab_path="Assets/Prefabs/Enemy.prefab")
+manage_editor(action="save_prefab_stage") # Save changes in the open prefab stage
manage_editor(action="close_prefab_stage") # Exit prefab editing mode back to main scene
-# Undo/Redo — returns the affected undo group name
-manage_editor(action="undo") # Undo last action
-manage_editor(action="redo") # Redo last undone action
-
# Package deployment (no confirmation dialog — designed for LLM-driven iteration)
manage_editor(action="deploy_package") # Copy configured MCPForUnity source into installed package
manage_editor(action="restore_package") # Revert to pre-deployment backup
@@ -1215,6 +1194,121 @@ manage_packages(
---
+## Physics Tools
+
+### `manage_physics`
+
+Manage 3D and 2D physics: settings, collision matrix, materials, joints, queries, validation, and simulation. All actions support `dimension="3d"` (default) or `dimension="2d"` where applicable.
+
+| Parameter | Type | Required | Description |
+|-----------|------|----------|-------------|
+| `action` | string | Yes | See action groups below |
+| `dimension` | string | No | `"3d"` (default) or `"2d"` |
+| `settings` | object | For set_settings | Key-value physics settings dict |
+| `layer_a` / `layer_b` | string | For collision matrix | Layer name or index |
+| `collide` | bool | For set_collision_matrix | `true` to enable, `false` to disable |
+| `name` | string | For create_physics_material | Material asset name |
+| `path` | string | No | Asset folder path (create) or asset path (configure) |
+| `dynamic_friction` / `static_friction` / `bounciness` | float | No | Material properties (0–1) |
+| `friction_combine` / `bounce_combine` | string | No | `Average`, `Minimum`, `Multiply`, `Maximum` |
+| `material_path` | string | For assign_physics_material | Path to physics material asset |
+| `target` | string | For joints/queries/validate | GameObject name or instance ID |
+| `joint_type` | string | For joints | 3D: `fixed`, `hinge`, `spring`, `character`, `configurable`; 2D: `distance`, `fixed`, `friction`, `hinge`, `relative`, `slider`, `spring`, `target`, `wheel` |
+| `connected_body` | string | For add_joint | Connected body GameObject |
+| `motor` / `limits` / `spring` / `drive` | object | For configure_joint | Joint sub-config objects |
+| `properties` | object | For configure_joint/material | Direct property dict |
+| `origin` / `direction` | float[] | For raycast | Ray origin and direction `[x,y,z]` or `[x,y]` |
+| `max_distance` | float | No | Max raycast distance |
+| `shape` | string | For overlap | `sphere`, `box`, `capsule` (3D); `circle`, `box`, `capsule` (2D) |
+| `position` | float[] | For overlap | `[x,y,z]` or `[x,y]` |
+| `size` | float or float[] | For overlap | Radius (sphere/circle) or half-extents `[x,y,z]` (box) |
+| `layer_mask` | string | No | Layer name or int mask for queries |
+| `start` / `end` | float[] | For linecast | Start and end points `[x,y,z]` or `[x,y]` |
+| `point1` / `point2` | float[] | For shapecast capsule | Capsule endpoints (3D alternative) |
+| `height` | float | For shapecast capsule | Capsule height |
+| `capsule_direction` | int | For shapecast capsule | 0=X, 1=Y (default), 2=Z |
+| `angle` | float | For 2D shapecasts | Rotation angle in degrees |
+| `force` | float[] | For apply_force | Force vector `[x,y,z]` or `[x,y]` |
+| `force_mode` | string | For apply_force | `Force`, `Impulse`, `Acceleration`, `VelocityChange` (3D); `Force`, `Impulse` (2D) |
+| `force_type` | string | For apply_force | `normal` (default) or `explosion` (3D only) |
+| `torque` | float[] | For apply_force | Torque `[x,y,z]` (3D) or `[z]` (2D) |
+| `explosion_position` | float[] | For apply_force explosion | Explosion center `[x,y,z]` |
+| `explosion_radius` | float | For apply_force explosion | Explosion sphere radius |
+| `explosion_force` | float | For apply_force explosion | Explosion force magnitude |
+| `upwards_modifier` | float | For apply_force explosion | Y-axis offset (default 0) |
+| `steps` | int | For simulate_step | Number of steps (1–100) |
+| `step_size` | float | No | Step size in seconds (default: `Time.fixedDeltaTime`) |
+
+**Action groups:**
+
+- **Settings:** `ping`, `get_settings`, `set_settings`
+- **Collision Matrix:** `get_collision_matrix`, `set_collision_matrix`
+- **Materials:** `create_physics_material`, `configure_physics_material`, `assign_physics_material`
+- **Joints:** `add_joint`, `configure_joint`, `remove_joint`
+- **Queries:** `raycast`, `raycast_all`, `linecast`, `shapecast`, `overlap`
+- **Forces:** `apply_force`
+- **Rigidbody:** `get_rigidbody`, `configure_rigidbody`
+- **Validation:** `validate`
+- **Simulation:** `simulate_step`
+
+```python
+# Check physics status
+manage_physics(action="ping")
+
+# Get/set gravity
+manage_physics(action="get_settings", dimension="3d")
+manage_physics(action="set_settings", dimension="3d", settings={"gravity": [0, -20, 0]})
+
+# Collision matrix
+manage_physics(action="get_collision_matrix")
+manage_physics(action="set_collision_matrix", layer_a="Player", layer_b="Enemy", collide=False)
+
+# Create a bouncy physics material and assign it
+manage_physics(action="create_physics_material", name="Bouncy", bounciness=0.9, dynamic_friction=0.2)
+manage_physics(action="assign_physics_material", target="Ball", material_path="Assets/Physics Materials/Bouncy.physicMaterial")
+
+# Add and configure a hinge joint
+manage_physics(action="add_joint", target="Door", joint_type="hinge", connected_body="DoorFrame")
+manage_physics(action="configure_joint", target="Door", joint_type="hinge",
+ motor={"targetVelocity": 90, "force": 100},
+ limits={"min": -90, "max": 0, "bounciness": 0})
+
+# Raycast and overlap
+manage_physics(action="raycast", origin=[0, 10, 0], direction=[0, -1, 0], max_distance=50)
+manage_physics(action="overlap", shape="sphere", position=[0, 0, 0], size=5.0)
+
+# Validate scene physics setup
+manage_physics(action="validate") # whole scene
+manage_physics(action="validate", target="Player") # single object
+
+# Multi-hit raycast (returns all hits sorted by distance)
+manage_physics(action="raycast_all", origin=[0, 10, 0], direction=[0, -1, 0])
+
+# Linecast (point A to point B)
+manage_physics(action="linecast", start=[0, 0, 0], end=[10, 0, 0])
+
+# Shapecast (sphere/box/capsule sweep)
+manage_physics(action="shapecast", shape="sphere", origin=[0, 5, 0], direction=[0, -1, 0], size=0.5)
+manage_physics(action="shapecast", shape="box", origin=[0, 5, 0], direction=[0, -1, 0], size=[1, 1, 1])
+
+# Apply force (works with simulate_step for edit-mode previewing)
+manage_physics(action="apply_force", target="Ball", force=[0, 500, 0], force_mode="Impulse")
+manage_physics(action="apply_force", target="Ball", torque=[0, 10, 0])
+
+# Explosion force (3D only)
+manage_physics(action="apply_force", target="Crate", force_type="explosion",
+ explosion_force=1000, explosion_position=[0, 0, 0], explosion_radius=10)
+
+# Configure rigidbody properties
+manage_physics(action="configure_rigidbody", target="Player",
+ properties={"mass": 80, "drag": 0.5, "useGravity": True, "collisionDetectionMode": "Continuous"})
+
+# Step physics in edit mode
+manage_physics(action="simulate_step", steps=10, step_size=0.02)
+```
+
+---
+
## ProBuilder Tools
### manage_probuilder
@@ -1330,6 +1424,77 @@ See also: [ProBuilder Workflow Guide](probuilder-guide.md) for detailed patterns
---
+## Profiler Tools
+
+### `manage_profiler`
+
+Unity Profiler session control, counter reads, memory snapshots, and Frame Debugger. Group: `profiling` (opt-in via `manage_tools`).
+
+| Parameter | Type | Required | Description |
+|-----------|------|----------|-------------|
+| `action` | string | Yes | See action groups below |
+| `category` | string | For get_counters | Profiler category name (e.g. `Render`, `Scripts`, `Memory`, `Physics`) |
+| `counters` | list[str] | No | Specific counter names for get_counters. Omit to read all in category |
+| `object_path` | string | For get_object_memory | Scene hierarchy or asset path |
+| `log_file` | string | No | Path to `.raw` file for profiler_start recording |
+| `enable_callstacks` | bool | No | Enable allocation callstacks for profiler_start |
+| `areas` | dict[str, bool] | For profiler_set_areas | Area name to enabled/disabled mapping |
+| `snapshot_path` | string | No | Output path for memory_take_snapshot |
+| `search_path` | string | No | Search directory for memory_list_snapshots |
+| `snapshot_a` | string | For memory_compare_snapshots | First snapshot file path |
+| `snapshot_b` | string | For memory_compare_snapshots | Second snapshot file path |
+| `page_size` | int | No | Page size for frame_debugger_get_events (default 50) |
+| `cursor` | int | No | Cursor offset for frame_debugger_get_events |
+
+**Action groups:**
+
+- **Session:** `profiler_start`, `profiler_stop`, `profiler_status`, `profiler_set_areas`
+- **Counters:** `get_frame_timing`, `get_counters`, `get_object_memory`
+- **Memory Snapshot:** `memory_take_snapshot`, `memory_list_snapshots`, `memory_compare_snapshots` (requires `com.unity.memoryprofiler`)
+- **Frame Debugger:** `frame_debugger_enable`, `frame_debugger_disable`, `frame_debugger_get_events`
+- **Utility:** `ping`
+
+```python
+# Check profiler availability
+manage_profiler(action="ping")
+
+# Start profiling (optionally record to file)
+manage_profiler(action="profiler_start")
+manage_profiler(action="profiler_start", log_file="Assets/profiler.raw", enable_callstacks=True)
+
+# Check profiler status
+manage_profiler(action="profiler_status")
+
+# Toggle profiler areas
+manage_profiler(action="profiler_set_areas", areas={"CPU": True, "GPU": True, "Rendering": True, "Memory": False})
+
+# Stop profiling
+manage_profiler(action="profiler_stop")
+
+# Read frame timing data (12 fields from FrameTimingManager)
+manage_profiler(action="get_frame_timing")
+
+# Read counters by category
+manage_profiler(action="get_counters", category="Render")
+manage_profiler(action="get_counters", category="Memory", counters=["Total Used Memory", "GC Used Memory"])
+
+# Get memory size of a specific object
+manage_profiler(action="get_object_memory", object_path="Player/Mesh")
+
+# Memory snapshots (requires com.unity.memoryprofiler)
+manage_profiler(action="memory_take_snapshot")
+manage_profiler(action="memory_take_snapshot", snapshot_path="Assets/Snapshots/baseline.snap")
+manage_profiler(action="memory_list_snapshots")
+manage_profiler(action="memory_compare_snapshots", snapshot_a="Assets/Snapshots/before.snap", snapshot_b="Assets/Snapshots/after.snap")
+
+# Frame Debugger
+manage_profiler(action="frame_debugger_enable")
+manage_profiler(action="frame_debugger_get_events", page_size=20, cursor=0)
+manage_profiler(action="frame_debugger_disable")
+```
+
+---
+
## Docs Tools
Tools for verifying Unity C# APIs and fetching official documentation. Group: `docs`.
@@ -1391,7 +1556,7 @@ No Unity connection needed for doc fetching. The `lookup` action with asset-rela
- **`get_doc`**: Fetch ScriptReference docs for a class or member. Parses HTML to extract description, signatures, parameters, return type, and code examples.
- **`get_manual`**: Fetch a Unity Manual page by slug. Returns title, sections, and code examples.
- **`get_package_doc`**: Fetch package documentation. Requires package name, page slug, and package version.
-- **`lookup`**: Search all doc sources in parallel (ScriptReference + Manual + package docs). Supports batch queries. For asset-related queries (shader, material, texture, etc.), also searches project assets via `manage_asset`.
+- **`lookup`**: Search doc sources in parallel (ScriptReference + Manual; also package docs if `package` + `pkg_version` provided). Supports batch queries. For asset-related queries (shader, material, texture, etc.), also searches project assets via `manage_asset`.
```python
# Fetch ScriptReference for a class
diff --git a/CLAUDE.md b/CLAUDE.md
index b6d9d72c7..11c17935e 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -70,7 +70,7 @@ from services.registry import mcp_for_unity_tool
@mcp_for_unity_tool(
description="Does something in Unity.",
- group="core", # core (default), vfx, animation, ui, scripting_ext, testing, probuilder
+ group="core", # core (default), vfx, animation, ui, scripting_ext, testing, probuilder, profiling, docs
)
async def manage_something(
ctx: Context,
diff --git a/MCPForUnity/Editor/Helpers/McpLogRecord.cs b/MCPForUnity/Editor/Helpers/McpLogRecord.cs
index 33002b78e..aeb1bd156 100644
--- a/MCPForUnity/Editor/Helpers/McpLogRecord.cs
+++ b/MCPForUnity/Editor/Helpers/McpLogRecord.cs
@@ -10,8 +10,9 @@ namespace MCPForUnity.Editor.Helpers
{
internal static class McpLogRecord
{
- private static readonly string LogPath = Path.Combine(Application.dataPath, "mcp.log");
- private static readonly string ErrorLogPath = Path.Combine(Application.dataPath, "mcpError.log");
+ private static readonly string LogDir = Path.Combine(Application.dataPath, "UnityMCP", "Log");
+ private static readonly string LogPath = Path.Combine(LogDir, "mcp.log");
+ private static readonly string ErrorLogPath = Path.Combine(LogDir, "mcpError.log");
private const long MaxLogSizeBytes = 1024 * 1024; // 1 MB
private static bool _sessionStarted;
private static readonly object _logLock = new();
@@ -79,6 +80,7 @@ internal static void Log(string commandType, JObject parameters, string type, st
private static void RotateAndAppend(string path, string line)
{
+ Directory.CreateDirectory(LogDir);
RotateIfNeeded(path);
File.AppendAllText(path, line + Environment.NewLine);
}
diff --git a/MCPForUnity/Editor/Services/IPackageUpdateService.cs b/MCPForUnity/Editor/Services/IPackageUpdateService.cs
index 612adee68..1a8daaf24 100644
--- a/MCPForUnity/Editor/Services/IPackageUpdateService.cs
+++ b/MCPForUnity/Editor/Services/IPackageUpdateService.cs
@@ -24,6 +24,12 @@ public interface IPackageUpdateService
///
UpdateCheckResult FetchAndCompare(string currentVersion);
+ ///
+ /// Performs only the network fetch and version comparison using pre-computed installation info.
+ /// Use this overload when calling from a background thread to avoid main-thread-only API calls.
+ ///
+ UpdateCheckResult FetchAndCompare(string currentVersion, bool isGitInstallation, string gitBranch);
+
///
/// Caches a successful fetch result in EditorPrefs. Must be called from the main thread.
///
@@ -43,6 +49,12 @@ public interface IPackageUpdateService
/// True if installed via Git, false if Asset Store or unknown
bool IsGitInstallation();
+ ///
+ /// Determines the Git branch to check for updates (e.g. "main" or "beta").
+ /// Must be called from the main thread (uses Unity PackageManager APIs).
+ ///
+ string GetGitUpdateBranch(string currentVersion);
+
///
/// Clears the cached update check data, forcing a fresh check on next request
///
diff --git a/MCPForUnity/Editor/Services/PackageUpdateService.cs b/MCPForUnity/Editor/Services/PackageUpdateService.cs
index 66fa923a2..8c441d9b9 100644
--- a/MCPForUnity/Editor/Services/PackageUpdateService.cs
+++ b/MCPForUnity/Editor/Services/PackageUpdateService.cs
@@ -118,7 +118,12 @@ public UpdateCheckResult FetchAndCompare(string currentVersion)
{
bool isGitInstallation = IsGitInstallation();
string gitBranch = isGitInstallation ? GetGitUpdateBranch(currentVersion) : "main";
+ return FetchAndCompare(currentVersion, isGitInstallation, gitBranch);
+ }
+ ///
+ public UpdateCheckResult FetchAndCompare(string currentVersion, bool isGitInstallation, string gitBranch)
+ {
string latestVersion = isGitInstallation
? FetchLatestVersionFromGitHub(gitBranch)
: FetchLatestVersionFromAssetStoreJson();
@@ -279,7 +284,8 @@ private static bool IsPreReleaseVersion(string version)
return version.IndexOf('-', StringComparison.Ordinal) >= 0;
}
- private static string GetGitUpdateBranch(string currentVersion)
+ ///
+ public string GetGitUpdateBranch(string currentVersion)
{
try
{
diff --git a/MCPForUnity/Editor/Tools/Graphics/RenderingStatsOps.cs b/MCPForUnity/Editor/Tools/Graphics/RenderingStatsOps.cs
index fbf018d1e..94f8837fa 100644
--- a/MCPForUnity/Editor/Tools/Graphics/RenderingStatsOps.cs
+++ b/MCPForUnity/Editor/Tools/Graphics/RenderingStatsOps.cs
@@ -8,6 +8,7 @@
using Unity.Profiling;
using Unity.Profiling.LowLevel.Unsafe;
using UnityEngine.Profiling;
+using UProfiler = UnityEngine.Profiling.Profiler;
namespace MCPForUnity.Editor.Tools.Graphics
{
@@ -126,12 +127,12 @@ internal static object GetMemory(JObject @params)
{
var data = new Dictionary
{
- ["totalAllocatedMB"] = Math.Round(Profiler.GetTotalAllocatedMemoryLong() / (1024.0 * 1024.0), 2),
- ["totalReservedMB"] = Math.Round(Profiler.GetTotalReservedMemoryLong() / (1024.0 * 1024.0), 2),
- ["totalUnusedReservedMB"] = Math.Round(Profiler.GetTotalUnusedReservedMemoryLong() / (1024.0 * 1024.0), 2),
- ["monoUsedMB"] = Math.Round(Profiler.GetMonoUsedSizeLong() / (1024.0 * 1024.0), 2),
- ["monoHeapMB"] = Math.Round(Profiler.GetMonoHeapSizeLong() / (1024.0 * 1024.0), 2),
- ["graphicsDriverMB"] = Math.Round(Profiler.GetAllocatedMemoryForGraphicsDriver() / (1024.0 * 1024.0), 2),
+ ["totalAllocatedMB"] = Math.Round(UProfiler.GetTotalAllocatedMemoryLong() / (1024.0 * 1024.0), 2),
+ ["totalReservedMB"] = Math.Round(UProfiler.GetTotalReservedMemoryLong() / (1024.0 * 1024.0), 2),
+ ["totalUnusedReservedMB"] = Math.Round(UProfiler.GetTotalUnusedReservedMemoryLong() / (1024.0 * 1024.0), 2),
+ ["monoUsedMB"] = Math.Round(UProfiler.GetMonoUsedSizeLong() / (1024.0 * 1024.0), 2),
+ ["monoHeapMB"] = Math.Round(UProfiler.GetMonoHeapSizeLong() / (1024.0 * 1024.0), 2),
+ ["graphicsDriverMB"] = Math.Round(UProfiler.GetAllocatedMemoryForGraphicsDriver() / (1024.0 * 1024.0), 2),
};
return new
diff --git a/MCPForUnity/Editor/Tools/Profiler.meta b/MCPForUnity/Editor/Tools/Profiler.meta
new file mode 100644
index 000000000..82a6285df
--- /dev/null
+++ b/MCPForUnity/Editor/Tools/Profiler.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 3ac9eeedc58b5d24aaf5c913954e0ec9
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/MCPForUnity/Editor/Tools/Profiler/ManageProfiler.cs b/MCPForUnity/Editor/Tools/Profiler/ManageProfiler.cs
new file mode 100644
index 000000000..606b53abd
--- /dev/null
+++ b/MCPForUnity/Editor/Tools/Profiler/ManageProfiler.cs
@@ -0,0 +1,85 @@
+using System;
+using System.Threading.Tasks;
+using MCPForUnity.Editor.Helpers;
+using Newtonsoft.Json.Linq;
+
+namespace MCPForUnity.Editor.Tools.Profiler
+{
+ [McpForUnityTool("manage_profiler", AutoRegister = false, Group = "profiling")]
+ public static class ManageProfiler
+ {
+ public static async Task