@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akiojin/unity-mcp-server",
3
- "version": "2.38.0",
3
+ "version": "2.38.1",
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",
@@ -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: '0.1.0',
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
- const tag = `v${version}`;
146
- const manifestUrl = `https://github.com/${repo}/releases/download/${tag}/csharp-lsp-manifest.json`;
147
- const manifest = await this.fetchJson(manifestUrl);
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 { fs.unlinkSync(tmp); } catch {}
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 { fs.renameSync(tmp, dest); } catch (e) {
184
+ try {
185
+ fs.renameSync(tmp, dest);
186
+ } catch (e) {
162
187
  // Windows may need removal before rename
163
- try { fs.unlinkSync(dest); } catch {}
188
+ try {
189
+ fs.unlinkSync(dest);
190
+ } catch {}
164
191
  fs.renameSync(tmp, dest);
165
192
  }
166
- try { if (process.platform !== 'win32') fs.chmodSync(dest, 0o755); } catch {}
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) {