Skip to main content
Glama

save_document

Save Markdown documents with configurable validation levels, optional backups, and flexible target paths for secure editing workflows.

Instructions

        Save the document (mainly for validation purposes since auto_save handles most cases).
        
        Args:
            document_path: Path to the source Markdown file
            target_path: Path to save to (if different from source)
            backup: Whether to create a backup before saving
            validation_level: Validation strictness - "STRICT", "NORMAL", or "PERMISSIVE"
        

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
document_pathYes
target_pathNo
backupNo
validation_levelNoNORMAL

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • Primary MCP tool handler for 'save_document'. Decorated with @self.mcp.tool() to register and define the tool execution logic. Loads document editor and delegates saving to processor.
    @self.mcp.tool()
    def save_document(document_path: str, target_path: Optional[str] = None,
                     backup: bool = True, validation_level: str = "NORMAL") -> Dict[str, Any]:
        """
        Save the document (mainly for validation purposes since auto_save handles most cases).
        
        Args:
            document_path: Path to the source Markdown file
            target_path: Path to save to (if different from source)
            backup: Whether to create a backup before saving
            validation_level: Validation strictness - "STRICT", "NORMAL", or "PERMISSIVE"
        """
        try:
            validation_map = {"STRICT": ValidationLevel.STRICT, "NORMAL": ValidationLevel.NORMAL, "PERMISSIVE": ValidationLevel.PERMISSIVE}
            validation_enum = validation_map.get(validation_level.upper(), ValidationLevel.NORMAL)
            
            editor = self.processor.load_document(document_path, validation_enum)
            
            # Determine save path
            save_path = target_path if target_path else document_path
            
            # Save the document
            save_result = self.processor.save_document(editor, save_path, backup)
            return save_result
            
        except Exception as e:
            return self.processor.create_error_response(str(e), type(e).__name__)
  • Core helper function in StatelessMarkdownProcessor that implements the actual file saving logic: resolves path, creates directories and backup, serializes editor content, and writes to file.
    @staticmethod
    def save_document(editor: SafeMarkdownEditor, document_path: str, backup: bool = True) -> Dict[str, Any]:
        """Save a document to the specified path."""
        target_path = StatelessMarkdownProcessor.resolve_path(document_path)
        
        # Create parent directories if they don't exist
        target_path.parent.mkdir(parents=True, exist_ok=True)
        
        # Create backup if requested and file exists
        if backup and target_path.exists():
            backup_path = target_path.with_suffix(f"{target_path.suffix}.bak")
            backup_path.write_bytes(target_path.read_bytes())
        
        # Save the document
        content = editor.to_markdown()
        target_path.write_text(content, encoding='utf-8')
        
        return {
            "success": True,
            "message": f"Successfully saved document to {target_path}",
            "file_path": str(target_path),
            "backup_created": backup and Path(str(target_path) + ".bak").exists(),
            "file_size": len(content)
        }
  • Alternative handler for 'save_document' in the enhanced MCP server variant, simpler version delegating to processor.
    def save_document(document_path: str, backup: bool = True) -> Dict[str, Any]:
        """Save document to file (stateless only)."""
        try:
            editor = self.processor.load_document(document_path)
            return self.processor.save_document(editor, document_path, backup)
        except Exception as e:
            return self.processor.create_error_response(str(e), type(e).__name__)
  • Internal registration of save_document handler (_save_document_impl) in the synchronous call_tool_sync method for testing.
    tools = {
        "load_document": self._load_document_impl,
        "list_sections": self._list_sections_impl,
        "get_section": self._get_section_impl,
        "insert_section": self._insert_section_impl,
        "update_section": self._update_section_impl,
        "delete_section": self._delete_section_impl,
        "move_section": self._move_section_impl,
        "get_document": self._get_document_impl,
        "save_document": self._save_document_impl,
        "analyze_document": self._analyze_document_impl,
    }
  • Internal implementation (_save_document_impl) used by synchronous tool calling and registered in call_tool_sync.
    def _save_document_impl(self, document_path: str, target_path: Optional[str] = None, backup: bool = True, validation_level: str = "NORMAL") -> Dict[str, Any]:
        """Implementation for save_document tool."""
        try:
            validation_map = {"STRICT": ValidationLevel.STRICT, "NORMAL": ValidationLevel.NORMAL, "PERMISSIVE": ValidationLevel.PERMISSIVE}
            validation_enum = validation_map.get(validation_level.upper(), ValidationLevel.NORMAL)
            
            editor = self.processor.load_document(document_path, validation_enum)
            
            # Determine save path
            save_path = target_path if target_path else document_path
            
            return self.processor.save_document(editor, save_path, backup)
        except Exception as e:
            return self.processor.create_error_response(str(e), type(e).__name__)

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/quantalogic/quantalogic_markdown_mcp'

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