Skip to main content
Glama

MCP Server for Unity

by zabaglione
unity-http-adapter.ts5.18 kB
// Using Node.js 18+ built-in fetch export interface UnityHttpAdapterOptions { url?: string; timeout?: number; } export interface UnityResponse { success: boolean; result?: any; error?: string; } export interface FolderEntry { path: string; name: string; type: 'file' | 'folder'; extension?: string; guid: string; } /** * HTTP adapter for Unity MCP Server * Provides a clean interface to communicate with Unity HTTP server */ export class UnityHttpAdapter { private url: string; private timeout: number; constructor(options: UnityHttpAdapterOptions = {}) { this.url = options.url || 'http://localhost:23457/'; this.timeout = options.timeout || 15000; } /** * Call a method on the Unity server */ async call(method: string, params: Record<string, any> = {}): Promise<any> { const startTime = Date.now(); console.error(`[Unity HTTP] Calling method: ${method}`); const maxRetries = 3; let lastError: any; for (let retry = 0; retry < maxRetries; retry++) { if (retry > 0) { console.error(`[Unity HTTP] Retry ${retry}/${maxRetries - 1} for method: ${method}`); await new Promise(resolve => setTimeout(resolve, 1000 * retry)); // Exponential backoff } try { const controller = new AbortController(); const timeoutId = setTimeout(() => { console.error(`[Unity HTTP] Request timeout after ${this.timeout}ms for method: ${method}`); controller.abort(); }, this.timeout); const response = await fetch(this.url, { method: 'POST', headers: { 'Content-Type': 'application/json; charset=utf-8', 'Accept': 'application/json; charset=utf-8' }, body: JSON.stringify({ method, ...params }), signal: controller.signal }); clearTimeout(timeoutId); const elapsed = Date.now() - startTime; console.error(`[Unity HTTP] Response received in ${elapsed}ms for method: ${method}`); const result = await response.json() as UnityResponse; if (!result.success) { throw new Error(result.error || 'Unknown error'); } return result.result; } catch (error: any) { lastError = error; if (error.name === 'AbortError') { lastError = new Error('Request timeout'); } else if (error.message?.includes('ECONNREFUSED')) { lastError = new Error('Unity HTTP server is not running'); } else if (error.message?.includes('Failed to fetch')) { lastError = new Error('Failed to connect to Unity HTTP server'); } console.error(`[Unity HTTP] Error on attempt ${retry + 1}: ${lastError.message}`); // Don't retry on certain errors if (error.message?.includes('Method not found')) { throw error; } } } // All retries failed throw lastError || new Error('Unknown error after retries'); } /** * Check if Unity server is connected */ async isConnected(): Promise<boolean> { try { await this.call('ping'); return true; } catch { return false; } } // Script operations async createScript(fileName: string, content?: string, folder?: string): Promise<any> { return this.call('script/create', { fileName, content, folder }); } async readScript(path: string): Promise<any> { return this.call('script/read', { path }); } async deleteScript(path: string): Promise<any> { return this.call('script/delete', { path }); } async applyDiff(path: string, diff: string, options?: any): Promise<any> { return this.call('script/applyDiff', { path, diff, options }); } // Shader operations async createShader(name: string, content?: string, folder?: string): Promise<any> { return this.call('shader/create', { name, content, folder }); } async readShader(path: string): Promise<any> { return this.call('shader/read', { path }); } async deleteShader(path: string): Promise<any> { return this.call('shader/delete', { path }); } // Project operations async getProjectInfo(): Promise<any> { return this.call('project/info'); } // Folder operations async createFolder(path: string): Promise<{ path: string; guid: string }> { return this.call('folder/create', { path }); } async renameFolder(oldPath: string, newName: string): Promise<{ oldPath: string; newPath: string; guid: string }> { return this.call('folder/rename', { oldPath, newName }); } async moveFolder(sourcePath: string, targetPath: string): Promise<{ sourcePath: string; targetPath: string; guid: string }> { return this.call('folder/move', { sourcePath, targetPath }); } async deleteFolder(path: string, recursive: boolean = true): Promise<{ path: string }> { return this.call('folder/delete', { path, recursive }); } async listFolder(path?: string, recursive: boolean = false): Promise<{ path: string; entries: FolderEntry[] }> { return this.call('folder/list', { path, recursive }); } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/zabaglione/mcp-server-unity'

If you have feedback or need assistance with the MCP directory API, please join our Discord server