Skip to main content
Glama

search_notes

Search your Obsidian vault by content, title, or tags to quickly find relevant notes and information across your knowledge base.

Instructions

Search the vault by content, title, tags, or all

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
folderNo
limitNo
queryYes
search_typeNoall

Implementation Reference

  • The primary handler for the 'search_notes' MCP tool. It handles input validation, invokes the VaultSearch.search method, formats the search results into a readable string, and includes error handling.
    @mcp.tool(name="search_notes", description="Search the vault by content, title, tags, or all") async def search_notes( query: str, search_type: SearchType = "all", folder: str = "", limit: int = 20 ) -> str: """ Search for notes in the vault. Args: query: Search query string search_type: Type of search - "content", "title", "tags", or "all" folder: Optional folder to limit search (e.g., "Projects") limit: Maximum number of results (default: 20) Returns: Formatted list of search results with snippets """ # Validate input if not query or not query.strip(): return "Error: Query cannot be empty" if len(query) > 500: return "Error: Query too long" if limit <= 0 or limit > 1000: return "Error: Limit must be between 1 and 1000" context = _get_context() try: results = await context.search.search( query=query, search_type=search_type, folder=folder, limit=limit ) if not results: return f"No results found for query: {query}" # Format results output = f"Found {len(results)} results for '{query}':\n\n" for i, result in enumerate(results, 1): output += f"{i}. **{result.name}**\n" output += f" Path: `{result.path}`\n" output += f" Score: {result.score:.1f}\n" if result.snippet: output += f" Snippet: {result.snippet}\n" if result.matched_tags: output += f" Tags: {', '.join(result.matched_tags)}\n" output += "\n" return output except VaultSecurityError as e: return f"Error: Security violation: {e}" except Exception as e: logger.exception("Error searching notes") return f"Error searching notes: {e}"
  • The @mcp.tool decorator registers the 'search_notes' function as an MCP tool with the specified name and description.
    @mcp.tool(name="search_notes", description="Search the vault by content, title, tags, or all")
  • Type definition for the search_type parameter used in the search_notes tool, defining valid literal values for search types.
    SearchType = Literal["content", "title", "tags", "all"]
  • The core search logic in VaultSearch.search method, called by the search_notes handler. Performs the actual searching based on type (content, title, tags, or all) and returns sorted SearchResult list.
    async def search( self, query: str, search_type: SearchType = "all", folder: str = "", limit: int = 20 ) -> list[SearchResult]: """ Search the vault. Args: query: Search query string search_type: Type of search to perform folder: Limit search to this folder limit: Maximum number of results Returns: List of search results sorted by relevance """ logger.debug( f"Searching for '{query}' (type={search_type}, folder={folder}, limit={limit})" ) if not query: return [] if search_type == "content": return await self._search_in_content(query, limit, folder) elif search_type == "title": return self._search_by_title(query, limit, folder) elif search_type == "tags": return self._search_by_tags(query, limit, folder) else: # "all" # Combine results from all search types (each with full limit to ensure enough results) title_results = self._search_by_title(query, limit, folder) tag_results = self._search_by_tags(query, limit, folder) content_results = await self._search_in_content(query, limit, folder) # Merge and deduplicate by path seen_paths = set() all_results = [] for result in title_results + tag_results + content_results: if result.path not in seen_paths: seen_paths.add(result.path) all_results.append(result) # Sort by score and return top results up to limit all_results.sort(key=lambda r: r.score, reverse=True) return all_results[:limit]
  • Dataclass defining the structure of each search result returned by the search functionality.
    @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

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