Skip to main content
Glama
xinyuzjj

Godot MCP Enhanced

by xinyuzjj

run_project

Run a Godot project from a specified path, optionally with a scene, and capture the output for debugging or monitoring.

Instructions

Run the Godot project and capture output

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
projectPathYesPath to the Godot project directory
sceneNoOptional: Specific scene to run

Implementation Reference

  • The handleRunProject method: spawns a Godot process in debug mode with --path, optional scene, captures stdout/stderr, manages active process lifecycle, and returns a success/error response.
    private async handleRunProject(args: any): Promise<ToolResult> {
      args = this.normalizeParameters(args);
    
      if (!args.projectPath) {
        return this.createErrorResponse('Project path is required');
      }
    
      if (!this.validatePath(args.projectPath)) {
        return this.createErrorResponse('Invalid project path');
      }
    
      try {
        const projectFile = join(args.projectPath, 'project.godot');
        if (!existsSync(projectFile)) {
          return this.createErrorResponse(`Not a valid Godot project: ${args.projectPath}`);
        }
    
        if (this.activeProcess) {
          this.logDebug('Killing existing Godot process before starting a new one');
          this.activeProcess.process.kill();
        }
    
        const cmdArgs = ['-d', '--path', args.projectPath];
        if (args.scene && this.validatePath(args.scene)) {
          this.logDebug(`Adding scene parameter: ${args.scene}`);
          cmdArgs.push(args.scene);
        }
    
        this.logDebug(`Running Godot project: ${args.projectPath}`);
        const process = spawn(this.godotPath!, cmdArgs, { stdio: 'pipe' });
        const output: string[] = [];
        const errors: string[] = [];
    
        process.stdout?.on('data', (data: Buffer) => {
          const lines = data.toString().split('\n');
          output.push(...lines);
          lines.forEach((line: string) => {
            if (line.trim()) this.logDebug(`[Godot stdout] ${line}`);
          });
        });
    
        process.stderr?.on('data', (data: Buffer) => {
          const lines = data.toString().split('\n');
          errors.push(...lines);
          lines.forEach((line: string) => {
            if (line.trim()) this.logDebug(`[Godot stderr] ${line}`);
          });
        });
    
        process.on('exit', (code: number | null) => {
          this.logDebug(`Godot process exited with code ${code}`);
          if (this.activeProcess && this.activeProcess.process === process) {
            this.activeProcess = null;
          }
        });
    
        process.on('error', (err: Error) => {
          console.error('Failed to start Godot process:', err);
          if (this.activeProcess && this.activeProcess.process === process) {
            this.activeProcess = null;
          }
        });
    
        this.activeProcess = { process, output, errors };
    
        return this.createSuccessResponse('Godot project started in debug mode. Use get_debug_output to see output.');
      } catch (error: unknown) {
        const errorMessage = error instanceof Error ? error.message : 'Unknown error';
        return this.createErrorResponse(`Failed to run Godot project: ${errorMessage}`);
      }
    }
  • src/index.ts:476-493 (registration)
    Tool registration for 'run_project' with description and inputSchema (projectPath required, scene optional).
    {
      name: 'run_project',
      description: 'Run the Godot project and capture output',
      inputSchema: {
        type: 'object',
        properties: {
          projectPath: {
            type: 'string',
            description: 'Path to the Godot project directory',
          },
          scene: {
            type: 'string',
            description: 'Optional: Specific scene to run',
          },
        },
        required: ['projectPath'],
      },
    },
  • src/index.ts:787-789 (registration)
    Switch case dispatching the 'run_project' tool request to handleRunProject.
    case 'run_project':
      result = await this.handleRunProject(request.params.arguments);
      break;

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv1.0.0

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

There are no annotations, so the description must carry the behavioral burden. It mentions 'capture output' but does not disclose side effects, blocking behavior, or whether the process continues running after invocation. The name 'run_project' implies execution but lacks specifics about what the user will observe.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence with no filler or redundant information. It efficiently conveys the primary purpose without unnecessary words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema is present, and the description does not clarify what 'capture output' means—whether it returns logs, exit codes, or streams. It also omits whether the tool blocks until the project closes or returns immediately. This leaves the agent uncertain about the expected behavior and return format.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already provides full coverage for both parameters with their descriptions. The tool description adds no extra semantic detail beyond the schema, so it neither enhances nor detracts from the schema's clarity. The baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear action ('Run') and object ('the Godot project'), plus a specific outcome ('capture output'). It is distinct from siblings like `launch_editor` or `stop_project`, though the phrase 'capture output' could be more detailed about what output is captured.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided about when to use this tool versus alternatives. It does not mention prerequisites, like whether the project must exist or if the Godot editor must be closed, nor does it explain the effect of the optional 'scene' parameter in context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.