list_templates
Browse available note templates to quickly create structured documents in your Obsidian vault. Select from pre-designed formats for consistent note-taking and organization.
Instructions
List available note templates
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| folder | No | Templates |
Implementation Reference
- src/obsidian_mcp/vault.py:744-870 (handler)Core implementation of list_templates in the ObsidianVault class that lists notes recursively in the specified folder (default Templates), returning NoteMetadata list or empty on folder not found. The handler in server.py calls this method.def list_templates(self, folder: str = "Templates") -> list[NoteMetadata]: """ List available templates. Args: folder: Folder where templates are stored Returns: List of template notes """ try: return self.list_notes(folder=folder, recursive=True, limit=None) except FileNotFoundError: return [] async def create_from_template( self, template_path: str, new_note_path: str, replacements: dict[str, str] | None = None, ) -> None: """ Create a new note from a template. Args: template_path: Path to the template note new_note_path: Path for the new note replacements: Dict of placeholder -> value replacements Raises: FileNotFoundError: If template doesn't exist """ # Read template template = await self.read_note(template_path) content = template.content frontmatter = template.frontmatter.copy() if template.frontmatter else None # Apply replacements if replacements: for placeholder, value in replacements.items(): content = content.replace(f"{{{{{placeholder}}}}}", value) # Also replace in frontmatter values if frontmatter: for key, fm_value in frontmatter.items(): if isinstance(fm_value, str): frontmatter[key] = fm_value.replace(f"{{{{{placeholder}}}}}", value) # Create new note self.create_note(new_note_path, content, frontmatter) async def get_link_graph(self, max_notes: int = 1000) -> dict[str, Any]: """ Build a link graph for the vault. Returns: Dict with 'nodes' and 'edges' for visualization """ nodes = [] edges = [] seen_paths = set() for note_meta in self.list_notes(limit=max_notes): # Add node if note_meta.path not in seen_paths: nodes.append( { "id": note_meta.path, "name": note_meta.name, "size": note_meta.size, "tags": note_meta.tags if note_meta.tags else [], } ) seen_paths.add(note_meta.path) # Add edges (links) try: note = await self.read_note(note_meta.path) links = self._extract_links(note.content) for link in links: resolved = self._resolve_link(link, note_meta.path) if resolved and resolved in seen_paths: edges.append( { "source": note_meta.path, "target": resolved, } ) except Exception as e: logger.debug(f"Error building graph for {note_meta.path}: {e}") continue return { "nodes": nodes, "edges": edges, "total_nodes": len(nodes), "total_edges": len(edges), } async def get_related_notes( self, relative_path: str, limit: int = 10 ) -> list[tuple[str, float]]: """ Find notes related to a given note. Uses shared links and tags to calculate similarity. Args: relative_path: Path to the note limit: Maximum number of related notes Returns: List of (note_path, similarity_score) tuples """ target_note = await self.read_note(relative_path) # Get target note's links and tags target_links = set(self._extract_links(target_note.content)) target_tags = set(self._extract_tags(target_note.content, target_note.frontmatter)) related: list[tuple[str, float]] = [] for note_meta in self.list_notes(limit=1000, include_tags=True): # Skip the target note itself if note_meta.path == relative_path: