Skip to main content
Glama

create_backup

Create compressed backups of Minecraft worlds while the server is running using save-off/save-on commands to ensure data integrity.

Instructions

Create a compressed backup (tar.gz) of a world. Safe to use while the server is running (uses save-off/save-on).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
world_nameYesWorld folder name to backup (e.g., 'world')

Implementation Reference

  • The actual logic for creating a world backup, including handling RCON save commands.
    async createBackup(
      worldName: string,
      rcon?: RconClient,
      serverRunning = false
    ): Promise<BackupInfo> {
      this.ensureBackupDir();
    
      const worldPath = path.join(this.serverDir, worldName);
      if (!fs.existsSync(worldPath)) {
        throw new Error(`World "${worldName}" not found at ${worldPath}`);
      }
    
      // If server is running, disable saving for consistent backup
      if (serverRunning && rcon) {
        try {
          await rcon.send("save-off");
          await rcon.send("save-all flush");
          // Wait briefly for save to complete
          await new Promise((r) => setTimeout(r, 2000));
        } catch {
          // Continue with backup anyway
        }
      }
    
      const timestamp = new Date()
        .toISOString()
        .replace(/[:.]/g, "-")
        .replace("T", "_")
        .split("Z")[0];
      const backupName = `${worldName}_${timestamp}`;
      const backupPath = path.join(this.backupDir, backupName);
    
      try {
        // Use tar for compression (available on macOS and Linux)
        const tarPath = `${backupPath}.tar.gz`;
        execSync(
          `tar -czf "${tarPath}" -C "${this.serverDir}" "${worldName}"`,
          { timeout: 300000 } // 5 min timeout
        );
    
        const stats = fs.statSync(tarPath);
    
        return {
          name: backupName,
          worldName,
          timestamp: new Date(),
          sizeMB: Math.round((stats.size / (1024 * 1024)) * 100) / 100,
          path: tarPath,
        };
      } finally {
        // Re-enable saving
        if (serverRunning && rcon) {
          try {
            await rcon.send("save-on");
          } catch {
            // Server may have stopped
          }
        }
      }
    }
  • MCP tool registration for 'create_backup' and the tool handler that calls BackupManager.
    server.tool(
      "create_backup",
      "Create a compressed backup (tar.gz) of a world. Safe to use while the server is running (uses save-off/save-on).",
      {
        world_name: z
          .string()
          .describe("World folder name to backup (e.g., 'world')"),
      },
      async ({ world_name }) => {
        try {
          const backup = await backupManager.createBackup(
            world_name,
            manager.rcon,
            manager.isRunning()
          );
          return {
            content: [
              {
                type: "text",
                text: [
                  `Backup created successfully:`,
                  `  Name: ${backup.name}`,
                  `  Size: ${backup.sizeMB} MB`,
                  `  Path: ${backup.path}`,
                  `  Time: ${backup.timestamp.toISOString()}`,
                ].join("\n"),
              },
            ],
          };
        } catch (error) {
          return {
            content: [
              {
                type: "text",
                text: `Backup failed: ${error instanceof Error ? error.message : String(error)}`,
              },
            ],
            isError: true,
          };
        }
      }
    );

Latest Blog Posts

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/tamo2918/Minecraft-Server-MCP'

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