Skip to main content
Glama

run_project

Execute a Godot game project to test functionality and capture runtime output for debugging purposes.

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

  • Implements the core logic for running a Godot project: validates input, spawns Godot process in debug mode with optional scene, captures stdout/stderr, stores in activeProcess for later retrieval.
    private async handleRunProject(args: any) {
      // Normalize parameters to camelCase
      args = this.normalizeParameters(args);
      
      if (!args.projectPath) {
        return this.createErrorResponse(
          'Project path is required',
          ['Provide a valid path to a Godot project directory']
        );
      }
    
      if (!this.validatePath(args.projectPath)) {
        return this.createErrorResponse(
          'Invalid project path',
          ['Provide a valid path without ".." or other potentially unsafe characters']
        );
      }
    
      try {
        // Check if the project directory exists and contains a project.godot file
        const projectFile = join(args.projectPath, 'project.godot');
        if (!existsSync(projectFile)) {
          return this.createErrorResponse(
            `Not a valid Godot project: ${args.projectPath}`,
            [
              'Ensure the path points to a directory containing a project.godot file',
              'Use list_projects to find valid Godot projects',
            ]
          );
        }
    
        // Kill any existing process
        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 {
          content: [
            {
              type: 'text',
              text: `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}`,
          [
            'Ensure Godot is installed correctly',
            'Check if the GODOT_PATH environment variable is set correctly',
            'Verify the project path is accessible',
          ]
        );
      }
    }
  • Defines the input schema for the run_project tool, including required projectPath and optional scene.
    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:937-937 (registration)
    Registers the handler dispatch for the 'run_project' tool in the CallToolRequestSchema switch statement.
    return await this.handleRunProject(request.params.arguments);
  • src/index.ts:667-928 (registration)
    Registers the run_project tool in the list of available tools returned by ListToolsRequestSchema.
    this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
      tools: [
        {
          name: 'launch_editor',
          description: 'Launch Godot editor for a specific project',
          inputSchema: {
            type: 'object',
            properties: {
              projectPath: {
                type: 'string',
                description: 'Path to the Godot project directory',
              },
            },
            required: ['projectPath'],
          },
        },
        {
          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'],
          },
        },
        {
          name: 'get_debug_output',
          description: 'Get the current debug output and errors',
          inputSchema: {
            type: 'object',
            properties: {},
            required: [],
          },
        },
        {
          name: 'stop_project',
          description: 'Stop the currently running Godot project',
          inputSchema: {
            type: 'object',
            properties: {},
            required: [],
          },
        },
        {
          name: 'get_godot_version',
          description: 'Get the installed Godot version',
          inputSchema: {
            type: 'object',
            properties: {},
            required: [],
          },
        },
        {
          name: 'list_projects',
          description: 'List Godot projects in a directory',
          inputSchema: {
            type: 'object',
            properties: {
              directory: {
                type: 'string',
                description: 'Directory to search for Godot projects',
              },
              recursive: {
                type: 'boolean',
                description: 'Whether to search recursively (default: false)',
              },
            },
            required: ['directory'],
          },
        },
        {
          name: 'get_project_info',
          description: 'Retrieve metadata about a Godot project',
          inputSchema: {
            type: 'object',
            properties: {
              projectPath: {
                type: 'string',
                description: 'Path to the Godot project directory',
              },
            },
            required: ['projectPath'],
          },
        },
        {
          name: 'create_scene',
          description: 'Create a new Godot scene file',
          inputSchema: {
            type: 'object',
            properties: {
              projectPath: {
                type: 'string',
                description: 'Path to the Godot project directory',
              },
              scenePath: {
                type: 'string',
                description: 'Path where the scene file will be saved (relative to project)',
              },
              rootNodeType: {
                type: 'string',
                description: 'Type of the root node (e.g., Node2D, Node3D)',
                default: 'Node2D',
              },
            },
            required: ['projectPath', 'scenePath'],
          },
        },
        {
          name: 'add_node',
          description: 'Add a node to an existing scene',
          inputSchema: {
            type: 'object',
            properties: {
              projectPath: {
                type: 'string',
                description: 'Path to the Godot project directory',
              },
              scenePath: {
                type: 'string',
                description: 'Path to the scene file (relative to project)',
              },
              parentNodePath: {
                type: 'string',
                description: 'Path to the parent node (e.g., "root" or "root/Player")',
                default: 'root',
              },
              nodeType: {
                type: 'string',
                description: 'Type of node to add (e.g., Sprite2D, CollisionShape2D)',
              },
              nodeName: {
                type: 'string',
                description: 'Name for the new node',
              },
              properties: {
                type: 'object',
                description: 'Optional properties to set on the node',
              },
            },
            required: ['projectPath', 'scenePath', 'nodeType', 'nodeName'],
          },
        },
        {
          name: 'load_sprite',
          description: 'Load a sprite into a Sprite2D node',
          inputSchema: {
            type: 'object',
            properties: {
              projectPath: {
                type: 'string',
                description: 'Path to the Godot project directory',
              },
              scenePath: {
                type: 'string',
                description: 'Path to the scene file (relative to project)',
              },
              nodePath: {
                type: 'string',
                description: 'Path to the Sprite2D node (e.g., "root/Player/Sprite2D")',
              },
              texturePath: {
                type: 'string',
                description: 'Path to the texture file (relative to project)',
              },
            },
            required: ['projectPath', 'scenePath', 'nodePath', 'texturePath'],
          },
        },
        {
          name: 'export_mesh_library',
          description: 'Export a scene as a MeshLibrary resource',
          inputSchema: {
            type: 'object',
            properties: {
              projectPath: {
                type: 'string',
                description: 'Path to the Godot project directory',
              },
              scenePath: {
                type: 'string',
                description: 'Path to the scene file (.tscn) to export',
              },
              outputPath: {
                type: 'string',
                description: 'Path where the mesh library (.res) will be saved',
              },
              meshItemNames: {
                type: 'array',
                items: {
                  type: 'string',
                },
                description: 'Optional: Names of specific mesh items to include (defaults to all)',
              },
            },
            required: ['projectPath', 'scenePath', 'outputPath'],
          },
        },
        {
          name: 'save_scene',
          description: 'Save changes to a scene file',
          inputSchema: {
            type: 'object',
            properties: {
              projectPath: {
                type: 'string',
                description: 'Path to the Godot project directory',
              },
              scenePath: {
                type: 'string',
                description: 'Path to the scene file (relative to project)',
              },
              newPath: {
                type: 'string',
                description: 'Optional: New path to save the scene to (for creating variants)',
              },
            },
            required: ['projectPath', 'scenePath'],
          },
        },
        {
          name: 'get_uid',
          description: 'Get the UID for a specific file in a Godot project (for Godot 4.4+)',
          inputSchema: {
            type: 'object',
            properties: {
              projectPath: {
                type: 'string',
                description: 'Path to the Godot project directory',
              },
              filePath: {
                type: 'string',
                description: 'Path to the file (relative to project) for which to get the UID',
              },
            },
            required: ['projectPath', 'filePath'],
          },
        },
        {
          name: 'update_project_uids',
          description: 'Update UID references in a Godot project by resaving resources (for Godot 4.4+)',
          inputSchema: {
            type: 'object',
            properties: {
              projectPath: {
                type: 'string',
                description: 'Path to the Godot project directory',
              },
            },
            required: ['projectPath'],
          },
        },
      ],
    }));

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.