Skip to main content
Glama
xxczaki

Local History MCP Server

by xxczaki

restore_from_history

Recover previous versions of files by restoring them to specific historical states from local history snapshots.

Instructions

Restore a file to a specific point in its local history

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
filePathYesThe absolute path to the file to restore (e.g., "/Users/user/project/biome.json").
entryIndexYesThe index of the history entry to restore (0 = most recent)
createBackupNoWhether to create a backup of the current file before restoring

Implementation Reference

  • The core handler function that executes the restore_from_history tool logic. It finds the file's history, validates the entry index, handles URI to path conversion, creates a backup if requested, writes the historical content to the target file, and returns a success or error message.
    private async restoreFromHistory(
    	filePath: string,
    	entryIndex: number,
    	createBackup: boolean,
    ) {
    	const history = this.historyParser.findHistoryByFilePath(filePath);
    
    	if (!history) {
    		return {
    			content: [
    				{
    					type: 'text',
    					text: `No local history found for: ${filePath}`,
    				},
    			],
    		};
    	}
    
    	if (entryIndex < 0 || entryIndex >= history.entries.length) {
    		return {
    			content: [
    				{
    					type: 'text',
    					text: `Invalid entry index ${entryIndex}. Available indices: 0-${history.entries.length - 1}`,
    				},
    			],
    		};
    	}
    
    	const entry = history.entries[entryIndex];
    
    	// Convert URIs to file system paths
    	const originalPath = uriToPath(history.originalFilePath);
    	const inputPath = uriToPath(filePath);
    
    	// Determine target path - prefer input path if it exists, otherwise use original
    	const targetPath = fs.existsSync(inputPath) ? inputPath : originalPath;
    
    	try {
    		// Ensure the directory exists
    		const dir = path.dirname(targetPath);
    		if (!fs.existsSync(dir)) {
    			fs.mkdirSync(dir, { recursive: true });
    		}
    
    		// Create backup if requested and file exists
    		if (createBackup && fs.existsSync(targetPath)) {
    			const backupPath = `${targetPath}.backup.${Date.now()}`;
    			fs.copyFileSync(targetPath, backupPath);
    
    			// Restore the file
    			fs.writeFileSync(targetPath, entry.content, 'utf-8');
    
    			return {
    				content: [
    					{
    						type: 'text',
    						text:
    							`βœ… Successfully restored ${targetPath} to history entry ${entryIndex}\n` +
    							`πŸ“„ Backup created at: ${backupPath}\n` +
    							`πŸ• Restored to state from: ${new Date(entry.timestamp).toLocaleString()}`,
    					},
    				],
    			};
    		}
    		// Restore without backup
    		fs.writeFileSync(targetPath, entry.content, 'utf-8');
    
    		return {
    			content: [
    				{
    					type: 'text',
    					text:
    						`βœ… Successfully restored ${targetPath} to history entry ${entryIndex}\n` +
    						`πŸ• Restored to state from: ${new Date(entry.timestamp).toLocaleString()}\n` +
    						'⚠️  No backup was created',
    				},
    			],
    		};
    	} catch (error) {
    		return {
    			content: [
    				{
    					type: 'text',
    					text: `❌ Failed to restore file: ${error instanceof Error ? error.message : String(error)}`,
    				},
    			],
    		};
    	}
    }
  • src/index.ts:99-126 (registration)
    Registers the 'restore_from_history' tool in the MCP server's ListTools response, defining its name, description, and input schema.
    {
    	name: 'restore_from_history',
    	description:
    		'Restore a file to a specific point in its local history',
    	inputSchema: {
    		type: 'object',
    		properties: {
    			filePath: {
    				type: 'string',
    				description:
    					'The absolute path to the file to restore (e.g., "/Users/user/project/biome.json").',
    			},
    			entryIndex: {
    				type: 'number',
    				description:
    					'The index of the history entry to restore (0 = most recent)',
    			},
    			createBackup: {
    				type: 'boolean',
    				description:
    					'Whether to create a backup of the current file before restoring',
    				default: true,
    			},
    		},
    		required: ['filePath', 'entryIndex'],
    		additionalProperties: false,
    	},
    },
  • Dispatch handler in the CallToolRequest that validates input parameters for 'restore_from_history' and invokes the restoreFromHistory method.
    case 'restore_from_history': {
    	if (
    		!args ||
    		typeof args !== 'object' ||
    		!('filePath' in args) ||
    		!('entryIndex' in args)
    	) {
    		throw new McpError(
    			ErrorCode.InvalidParams,
    			'Missing required parameters: filePath, entryIndex',
    		);
    	}
    	const filePathRestore = args.filePath as string;
    	if (!path.isAbsolute(filePathRestore)) {
    		throw new McpError(
    			ErrorCode.InvalidParams,
    			'filePath must be an absolute path',
    		);
    	}
    	return await this.restoreFromHistory(
    		filePathRestore,
    		args.entryIndex as number,
    		((args as Record<string, unknown>).createBackup as boolean) ??
    			true,
    	);
    }
  • Helper utility function used by restoreFromHistory to convert VS Code history file URIs to file system paths.
    export function uriToPath(uri: string): string {
    	if (uri.startsWith('file://')) {
    		// Remove file:// prefix and decode URI components
    		let path = uri.slice(7);
    		// Decode URI-encoded characters
    		path = decodeURIComponent(path);
    		return path;
    	}
    	return uri; // Return as-is if not a URI
    }

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/xxczaki/local-history-mcp'

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