@mseep/anklebreaker-unity-mcp 2.30.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/.github/workflows/npm-publish.yml +34 -0
- package/.mcpbignore +9 -0
- package/CHANGELOG.md +85 -0
- package/LICENSE +69 -0
- package/README.md +368 -0
- package/claude-desktop-config.json +12 -0
- package/docs/unity-mcp-architecture.gif +0 -0
- package/docs/unity-mcp-features.gif +0 -0
- package/docs/unity-mcp-showcase-brickbreaker.gif +0 -0
- package/docs/unity-mcp-showcase-castle.gif +0 -0
- package/docs/unity-mcp-showcase-village.gif +0 -0
- package/icon.png +0 -0
- package/manifest.json +178 -0
- package/package.json +26 -0
- package/src/config.js +52 -0
- package/src/index.js +529 -0
- package/src/instance-discovery.js +501 -0
- package/src/state-persistence.js +97 -0
- package/src/tool-tiers.js +348 -0
- package/src/tools/context-tools.js +33 -0
- package/src/tools/editor-tools.js +4521 -0
- package/src/tools/hub-tools.js +96 -0
- package/src/tools/instance-tools.js +114 -0
- package/src/tools/uma-tools.js +627 -0
- package/src/uma-bridge.js +63 -0
- package/src/unity-editor-bridge.js +1690 -0
- package/src/unity-hub.js +125 -0
- package/tests/multi-agent-stress-test.mjs +400 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// AnkleBreaker Unity MCP — Tool definitions for Unity Hub operations
|
|
2
|
+
import * as hub from "../unity-hub.js";
|
|
3
|
+
|
|
4
|
+
export const hubTools = [
|
|
5
|
+
{
|
|
6
|
+
name: "unity_hub_list_editors",
|
|
7
|
+
description: "List all Unity Editor versions currently installed via Unity Hub, including their installation paths.",
|
|
8
|
+
inputSchema: {
|
|
9
|
+
type: "object",
|
|
10
|
+
properties: {},
|
|
11
|
+
},
|
|
12
|
+
handler: async () => {
|
|
13
|
+
const result = await hub.listInstalledEditors();
|
|
14
|
+
return JSON.stringify(result, null, 2);
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: "unity_hub_available_releases",
|
|
19
|
+
description: "List Unity Editor versions available for download from Unity Hub.",
|
|
20
|
+
inputSchema: {
|
|
21
|
+
type: "object",
|
|
22
|
+
properties: {},
|
|
23
|
+
},
|
|
24
|
+
handler: async () => {
|
|
25
|
+
const result = await hub.listAvailableReleases();
|
|
26
|
+
return JSON.stringify(result, null, 2);
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: "unity_hub_install_editor",
|
|
31
|
+
description: "Install a specific Unity Editor version. Optionally include platform modules (android, ios, webgl, linux, macos, windows-il2cpp).",
|
|
32
|
+
inputSchema: {
|
|
33
|
+
type: "object",
|
|
34
|
+
properties: {
|
|
35
|
+
version: { type: "string", description: "Unity version to install (e.g. '2022.3.20f1', '6000.3.7f1')" },
|
|
36
|
+
modules: {
|
|
37
|
+
type: "array",
|
|
38
|
+
items: { type: "string" },
|
|
39
|
+
description: "Optional modules to install: android, android-sdk-ndk-tools, android-open-jdk, ios, webgl, linux-il2cpp, mac-il2cpp, windows-il2cpp, etc.",
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
required: ["version"],
|
|
43
|
+
},
|
|
44
|
+
handler: async ({ version, modules }) => {
|
|
45
|
+
const result = await hub.installEditor(version, modules || []);
|
|
46
|
+
return JSON.stringify(result, null, 2);
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: "unity_hub_install_modules",
|
|
51
|
+
description: "Install additional platform modules to an already-installed Unity Editor version.",
|
|
52
|
+
inputSchema: {
|
|
53
|
+
type: "object",
|
|
54
|
+
properties: {
|
|
55
|
+
version: { type: "string", description: "Target Unity version" },
|
|
56
|
+
modules: {
|
|
57
|
+
type: "array",
|
|
58
|
+
items: { type: "string" },
|
|
59
|
+
description: "Modules to add: android, ios, webgl, etc.",
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
required: ["version", "modules"],
|
|
63
|
+
},
|
|
64
|
+
handler: async ({ version, modules }) => {
|
|
65
|
+
const result = await hub.installModules(version, modules);
|
|
66
|
+
return JSON.stringify(result, null, 2);
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: "unity_hub_get_install_path",
|
|
71
|
+
description: "Get the current default installation path for Unity Editors.",
|
|
72
|
+
inputSchema: {
|
|
73
|
+
type: "object",
|
|
74
|
+
properties: {},
|
|
75
|
+
},
|
|
76
|
+
handler: async () => {
|
|
77
|
+
const result = await hub.getInstallPath();
|
|
78
|
+
return JSON.stringify(result, null, 2);
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: "unity_hub_set_install_path",
|
|
83
|
+
description: "Set the default installation directory for Unity Editors.",
|
|
84
|
+
inputSchema: {
|
|
85
|
+
type: "object",
|
|
86
|
+
properties: {
|
|
87
|
+
path: { type: "string", description: "New installation directory path" },
|
|
88
|
+
},
|
|
89
|
+
required: ["path"],
|
|
90
|
+
},
|
|
91
|
+
handler: async ({ path }) => {
|
|
92
|
+
const result = await hub.setInstallPath(path);
|
|
93
|
+
return JSON.stringify(result, null, 2);
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
];
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// AnkleBreaker Unity MCP — Tool definitions for Multi-Instance Management
|
|
2
|
+
// These tools let agents discover, list, and select which Unity Editor instance to work with.
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
discoverInstances,
|
|
6
|
+
selectInstance,
|
|
7
|
+
getSelectedInstance,
|
|
8
|
+
autoSelectInstance,
|
|
9
|
+
} from "../instance-discovery.js";
|
|
10
|
+
|
|
11
|
+
export const instanceTools = [
|
|
12
|
+
{
|
|
13
|
+
name: "unity_list_instances",
|
|
14
|
+
description:
|
|
15
|
+
"List all running Unity Editor instances that the MCP can connect to. " +
|
|
16
|
+
"Returns each instance's project name, port, Unity version, and whether it's a ParrelSync clone. " +
|
|
17
|
+
"Use this to see which Unity projects are currently open before selecting one to work with. " +
|
|
18
|
+
"IMPORTANT: When multiple instances are detected, always call this first and then use " +
|
|
19
|
+
"unity_select_instance to choose which project to target.",
|
|
20
|
+
inputSchema: {
|
|
21
|
+
type: "object",
|
|
22
|
+
properties: {
|
|
23
|
+
refresh: {
|
|
24
|
+
type: "boolean",
|
|
25
|
+
description:
|
|
26
|
+
"Force a fresh discovery scan (default: true). Set to false to use cached results.",
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
handler: async ({ refresh = true } = {}) => {
|
|
31
|
+
const instances = await discoverInstances();
|
|
32
|
+
const selected = getSelectedInstance();
|
|
33
|
+
|
|
34
|
+
const result = {
|
|
35
|
+
instances: instances.map((inst) => ({
|
|
36
|
+
port: inst.port,
|
|
37
|
+
projectName: inst.projectName,
|
|
38
|
+
projectPath: inst.projectPath,
|
|
39
|
+
unityVersion: inst.unityVersion,
|
|
40
|
+
isClone: inst.isClone,
|
|
41
|
+
cloneIndex: inst.cloneIndex,
|
|
42
|
+
source: inst.source,
|
|
43
|
+
isSelected: selected ? selected.port === inst.port : false,
|
|
44
|
+
})),
|
|
45
|
+
totalCount: instances.length,
|
|
46
|
+
selectedPort: selected?.port || null,
|
|
47
|
+
selectedProject: selected?.projectName || null,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
if (instances.length === 0) {
|
|
51
|
+
result.message =
|
|
52
|
+
"No Unity Editor instances found. Make sure Unity is running with the MCP plugin enabled.";
|
|
53
|
+
} else if (!selected) {
|
|
54
|
+
result.message = `Found ${instances.length} Unity instance(s). Use unity_select_instance to choose which project to work with.`;
|
|
55
|
+
} else {
|
|
56
|
+
result.message = `Found ${instances.length} Unity instance(s). Currently targeting: ${selected.projectName} (port ${selected.port})`;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return JSON.stringify(result, null, 2);
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
{
|
|
64
|
+
name: "unity_select_instance",
|
|
65
|
+
description:
|
|
66
|
+
"Select which Unity Editor instance to work with for this session. " +
|
|
67
|
+
"All subsequent unity_* commands will be routed to the selected instance. " +
|
|
68
|
+
"You must provide the port number of the instance (get it from unity_list_instances). " +
|
|
69
|
+
"IMPORTANT: Call unity_list_instances first to see available instances and their ports. " +
|
|
70
|
+
"PARALLEL SAFETY: After selecting, include 'port: <number>' as a parameter in ALL " +
|
|
71
|
+
"subsequent unity_* tool calls to guarantee routing to this instance even when " +
|
|
72
|
+
"multiple agents share the same MCP process.",
|
|
73
|
+
inputSchema: {
|
|
74
|
+
type: "object",
|
|
75
|
+
properties: {
|
|
76
|
+
port: {
|
|
77
|
+
type: "number",
|
|
78
|
+
description:
|
|
79
|
+
"The port number of the Unity instance to select (from unity_list_instances output).",
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
required: ["port"],
|
|
83
|
+
},
|
|
84
|
+
handler: async ({ port }) => {
|
|
85
|
+
if (!port || typeof port !== "number") {
|
|
86
|
+
return JSON.stringify(
|
|
87
|
+
{
|
|
88
|
+
success: false,
|
|
89
|
+
error:
|
|
90
|
+
"Port number is required. Use unity_list_instances to see available instances.",
|
|
91
|
+
},
|
|
92
|
+
null,
|
|
93
|
+
2
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const result = await selectInstance(port);
|
|
98
|
+
|
|
99
|
+
// Enhance successful responses with parallel-safe routing instructions
|
|
100
|
+
if (result.success) {
|
|
101
|
+
result.routing = {
|
|
102
|
+
port: port,
|
|
103
|
+
instruction:
|
|
104
|
+
`IMPORTANT — PARALLEL SAFETY: To guarantee your commands reach "${result.instance?.projectName || "this instance"}" ` +
|
|
105
|
+
`(port ${port}), you MUST include port: ${port} as a parameter in ALL subsequent unity_* tool calls. ` +
|
|
106
|
+
`This prevents cross-agent routing issues when multiple tasks run in parallel. ` +
|
|
107
|
+
`Example: unity_execute_code({ code: "...", port: ${port} })`,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return JSON.stringify(result, null, 2);
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
];
|