@akiojin/unity-mcp-server 2.38.0 → 2.38.1
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/package.json +1 -1
- package/src/core/config.js +27 -1
- package/src/lsp/CSharpLspUtils.js +48 -9
package/package.json
CHANGED
package/src/core/config.js
CHANGED
|
@@ -17,6 +17,32 @@ function merge(a, b) {
|
|
|
17
17
|
return out;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
function resolvePackageVersion() {
|
|
21
|
+
const candidates = [];
|
|
22
|
+
|
|
23
|
+
// Resolve relative to this module (always inside mcp-server/src/core)
|
|
24
|
+
try {
|
|
25
|
+
const moduleDir = path.dirname(new URL(import.meta.url).pathname);
|
|
26
|
+
candidates.push(path.resolve(moduleDir, '../../package.json'));
|
|
27
|
+
} catch {}
|
|
28
|
+
|
|
29
|
+
// When executed from workspace root (monorepo) or inside mcp-server package
|
|
30
|
+
try {
|
|
31
|
+
const here = findUpSync('package.json', { cwd: process.cwd() });
|
|
32
|
+
if (here) candidates.push(here);
|
|
33
|
+
} catch {}
|
|
34
|
+
|
|
35
|
+
for (const candidate of candidates) {
|
|
36
|
+
try {
|
|
37
|
+
if (!candidate || !fs.existsSync(candidate)) continue;
|
|
38
|
+
const pkg = JSON.parse(fs.readFileSync(candidate, 'utf8'));
|
|
39
|
+
if (pkg?.version) return pkg.version;
|
|
40
|
+
} catch {}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return '0.1.0';
|
|
44
|
+
}
|
|
45
|
+
|
|
20
46
|
/**
|
|
21
47
|
* Base configuration for Unity MCP Server Server
|
|
22
48
|
*/
|
|
@@ -44,7 +70,7 @@ const baseConfig = {
|
|
|
44
70
|
// Server settings
|
|
45
71
|
server: {
|
|
46
72
|
name: 'unity-mcp-server',
|
|
47
|
-
version:
|
|
73
|
+
version: resolvePackageVersion(),
|
|
48
74
|
description: 'MCP server for Unity Editor integration'
|
|
49
75
|
},
|
|
50
76
|
|
|
@@ -134,17 +134,38 @@ export class CSharpLspUtils {
|
|
|
134
134
|
if (!desired) throw new Error('mcp-server version not found; cannot resolve LSP tag');
|
|
135
135
|
const current = this.readLocalVersion(rid);
|
|
136
136
|
if (fs.existsSync(p) && current === desired) return p;
|
|
137
|
-
await this.autoDownload(rid, desired);
|
|
137
|
+
const resolved = await this.autoDownload(rid, desired);
|
|
138
138
|
if (!fs.existsSync(p)) throw new Error('csharp-lsp binary not found after download');
|
|
139
|
-
this.writeLocalVersion(rid, desired);
|
|
139
|
+
this.writeLocalVersion(rid, resolved || desired);
|
|
140
140
|
return p;
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
async autoDownload(rid, version) {
|
|
144
144
|
const repo = process.env.GITHUB_REPOSITORY || 'akiojin/unity-mcp-server';
|
|
145
|
-
|
|
146
|
-
const
|
|
147
|
-
|
|
145
|
+
|
|
146
|
+
const fetchManifest = async ver => {
|
|
147
|
+
const tag = `v${ver}`;
|
|
148
|
+
const manifestUrl = `https://github.com/${repo}/releases/download/${tag}/csharp-lsp-manifest.json`;
|
|
149
|
+
const manifest = await this.fetchJson(manifestUrl);
|
|
150
|
+
return { manifest, tag };
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
let targetVersion = version;
|
|
154
|
+
let manifest;
|
|
155
|
+
try {
|
|
156
|
+
({ manifest } = await fetchManifest(targetVersion));
|
|
157
|
+
} catch (e) {
|
|
158
|
+
// Gracefully fall back to the latest release when the requested manifest is missing (404).
|
|
159
|
+
if (String(e?.message || '').includes('HTTP 404')) {
|
|
160
|
+
const latest = await this.fetchLatestReleaseVersion(repo);
|
|
161
|
+
if (!latest) throw e;
|
|
162
|
+
targetVersion = latest;
|
|
163
|
+
({ manifest } = await fetchManifest(targetVersion));
|
|
164
|
+
} else {
|
|
165
|
+
throw e;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
148
169
|
const entry = manifest?.assets?.[rid];
|
|
149
170
|
if (!entry?.url || !entry?.sha256) throw new Error(`manifest missing entry for ${rid}`);
|
|
150
171
|
|
|
@@ -154,17 +175,35 @@ export class CSharpLspUtils {
|
|
|
154
175
|
await this.downloadTo(entry.url, tmp);
|
|
155
176
|
const actual = await this.sha256File(tmp);
|
|
156
177
|
if (String(actual).toLowerCase() !== String(entry.sha256).toLowerCase()) {
|
|
157
|
-
try {
|
|
178
|
+
try {
|
|
179
|
+
fs.unlinkSync(tmp);
|
|
180
|
+
} catch {}
|
|
158
181
|
throw new Error('checksum mismatch for csharp-lsp asset');
|
|
159
182
|
}
|
|
160
183
|
// atomic replace
|
|
161
|
-
try {
|
|
184
|
+
try {
|
|
185
|
+
fs.renameSync(tmp, dest);
|
|
186
|
+
} catch (e) {
|
|
162
187
|
// Windows may need removal before rename
|
|
163
|
-
try {
|
|
188
|
+
try {
|
|
189
|
+
fs.unlinkSync(dest);
|
|
190
|
+
} catch {}
|
|
164
191
|
fs.renameSync(tmp, dest);
|
|
165
192
|
}
|
|
166
|
-
try {
|
|
193
|
+
try {
|
|
194
|
+
if (process.platform !== 'win32') fs.chmodSync(dest, 0o755);
|
|
195
|
+
} catch {}
|
|
167
196
|
logger.info(`[csharp-lsp] downloaded: ${path.basename(dest)} @ ${path.dirname(dest)}`);
|
|
197
|
+
return targetVersion;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
async fetchLatestReleaseVersion(repo) {
|
|
201
|
+
const url = `https://api.github.com/repos/${repo}/releases/latest`;
|
|
202
|
+
const json = await this.fetchJson(url);
|
|
203
|
+
const tag = json?.tag_name || '';
|
|
204
|
+
const version = tag.replace(/^v/, '');
|
|
205
|
+
if (!version) throw new Error('latest release version not found');
|
|
206
|
+
return version;
|
|
168
207
|
}
|
|
169
208
|
|
|
170
209
|
async fetchJson(url) {
|