Skip to main content
Glama

backup-database

backup-database

Create backups of Firebird databases to protect data. Specify backup format, compression, and storage path for database protection.

Instructions

Creates a backup of the Firebird database

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
backupPathYesPath where the backup file will be saved
optionsNo

Implementation Reference

  • Zod input schema for backup-database tool defining backup path and options.
    export const BackupDatabaseArgsSchema = z.object({
        backupPath: z.string().min(1).describe("Path where the backup file will be saved"),
        options: z.object({
            format: z.enum(['gbak', 'nbackup']).default('gbak').describe("Backup format: gbak (full backup) or nbackup (incremental)"),
            compress: z.boolean().default(false).describe("Whether to compress the backup"),
            metadata_only: z.boolean().default(false).describe("Whether to backup only metadata (no data)"),
            verbose: z.boolean().default(false).describe("Whether to show detailed progress")
        }).optional()
    });
  • Registration of backup-database tool in the tools map with handler that calls backupDatabase and formats response for MCP.
    // Add backup-database tool
    tools.set("backup-database", {
        name: "backup-database",
        description: "Creates a backup of the Firebird database",
        inputSchema: BackupDatabaseArgsSchema,
        handler: async (request) => {
            const { backupPath, options } = request;
            logger.info(`Executing backup-database tool to: ${backupPath}`);
    
            try {
                const result = await backupDatabase(backupPath, options);
    
                return {
                    content: [{
                        type: "text",
                        text: formatForClaude(result)
                    }]
                };
            } catch (error) {
                const errorResponse = wrapError(error);
                logger.error(`Error backing up database: ${errorResponse.error} [${errorResponse.errorType || 'UNKNOWN'}]`);
    
                return {
                    content: [{
                        type: "text",
                        text: formatForClaude(errorResponse)
                    }]
                };
            }
        }
    });
  • Core implementation of database backup using gbak or nbackup Firebird tools via child_process.spawn.
    export const backupDatabase = async (
        backupPath: string,
        options: BackupOptions = {},
        config = DEFAULT_CONFIG
    ): Promise<BackupResult> => {
        const startTime = Date.now();
    
        try {
            // Check if Firebird tools are installed
            const toolsCheck = await checkFirebirdTools();
            if (!toolsCheck.installed) {
                throw new FirebirdError(
                    `Firebird client tools are not installed. ${toolsCheck.installInstructions}`,
                    'MISSING_FIREBIRD_TOOLS'
                );
            }
    
            // Ensure the backup directory exists
            const backupDir = path.dirname(backupPath);
            if (!fs.existsSync(backupDir)) {
                fs.mkdirSync(backupDir, { recursive: true });
            }
    
            // Determine which backup tool to use
            const format = options.format || 'gbak';
            let command: string;
            let args: string[] = [];
    
            // Try to find Firebird bin directory
            const firebirdBinPath = await findFirebirdBinPath();
            if (firebirdBinPath) {
                logger.info(`Found Firebird bin directory: ${firebirdBinPath}`);
                // Use full path to command if bin directory was found
                command = path.join(firebirdBinPath, format);
            } else {
                // Use command name only, relying on system PATH
                command = format;
            }
    
            if (format === 'gbak') {
                args = [
                    '-b',  // Backup
                    '-v',  // Verbose output
                    '-user', config.user || 'SYSDBA',
                    '-password', config.password || 'masterkey'
                ];
    
                if (options.metadata_only) {
                    args.push('-m');  // Metadata only
                }
    
                if (options.compress) {
                    args.push('-z');  // Compress
                }
    
                // Add connection string and backup path
                const connectionString = `${config.host}/${config.port}:${config.database}`;
                args.push(connectionString, backupPath);
            } else if (format === 'nbackup') {
                args = [
                    '-B', '0',  // Level 0 backup (full)
                    '-user', config.user || 'SYSDBA',
                    '-password', config.password || 'masterkey'
                ];
    
                // Add database path and backup path
                args.push(config.database, backupPath);
            } else {
                throw new FirebirdError(
                    `Invalid backup format: ${format}`,
                    'CONFIGURATION_ERROR'
                );
            }
    
            logger.info(`Starting database backup to ${backupPath} using ${format}`);
            if (options.verbose) {
                logger.debug(`Backup command: ${command} ${args.join(' ')}`);
            }
    
            // Execute the backup command
            const result = await executeCommand(command, args, options.verbose);
    
            // Get the size of the backup file
            const stats = fs.statSync(backupPath);
            const duration = Date.now() - startTime;
    
            logger.info(`Backup completed successfully in ${duration}ms, size: ${stats.size} bytes`);
    
            return {
                success: true,
                backupPath,
                size: stats.size,
                duration,
                details: result
            };
        } catch (error: any) {
            const duration = Date.now() - startTime;
            const errorMessage = `Error creating database backup: ${error.message || error}`;
            logger.error(errorMessage);
    
            return {
                success: false,
                backupPath,
                size: 0,
                duration,
                error: errorMessage,
                details: error.details || ''
            };
        }
    };
  • Helper function to execute Firebird command-line tools (gbak, nbackup, etc.) using child_process.spawn and capture output.
    async function executeCommand(command: string, args: string[], verbose: boolean = false): Promise<string> {
        return new Promise((resolve, reject) => {
            const process = spawn(command, args);
            let stdout = '';
            let stderr = '';
    
            process.stdout.on('data', (data) => {
                const output = data.toString();
                stdout += output;
                if (verbose) {
                    logger.debug(`[${command}] ${output.trim()}`);
                }
            });
    
            process.stderr.on('data', (data) => {
                const output = data.toString();
                stderr += output;
                if (verbose) {
                    logger.error(`[${command}] ${output.trim()}`);
                }
            });
    
            process.on('close', (code) => {
                if (code === 0) {
                    resolve(stdout);
                } else {
                    const error = new FirebirdError(
                        `Command failed with code ${code}: ${stderr || 'No error message'}`,
                        'COMMAND_EXECUTION_ERROR'
                    );
                    (error as any).details = stderr;
                    reject(error);
                }
            });
    
            process.on('error', (error) => {
                const fbError = new FirebirdError(
                    `Failed to execute command: ${error.message}`,
                    'COMMAND_EXECUTION_ERROR'
                );
                (fbError as any).details = error.message;
                reject(fbError);
            });
        });
    }
  • TypeScript interface for BackupOptions used in the backupDatabase function.
    export interface BackupOptions {
        format?: 'gbak' | 'nbackup';
        compress?: boolean;
        metadata_only?: boolean;
        verbose?: boolean;
    }
Behavior2/5

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

With no annotations provided, the description carries full burden for behavioral disclosure. It states the action ('creates a backup') which implies a write operation, but doesn't mention important behavioral aspects like whether it locks the database during backup, requires admin permissions, has performance impact, or what happens on failure. The description is too minimal for a mutation tool.

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, efficient sentence with zero wasted words. It's appropriately sized for a tool with a clear primary function and gets straight to the point without unnecessary elaboration.

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?

For a database backup tool (a potentially destructive operation) with no annotations and no output schema, the description is inadequate. It doesn't explain what the backup contains, how to verify it, what format it produces, or what happens to the original database. The context signals show complexity (nested objects, multiple parameters) that isn't addressed.

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?

Schema description coverage is 50%, with the 'backupPath' parameter well-described in the schema but the 'options' object lacking description. The tool description adds no parameter information beyond what's in the schema, so it doesn't compensate for the coverage gap. The baseline 3 is appropriate given the schema does some work.

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 clearly states the action ('creates a backup') and target resource ('Firebird database'), providing a specific verb+resource combination. However, it doesn't differentiate from its sibling 'restore-database' or other database tools, which prevents a perfect score.

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?

The description provides no guidance on when to use this tool versus alternatives like 'restore-database' or other maintenance tools. There's no mention of prerequisites, timing considerations, or typical use cases for database backups.

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

Install Server

Other Tools

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/PuroDelphi/mcpFirebird'

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