Skip to main content
Glama

search_by_property

Search for notes by frontmatter property values to quickly locate specific content based on metadata fields in your Obsidian vault.

Instructions

Search for notes by frontmatter property (metadata field)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
limitNo
property_nameYes
property_valueNo

Implementation Reference

  • Primary MCP tool handler for 'search_by_property'. Validates inputs, invokes the VaultSearch method, formats results as markdown list.
    name="search_by_property", description="Search for notes by frontmatter property (metadata field)", ) async def search_by_property(property_name: str, property_value: str = "", limit: int = 50) -> str: """ Search for notes by frontmatter property. Args: property_name: Name of the frontmatter property to search property_value: Optional value to match (empty to find all notes with this property) limit: Maximum number of results (default: 50) Returns: Formatted list of notes matching the property """ if not property_name or not property_name.strip(): return "Error: Property name cannot be empty" if limit <= 0 or limit > 1000: return "Error: Limit must be between 1 and 1000" context = _get_context() try: # Convert empty string to None for "any value" search value = property_value if property_value else None results = await context.search.search_by_property(property_name, value, limit=limit) if not results: if value: return f"No notes found with property '{property_name}' = '{value}'" else: return f"No notes found with property '{property_name}'" # Format results if value: output = f"Found {len(results)} note(s) with '{property_name}' = '{value}':\n\n" else: output = f"Found {len(results)} note(s) with property '{property_name}':\n\n" for i, result in enumerate(results, 1): output += f"{i}. **{result.name}**\n" output += f" Path: `{result.path}`\n" if result.snippet: output += f" {result.snippet}\n" output += "\n" return output except Exception as e: logger.exception(f"Error searching by property: {property_name}") return f"Error searching by property: {e}"
  • Core implementation logic in VaultSearch class that scans notes, matches frontmatter properties, scores results, and returns SearchResult list.
    async def search_by_property( self, property_name: str, property_value: str | None = None, limit: int = 50 ) -> list[SearchResult]: """ Search for notes by frontmatter property. Args: property_name: Name of the frontmatter property property_value: Optional value to match (if None, matches any note with the property) limit: Maximum number of results Returns: List of search results """ results: list[SearchResult] = [] notes = self.vault.list_notes(limit=None) for note_meta in notes: if len(results) >= limit: break try: note = await self.vault.read_note(note_meta.path) if not note.frontmatter: continue # Check if property exists if property_name not in note.frontmatter: continue prop_val = note.frontmatter[property_name] # If no value specified, just match presence if property_value is None: score = 1.0 else: # Check if value matches if isinstance(prop_val, list): # Check if value is in list if property_value in prop_val or property_value in str(prop_val): score = 2.0 else: continue elif str(prop_val).lower() == property_value.lower(): score = 5.0 # Exact match elif property_value.lower() in str(prop_val).lower(): score = 2.0 # Partial match else: continue # Create snippet from frontmatter snippet = f"{property_name}: {prop_val}" results.append( SearchResult( path=note_meta.path, name=note_meta.name, score=score, snippet=snippet ) ) except (OSError, UnicodeDecodeError) as e: logger.debug(f"Failed to read note {note_meta.path}: {e}") continue results.sort(key=lambda r: r.score, reverse=True) return results[:limit]
  • Dataclass defining the structure of search results used by search_by_property.
    @dataclass(slots=True, frozen=True) class SearchResult: """A search result with context (immutable).""" path: str name: str score: float snippet: str | None = None matched_tags: list[str] | None = None
  • MCP tool registration decorator specifying the tool name and description.
    name="search_by_property", description="Search for notes by frontmatter property (metadata field)", ) async def search_by_property(property_name: str, property_value: str = "", limit: int = 50) -> str:

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/getglad/obsidian_mcp'

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