Skip to main content
Glama

undo

Reverts recent editing operations in Markdown documents to correct mistakes or restore previous content states.

Instructions

Reverts the last N operations on the document.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
file_pathYes
countNo

Implementation Reference

  • MCP tool registration for 'undo' including input schema (file_path required, count optional) and output schema.
    Tool( name="undo", title="Undo Last Changes", description="Reverts the last N operations on the document.", inputSchema={ "type": "object", "properties": { "file_path": {"type": "string", "examples": ["./document.md"]}, "count": {"type": "integer", "default": 1, "examples": [1, 2, 5]}, }, "required": ["file_path"], "additionalProperties": False, }, outputSchema={ "type": "object", "properties": { "success": {"type": "boolean"}, "reverted_count": { "type": "integer", "description": "Number of operations reverted", }, }, }, ),
  • Dispatch logic in MCP server's call_tool method for the 'undo' tool.
    elif name == "undo": res = await undo_changes(file_path, arguments.get("count", 1)) return CallToolResult( content=[TextContent(type="text", text="Undo performed")], structuredContent=res, isError="error" in res, )
  • Exported async handler function 'undo_changes' called by the MCP server for 'undo' tool invocations.
    async def undo_changes(file_path: str, count: int = 1): return await _instance.undo(file_path, count)
  • EditTool.undo method: handles file locking, invokes Document.undo, performs atomic file write, and manages cache/journal.
    async def undo(self, file_path: str, count: int = 1) -> Dict[str, Any]: abs_path = resolve_path(file_path) with FileLock(abs_path): doc = self.get_doc(file_path) result = doc.undo(count) if "success" in result: try: self._atomic_write(file_path, doc.get_content()) self._update_cache_mtime(abs_path) doc.confirm_journal() except Exception as e: self.invalidate_cache(file_path) return {"error": f"Failed to write file: {e}"} return result
  • Core Document class undo method: reverses the last N journaled operations (replace, delete, insert, metadata) by popping journal and applying inverse actions.
    def undo(self, count: int = 1) -> Dict[str, Any]: """Undo last operations""" if not self.journal: return {"error": "Journal is empty"} undone = [] errors = [] for _ in range(min(count, len(self.journal))): entry = self.journal.pop() success = False # Apply reverse operation if entry.operation == "replace": # Prefer ID-based lookup for reliability element = None if entry.element_id: element = self.find_by_id(entry.element_id) if not element: element = self.find_by_path(entry.path) if element and entry.old_value is not None: element.content = entry.old_value success = True else: errors.append( f"Cannot undo replace: element not found at {entry.path}" ) elif entry.operation == "delete": # Restore deleted element at its original position success = self._restore_element_at_position(entry) if not success: errors.append( f"Cannot undo delete: failed to restore element at {entry.path}" ) elif entry.operation in ("insert_after", "insert_before"): # Remove the inserted element success = self._remove_inserted_element(entry) if not success: errors.append( f"Cannot undo {entry.operation}: element not found at {entry.path}" ) elif entry.operation == "update_metadata": # Restore old metadata if entry.old_value: try: old_metadata = json.loads(entry.old_value) self.metadata = old_metadata success = True except (json.JSONDecodeError, TypeError): errors.append("Cannot undo update_metadata: invalid old value") else: errors.append("Cannot undo update_metadata: no old value stored") if success: undone.append(entry.operation) self._rebuild_raw_content() self._save_journal() result = {"success": True, "undone_operations": undone} if errors: result["warnings"] = errors return result

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/KazKozDev/markdown-editor-mcp-server'

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