Skip to main content
Glama

search_notes

Search through notes using keywords, categories, or tags to find relevant information in your knowledge base.

Instructions

Search through all notes by query, category path, or tags

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryNoSearch term (searches title, content, tags) - case insensitive
category_pathNoOptional category path filter (e.g., 'work/clients'). Searches in this path and all subcategories by default.
tagsNoOptional comma-separated tags to filter by (matches any)
recursiveNoIf true, search in subcategories too (default: true)

Implementation Reference

  • The handler function that executes the search_notes MCP tool. Parses input arguments and calls the search engine to perform the search.
    async def handle_search_notes(arguments: dict) -> list[TextContent]: """Handle search_notes tool call.""" query = arguments.get("query", "") category_path = arguments.get("category_path") tags_str = arguments.get("tags") recursive = arguments.get("recursive", True) # Parse tags tags = None if tags_str: tags = [tag.strip() for tag in tags_str.split(",") if tag.strip()] # Search result = search_engine.search_formatted( query=query, category_path=category_path, tags=tags, recursive=recursive ) return [TextContent(type="text", text=result)]
  • Registers the search_notes tool in the MCP server's list_tools() with its input schema and description.
    Tool( name="search_notes", description="Search through all notes by query, category path, or tags", inputSchema={ "type": "object", "properties": { "query": { "type": "string", "description": "Search term (searches title, content, tags) - case insensitive", "default": "", }, "category_path": { "type": "string", "description": "Optional category path filter (e.g., 'work/clients'). Searches in this path and all subcategories by default.", }, "tags": { "type": "string", "description": "Optional comma-separated tags to filter by (matches any)", }, "recursive": { "type": "boolean", "description": "If true, search in subcategories too (default: true)", "default": True, }, }, }, ),
  • Dispatches tool calls to the search_notes handler in the main call_tool function.
    elif name == "search_notes": return await handle_search_notes(arguments)
  • Core search logic in KnowledgeBaseSearch class: retrieves notes, applies filters, calculates relevance, and sorts results.
    def search( self, query: str = "", category_path: Optional[str] = None, tags: Optional[list[str]] = None, recursive: bool = True ) -> list[SearchResult]: """ Search through all notes. Args: query: Search term (searches title, content, tags) - case insensitive category_path: Optional category path filter (e.g., "work/clients") tags: Optional list of tags to filter by (matches any) recursive: If True, search in subcategories too (default: True) Returns: List of SearchResult objects sorted by relevance """ # Get all notes (potentially filtered by category path) all_notes = self.storage.list_notes( category_path=category_path, recursive=recursive ) results = [] for note in all_notes: # Apply tag filter if specified (match any tag) if tags: note_tags_lower = [t.lower() for t in note.frontmatter.tags] search_tags_lower = [t.lower() for t in tags] if not any(tag in note_tags_lower for tag in search_tags_lower): continue # Calculate relevance score relevance = self._calculate_relevance(note, query) # Include all notes if no query, or only matches if query provided if not query or relevance > 0: results.append(SearchResult(note=note, relevance_score=relevance)) # Sort by relevance (highest first) results.sort(key=lambda r: r.relevance_score, reverse=True) return results
  • Helper method called by the handler to perform the formatted search and return the text output.
    def search_formatted( self, query: str = "", category_path: Optional[str] = None, tags: Optional[list[str]] = None, recursive: bool = True ) -> str: """ Search and return formatted results as a string. Args: query: Search term category_path: Optional category path filter (e.g., "work/clients") tags: Optional list of tags to filter by recursive: If True, search in subcategories too (default: True) Returns: Formatted search results string """ results = self.search( query=query, category_path=category_path, tags=tags, recursive=recursive ) if not results: return "No results found." # Format results output_lines = [f"Found {len(results)} result(s):\n"] for result in results: output_lines.append(str(result)) output_lines.append("") # Blank line between results return "\n".join(output_lines)

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/cwente25/KnowledgeBaseMCP'

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