Skip to content

Commit 115f0f3

Browse files
Fix: Limit get_debug_output error lines in Godot MCP server
1 parent f8d91e3 commit 115f0f3

File tree

1 file changed

+52
-23
lines changed

1 file changed

+52
-23
lines changed

src/index.ts

+52-23
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { existsSync, readdirSync, mkdirSync } from 'fs';
1313
import { spawn } from 'child_process';
1414
import { promisify } from 'util';
1515
import { exec } from 'child_process';
16+
import * as fs from 'fs'; // Import the 'fs' module
1617

1718
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
1819
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
@@ -1010,31 +1011,44 @@ class GodotServer {
10101011
commandArgs.push('--debug');
10111012
}
10121013

1014+
// Define the log file path within the project directory
1015+
const logFilePath = join(args.projectPath, 'cline_godot_run.log');
1016+
// Add the --log-file argument for Godot
1017+
commandArgs.push('--log-file', logFilePath);
1018+
this.logDebug(`Using Godot's --log-file argument: ${logFilePath}`);
1019+
1020+
10131021
this.logDebug(`Spawning Godot project: "${this.godotPath}" with args: ${commandArgs.join(' ')}`);
10141022

10151023
try {
1016-
// Use spawn to manage the running process and capture output
1017-
const godotProcess = spawn(`"${this.godotPath}"`, commandArgs, {
1018-
shell: true, // Using shell might be necessary depending on how GODOT_PATH is set
1019-
stdio: ['ignore', 'pipe', 'pipe'], // Ignore stdin, capture stdout/stderr
1024+
// Use spawn, revert stdio back to pipes to capture potential early launch errors
1025+
const godotProcess = spawn(this.godotPath, commandArgs, {
1026+
shell: false, // Keep shell false
1027+
detached: false, // Keep attached to monitor exit/errors more easily initially
1028+
stdio: ['ignore', 'pipe', 'pipe'], // Ignore stdin, capture stdout/stderr via pipes
10201029
});
10211030

1031+
// No need to unref if not detached
1032+
10221033
this.activeProcess = {
10231034
process: godotProcess,
1024-
output: [],
1025-
errors: [],
1035+
output: [], // Capture output via pipes again
1036+
errors: [], // Capture errors via pipes again
10261037
};
10271038

1039+
// Capture piped output/error
10281040
godotProcess.stdout.on('data', (data) => {
10291041
const output = data.toString();
10301042
this.activeProcess?.output.push(output);
1031-
this.logDebug(`Project stdout: ${output}`);
1043+
// Optionally log to server console, but primary log is the file
1044+
// this.logDebug(`Project stdout pipe: ${output}`);
10321045
});
10331046

10341047
godotProcess.stderr.on('data', (data) => {
10351048
const errorOutput = data.toString();
10361049
this.activeProcess?.errors.push(errorOutput);
1037-
console.error(`Project stderr: ${errorOutput}`);
1050+
// Log stderr immediately to server console for visibility
1051+
console.error(`Project stderr pipe: ${errorOutput}`);
10381052
});
10391053

10401054
godotProcess.on('close', (code) => {
@@ -1062,21 +1076,36 @@ class GodotServer {
10621076
/**
10631077
* Handle the get_debug_output tool
10641078
*/
1065-
private async handleGetDebugOutput() {
1066-
this.logDebug('Handling get_debug_output');
1067-
if (this.activeProcess) {
1068-
// Return copies of the arrays
1069-
return {
1070-
content: [
1071-
{ type: 'text', text: `Output lines: ${this.activeProcess.output.length}, Error lines: ${this.activeProcess.errors.length}` }
1072-
],
1073-
output: [...this.activeProcess.output],
1074-
errors: [...this.activeProcess.errors]
1075-
};
1076-
} else {
1077-
return this.createErrorResponse('No active Godot project is running.');
1078-
}
1079-
}
1079+
private async handleGetDebugOutput() {
1080+
this.logDebug('Handling get_debug_output');
1081+
if (this.activeProcess) {
1082+
// Limit the number of error lines returned
1083+
const maxErrorLines = 100; // Keep the last 100 error lines
1084+
const totalErrorLines = this.activeProcess.errors.length;
1085+
const recentErrors = this.activeProcess.errors.slice(-maxErrorLines);
1086+
const recentErrorsText = recentErrors.join('\n');
1087+
1088+
let responseText = `--- Recent Errors (${Math.min(maxErrorLines, totalErrorLines)}/${totalErrorLines} lines shown) ---\n`;
1089+
responseText += recentErrorsText || '(No recent errors)';
1090+
1091+
// Also include total output line count for context
1092+
const totalOutputLines = this.activeProcess.output.length;
1093+
responseText += `\n(Total output lines: ${totalOutputLines})`;
1094+
1095+
1096+
return {
1097+
content: [
1098+
{ type: 'text', text: responseText }
1099+
],
1100+
// Return only the sliced recent errors and a limited amount of recent output for context if needed
1101+
// For now, let's keep the full arrays but the primary content is limited
1102+
output: [...this.activeProcess.output], // Keep full output array for now
1103+
errors: [...this.activeProcess.errors] // Keep full error array for now
1104+
};
1105+
} else {
1106+
return this.createErrorResponse('No active Godot project is running.');
1107+
}
1108+
}
10801109

10811110
/**
10821111
* Handle the stop_project tool

0 commit comments

Comments
 (0)