@akiojin/unity-mcp-server 2.16.0 → 2.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +0 -0
- package/README.md +153 -100
- package/bin/unity-mcp-server +7 -1
- package/package.json +30 -7
- package/src/core/codeIndex.js +0 -0
- package/src/core/codeIndexDb.js +0 -0
- package/src/core/config.js +47 -14
- package/src/core/indexWatcher.js +84 -15
- package/src/core/jobManager.js +178 -0
- package/src/core/projectInfo.js +21 -67
- package/src/core/server.js +15 -2
- package/src/core/unityConnection.js +0 -0
- package/src/handlers/addressables/AddressablesAnalyzeToolHandler.js +170 -0
- package/src/handlers/addressables/AddressablesBuildToolHandler.js +145 -0
- package/src/handlers/addressables/AddressablesManageToolHandler.js +266 -0
- package/src/handlers/analysis/AnalyzeSceneContentsToolHandler.js +1 -1
- package/src/handlers/analysis/FindByComponentToolHandler.js +2 -2
- package/src/handlers/analysis/GetAnimatorStateToolHandler.js +1 -1
- package/src/handlers/analysis/GetComponentValuesToolHandler.js +2 -2
- package/src/handlers/analysis/GetGameObjectDetailsToolHandler.js +1 -1
- package/src/handlers/analysis/GetInputActionsStateToolHandler.js +1 -1
- package/src/handlers/analysis/GetObjectReferencesToolHandler.js +2 -2
- package/src/handlers/asset/{AssetDatabaseToolHandler.js → AssetDatabaseManageToolHandler.js} +2 -2
- package/src/handlers/asset/{AssetDependencyToolHandler.js → AssetDependencyAnalyzeToolHandler.js} +2 -2
- package/src/handlers/asset/{AssetImportSettingsToolHandler.js → AssetImportSettingsManageToolHandler.js} +2 -2
- package/src/handlers/asset/{CreateMaterialToolHandler.js → AssetMaterialCreateToolHandler.js} +2 -2
- package/src/handlers/asset/{ModifyMaterialToolHandler.js → AssetMaterialModifyToolHandler.js} +2 -2
- package/src/handlers/asset/{CreatePrefabToolHandler.js → AssetPrefabCreateToolHandler.js} +2 -2
- package/src/handlers/asset/{ExitPrefabModeToolHandler.js → AssetPrefabExitModeToolHandler.js} +2 -2
- package/src/handlers/asset/{InstantiatePrefabToolHandler.js → AssetPrefabInstantiateToolHandler.js} +2 -2
- package/src/handlers/asset/{ModifyPrefabToolHandler.js → AssetPrefabModifyToolHandler.js} +2 -2
- package/src/handlers/asset/{OpenPrefabToolHandler.js → AssetPrefabOpenToolHandler.js} +2 -2
- package/src/handlers/asset/{SavePrefabToolHandler.js → AssetPrefabSaveToolHandler.js} +2 -2
- package/src/handlers/base/BaseToolHandler.js +0 -0
- package/src/handlers/compilation/{GetCompilationStateToolHandler.js → CompilationGetStateToolHandler.js} +2 -2
- package/src/handlers/component/{AddComponentToolHandler.js → ComponentAddToolHandler.js} +2 -2
- package/src/handlers/component/ComponentFieldSetToolHandler.js +419 -0
- package/src/handlers/component/{GetComponentTypesToolHandler.js → ComponentGetTypesToolHandler.js} +2 -2
- package/src/handlers/component/{ListComponentsToolHandler.js → ComponentListToolHandler.js} +2 -2
- package/src/handlers/component/{ModifyComponentToolHandler.js → ComponentModifyToolHandler.js} +2 -2
- package/src/handlers/component/{RemoveComponentToolHandler.js → ComponentRemoveToolHandler.js} +2 -2
- package/src/handlers/console/{ClearConsoleToolHandler.js → ConsoleClearToolHandler.js} +2 -2
- package/src/handlers/console/{ReadConsoleToolHandler.js → ConsoleReadToolHandler.js} +83 -64
- package/src/handlers/editor/{LayerManagementToolHandler.js → EditorLayersManageToolHandler.js} +2 -2
- package/src/handlers/editor/{SelectionToolHandler.js → EditorSelectionManageToolHandler.js} +2 -2
- package/src/handlers/editor/{TagManagementToolHandler.js → EditorTagsManageToolHandler.js} +2 -2
- package/src/handlers/editor/{ToolManagementToolHandler.js → EditorToolsManageToolHandler.js} +2 -2
- package/src/handlers/editor/{WindowManagementToolHandler.js → EditorWindowsManageToolHandler.js} +2 -2
- package/src/handlers/gameobject/{CreateGameObjectToolHandler.js → GameObjectCreateToolHandler.js} +3 -3
- package/src/handlers/gameobject/{DeleteGameObjectToolHandler.js → GameObjectDeleteToolHandler.js} +3 -3
- package/src/handlers/gameobject/{FindGameObjectToolHandler.js → GameObjectFindToolHandler.js} +3 -3
- package/src/handlers/gameobject/{GetHierarchyToolHandler.js → GameObjectGetHierarchyToolHandler.js} +3 -3
- package/src/handlers/gameobject/{ModifyGameObjectToolHandler.js → GameObjectModifyToolHandler.js} +3 -3
- package/src/handlers/index.js +331 -293
- package/src/handlers/input/{AddInputActionToolHandler.js → InputActionAddToolHandler.js} +2 -2
- package/src/handlers/input/{CreateActionMapToolHandler.js → InputActionMapCreateToolHandler.js} +2 -2
- package/src/handlers/input/{RemoveActionMapToolHandler.js → InputActionMapRemoveToolHandler.js} +2 -2
- package/src/handlers/input/{RemoveInputActionToolHandler.js → InputActionRemoveToolHandler.js} +2 -2
- package/src/handlers/input/{AddInputBindingToolHandler.js → InputBindingAddToolHandler.js} +2 -2
- package/src/handlers/input/{CreateCompositeBindingToolHandler.js → InputBindingCompositeCreateToolHandler.js} +2 -2
- package/src/handlers/input/{RemoveAllBindingsToolHandler.js → InputBindingRemoveAllToolHandler.js} +2 -2
- package/src/handlers/input/{RemoveInputBindingToolHandler.js → InputBindingRemoveToolHandler.js} +2 -2
- package/src/handlers/input/{ManageControlSchemesToolHandler.js → InputControlSchemesManageToolHandler.js} +2 -2
- package/src/handlers/input/{GamepadSimulationHandler.js → InputGamepadSimulateToolHandler.js} +3 -3
- package/src/handlers/input/{KeyboardSimulationHandler.js → InputKeyboardSimulateToolHandler.js} +3 -3
- package/src/handlers/input/{MouseSimulationHandler.js → InputMouseSimulateToolHandler.js} +3 -3
- package/src/handlers/input/{InputSystemHandler.js → InputSystemControlToolHandler.js} +4 -4
- package/src/handlers/input/{TouchSimulationHandler.js → InputTouchSimulateToolHandler.js} +3 -3
- package/src/handlers/menu/{ExecuteMenuItemToolHandler.js → MenuItemExecuteToolHandler.js} +2 -2
- package/src/handlers/package/PackageManagerToolHandler.js +1 -1
- package/src/handlers/package/RegistryConfigToolHandler.js +1 -1
- package/src/handlers/playmode/{GetEditorStateToolHandler.js → PlaymodeGetStateToolHandler.js} +3 -3
- package/src/handlers/playmode/{PauseToolHandler.js → PlaymodePauseToolHandler.js} +4 -4
- package/src/handlers/playmode/{PlayToolHandler.js → PlaymodePlayToolHandler.js} +4 -4
- package/src/handlers/playmode/{StopToolHandler.js → PlaymodeStopToolHandler.js} +4 -4
- package/src/handlers/playmode/{WaitForEditorStateToolHandler.js → PlaymodeWaitForStateToolHandler.js} +3 -3
- package/src/handlers/scene/GetSceneInfoToolHandler.js +1 -1
- package/src/handlers/scene/{CreateSceneToolHandler.js → SceneCreateToolHandler.js} +2 -2
- package/src/handlers/scene/{ListScenesToolHandler.js → SceneListToolHandler.js} +2 -2
- package/src/handlers/scene/{LoadSceneToolHandler.js → SceneLoadToolHandler.js} +2 -2
- package/src/handlers/scene/{SaveSceneToolHandler.js → SceneSaveToolHandler.js} +2 -2
- package/src/handlers/screenshot/{AnalyzeScreenshotToolHandler.js → ScreenshotAnalyzeToolHandler.js} +2 -2
- package/src/handlers/screenshot/{CaptureScreenshotToolHandler.js → ScreenshotCaptureToolHandler.js} +2 -2
- package/src/handlers/script/{BuildCodeIndexToolHandler.js → CodeIndexBuildToolHandler.js} +127 -17
- package/src/handlers/script/CodeIndexStatusToolHandler.js +129 -0
- package/src/handlers/script/CodeIndexUpdateToolHandler.js +234 -0
- package/src/handlers/script/{ScriptCreateClassFileToolHandler.js → ScriptCreateClassToolHandler.js} +2 -2
- package/src/handlers/script/ScriptEditSnippetToolHandler.js +272 -0
- package/src/handlers/script/ScriptEditStructuredToolHandler.js +1 -1
- package/src/handlers/script/ScriptPackagesListToolHandler.js +0 -0
- package/src/handlers/script/ScriptReadToolHandler.js +0 -0
- package/src/handlers/script/ScriptRefactorRenameToolHandler.js +0 -0
- package/src/handlers/script/ScriptRefsFindToolHandler.js +0 -0
- package/src/handlers/script/ScriptRemoveSymbolToolHandler.js +0 -0
- package/src/handlers/script/ScriptSearchToolHandler.js +0 -0
- package/src/handlers/script/ScriptSymbolFindToolHandler.js +0 -0
- package/src/handlers/script/ScriptSymbolsGetToolHandler.js +0 -0
- package/src/handlers/settings/{GetProjectSettingsToolHandler.js → SettingsGetToolHandler.js} +2 -2
- package/src/handlers/settings/{UpdateProjectSettingsToolHandler.js → SettingsUpdateToolHandler.js} +2 -2
- package/src/handlers/system/{GetCommandStatsToolHandler.js → SystemGetCommandStatsToolHandler.js} +2 -3
- package/src/handlers/system/{PingToolHandler.js → SystemPingToolHandler.js} +3 -3
- package/src/handlers/system/{RefreshAssetsToolHandler.js → SystemRefreshAssetsToolHandler.js} +3 -3
- package/src/handlers/test/{GetTestStatusToolHandler.js → TestGetStatusToolHandler.js} +2 -2
- package/src/handlers/test/{RunTestsToolHandler.js → TestRunToolHandler.js} +2 -2
- package/src/handlers/ui/{ClickUIElementToolHandler.js → UIClickElementToolHandler.js} +2 -2
- package/src/handlers/ui/{FindUIElementsToolHandler.js → UIFindElementsToolHandler.js} +2 -2
- package/src/handlers/ui/{GetUIElementStateToolHandler.js → UIGetElementStateToolHandler.js} +2 -2
- package/src/handlers/ui/{SetUIElementValueToolHandler.js → UISetElementValueToolHandler.js} +2 -2
- package/src/handlers/ui/{SimulateUIInputToolHandler.js → UISimulateInputToolHandler.js} +2 -2
- package/src/handlers/video/{CaptureVideoForToolHandler.js → VideoCaptureForToolHandler.js} +8 -8
- package/src/handlers/video/{CaptureVideoStartToolHandler.js → VideoCaptureStartToolHandler.js} +2 -2
- package/src/handlers/video/{CaptureVideoStatusToolHandler.js → VideoCaptureStatusToolHandler.js} +2 -2
- package/src/handlers/video/{CaptureVideoStopToolHandler.js → VideoCaptureStopToolHandler.js} +3 -3
- package/src/lsp/CSharpLspUtils.js +95 -14
- package/src/lsp/LspProcessManager.js +0 -0
- package/src/lsp/LspRpcClient.js +14 -0
- package/src/tools/analysis/analyzeSceneContents.js +3 -3
- package/src/tools/analysis/findByComponent.js +3 -3
- package/src/tools/analysis/getAnimatorState.js +6 -6
- package/src/tools/analysis/getComponentValues.js +3 -3
- package/src/tools/analysis/getGameObjectDetails.js +3 -3
- package/src/tools/analysis/getInputActionsState.js +4 -4
- package/src/tools/analysis/getObjectReferences.js +3 -3
- package/src/tools/input/inputActionsEditor.js +18 -18
- package/src/tools/scene/createScene.js +3 -3
- package/src/tools/scene/getSceneInfo.js +3 -3
- package/src/tools/scene/listScenes.js +3 -3
- package/src/tools/scene/loadScene.js +3 -3
- package/src/tools/scene/saveScene.js +3 -3
- package/src/tools/system/ping.js +5 -5
- package/src/tools/video/recordFor.js +2 -2
- package/src/tools/video/recordPlayMode.js +0 -0
- package/src/utils/csharpParse.js +0 -0
- package/src/utils/validators.js +0 -0
- package/src/handlers/script/ScriptIndexStatusToolHandler.js +0 -61
package/LICENSE
CHANGED
|
File without changes
|
package/README.md
CHANGED
|
@@ -74,105 +74,158 @@ Add to your `claude_desktop_config.json`:
|
|
|
74
74
|
}
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
-
##
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
###
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
-
|
|
95
|
-
- `
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
- `
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
- `
|
|
109
|
-
- `
|
|
110
|
-
- `
|
|
111
|
-
- `
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
- `
|
|
116
|
-
- `
|
|
117
|
-
- `
|
|
118
|
-
- `
|
|
119
|
-
- `
|
|
120
|
-
- `
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
- `
|
|
124
|
-
- `
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
- `
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
- `
|
|
131
|
-
- `
|
|
132
|
-
- `
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
- `
|
|
136
|
-
- `
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
- `
|
|
142
|
-
- `
|
|
143
|
-
- `
|
|
144
|
-
- `
|
|
145
|
-
- `
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
- `
|
|
149
|
-
- `
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
- `
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
- `
|
|
156
|
-
- `
|
|
157
|
-
- `
|
|
158
|
-
- `
|
|
159
|
-
- `
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
- `
|
|
163
|
-
- `
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
- `
|
|
167
|
-
- `
|
|
168
|
-
|
|
169
|
-
###
|
|
170
|
-
- `
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
- `
|
|
174
|
-
|
|
175
|
-
|
|
77
|
+
## Code Index Workflow
|
|
78
|
+
|
|
79
|
+
コードの自動編集を安定させるには、以下の 3 ステップでコードインデックスを運用してください。重いフルテストを回す必要はありません。
|
|
80
|
+
|
|
81
|
+
1. **初回または大幅変更後に `code_index_build`**
|
|
82
|
+
プロジェクト内の `Assets/` と `Packages/` の C# をすべてスキャンし、`.unity/cache/code-index/code-index.db` にシンボルを格納します。
|
|
83
|
+
2. **ファイル更新後は `code_index_update`**
|
|
84
|
+
編集したファイルだけを配列で渡すと、LSP から最新シンボルを再取得してインデックスを差分更新します。長時間待ちになる `code_index_build` の再実行を避けられます。
|
|
85
|
+
3. **シンボル取得時は `script_symbol_find`**
|
|
86
|
+
インデックスが利用可能なら高速に、未構築でも LSP にフォールバックして定義位置を取得できます。`script_edit_*` ツールに渡す `symbolName` 構築に活用してください。
|
|
87
|
+
|
|
88
|
+
> **Tip:** `code_index_update` は JSON パラメータ `paths` に絶対パス/相対パスの配列を渡すだけで完了します。内部で存在チェックと LSP リトライを行うため、Unity を起動したままでも短時間で終わります。
|
|
89
|
+
|
|
90
|
+
### インデックス状態を検証したいとき
|
|
91
|
+
|
|
92
|
+
ビルド中・未構築・完了後といったステータスを再現したい場合は、`code_index_build` に `delayStartMs` や `throttleMs` を付けて進捗を意図的に保ちます。さらに、`npm run simulate:code-index` を実行すると以下が自動化されます。
|
|
93
|
+
|
|
94
|
+
- 既存インデックスのリセット(`--reset`)
|
|
95
|
+
- `code_index_build` のバックグラウンド実行(任意の `--delayStart=MS` / `--throttle=MS`)
|
|
96
|
+
- 指定間隔での `code_index_status` ポーリング(`--poll=MS`)
|
|
97
|
+
|
|
98
|
+
出力される JSON を追うことで、`ready: false` → `true` へ遷移する様子や `buildJob.status` の変化を簡単に確認できます。
|
|
99
|
+
|
|
100
|
+
## Available Tools (Standardized Names)
|
|
101
|
+
|
|
102
|
+
### System & Core Tools
|
|
103
|
+
- `system_ping` — Test connection to Unity Editor and verify server status
|
|
104
|
+
- `system_refresh_assets` — Refresh Unity assets and trigger recompilation
|
|
105
|
+
- `system_get_command_stats` — Retrieve recent MCP command usage metrics
|
|
106
|
+
|
|
107
|
+
### GameObject Management
|
|
108
|
+
- `gameobject_create` — Create GameObjects with primitives, transforms, tags, and layers
|
|
109
|
+
- `gameobject_find` — Find GameObjects by name, tag, or layer with pattern matching
|
|
110
|
+
- `gameobject_modify` — Modify GameObject properties (transform, name, active state, parent)
|
|
111
|
+
- `gameobject_delete` — Delete single or multiple GameObjects with child handling
|
|
112
|
+
- `gameobject_get_hierarchy` — Inspect scene hierarchy with component details
|
|
113
|
+
|
|
114
|
+
### Component System
|
|
115
|
+
- `component_add` — Add Unity components to GameObjects with initial properties
|
|
116
|
+
- `component_remove` — Remove components from GameObjects with safety checks
|
|
117
|
+
- `component_modify` — Modify component properties with nested support
|
|
118
|
+
- `component_field_set` — Update serialized fields (including private `[SerializeField]` values, arrays, and nested structs)
|
|
119
|
+
- `component_list` — List all components on a GameObject with type information
|
|
120
|
+
- `component_get_types` — Discover available component types with filtering
|
|
121
|
+
|
|
122
|
+
### Scene Management
|
|
123
|
+
- `scene_create` — Create new scenes with build-settings integration
|
|
124
|
+
- `scene_load` — Load scenes in Single or Additive mode
|
|
125
|
+
- `scene_save` — Save the active scene (supports Save As)
|
|
126
|
+
- `scene_list` — List scenes in the project with filtering options
|
|
127
|
+
- `scene_info_get` — Retrieve detailed scene information including GameObject counts
|
|
128
|
+
|
|
129
|
+
### Analysis & Diagnostics
|
|
130
|
+
- `analysis_scene_contents_analyze` — Gather scene statistics and performance metrics
|
|
131
|
+
- `analysis_component_find` — Locate GameObjects by component type with scope filtering
|
|
132
|
+
- `analysis_component_values_get` — Inspect component properties and values
|
|
133
|
+
- `analysis_gameobject_details_get` — Deep inspection of GameObjects and components
|
|
134
|
+
- `analysis_object_references_get` — Trace references between objects and assets
|
|
135
|
+
- `analysis_animator_state_get` — Inspect Animator layers, parameters, and transitions
|
|
136
|
+
- `analysis_animator_runtime_info_get` — Retrieve runtime Animator diagnostics (Play Mode)
|
|
137
|
+
|
|
138
|
+
### Asset Management
|
|
139
|
+
- `asset_prefab_create` — Create prefabs from GameObjects or blank templates
|
|
140
|
+
- `asset_prefab_instantiate` — Instantiate prefabs with custom transforms
|
|
141
|
+
- `asset_prefab_modify` — Apply property overrides to existing prefabs
|
|
142
|
+
- `asset_prefab_open` — Open prefabs in Prefab Mode for editing
|
|
143
|
+
- `asset_prefab_exit_mode` — Exit Prefab Mode with save/discard handling
|
|
144
|
+
- `asset_prefab_save` — Save prefab changes or apply instance overrides
|
|
145
|
+
- `asset_material_create` — Create materials with shader and property setup
|
|
146
|
+
- `asset_material_modify` — Update material properties and shaders
|
|
147
|
+
- `asset_import_settings_manage` — Inspect or modify asset-import settings and presets
|
|
148
|
+
- `asset_database_manage` — Perform asset database operations (find, move, copy, delete)
|
|
149
|
+
- `asset_dependency_analyze` — Audit asset dependencies and identify unused assets
|
|
150
|
+
|
|
151
|
+
### Script & Code Tools
|
|
152
|
+
- `script_read` — Read script file contents with syntax-aware formatting
|
|
153
|
+
- `script_search` — Search C# sources by substring/regex/glob filters
|
|
154
|
+
- `script_symbols_get` — Enumerate symbols within a specific C# file
|
|
155
|
+
- `script_symbol_find` — Locate symbol definitions across the project
|
|
156
|
+
- `script_refs_find` — List references/usages for a symbol via C# LSP
|
|
157
|
+
- `script_edit_snippet` — Apply small text edits within C# files
|
|
158
|
+
- `script_edit_structured` — Perform structured symbol edits via C# LSP extensions
|
|
159
|
+
- `script_create_class` — Generate a new C# class file from parameters
|
|
160
|
+
- `script_remove_symbol` — Delete symbols (types/members) with reference checks
|
|
161
|
+
- `script_refactor_rename` — Rename symbols project-wide via LSP
|
|
162
|
+
- `script_packages_list` — List installed packages relevant to scripting
|
|
163
|
+
- `code_index_status` — Report status of the persistent code index
|
|
164
|
+
|
|
165
|
+
### Code Index Utilities
|
|
166
|
+
- `code_index_build` — フルスキャンでシンボルインデックスを再構築(開発時は `delayStartMs` や `throttleMs` で進捗観測用に速度調整可能)
|
|
167
|
+
- `code_index_update` — 変更した C# ファイルのみ差分再インデックス
|
|
168
|
+
|
|
169
|
+
### Play Mode Controls
|
|
170
|
+
- `playmode_play` — Enter Play Mode
|
|
171
|
+
- `playmode_pause` — Pause or resume Play Mode
|
|
172
|
+
- `playmode_stop` — Exit Play Mode back to Edit Mode
|
|
173
|
+
- `playmode_get_state` — Inspect current play/edit/compilation state
|
|
174
|
+
- `playmode_wait_for_state` — Await a target play/edit state
|
|
175
|
+
|
|
176
|
+
### UI Automation
|
|
177
|
+
- `ui_find_elements` — Locate UI elements by type, tag, or name
|
|
178
|
+
- `ui_click_element` — Simulate clicking UI buttons, toggles, etc.
|
|
179
|
+
- `ui_get_element_state` — Inspect UI element properties and interactability
|
|
180
|
+
- `ui_set_element_value` — Modify UI input values (sliders, fields, dropdowns)
|
|
181
|
+
- `ui_simulate_input` — Execute complex multi-step UI interaction sequences
|
|
182
|
+
|
|
183
|
+
### Input System Utilities
|
|
184
|
+
- `input_system_control` — Dispatch keyboard/mouse/gamepad/touch operations
|
|
185
|
+
- `input_keyboard_simulate` — Simulate keyboard input with combos or text
|
|
186
|
+
- `input_mouse_simulate` — Simulate mouse movement, clicks, drags, and scrolling
|
|
187
|
+
- `input_gamepad_simulate` — Simulate gamepad buttons, sticks, and triggers
|
|
188
|
+
- `input_touch_simulate` — Simulate touch gestures (tap, swipe, pinch)
|
|
189
|
+
- `input_action_add` — Add actions to an Input Action map
|
|
190
|
+
- `input_action_remove` — Remove actions from an Input Action map
|
|
191
|
+
- `input_action_map_create` — Create new Input Action maps
|
|
192
|
+
- `input_action_map_remove` — Delete existing Input Action maps
|
|
193
|
+
- `input_binding_add` — Add bindings to an action (including composites)
|
|
194
|
+
- `input_binding_remove` — Remove a specific binding from an action
|
|
195
|
+
- `input_binding_remove_all` — Clear all bindings from an action
|
|
196
|
+
- `input_binding_composite_create` — Create composite bindings (e.g., 2D vectors)
|
|
197
|
+
- `input_control_schemes_manage` — Manage control schemes and device lists
|
|
198
|
+
- `input_actions_state_get` — Inspect current Input Actions asset configuration
|
|
199
|
+
- `input_actions_asset_analyze` — Produce structured summaries of Input Actions assets
|
|
200
|
+
|
|
201
|
+
### Editor & Console Utilities
|
|
202
|
+
- `menu_item_execute` — Trigger Unity Editor menu items programmatically
|
|
203
|
+
- `console_clear` — Clear Unity console logs with filtering options
|
|
204
|
+
- `console_read` — Stream Unity console output with advanced filters
|
|
205
|
+
- `editor_tags_manage` — Manage project tags (add/remove/list)
|
|
206
|
+
- `editor_layers_manage` — Manage project layers with index conversion
|
|
207
|
+
- `editor_selection_manage` — Inspect or mutate the current editor selection
|
|
208
|
+
- `editor_windows_manage` — Enumerate or focus Unity editor windows
|
|
209
|
+
- `editor_tools_manage` — Manage editor tools and plugins
|
|
210
|
+
- `compilation_get_state` — Inspect current compilation state and errors
|
|
211
|
+
|
|
212
|
+
### Project Settings & Packages
|
|
213
|
+
- `settings_get` — Read Unity project settings with granular control
|
|
214
|
+
- `settings_update` — Safely update project settings (requires confirmation)
|
|
215
|
+
- `package_manage` — List or manage Unity packages via Package Manager
|
|
216
|
+
- `package_registry_config` — Configure package registries/scopes
|
|
217
|
+
|
|
218
|
+
### Asset Visualization & Capture
|
|
219
|
+
- `screenshot_capture` — Capture Game/Scene view screenshots
|
|
220
|
+
- `screenshot_analyze` — Run image analysis on captured screenshots
|
|
221
|
+
- `video_capture_start` — Begin recording the Game view to video
|
|
222
|
+
- `video_capture_stop` — Stop the current video recording
|
|
223
|
+
- `video_capture_status` — Inspect capture status / metadata
|
|
224
|
+
- `video_capture_for` — Record for a fixed duration before auto-stop
|
|
225
|
+
|
|
226
|
+
### Testing & Diagnostics
|
|
227
|
+
- `test_run` — Run Unity tests (EditMode/PlayMode)
|
|
228
|
+
- `test_get_status` — Query test runner progress/results
|
|
176
229
|
|
|
177
230
|
## Requirements
|
|
178
231
|
|
|
@@ -199,7 +252,7 @@ npm install -g @akiojin/unity-mcp-server
|
|
|
199
252
|
|
|
200
253
|
## Repository
|
|
201
254
|
|
|
202
|
-
Full source code and documentation: https://github.com/akiojin/unity-mcp-server
|
|
255
|
+
Full source code and documentation: <https://github.com/akiojin/unity-mcp-server>
|
|
203
256
|
|
|
204
257
|
## License
|
|
205
258
|
|
package/bin/unity-mcp-server
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akiojin/unity-mcp-server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.25.0",
|
|
4
4
|
"description": "MCP server and Unity Editor bridge — enables AI assistants to control Unity for AI-assisted workflows",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/core/server.js",
|
|
@@ -13,18 +13,24 @@
|
|
|
13
13
|
"build:index": "node src/tools/buildCodeIndex.js",
|
|
14
14
|
"test": "node --test tests/unit/**/*.test.js tests/integration/*.test.js",
|
|
15
15
|
"test:unit": "NODE_ENV=test node --test tests/unit/**/*.test.js",
|
|
16
|
-
"test:integration": "NODE_ENV=test node
|
|
16
|
+
"test:integration": "NODE_ENV=test node scripts/run-non-unity-tests.mjs",
|
|
17
17
|
"test:e2e": "NODE_ENV=test node --test tests/e2e/*.test.js",
|
|
18
18
|
"test:coverage": "c8 --reporter=lcov --reporter=text --reporter=html node --test tests/unit/**/*.test.js tests/integration/*.test.js",
|
|
19
19
|
"test:coverage:full": "c8 --reporter=lcov --reporter=text --reporter=html node --test tests/**/*.test.js",
|
|
20
20
|
"test:watch": "node --watch --test tests/unit/**/*.test.js",
|
|
21
21
|
"test:watch:all": "node --watch --test tests/**/*.test.js",
|
|
22
22
|
"test:performance": "node --test tests/performance/*.test.js",
|
|
23
|
-
"test:ci": "
|
|
23
|
+
"test:ci": "CI=true NODE_ENV=test node --test tests/unit/core/codeIndex.test.js tests/unit/core/codeIndexDb.test.js tests/unit/core/config.test.js tests/unit/core/indexWatcher.test.js tests/unit/core/projectInfo.test.js tests/unit/core/server.test.js tests/unit/handlers/script/CodeIndexStatusToolHandler.test.js",
|
|
24
24
|
"test:ci:all": "c8 --reporter=lcov node --test tests/unit/**/*.test.js",
|
|
25
|
+
"simulate:code-index": "node scripts/simulate-code-index-status.mjs",
|
|
25
26
|
"test:verbose": "VERBOSE_TEST=true node --test tests/**/*.test.js",
|
|
27
|
+
"prepare": "cd .. && husky || true",
|
|
26
28
|
"prepublishOnly": "npm run test:ci",
|
|
27
|
-
"postinstall": "chmod +x bin/unity-mcp-server || true"
|
|
29
|
+
"postinstall": "chmod +x bin/unity-mcp-server || true",
|
|
30
|
+
"test:ci:unity": "timeout 60 node --test tests/unit/core/codeIndex.test.js tests/unit/core/codeIndexDb.test.js tests/unit/core/config.test.js tests/unit/core/indexWatcher.test.js tests/unit/core/projectInfo.test.js tests/unit/core/server.test.js || exit 0",
|
|
31
|
+
"test:unity": "node tests/run-unity-integration.mjs",
|
|
32
|
+
"test:nounity": "npm run test:integration",
|
|
33
|
+
"test:ci:integration": "CI=true NODE_ENV=test node --test tests/integration/code-index-background.test.js"
|
|
28
34
|
},
|
|
29
35
|
"keywords": [
|
|
30
36
|
"mcp",
|
|
@@ -42,10 +48,11 @@
|
|
|
42
48
|
"license": "MIT",
|
|
43
49
|
"dependencies": {
|
|
44
50
|
"@modelcontextprotocol/sdk": "^0.6.1",
|
|
45
|
-
"better-sqlite3": "^9.4.3"
|
|
51
|
+
"better-sqlite3": "^9.4.3",
|
|
52
|
+
"find-up": "^6.3.0"
|
|
46
53
|
},
|
|
47
54
|
"engines": {
|
|
48
|
-
"node": ">=18
|
|
55
|
+
"node": ">=18 <21"
|
|
49
56
|
},
|
|
50
57
|
"repository": {
|
|
51
58
|
"type": "git",
|
|
@@ -67,7 +74,23 @@
|
|
|
67
74
|
"access": "public"
|
|
68
75
|
},
|
|
69
76
|
"devDependencies": {
|
|
77
|
+
"@commitlint/cli": "^18.6.1",
|
|
78
|
+
"@commitlint/config-conventional": "^18.6.3",
|
|
79
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
80
|
+
"@semantic-release/commit-analyzer": "^11.1.0",
|
|
81
|
+
"@semantic-release/exec": "^6.0.3",
|
|
82
|
+
"@semantic-release/git": "^10.0.1",
|
|
83
|
+
"@semantic-release/release-notes-generator": "^12.1.0",
|
|
70
84
|
"c8": "^10.1.3",
|
|
71
|
-
"
|
|
85
|
+
"eslint": "^8.57.1",
|
|
86
|
+
"eslint-config-standard": "^17.1.0",
|
|
87
|
+
"eslint-plugin-import": "^2.31.0",
|
|
88
|
+
"eslint-plugin-n": "^16.6.2",
|
|
89
|
+
"eslint-plugin-promise": "^6.6.0",
|
|
90
|
+
"husky": "^9.1.7",
|
|
91
|
+
"markdownlint-cli": "^0.43.0",
|
|
92
|
+
"nodemon": "^3.1.7",
|
|
93
|
+
"prettier": "^3.4.2",
|
|
94
|
+
"semantic-release": "^22.0.12"
|
|
72
95
|
}
|
|
73
96
|
}
|
package/src/core/codeIndex.js
CHANGED
|
File without changes
|
package/src/core/codeIndexDb.js
CHANGED
|
File without changes
|
package/src/core/config.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
+
import { findUpSync } from 'find-up';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Shallow merge utility (simple objects only)
|
|
@@ -92,25 +93,44 @@ const baseConfig = {
|
|
|
92
93
|
* 1) UNITY_MCP_CONFIG (explicit file path)
|
|
93
94
|
* 2) ./.unity/config.json (project-local)
|
|
94
95
|
* 3) ~/.unity/config.json (user-global)
|
|
95
|
-
* If none found,
|
|
96
|
+
* If none found, create ./.unity/config.json with defaults.
|
|
96
97
|
*/
|
|
97
|
-
function
|
|
98
|
-
const
|
|
98
|
+
function ensureDefaultProjectConfig(baseDir) {
|
|
99
|
+
const dir = path.resolve(baseDir, '.unity');
|
|
100
|
+
const file = path.join(dir, 'config.json');
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
if (!fs.existsSync(dir)) {
|
|
104
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
105
|
+
}
|
|
99
106
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
if (!fs.existsSync(file)) {
|
|
108
|
+
const inferredRoot = fs.existsSync(path.join(baseDir, 'Assets')) ? baseDir : '';
|
|
109
|
+
const defaultConfig = {
|
|
110
|
+
unity: {
|
|
111
|
+
unityHost: 'localhost',
|
|
112
|
+
mcpHost: 'localhost',
|
|
113
|
+
port: 6400,
|
|
114
|
+
},
|
|
115
|
+
project: {
|
|
116
|
+
root: inferredRoot ? inferredRoot.replace(/\\/g, '/') : '',
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
fs.writeFileSync(file, `${JSON.stringify(defaultConfig, null, 2)}\n`, 'utf8');
|
|
109
120
|
}
|
|
121
|
+
return file;
|
|
122
|
+
} catch (error) {
|
|
110
123
|
return null;
|
|
111
|
-
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
112
126
|
|
|
113
|
-
|
|
127
|
+
function loadExternalConfig() {
|
|
128
|
+
const explicitPath = process.env.UNITY_MCP_CONFIG;
|
|
129
|
+
|
|
130
|
+
const projectPath = findUpSync((directory) => {
|
|
131
|
+
const candidate = path.resolve(directory, '.unity', 'config.json');
|
|
132
|
+
return fs.existsSync(candidate) ? candidate : undefined;
|
|
133
|
+
}, { cwd: process.cwd() });
|
|
114
134
|
const homeDir = process.env.HOME || process.env.USERPROFILE || '';
|
|
115
135
|
const userPath = homeDir ? path.resolve(homeDir, '.unity', 'config.json') : null;
|
|
116
136
|
|
|
@@ -128,6 +148,19 @@ function loadExternalConfig() {
|
|
|
128
148
|
return { __configLoadError: `${p}: ${e.message}` };
|
|
129
149
|
}
|
|
130
150
|
}
|
|
151
|
+
const fallbackPath = ensureDefaultProjectConfig(process.cwd());
|
|
152
|
+
if (fallbackPath && fs.existsSync(fallbackPath)) {
|
|
153
|
+
try {
|
|
154
|
+
const raw = fs.readFileSync(fallbackPath, 'utf8');
|
|
155
|
+
const json = JSON.parse(raw);
|
|
156
|
+
const out = json && typeof json === 'object' ? json : {};
|
|
157
|
+
out.__configPath = fallbackPath;
|
|
158
|
+
out.__configGenerated = true;
|
|
159
|
+
return out;
|
|
160
|
+
} catch (e) {
|
|
161
|
+
return { __configLoadError: `${fallbackPath}: ${e.message}` };
|
|
162
|
+
}
|
|
163
|
+
}
|
|
131
164
|
return {};
|
|
132
165
|
}
|
|
133
166
|
|
package/src/core/indexWatcher.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { logger, config } from './config.js';
|
|
2
|
+
import { JobManager } from './jobManager.js';
|
|
2
3
|
|
|
3
4
|
export class IndexWatcher {
|
|
4
5
|
constructor(unityConnection) {
|
|
5
6
|
this.unityConnection = unityConnection;
|
|
6
7
|
this.timer = null;
|
|
7
8
|
this.running = false;
|
|
9
|
+
this.jobManager = JobManager.getInstance();
|
|
10
|
+
this.currentWatcherJobId = null;
|
|
8
11
|
}
|
|
9
12
|
|
|
10
13
|
start() {
|
|
@@ -13,6 +16,9 @@ export class IndexWatcher {
|
|
|
13
16
|
const interval = Math.max(2000, Number(config.indexing.intervalMs || 15000));
|
|
14
17
|
logger.info(`[index] watcher enabled (interval=${interval}ms)`);
|
|
15
18
|
this.timer = setInterval(() => this.tick(), interval);
|
|
19
|
+
if (typeof this.timer.unref === 'function') {
|
|
20
|
+
this.timer.unref();
|
|
21
|
+
}
|
|
16
22
|
// Initial kick
|
|
17
23
|
this.tick();
|
|
18
24
|
}
|
|
@@ -28,25 +34,88 @@ export class IndexWatcher {
|
|
|
28
34
|
if (this.running) return;
|
|
29
35
|
this.running = true;
|
|
30
36
|
try {
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (ok) {
|
|
41
|
-
logger.info(`[index] updated=${res.result.updatedFiles || 0} removed=${res.result.removedFiles || 0} total=${res.result.totalIndexedSymbols || 0}`);
|
|
42
|
-
} else if (res?.result?.error) {
|
|
43
|
-
logger.warn(`[index] update failed: ${res.result.error}`);
|
|
37
|
+
// Check if manual build is already running (jobs starting with 'build-')
|
|
38
|
+
const allJobs = this.jobManager.getAllJobs();
|
|
39
|
+
const manualBuildRunning = allJobs.some(job =>
|
|
40
|
+
job.id.startsWith('build-') && job.status === 'running'
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
if (manualBuildRunning) {
|
|
44
|
+
logger.info('[index] watcher: skipping auto-build (manual build in progress)');
|
|
45
|
+
return;
|
|
44
46
|
}
|
|
47
|
+
|
|
48
|
+
// Check if our watcher job is still running
|
|
49
|
+
if (this.currentWatcherJobId) {
|
|
50
|
+
const watcherJob = this.jobManager.get(this.currentWatcherJobId);
|
|
51
|
+
if (watcherJob && watcherJob.status === 'running') {
|
|
52
|
+
logger.info('[index] watcher: previous auto-build still running, skipping');
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
// Previous watcher job completed or cleaned up
|
|
56
|
+
this.currentWatcherJobId = null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Start new watcher build job
|
|
60
|
+
const jobId = `watcher-${Date.now()}`;
|
|
61
|
+
this.currentWatcherJobId = jobId;
|
|
62
|
+
|
|
63
|
+
const { CodeIndexBuildToolHandler } = await import('../handlers/script/CodeIndexBuildToolHandler.js');
|
|
64
|
+
const handler = new CodeIndexBuildToolHandler(this.unityConnection);
|
|
65
|
+
|
|
66
|
+
// Create the build job through JobManager
|
|
67
|
+
this.jobManager.create(jobId, async (job) => {
|
|
68
|
+
const params = {
|
|
69
|
+
concurrency: config.indexing.concurrency || 8,
|
|
70
|
+
retry: config.indexing.retry || 2,
|
|
71
|
+
reportEvery: config.indexing.reportEvery || 500,
|
|
72
|
+
};
|
|
73
|
+
return await handler._executeBuild(params, job);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
logger.info(`[index] watcher: started auto-build job ${jobId}`);
|
|
77
|
+
|
|
78
|
+
// Monitor job completion in background
|
|
79
|
+
// (Job result will be logged when it completes/fails)
|
|
80
|
+
this._monitorJob(jobId);
|
|
81
|
+
|
|
45
82
|
} catch (e) {
|
|
46
|
-
logger.warn(`[index]
|
|
83
|
+
logger.warn(`[index] watcher exception: ${e.message}`);
|
|
47
84
|
} finally {
|
|
48
85
|
this.running = false;
|
|
49
86
|
}
|
|
50
87
|
}
|
|
51
|
-
}
|
|
52
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Monitor job completion for logging
|
|
91
|
+
* @private
|
|
92
|
+
*/
|
|
93
|
+
async _monitorJob(jobId) {
|
|
94
|
+
// Check job status periodically
|
|
95
|
+
const checkInterval = setInterval(() => {
|
|
96
|
+
const job = this.jobManager.get(jobId);
|
|
97
|
+
if (!job) {
|
|
98
|
+
// Job cleaned up
|
|
99
|
+
clearInterval(checkInterval);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (job.status === 'completed') {
|
|
104
|
+
logger.info(`[index] watcher: auto-build completed - updated=${job.result?.updatedFiles || 0} removed=${job.result?.removedFiles || 0} total=${job.result?.totalIndexedSymbols || 0}`);
|
|
105
|
+
clearInterval(checkInterval);
|
|
106
|
+
} else if (job.status === 'failed') {
|
|
107
|
+
logger.warn(`[index] watcher: auto-build failed - ${job.error}`);
|
|
108
|
+
clearInterval(checkInterval);
|
|
109
|
+
}
|
|
110
|
+
}, 1000);
|
|
111
|
+
if (typeof checkInterval.unref === 'function') {
|
|
112
|
+
checkInterval.unref();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Cleanup interval after 10 minutes (longer than job cleanup)
|
|
116
|
+
const cleanupTimeout = setTimeout(() => clearInterval(checkInterval), 600000);
|
|
117
|
+
if (typeof cleanupTimeout.unref === 'function') {
|
|
118
|
+
cleanupTimeout.unref();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|