obsidian_update_frontmatter
Modify YAML frontmatter metadata in Obsidian notes to add or update fields like tags and status while keeping note content unchanged.
Instructions
Update YAML frontmatter metadata without modifying note content.
Add or update metadata fields like tags, status, or custom properties in
Zettelkasten notes while preserving all content.
Args:
params (UpdateFrontmatterInput): Contains:
- filepath (str): Path to file
- updates (Dict): Frontmatter fields to add/update
Returns:
str: Success message with updated frontmatter
Example:
Add tags to existing note: updates={'tags': ['zettelkasten', 'systems-thinking']}
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Implementation Reference
- Main handler function that orchestrates the frontmatter update by calling the ObsidianClient helper and formatting the JSON response.async def update_frontmatter(params: UpdateFrontmatterInput) -> str: """Update YAML frontmatter metadata without modifying note content. Add or update metadata fields like tags, status, or custom properties in Zettelkasten notes while preserving all content. Args: params (UpdateFrontmatterInput): Contains: - filepath (str): Path to file - updates (Dict): Frontmatter fields to add/update Returns: str: Success message with updated frontmatter Example: Add tags to existing note: updates={'tags': ['zettelkasten', 'systems-thinking']} """ try: result = await obsidian_client.update_file_frontmatter( params.filepath, params.updates ) return json.dumps({ "success": True, "message": "Frontmatter updated successfully", "filepath": params.filepath, "frontmatter": result["frontmatter"] }, indent=2) except ObsidianAPIError as e: return json.dumps({ "error": str(e), "filepath": params.filepath, "success": False }, indent=2)
- Pydantic input model defining the parameters for the tool: filepath (str) and updates (Dict[str, Any]).class UpdateFrontmatterInput(BaseModel): """Input for updating frontmatter.""" model_config = ConfigDict(str_strip_whitespace=True, extra='forbid') filepath: str = Field( description="Path to the file", min_length=1, max_length=500 ) updates: Dict[str, Any] = Field( description="Frontmatter fields to update or add (e.g., {'tags': ['new-tag'], 'status': 'published'})" )
- src/custom_obsidian_mcp/server.py:1012-1021 (registration)MCP decorator registering the tool with name 'obsidian_update_frontmatter' and appropriate annotations.@mcp.tool( name="obsidian_update_frontmatter", annotations={ "title": "Update Note Frontmatter", "readOnlyHint": False, "destructiveHint": False, "idempotentHint": False, "openWorldHint": False } )
- Core implementation in ObsidianClient: reads file, parses frontmatter, merges updates, serializes with frontmatter library, and writes back preserving body content.async def update_file_frontmatter( self, filepath: str, updates: Dict[str, Any] ) -> Dict[str, Any]: """ Update frontmatter in a file without modifying body content. Args: filepath: Path to the file updates: Dictionary of frontmatter fields to update Returns: Dictionary with success status and updated frontmatter """ content = await self.read_file(filepath) current_fm, body = self.parse_frontmatter(content) # Merge updates into current frontmatter current_fm.update(updates) # Serialize and write back new_content = self.serialize_with_frontmatter(current_fm, body) await self.write_file(filepath, new_content) return { "success": True, "frontmatter": current_fm }