@akiojin/unity-mcp-server 5.2.1 → 5.3.2
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 +1 -0
- package/package.json +28 -40
- package/src/core/codeIndex.js +54 -7
- package/src/core/config.js +15 -1
- package/src/core/httpServer.js +30 -6
- package/src/core/indexBuildWorkerPool.js +57 -3
- package/src/core/indexWatcher.js +10 -4
- package/src/core/projectInfo.js +34 -12
- package/src/core/server.js +58 -27
- package/src/core/toolManifest.json +145 -629
- package/src/handlers/addressables/AddressablesAnalyzeToolHandler.js +14 -6
- package/src/handlers/addressables/AddressablesBuildToolHandler.js +6 -3
- package/src/handlers/addressables/AddressablesManageToolHandler.js +6 -3
- package/src/handlers/input/InputSystemControlToolHandler.js +1 -1
- package/src/handlers/input/InputTouchToolHandler.js +7 -3
- package/src/handlers/package/PackageManagerToolHandler.js +6 -3
- package/src/handlers/script/CodeIndexStatusToolHandler.js +37 -1
- package/src/handlers/script/CodeIndexUpdateToolHandler.js +1 -1
- package/src/handlers/script/ScriptEditSnippetToolHandler.js +1 -2
- package/src/handlers/script/ScriptEditStructuredToolHandler.js +6 -1
- package/src/handlers/script/ScriptRefactorRenameToolHandler.js +3 -1
- package/src/handlers/script/ScriptRefsFindToolHandler.js +22 -4
- package/src/handlers/script/ScriptRemoveSymbolToolHandler.js +6 -1
- package/src/handlers/script/ScriptSymbolsGetToolHandler.js +1 -1
- package/src/lsp/CSharpLspUtils.js +11 -3
- package/src/lsp/LspProcessManager.js +24 -5
- package/src/lsp/LspRpcClient.js +115 -23
- package/src/lsp/LspRpcClientSingleton.js +79 -2
package/src/core/server.js
CHANGED
|
@@ -23,6 +23,14 @@ let config = null;
|
|
|
23
23
|
let logger = null;
|
|
24
24
|
let initializationPromise = null;
|
|
25
25
|
|
|
26
|
+
const fallbackLogger = {
|
|
27
|
+
info() {},
|
|
28
|
+
warn() {},
|
|
29
|
+
error() {},
|
|
30
|
+
debug() {},
|
|
31
|
+
setServer() {}
|
|
32
|
+
};
|
|
33
|
+
|
|
26
34
|
let cachedToolManifest = null;
|
|
27
35
|
function readToolManifest() {
|
|
28
36
|
if (cachedToolManifest) return cachedToolManifest;
|
|
@@ -46,7 +54,7 @@ function readToolManifest() {
|
|
|
46
54
|
* Lazily load handlers and dependencies
|
|
47
55
|
* Called after MCP transport is connected
|
|
48
56
|
*/
|
|
49
|
-
async function ensureInitialized() {
|
|
57
|
+
async function ensureInitialized(deps = {}) {
|
|
50
58
|
if (handlers !== null) return;
|
|
51
59
|
if (initializationPromise) {
|
|
52
60
|
await initializationPromise;
|
|
@@ -55,17 +63,23 @@ async function ensureInitialized() {
|
|
|
55
63
|
|
|
56
64
|
initializationPromise = (async () => {
|
|
57
65
|
// Load config first (needed for logging)
|
|
58
|
-
const configModule =
|
|
66
|
+
const configModule = deps.config
|
|
67
|
+
? { config: deps.config, logger: deps.logger }
|
|
68
|
+
: await import('./config.js');
|
|
59
69
|
config = configModule.config;
|
|
60
|
-
logger = configModule.logger;
|
|
70
|
+
logger = configModule.logger ?? deps.logger ?? fallbackLogger;
|
|
61
71
|
|
|
62
72
|
// Load UnityConnection
|
|
63
|
-
const
|
|
64
|
-
|
|
73
|
+
const UnityConnectionClass = deps.UnityConnection
|
|
74
|
+
? deps.UnityConnection
|
|
75
|
+
: (await import('./unityConnection.js')).UnityConnection;
|
|
76
|
+
unityConnection = deps.unityConnectionInstance || new UnityConnectionClass();
|
|
65
77
|
|
|
66
78
|
// Load and create handlers
|
|
67
|
-
const
|
|
68
|
-
|
|
79
|
+
const createHandlersFn = deps.createHandlers
|
|
80
|
+
? deps.createHandlers
|
|
81
|
+
: (await import('../handlers/index.js')).createHandlers;
|
|
82
|
+
handlers = createHandlersFn(unityConnection);
|
|
69
83
|
|
|
70
84
|
// Set up Unity connection event handlers
|
|
71
85
|
unityConnection.on('connected', () => {
|
|
@@ -91,6 +105,7 @@ async function ensureInitialized() {
|
|
|
91
105
|
// Initialize server
|
|
92
106
|
export async function startServer(options = {}) {
|
|
93
107
|
try {
|
|
108
|
+
const deps = options.deps || {};
|
|
94
109
|
// MCP stdio transport requires stdout to stay clean (JSON-RPC only).
|
|
95
110
|
// Guard against accidental console.log usage breaking the protocol.
|
|
96
111
|
if (options.stdioEnabled !== false && process.env.UNITY_MCP_ALLOW_STDOUT !== '1') {
|
|
@@ -99,9 +114,12 @@ export async function startServer(options = {}) {
|
|
|
99
114
|
|
|
100
115
|
// Step 1: Load minimal config for server metadata
|
|
101
116
|
// (config import is lightweight; avoid importing the MCP TS SDK on startup)
|
|
102
|
-
const
|
|
117
|
+
const configModule = deps.config
|
|
118
|
+
? { config: deps.config, logger: deps.logger }
|
|
119
|
+
: await import('./config.js');
|
|
120
|
+
const { config: serverConfig, logger: serverLogger } = configModule;
|
|
103
121
|
config = serverConfig;
|
|
104
|
-
logger = serverLogger;
|
|
122
|
+
logger = serverLogger ?? deps.logger ?? fallbackLogger;
|
|
105
123
|
|
|
106
124
|
const runtimeConfig = {
|
|
107
125
|
...config,
|
|
@@ -114,7 +132,7 @@ export async function startServer(options = {}) {
|
|
|
114
132
|
const server =
|
|
115
133
|
runtimeConfig.stdioEnabled === false
|
|
116
134
|
? null
|
|
117
|
-
: new StdioRpcServer({
|
|
135
|
+
: new (deps.StdioRpcServer || StdioRpcServer)({
|
|
118
136
|
serverInfo: {
|
|
119
137
|
name: config.server.name,
|
|
120
138
|
version: config.server.version
|
|
@@ -145,15 +163,17 @@ export async function startServer(options = {}) {
|
|
|
145
163
|
}
|
|
146
164
|
|
|
147
165
|
// Start loading handlers in background so first request is faster
|
|
148
|
-
ensureInitialized().catch(err => {
|
|
166
|
+
ensureInitialized(deps).catch(err => {
|
|
149
167
|
console.error(`[unity-mcp-server] Background initialization failed: ${err.message}`);
|
|
150
168
|
});
|
|
151
169
|
|
|
152
170
|
// Optional HTTP transport (requires handlers)
|
|
153
171
|
if (runtimeConfig.http?.enabled) {
|
|
154
172
|
(async () => {
|
|
155
|
-
await ensureInitialized();
|
|
156
|
-
const
|
|
173
|
+
await ensureInitialized(deps);
|
|
174
|
+
const createHttpServer = deps.createHttpServer
|
|
175
|
+
? deps.createHttpServer
|
|
176
|
+
: (await import('./httpServer.js')).createHttpServer;
|
|
157
177
|
httpServerInstance = createHttpServer({
|
|
158
178
|
handlers,
|
|
159
179
|
host: runtimeConfig.http.host,
|
|
@@ -175,7 +195,7 @@ export async function startServer(options = {}) {
|
|
|
175
195
|
|
|
176
196
|
// Attempt to connect to Unity (deferred, non-blocking)
|
|
177
197
|
(async () => {
|
|
178
|
-
await ensureInitialized();
|
|
198
|
+
await ensureInitialized(deps);
|
|
179
199
|
console.error(`[unity-mcp-server] Unity connection starting...`);
|
|
180
200
|
try {
|
|
181
201
|
await unityConnection.connect();
|
|
@@ -190,8 +210,10 @@ export async function startServer(options = {}) {
|
|
|
190
210
|
// Best-effort: prepare and start persistent C# LSP process (non-blocking)
|
|
191
211
|
(async () => {
|
|
192
212
|
try {
|
|
193
|
-
const
|
|
194
|
-
|
|
213
|
+
const LspProcessManagerClass = deps.LspProcessManager
|
|
214
|
+
? deps.LspProcessManager
|
|
215
|
+
: (await import('../lsp/LspProcessManager.js')).LspProcessManager;
|
|
216
|
+
const mgr = new LspProcessManagerClass();
|
|
195
217
|
await mgr.ensureStarted();
|
|
196
218
|
// Attach graceful shutdown
|
|
197
219
|
const shutdown = async () => {
|
|
@@ -208,9 +230,14 @@ export async function startServer(options = {}) {
|
|
|
208
230
|
|
|
209
231
|
// Start periodic index watcher (incremental)
|
|
210
232
|
(async () => {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
233
|
+
if (process.env.NODE_ENV === 'test') {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
await ensureInitialized(deps);
|
|
237
|
+
const IndexWatcherClass = deps.IndexWatcher
|
|
238
|
+
? deps.IndexWatcher
|
|
239
|
+
: (await import('./indexWatcher.js')).IndexWatcher;
|
|
240
|
+
const watcher = new IndexWatcherClass(unityConnection);
|
|
214
241
|
watcher.start();
|
|
215
242
|
const stopWatch = () => {
|
|
216
243
|
try {
|
|
@@ -223,10 +250,12 @@ export async function startServer(options = {}) {
|
|
|
223
250
|
|
|
224
251
|
// Auto-initialize code index if DB doesn't exist
|
|
225
252
|
(async () => {
|
|
226
|
-
await ensureInitialized();
|
|
253
|
+
await ensureInitialized(deps);
|
|
227
254
|
try {
|
|
228
|
-
const
|
|
229
|
-
|
|
255
|
+
const CodeIndexClass = deps.CodeIndex
|
|
256
|
+
? deps.CodeIndex
|
|
257
|
+
: (await import('./codeIndex.js')).CodeIndex;
|
|
258
|
+
const index = new CodeIndexClass(unityConnection);
|
|
230
259
|
const ready = await index.isReady();
|
|
231
260
|
|
|
232
261
|
if (!ready) {
|
|
@@ -237,9 +266,11 @@ export async function startServer(options = {}) {
|
|
|
237
266
|
return;
|
|
238
267
|
}
|
|
239
268
|
logger.info('[startup] Code index DB not ready. Starting auto-build...');
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
269
|
+
const CodeIndexBuildToolHandlerClass = deps.CodeIndexBuildToolHandler
|
|
270
|
+
? deps.CodeIndexBuildToolHandler
|
|
271
|
+
: (await import('../handlers/script/CodeIndexBuildToolHandler.js'))
|
|
272
|
+
.CodeIndexBuildToolHandler;
|
|
273
|
+
const builder = new CodeIndexBuildToolHandlerClass(unityConnection);
|
|
243
274
|
const result = await builder.execute({});
|
|
244
275
|
|
|
245
276
|
if (result.success) {
|
|
@@ -294,7 +325,7 @@ export async function startServer(options = {}) {
|
|
|
294
325
|
return { tools: manifestTools };
|
|
295
326
|
}
|
|
296
327
|
|
|
297
|
-
await ensureInitialized();
|
|
328
|
+
await ensureInitialized(deps);
|
|
298
329
|
|
|
299
330
|
const tools = Array.from(handlers.values())
|
|
300
331
|
.map((handler, index) => {
|
|
@@ -321,7 +352,7 @@ export async function startServer(options = {}) {
|
|
|
321
352
|
|
|
322
353
|
// Handle tool execution
|
|
323
354
|
server?.setRequestHandler('tools/call', async request => {
|
|
324
|
-
await ensureInitialized();
|
|
355
|
+
await ensureInitialized(deps);
|
|
325
356
|
|
|
326
357
|
const { name, arguments: args } = request.params || {};
|
|
327
358
|
const requestTime = Date.now();
|