From 02ac2175ddd8ce367ffe177c8519123e2ae72859 Mon Sep 17 00:00:00 2001 From: twinlunarstarz-dev Date: Wed, 29 Apr 2026 23:37:45 -0400 Subject: [PATCH] feat: add quit_godot tool to close launched editor --- src/index.ts | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/src/index.ts b/src/index.ts index f47babcb..b1235c71 100644 --- a/src/index.ts +++ b/src/index.ts @@ -68,6 +68,8 @@ class GodotServer { private operationsScriptPath: string; private validatedPaths: Map = new Map(); private strictPathValidation: boolean = false; + // Track the editor process spawned by launch_editor so quit_godot can close it + private editorProcess: any = null; /** * Parameter name mappings between snake_case and camelCase @@ -398,6 +400,13 @@ class GodotServer { this.activeProcess.process.kill(); this.activeProcess = null; } + if (this.editorProcess) { + this.logDebug('Killing tracked editor process'); + try { + this.editorProcess.kill(); + } catch (_) {} + this.editorProcess = null; + } await this.server.close(); } @@ -923,6 +932,15 @@ class GodotServer { required: ['projectPath'], }, }, + { + name: 'quit_godot', + description: 'Close the Godot editor that was launched by this MCP server via launch_editor. Only closes editors spawned by this server.', + inputSchema: { + type: 'object', + properties: {}, + required: [], + }, + }, ], })); @@ -958,6 +976,8 @@ class GodotServer { return await this.handleGetUid(request.params.arguments); case 'update_project_uids': return await this.handleUpdateProjectUids(request.params.arguments); + case 'quit_godot': + return await this.handleQuitGodot(); default: throw new McpError( ErrorCode.MethodNotFound, @@ -1021,6 +1041,16 @@ class GodotServer { stdio: 'pipe', }); + // Track the spawned editor so quit_godot can close it later + this.editorProcess = process; + + process.on('exit', () => { + if (this.editorProcess === process) { + this.logDebug('Godot editor exited naturally'); + this.editorProcess = null; + } + }); + process.on('error', (err: Error) => { console.error('Failed to start Godot editor:', err); }); @@ -2168,6 +2198,40 @@ class GodotServer { } } + /** + * Handle the quit_godot tool + */ + private async handleQuitGodot() { + if (!this.editorProcess) { + return this.createErrorResponse( + 'No Godot editor process is currently tracked', + ['The editor may have been closed already, or launch_editor was not used to start it'] + ); + } + + try { + this.logDebug('Quitting Godot editor'); + this.editorProcess.kill(); + } catch (error: unknown) { + const errorMessage = error instanceof Error ? error.message : 'Unknown error'; + return this.createErrorResponse( + `Failed to quit Godot editor: ${errorMessage}`, + ['The process may have already exited'] + ); + } finally { + this.editorProcess = null; + } + + return { + content: [ + { + type: 'text', + text: 'Godot editor closed successfully.', + }, + ], + }; + } + /** * Run the MCP server */