obsidian_recent_periodic_notes
Retrieve recent periodic notes (daily, weekly, monthly, quarterly, yearly) from Obsidian vaults with optional content and metadata inclusion for enhanced analysis.
Instructions
Get most recent periodic notes for the specified period type. When include_content=True, return notes' comprehensive metadata (tags, links, titles, etc.) and note content using the enhanced API approach.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| period | Yes | The period type (daily, weekly, monthly, quarterly, yearly) | |
| limit | No | Maximum number of notes to return (default: 5) | |
| include_content | No | Whether to include note content and comprehensive metadata (default: false) |
Implementation Reference
- src/mcp_obsidian_advanced/server.py:36-36 (registration)Registration of the tool handler class in the TOOL_MAPPING dictionary.tools.TOOL_RECENT_PERIODIC_NOTES: tools.RecentPeriodicNotesToolHandler,
- Input schema definition for the tool in get_tool_description method.def get_tool_description(self): return Tool( name=self.name, description="Get most recent periodic notes for the specified period type. When include_content=True, return notes' comprehensive metadata (tags, links, titles, etc.) and note content using the enhanced API approach.", inputSchema={ "type": "object", "properties": { "period": { "type": "string", "description": "The period type (daily, weekly, monthly, quarterly, yearly)", "enum": ["daily", "weekly", "monthly", "quarterly", "yearly"] }, "limit": { "type": "integer", "description": "Maximum number of notes to return (default: 5)", "default": 5, "minimum": 1, "maximum": 50 }, "include_content": { "type": "boolean", "description": "Whether to include note content and comprehensive metadata (default: false)", "default": False } }, "required": ["period"] } )
- The run_tool method executing the tool logic, validating arguments and calling the Obsidian API, with optional enhancement of results.def run_tool(self, args: dict) -> Sequence[TextContent | ImageContent | EmbeddedResource]: if "period" not in args: raise RuntimeError("period argument missing in arguments") period = args["period"] valid_periods = ["daily", "weekly", "monthly", "quarterly", "yearly"] if period not in valid_periods: raise RuntimeError(f"Invalid period: {period}. Must be one of: {', '.join(valid_periods)}") limit = args.get("limit", 5) if not isinstance(limit, int) or limit < 1: raise RuntimeError(f"Invalid limit: {limit}. Must be a positive integer") include_content = args.get("include_content", False) if not isinstance(include_content, bool): raise RuntimeError(f"Invalid include_content: {include_content}. Must be a boolean") results = api.get_recent_periodic_notes(period, limit, include_content) # If include_content is False, return the results as-is (no enhancement needed) if not include_content: return [ TextContent( type="text", text=json.dumps(results, indent=2) ) ] # If include_content is True, enhance each note with comprehensive metadata enhanced_results = [] for note in results: try: filepath = note.get('path', '') if not filepath: # Keep the original note if no path is available enhanced_results.append(note) continue # Get enhanced metadata using REST API url = f"{api.get_base_url()}/vault/{filepath}" headers = api._get_headers() | {'Accept': 'application/vnd.olrapi.note+json'} def call_fn(): response = requests.get(url, headers=headers, verify=api.verify_ssl, timeout=api.timeout) response.raise_for_status() return response.json() file_data = api._safe_call(call_fn) # Extract data from the API response api_frontmatter = file_data.get('frontmatter', {}) api_stat = file_data.get('stat', {}) api_tags = file_data.get('tags', []) # Get additional note info using obsidiantools for connections/links try: note_info = api.get_note_info(filepath) # Replace the tags from get_note_info with the more accurate API tags note_info['metadata']['tags'] = api_tags # Also update frontmatter with API data for accuracy note_info['metadata']['front_matter'] = api_frontmatter # Update file info with API stat data note_info['metadata']['file_info'].update({ 'ctime': api_stat.get('ctime'), 'mtime': api_stat.get('mtime'), 'size': api_stat.get('size') }) except Exception as note_info_error: # Fallback: create basic note info from API data note_info = { 'metadata': { 'tags': api_tags, 'front_matter': api_frontmatter, 'file_info': { 'rel_filepath': filepath, 'ctime': api_stat.get('ctime'), 'mtime': api_stat.get('mtime'), 'size': api_stat.get('size') }, 'counts': { 'n_backlinks': 0, 'n_wikilinks': 0, 'n_embedded_files': 0, 'n_tags': len(api_tags) } }, 'connections': { 'direct_links': [], 'backlinks': [], 'non_existent_links': [] } } # Add note_info to the existing note object enhanced_note = note.copy() enhanced_note['note_info'] = note_info enhanced_results.append(enhanced_note) except Exception as e: # Keep the original note but add an error field enhanced_note = note.copy() enhanced_note['metadata_error'] = f"Error getting enhanced metadata: {str(e)}" enhanced_results.append(enhanced_note) return [ TextContent( type="text", text=json.dumps(enhanced_results, indent=2) ) ]
- Core helper method in Obsidian class that performs the HTTP request to retrieve recent periodic notes from the Obsidian API.def get_recent_periodic_notes(self, period: str, limit: int = 5, include_content: bool = False) -> Any: """Get most recent periodic notes for the specified period type. Args: period: The period type (daily, weekly, monthly, quarterly, yearly) limit: Maximum number of notes to return (default: 5) include_content: Whether to include note content (default: False) Returns: List of recent periodic notes """ url = f"{self.get_base_url()}/periodic/{period}/recent" params = { "limit": limit, "includeContent": include_content } def call_fn(): response = requests.get( url, headers=self._get_headers(), params=params, verify=self.verify_ssl, timeout=self.timeout ) response.raise_for_status() return response.json() return self._safe_call(call_fn)