unity-mcp-server 1.0.0 → 1.2.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/README.md CHANGED
@@ -16,13 +16,41 @@ Unity MCP Server runs as a separate process and reads your Unity project from di
16
16
 
17
17
  ---
18
18
 
19
- ## Features
19
+ ## Tools (by category)
20
20
 
21
- | Tool | Description |
22
- |------|-------------|
23
- | `get_project_info` | Returns project root path, Unity version, and build scene count. |
24
- | `list_build_scenes` | Returns scenes in `EditorBuildSettings` in build order (JSON). |
25
- | `read_agent_docs` | Returns contents of `.agents/AGENT.md`; optionally includes `REPO_UNDERSTANDING.md`. |
21
+ **Project & build** `get_project_info`, `list_build_scenes`, `get_player_settings`, `list_packages`, `get_quality_settings`, `get_scripting_defines`, `get_physics_settings`, `get_project_version`, `get_changelog`
22
+
23
+ **Code & assemblies** `list_assemblies`, `list_scripts`, `find_scripts_by_content`, `get_assembly_dependency_graph`, `list_editor_scripts`
24
+
25
+ **Scenes & prefabs** `list_all_scenes`, `get_scene_summary`, `list_prefabs`, `get_prefab_script_guids`
26
+
27
+ **Assets & references** — `get_asset_folder_tree`, `list_assets_by_extension`, `find_references`, `list_large_assets`
28
+
29
+ **Materials & shaders** — `list_materials`, `list_shaders`, `list_shader_graphs`, `list_vfx_graphs`
30
+
31
+ **Animation** — `list_animator_controllers`, `list_animation_clips`, `get_animator_states`, `list_timeline_playables`
32
+
33
+ **2D & sprites** — `list_sprite_atlases`, `list_tilemap_assets`
34
+
35
+ **Rendering** — `list_render_pipelines` (URP/HDRP, volume profiles)
36
+
37
+ **TextMeshPro & UI** — `list_tmp_fonts`, `get_tmp_settings_path`, `list_ui_documents` (UXML, USS)
38
+
39
+ **Input** — `get_input_axes`, `list_input_action_assets`, `get_input_actions_summary`
40
+
41
+ **Tags & layers** — `get_tags_and_layers`
42
+
43
+ **Addressables & localization** — `get_addressables_info`, `get_localization_tables`
44
+
45
+ **Audio** — `list_audio_clips`, `list_audio_mixers`
46
+
47
+ **Testing & docs** — `list_test_assemblies`, `get_repo_docs`, `read_agent_docs`
48
+
49
+ **CI & version control** — `list_ci_configs`, `list_presets`, `get_git_lfs_tracked`, `get_plastic_config`
50
+
51
+ **Integrations (config discovery)** — `get_playfab_config`, `list_figma_related_assets`, `get_firebase_config`, `get_steam_config`, `get_discord_config`, `get_fmod_config`, `get_wwise_config`, `list_substance_assets`, `list_speedtree_assets`, `list_lottie_assets`, `get_analytics_or_crash_config`, `get_ads_config`
52
+
53
+ All tools read from the project filesystem only; no Unity Editor is required.
26
54
 
27
55
  ---
28
56
 
package/dist/index.d.ts CHANGED
@@ -1,8 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
3
  * unity-mcp-server – Lightweight MCP server for any Unity project.
4
- * Exposes tools: project info, build scenes, agent docs. No Unity Editor required.
5
- * Set UNITY_PROJECT_PATH to the Unity project root in your MCP client config.
6
- * Run: node dist/index.js (after npm run build).
4
+ * Exposes tools for project info, build scenes, agent docs, packages, code, assets, and more. No Unity Editor required.
7
5
  */
8
6
  export {};
package/dist/index.js CHANGED
@@ -1,37 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
3
  * unity-mcp-server – Lightweight MCP server for any Unity project.
4
- * Exposes tools: project info, build scenes, agent docs. No Unity Editor required.
5
- * Set UNITY_PROJECT_PATH to the Unity project root in your MCP client config.
6
- * Run: node dist/index.js (after npm run build).
4
+ * Exposes tools for project info, build scenes, agent docs, packages, code, assets, and more. No Unity Editor required.
7
5
  */
8
- import { readFileSync, existsSync } from "node:fs";
9
- import { join, resolve } from "node:path";
6
+ import { resolve } from "node:path";
10
7
  import { z } from "zod";
8
+ import * as R from "./readers.js";
11
9
  function getProjectRoot() {
12
10
  const env = process.env.UNITY_PROJECT_PATH;
13
11
  if (env)
14
12
  return resolve(env);
15
13
  console.error("UNITY_PROJECT_PATH is required. Set it in your MCP client config (e.g. Cursor) to your Unity project root.");
16
14
  process.exit(1);
17
- return ""; // unreachable
18
- }
19
- function getBuildScenes(projectRoot) {
20
- const path = join(projectRoot, "ProjectSettings", "EditorBuildSettings.asset");
21
- if (!existsSync(path))
22
- return [];
23
- const content = readFileSync(path, "utf-8");
24
- const scenes = [];
25
- let index = 0;
26
- const pathRe = /path: (Assets\/[^\n]+\.unity)/g;
27
- let m;
28
- while ((m = pathRe.exec(content)) !== null) {
29
- const fullPath = m[1];
30
- const name = fullPath.replace(/^.*\//, "").replace(/\.unity$/, "");
31
- scenes.push({ index, path: fullPath, name });
32
- index++;
33
- }
34
- return scenes;
15
+ return "";
35
16
  }
36
17
  async function main() {
37
18
  const projectRoot = getProjectRoot();
@@ -39,59 +20,214 @@ async function main() {
39
20
  const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
40
21
  const server = new McpServer({
41
22
  name: "unity-mcp-server",
42
- version: "1.0.0",
23
+ version: "1.2.0",
43
24
  });
25
+ const text = (s) => ({ content: [{ type: "text", text: s }] });
26
+ const json = (o) => text(JSON.stringify(o, null, 2));
27
+ // --- Existing + expanded project info ---
44
28
  server.registerTool("get_project_info", {
45
- description: "Get Unity project info (path, Unity version, build scene count).",
29
+ description: "Get Unity project info: path, Unity version, build scene count, player/product name.",
46
30
  inputSchema: {},
47
31
  }, async () => {
48
- let unityVersion = "unknown";
49
- const pvPath = join(projectRoot, "ProjectSettings", "ProjectVersion.txt");
50
- if (existsSync(pvPath)) {
51
- const m = readFileSync(pvPath, "utf-8").match(/m_EditorVersion:\s*(.+)/);
52
- if (m)
53
- unityVersion = m[1].trim();
54
- }
55
- const scenes = getBuildScenes(projectRoot);
56
- const text = [
32
+ const unityVersion = R.getUnityVersion(projectRoot);
33
+ const scenes = R.getBuildScenes(projectRoot);
34
+ const player = R.getPlayerSettings(projectRoot);
35
+ const lines = [
57
36
  `Project root: ${projectRoot}`,
58
37
  `Unity version: ${unityVersion}`,
59
38
  `Build scenes: ${scenes.length}`,
60
- scenes.map((s) => ` ${s.index}: ${s.name} (${s.path})`).join("\n"),
61
- ].join("\n");
62
- return { content: [{ type: "text", text }] };
63
- });
64
- server.registerTool("list_build_scenes", {
65
- description: "List all scenes in Unity EditorBuildSettings (build order).",
66
- inputSchema: {},
67
- }, async () => {
68
- const scenes = getBuildScenes(projectRoot);
69
- const text = JSON.stringify(scenes, null, 2);
70
- return { content: [{ type: "text", text }] };
39
+ ...scenes.map((s) => ` ${s.index}: ${s.name} (${s.path})`),
40
+ "",
41
+ "Player / product (if available):",
42
+ ...Object.entries(player).map(([k, v]) => ` ${k}: ${v}`),
43
+ ];
44
+ return text(lines.join("\n"));
71
45
  });
46
+ server.registerTool("list_build_scenes", { description: "List scenes in EditorBuildSettings (build order) as JSON.", inputSchema: {} }, async () => json(R.getBuildScenes(projectRoot)));
72
47
  server.registerTool("read_agent_docs", {
73
- description: "Read the agent development guide (.agents/AGENT.md) and optionally REPO_UNDERSTANDING.md.",
48
+ description: "Read .agents/AGENT.md and optionally REPO_UNDERSTANDING.md.",
74
49
  inputSchema: {
75
- include_repo_understanding: z.boolean().optional().describe("If true, also return REPO_UNDERSTANDING.md content").default(false),
50
+ include_repo_understanding: z.boolean().optional().describe("If true, also return REPO_UNDERSTANDING.md").default(false),
76
51
  },
77
52
  }, async (args) => {
78
53
  const include = args?.include_repo_understanding ?? false;
79
- const agentPath = join(projectRoot, ".agents", "AGENT.md");
80
- let text = "";
81
- if (existsSync(agentPath)) {
82
- text = readFileSync(agentPath, "utf-8");
54
+ let content = R.readFileSafe(projectRoot, ".agents", "AGENT.md") ?? "(No .agents/AGENT.md found)";
55
+ if (include) {
56
+ const rep = R.readFileSafe(projectRoot, "REPO_UNDERSTANDING.md");
57
+ if (rep)
58
+ content += "\n\n---\n\n# REPO_UNDERSTANDING.md\n\n" + rep;
83
59
  }
84
- else {
85
- text = "(No .agents/AGENT.md found)";
60
+ return text(content);
61
+ });
62
+ // --- 1. Project & package info ---
63
+ server.registerTool("get_player_settings", { description: "Get Player/ProjectSettings (product name, company, bundle ID, version, etc.).", inputSchema: {} }, async () => json(R.getPlayerSettings(projectRoot)));
64
+ server.registerTool("list_packages", { description: "List Unity packages from Packages/manifest.json (and optional packages-lock.json).", inputSchema: {} }, async () => json(R.getPackages(projectRoot)));
65
+ server.registerTool("get_quality_settings", { description: "Get QualitySettings (quality levels) from ProjectSettings.", inputSchema: {} }, async () => json(R.getQualitySettings(projectRoot)));
66
+ server.registerTool("get_scripting_defines", { description: "Get global and per-assembly scripting define symbols.", inputSchema: {} }, async () => json(R.getScriptingDefines(projectRoot)));
67
+ // --- 2. Code & assemblies ---
68
+ server.registerTool("list_assemblies", {
69
+ description: "List assembly definitions (.asmdef) with path, name, references, platforms.",
70
+ inputSchema: {},
71
+ }, async () => json(R.getAssemblyDefinitions(projectRoot)));
72
+ server.registerTool("list_scripts", {
73
+ description: "List all C# scripts under Assets. Optionally filter by folder prefix (e.g. Scripts).",
74
+ inputSchema: {
75
+ folder: z.string().optional().describe("Optional folder under Assets, e.g. Scripts/Runtime"),
76
+ },
77
+ }, async (args) => json(R.listScripts(projectRoot, args?.folder)));
78
+ server.registerTool("find_scripts_by_content", {
79
+ description: "Find C# scripts that contain a type or pattern (e.g. MonoBehaviour, ScriptableObject, or custom). Optionally filter by namespace.",
80
+ inputSchema: {
81
+ pattern: z.string().describe("Pattern to search for, e.g. MonoBehaviour or a type name"),
82
+ namespace_filter: z.string().optional().describe("Optional namespace pattern, e.g. Game.*"),
83
+ },
84
+ }, async (args) => {
85
+ const a = args;
86
+ return json(R.findScriptsByContent(projectRoot, a.pattern, a.namespace_filter));
87
+ });
88
+ // --- 3. Scenes ---
89
+ server.registerTool("list_all_scenes", { description: "List all .unity scene files under Assets (not only build-indexed).", inputSchema: {} }, async () => json(R.getAllScenes(projectRoot)));
90
+ server.registerTool("get_scene_summary", {
91
+ description: "Get a short summary of a scene: root GameObject names and approximate component count.",
92
+ inputSchema: { scene_path: z.string().describe("Path relative to project, e.g. Assets/Scenes/Main.unity") },
93
+ }, async (args) => json(R.getSceneSummary(projectRoot, args.scene_path)));
94
+ // --- 4. Prefabs ---
95
+ server.registerTool("list_prefabs", {
96
+ description: "List all .prefab files. Optionally filter by path prefix under Assets.",
97
+ inputSchema: { path_prefix: z.string().optional().describe("e.g. Prefabs/Characters") },
98
+ }, async (args) => json(R.getPrefabs(projectRoot, args?.path_prefix)));
99
+ // --- 5. Assets & references ---
100
+ server.registerTool("find_references", {
101
+ description: "Find all assets (scenes, prefabs, materials, etc.) that reference the given asset. Pass asset path (e.g. Assets/Texture.png) or GUID.",
102
+ inputSchema: {
103
+ asset_path_or_guid: z.string().describe("Asset path relative to project (e.g. Assets/My.asset) or 32-char GUID"),
104
+ },
105
+ }, async (args) => {
106
+ const input = args.asset_path_or_guid.trim();
107
+ let guid;
108
+ if (/^[a-f0-9]{32}$/i.test(input)) {
109
+ guid = input;
86
110
  }
87
- if (include) {
88
- const repPath = join(projectRoot, "REPO_UNDERSTANDING.md");
89
- if (existsSync(repPath)) {
90
- text += "\n\n---\n\n# REPO_UNDERSTANDING.md\n\n" + readFileSync(repPath, "utf-8");
91
- }
111
+ else {
112
+ guid = R.getGuidFromMeta(projectRoot, input) ?? "";
113
+ if (!guid)
114
+ return text(`No .meta found for ${input}; cannot resolve GUID.`);
92
115
  }
93
- return { content: [{ type: "text", text }] };
116
+ const refs = R.findReferencesToGuid(projectRoot, guid);
117
+ return json({ guid, references: refs });
118
+ });
119
+ server.registerTool("get_asset_folder_tree", {
120
+ description: "Get a tree of Assets folder (directories and file names). Useful for understanding project layout.",
121
+ inputSchema: { max_depth: z.number().optional().describe("Max folder depth, default 4").default(4) },
122
+ }, async (args) => json(R.getAssetFolderTree(projectRoot, args?.max_depth ?? 4)));
123
+ server.registerTool("list_assets_by_extension", {
124
+ description: "List assets by file extension (e.g. .png, .fbx, .mp3). Optionally under a folder.",
125
+ inputSchema: {
126
+ extension: z.string().describe("e.g. .png, .fbx, .mp3"),
127
+ folder: z.string().optional().describe("Optional folder under Assets"),
128
+ },
129
+ }, async (args) => {
130
+ const a = args;
131
+ const ext = a.extension.startsWith(".") ? a.extension : `.${a.extension}`;
132
+ return json(R.listAssetsByExtension(projectRoot, ext, a.folder));
133
+ });
134
+ // --- 6. Materials & shaders ---
135
+ server.registerTool("list_materials", {
136
+ description: "List .mat materials; optionally under a folder. Includes shader GUID when readable.",
137
+ inputSchema: { folder: z.string().optional() },
138
+ }, async (args) => json(R.getMaterials(projectRoot, args?.folder)));
139
+ server.registerTool("list_shaders", { description: "List all .shader files in Assets and Packages.", inputSchema: {} }, async () => json(R.getShaders(projectRoot)));
140
+ // --- 7. Animation ---
141
+ server.registerTool("list_animator_controllers", { description: "List all Animator Controller (.controller) assets.", inputSchema: {} }, async () => json(R.getAnimatorControllers(projectRoot)));
142
+ server.registerTool("list_animation_clips", { description: "List all Animation Clip (.anim) assets.", inputSchema: {} }, async () => json(R.getAnimationClips(projectRoot)));
143
+ server.registerTool("get_animator_states", {
144
+ description: "Get state names from an Animator Controller (.controller) file.",
145
+ inputSchema: { controller_path: z.string().describe("e.g. Assets/Animations/Player.controller") },
146
+ }, async (args) => json(R.getAnimatorStates(projectRoot, args.controller_path)));
147
+ // --- 8. Audio ---
148
+ server.registerTool("list_audio_clips", { description: "List audio clip files (.wav, .mp3, .ogg, .aiff) under Assets.", inputSchema: {} }, async () => json(R.getAudioClips(projectRoot)));
149
+ server.registerTool("list_audio_mixers", { description: "List Audio Mixer (.mixer) assets.", inputSchema: {} }, async () => json(R.getAudioMixers(projectRoot)));
150
+ // --- 9. Addressables ---
151
+ server.registerTool("get_addressables_info", { description: "Get Addressables groups and config path if the project uses Addressables.", inputSchema: {} }, async () => json(R.getAddressablesInfo(projectRoot)));
152
+ // --- 10. Localization ---
153
+ server.registerTool("get_localization_tables", { description: "List localization table files under Assets/Localization if present.", inputSchema: {} }, async () => json(R.getLocalizationTables(projectRoot)));
154
+ // --- 11. Input ---
155
+ server.registerTool("get_input_axes", { description: "Get input axes from InputManager (name, descriptive name, positive button).", inputSchema: {} }, async () => json(R.getInputAxes(projectRoot)));
156
+ // --- 12. Tags & layers ---
157
+ server.registerTool("get_tags_and_layers", { description: "Get Tags and Layers from TagManager.", inputSchema: {} }, async () => json(R.getTagsAndLayers(projectRoot)));
158
+ // --- 13. Testing ---
159
+ server.registerTool("list_test_assemblies", { description: "List assembly definitions that look like test assemblies (path contains test/editor).", inputSchema: {} }, async () => json(R.getTestAssemblies(projectRoot)));
160
+ // --- 14. Docs & conventions ---
161
+ server.registerTool("get_repo_docs", {
162
+ description: "Read README, CONTRIBUTING, .cursorrules, CODING_STANDARDS, STYLE if present at project root.",
163
+ inputSchema: {},
164
+ }, async () => json(R.getRepoDocs(projectRoot)));
165
+ // --- 15. CI / versioning ---
166
+ server.registerTool("get_project_version", { description: "Get project/bundle version from PlayerSettings.", inputSchema: {} }, async () => text(R.getProjectVersion(projectRoot)));
167
+ server.registerTool("get_changelog", { description: "Read CHANGELOG.md or CHANGELOG if present.", inputSchema: {} }, async () => {
168
+ const content = R.getChangelog(projectRoot);
169
+ return text(content ?? "(No CHANGELOG found)");
94
170
  });
171
+ // --- 16. Physics ---
172
+ server.registerTool("get_physics_settings", { description: "Get Physics/DynamicsManager or Physics2D settings (key-value).", inputSchema: {} }, async () => json(R.getPhysicsSettings(projectRoot)));
173
+ // --- 17. Render pipelines ---
174
+ server.registerTool("list_render_pipelines", { description: "List render pipeline assets and volume profiles (URP/HDRP).", inputSchema: {} }, async () => json(R.listRenderPipelines(projectRoot)));
175
+ // --- 18. Timeline ---
176
+ server.registerTool("list_timeline_playables", { description: "List Timeline .playable assets.", inputSchema: {} }, async () => json(R.listTimelinePlayables(projectRoot)));
177
+ // --- 19. Sprites / 2D ---
178
+ server.registerTool("list_sprite_atlases", { description: "List Sprite Atlas (.spriteatlas) assets.", inputSchema: {} }, async () => json(R.listSpriteAtlases(projectRoot)));
179
+ server.registerTool("list_tilemap_assets", { description: "List tilemap-related .asset files.", inputSchema: {} }, async () => json(R.listTilemapAssets(projectRoot)));
180
+ // --- 20. Shader Graph / VFX ---
181
+ server.registerTool("list_shader_graphs", { description: "List Shader Graph (.shadergraph) assets.", inputSchema: {} }, async () => json(R.listShaderGraphs(projectRoot)));
182
+ server.registerTool("list_vfx_graphs", { description: "List VFX Graph (.vfx) assets.", inputSchema: {} }, async () => json(R.listVfxGraphs(projectRoot)));
183
+ // --- 21. TextMeshPro ---
184
+ server.registerTool("list_tmp_fonts", { description: "List TMP/font-related assets.", inputSchema: {} }, async () => json(R.listTmpFonts(projectRoot)));
185
+ server.registerTool("get_tmp_settings_path", { description: "Get path to TMP Settings asset if present.", inputSchema: {} }, async () => json(R.getTmpSettingsPath(projectRoot)));
186
+ // --- 22. UI Toolkit ---
187
+ server.registerTool("list_ui_documents", { description: "List UI Toolkit .uxml and .uss files.", inputSchema: {} }, async () => json(R.listUiDocuments(projectRoot)));
188
+ // --- 23. New Input System ---
189
+ server.registerTool("list_input_action_assets", { description: "List New Input System .inputactions assets.", inputSchema: {} }, async () => json(R.listInputActionAssets(projectRoot)));
190
+ server.registerTool("get_input_actions_summary", { description: "Get action maps and actions from an .inputactions file.", inputSchema: { path: z.string().describe("e.g. Assets/Input/Player.inputactions") } }, async (args) => json(R.getInputActionsSummary(projectRoot, args.path)));
191
+ // --- 24. Presets ---
192
+ server.registerTool("list_presets", { description: "List .preset assets.", inputSchema: {} }, async () => json(R.listPresets(projectRoot)));
193
+ // --- 25. Editor scripts ---
194
+ server.registerTool("list_editor_scripts", { description: "List C# scripts in Editor folders or with Editor in path.", inputSchema: {} }, async () => json(R.listEditorScripts(projectRoot)));
195
+ // --- 26. Prefab script refs ---
196
+ server.registerTool("get_prefab_script_guids", { description: "Get script GUIDs (MonoBehaviour) referenced by a prefab.", inputSchema: { prefab_path: z.string().describe("e.g. Assets/Prefabs/Player.prefab") } }, async (args) => json(R.getPrefabScriptGuids(projectRoot, args.prefab_path)));
197
+ // --- 27. Assembly dependency graph ---
198
+ server.registerTool("get_assembly_dependency_graph", { description: "Get assembly definition dependency graph (nodes and edges).", inputSchema: {} }, async () => json(R.getAssemblyDependencyGraph(projectRoot)));
199
+ // --- 28. CI configs ---
200
+ server.registerTool("list_ci_configs", { description: "List CI config files (.github/workflows, Jenkinsfile, unity-cloud-build).", inputSchema: {} }, async () => json(R.listCiConfigs(projectRoot)));
201
+ // --- 29. Large assets ---
202
+ server.registerTool("list_large_assets", { description: "List assets over a size threshold (default 5 MB).", inputSchema: { min_size_mb: z.number().optional().default(5) } }, async (args) => json(R.listLargeAssets(projectRoot, args?.min_size_mb ?? 5)));
203
+ // --- 30. PlayFab ---
204
+ server.registerTool("get_playfab_config", { description: "Get PlayFab config (title ID, config paths) from project. No secrets.", inputSchema: {} }, async () => json(R.getPlayFabConfig(projectRoot)));
205
+ // --- 31. Figma ---
206
+ server.registerTool("list_figma_related_assets", { description: "List assets in Figma folder or with figma in path.", inputSchema: {} }, async () => json(R.listFigmaRelatedAssets(projectRoot)));
207
+ // --- 32. Firebase ---
208
+ server.registerTool("get_firebase_config", { description: "Get Firebase config (GoogleServices path, project ID). No secrets.", inputSchema: {} }, async () => json(R.getFirebaseConfig(projectRoot)));
209
+ // --- 33. Steam ---
210
+ server.registerTool("get_steam_config", { description: "Get Steam config (steam_appid.txt, Steamworks path).", inputSchema: {} }, async () => json(R.getSteamConfig(projectRoot)));
211
+ // --- 34. Discord ---
212
+ server.registerTool("get_discord_config", { description: "Detect Discord SDK path in Plugins.", inputSchema: {} }, async () => json(R.getDiscordConfig(projectRoot)));
213
+ // --- 35. FMOD ---
214
+ server.registerTool("get_fmod_config", { description: "Get FMOD config (banks path, bank files).", inputSchema: {} }, async () => json(R.getFmodConfig(projectRoot)));
215
+ // --- 36. Wwise ---
216
+ server.registerTool("get_wwise_config", { description: "Get Wwise config (sound banks, project paths).", inputSchema: {} }, async () => json(R.getWwiseConfig(projectRoot)));
217
+ // --- 37. Substance ---
218
+ server.registerTool("list_substance_assets", { description: "List Substance .sbsar and .sbs assets.", inputSchema: {} }, async () => json(R.listSubstanceAssets(projectRoot)));
219
+ // --- 38. SpeedTree ---
220
+ server.registerTool("list_speedtree_assets", { description: "List SpeedTree .spm and .stm assets.", inputSchema: {} }, async () => json(R.listSpeedTreeAssets(projectRoot)));
221
+ // --- 39. Lottie ---
222
+ server.registerTool("list_lottie_assets", { description: "List Lottie-related JSON assets.", inputSchema: {} }, async () => json(R.listLottieAssets(projectRoot)));
223
+ // --- 40. Analytics / crash ---
224
+ server.registerTool("get_analytics_or_crash_config", { description: "Detect analytics/crash reporting services (Unity, Sentry, Crashlytics, BugSnag).", inputSchema: {} }, async () => json(R.getAnalyticsOrCrashConfig(projectRoot)));
225
+ // --- 41. Ads ---
226
+ server.registerTool("get_ads_config", { description: "Detect ad SDK presence (Unity Ads, AdMob, ironSource).", inputSchema: {} }, async () => json(R.getAdsConfig(projectRoot)));
227
+ // --- 42. Git LFS ---
228
+ server.registerTool("get_git_lfs_tracked", { description: "Get Git LFS patterns from .gitattributes.", inputSchema: {} }, async () => json(R.getGitLfsTracked(projectRoot)));
229
+ // --- 43. Plastic SCM ---
230
+ server.registerTool("get_plastic_config", { description: "Get Plastic SCM config (.plastic, workspace name).", inputSchema: {} }, async () => json(R.getPlasticConfig(projectRoot)));
95
231
  const transport = new StdioServerTransport();
96
232
  await server.connect(transport);
97
233
  }
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Unity project filesystem readers. No Unity Editor required.
3
+ * All paths are relative to project root.
4
+ */
5
+ export declare function readFileSafe(root: string, ...path: string[]): string | null;
6
+ export declare function readJsonSafe<T>(root: string, ...path: string[]): T | null;
7
+ /** Recursively list files under dir, relative to root. Optional extension filter (e.g. ".cs"). */
8
+ export declare function listFilesRecursive(root: string, dir: string, opts?: {
9
+ ext?: string;
10
+ excludeMeta?: boolean;
11
+ }): string[];
12
+ /** Parse Unity YAML-like key-value (m_Key: value) from content. */
13
+ export declare function parseUnityKeyValue(content: string): Record<string, string>;
14
+ /** Get GUID from a .meta file path (reads sibling .meta of asset). */
15
+ export declare function getGuidFromMeta(root: string, assetPath: string): string | null;
16
+ /** Get asset path by GUID (scan Assets for .meta with this guid). */
17
+ export declare function getAssetPathByGuid(root: string, guid: string): string | null;
18
+ /** Find all Asset/Scene/Prefab files that reference this GUID (fileRef or guid:). */
19
+ export declare function findReferencesToGuid(root: string, guid: string): string[];
20
+ export declare function getUnityVersion(root: string): string;
21
+ export declare function getBuildScenes(root: string): {
22
+ index: number;
23
+ path: string;
24
+ name: string;
25
+ }[];
26
+ export interface PackageInfo {
27
+ name: string;
28
+ version: string;
29
+ type?: string;
30
+ }
31
+ export declare function getPackages(root: string): {
32
+ dependencies: PackageInfo[];
33
+ lock?: Record<string, string>;
34
+ };
35
+ export declare function getPlayerSettings(root: string): Record<string, string>;
36
+ export declare function getQualitySettings(root: string): Record<string, string>[];
37
+ export declare function getScriptingDefines(root: string): {
38
+ global: string[];
39
+ perAssembly: Record<string, string[]>;
40
+ };
41
+ export interface AsmDefInfo {
42
+ path: string;
43
+ name: string;
44
+ references: string[];
45
+ defineConstraints?: string[];
46
+ optionalUnityReferences?: string[];
47
+ includePlatforms?: string[];
48
+ }
49
+ export declare function getAssemblyDefinitions(root: string): AsmDefInfo[];
50
+ export declare function listScripts(root: string, folderPrefix?: string): string[];
51
+ /** Simple grep for type/namespace in .cs file content. */
52
+ export declare function findScriptsByContent(root: string, pattern: "MonoBehaviour" | "ScriptableObject" | string, namespaceFilter?: string): string[];
53
+ export declare function getAllScenes(root: string): string[];
54
+ /** Minimal scene summary: root GameObjects (top-level in hierarchy). */
55
+ export declare function getSceneSummary(root: string, scenePath: string): {
56
+ rootObjects: string[];
57
+ componentCount: number;
58
+ };
59
+ export declare function getPrefabs(root: string, pathPrefix?: string): string[];
60
+ export declare function getAssetFolderTree(root: string, maxDepth?: number): Record<string, string[]>;
61
+ export declare function listAssetsByExtension(root: string, ext: string, folder?: string): string[];
62
+ export declare function getMaterials(root: string, folder?: string): {
63
+ path: string;
64
+ shader?: string;
65
+ }[];
66
+ export declare function getShaders(root: string): string[];
67
+ export declare function getAnimatorControllers(root: string): string[];
68
+ export declare function getAnimationClips(root: string): string[];
69
+ /** High-level state names from .controller (m_StateMachine -> states). */
70
+ export declare function getAnimatorStates(root: string, controllerPath: string): string[];
71
+ export declare function getAudioClips(root: string): string[];
72
+ export declare function getAudioMixers(root: string): string[];
73
+ export declare function getAddressablesInfo(root: string): {
74
+ groups: string[];
75
+ configPath: string | null;
76
+ };
77
+ export declare function getLocalizationTables(root: string): string[];
78
+ export declare function getInputAxes(root: string): {
79
+ name: string;
80
+ descriptiveName?: string;
81
+ positiveButton?: string;
82
+ }[];
83
+ export declare function getTagsAndLayers(root: string): {
84
+ tags: string[];
85
+ layers: string[];
86
+ };
87
+ export declare function getTestAssemblies(root: string): AsmDefInfo[];
88
+ export declare function getRepoDocs(root: string): Record<string, string>;
89
+ export declare function getProjectVersion(root: string): string;
90
+ export declare function getChangelog(root: string): string | null;
91
+ export declare function getPhysicsSettings(root: string): {
92
+ dynamics?: Record<string, string>;
93
+ physics2d?: Record<string, string>;
94
+ };
95
+ export declare function listRenderPipelines(root: string): {
96
+ pipelines: string[];
97
+ volumeProfiles: string[];
98
+ };
99
+ export declare function listTimelinePlayables(root: string): string[];
100
+ export declare function listSpriteAtlases(root: string): string[];
101
+ export declare function listTilemapAssets(root: string): string[];
102
+ export declare function listShaderGraphs(root: string): string[];
103
+ export declare function listVfxGraphs(root: string): string[];
104
+ export declare function listTmpFonts(root: string): string[];
105
+ export declare function getTmpSettingsPath(root: string): string | null;
106
+ export declare function listUiDocuments(root: string): {
107
+ uxml: string[];
108
+ uss: string[];
109
+ };
110
+ export declare function listInputActionAssets(root: string): string[];
111
+ export declare function getInputActionsSummary(root: string, path: string): {
112
+ maps: string[];
113
+ actions: string[];
114
+ };
115
+ export declare function listPresets(root: string): string[];
116
+ export declare function listEditorScripts(root: string): string[];
117
+ export declare function getPrefabScriptGuids(root: string, prefabPath: string): string[];
118
+ export declare function getAssemblyDependencyGraph(root: string): {
119
+ nodes: string[];
120
+ edges: [string, string][];
121
+ };
122
+ export declare function listCiConfigs(root: string): string[];
123
+ export declare function listLargeAssets(root: string, minSizeMb?: number): {
124
+ path: string;
125
+ sizeMb: number;
126
+ }[];
127
+ export declare function getPlayFabConfig(root: string): {
128
+ titleId?: string;
129
+ configPaths: string[];
130
+ };
131
+ export declare function listFigmaRelatedAssets(root: string): string[];
132
+ export declare function getFirebaseConfig(root: string): {
133
+ googleServicesJson?: string;
134
+ plist?: string;
135
+ projectId?: string;
136
+ };
137
+ export declare function getSteamConfig(root: string): {
138
+ steamAppIdTxt?: string;
139
+ steamworksPath?: string;
140
+ };
141
+ export declare function getDiscordConfig(root: string): {
142
+ sdkPath?: string;
143
+ };
144
+ export declare function getFmodConfig(root: string): {
145
+ banksPath?: string;
146
+ projectPath?: string;
147
+ bankFiles: string[];
148
+ };
149
+ export declare function getWwiseConfig(root: string): {
150
+ soundBanksPath?: string;
151
+ projectPaths: string[];
152
+ };
153
+ export declare function listSubstanceAssets(root: string): string[];
154
+ export declare function listSpeedTreeAssets(root: string): string[];
155
+ export declare function listLottieAssets(root: string): string[];
156
+ export declare function getAnalyticsOrCrashConfig(root: string): {
157
+ services: string[];
158
+ };
159
+ export declare function getAdsConfig(root: string): {
160
+ sdkPresence: string[];
161
+ };
162
+ export declare function getGitLfsTracked(root: string): string[];
163
+ export declare function getPlasticConfig(root: string): {
164
+ plasticDir: boolean;
165
+ workspaceName?: string;
166
+ };