list_notes
Retrieve notes from your knowledge base, with optional filtering by category or tag to organize information.
Instructions
List all notes, optionally filtered by category path or tag
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| category_path | No | Optional category path filter (e.g., 'work/clients') | |
| tag | No | Optional tag filter | |
| recursive | No | If true, list notes in subcategories too (default: true) |
Implementation Reference
- src/knowledge_base_mcp/server.py:537-578 (handler)MCP tool handler function for list_notes. Processes input arguments, retrieves notes from storage, groups them by category, and returns a formatted text list.
async def handle_list_notes(arguments: dict) -> list[TextContent]: """Handle list_notes tool call.""" category_path = arguments.get("category_path") tag = arguments.get("tag") recursive = arguments.get("recursive", True) # Get notes notes = storage.list_notes( category_path=category_path, tag=tag, recursive=recursive ) if not notes: return [TextContent(type="text", text="No notes found.")] # Group by category by_category = {} for note in notes: cat = note.category or 'root' if cat not in by_category: by_category[cat] = [] by_category[cat].append(note) # Format output output_lines = [] if category_path: recursive_str = " (including subcategories)" if recursive else " (non-recursive)" output_lines.append(f"Notes in {category_path}/{recursive_str} ({len(notes)} total):\n") else: output_lines.append(f"All notes ({len(notes)} total):\n") for cat in sorted(by_category.keys()): cat_notes = by_category[cat] output_lines.append(f"\n{cat}/ ({len(cat_notes)} notes):") for note in sorted(cat_notes, key=lambda n: n.title): tags_str = ', '.join(note.frontmatter.tags) if note.frontmatter.tags else 'no tags' output_lines.append(f" - {note.title} [{tags_str}]") return [TextContent(type="text", text="\n".join(output_lines))] - src/knowledge_base_mcp/server.py:242-262 (registration)Registration of the list_notes tool in the MCP server's list_tools() method, defining its name, description, and input schema.
name="list_notes", description="List all notes, optionally filtered by category path or tag", inputSchema={ "type": "object", "properties": { "category_path": { "type": "string", "description": "Optional category path filter (e.g., 'work/clients')", }, "tag": { "type": "string", "description": "Optional tag filter", }, "recursive": { "type": "boolean", "description": "If true, list notes in subcategories too (default: true)", "default": True, }, }, }, ), - Input schema/JSON Schema for the list_notes tool defining parameters: category_path, tag, recursive.
inputSchema={ "type": "object", "properties": { "category_path": { "type": "string", "description": "Optional category path filter (e.g., 'work/clients')", }, "tag": { "type": "string", "description": "Optional tag filter", }, "recursive": { "type": "boolean", "description": "If true, list notes in subcategories too (default: true)", "default": True, }, }, }, - Helper method in KnowledgeBaseStorage that implements the core listing logic: scans directories for .md files recursively or not, parses each into Note objects, filters by tag, skips invalid files.
def list_notes( self, category_path: Optional[str] = None, tag: Optional[str] = None, recursive: bool = True ) -> list[Note]: """ List all notes, optionally filtered by category path or tag. Args: category_path: Optional category path filter (e.g., "work/clients") tag: Optional tag filter recursive: If True, include notes from subcategories (default: True) Returns: List of Note objects """ notes = [] # Determine which path to search if category_path: normalized = normalize_path(category_path) search_path = self._get_category_path(normalized) if not search_path.exists(): return [] else: search_path = self.base_path # Find all markdown files if recursive: pattern = "**/*.md" else: pattern = "*.md" for file_path in search_path.glob(pattern): # Skip backup and temp files if file_path.suffix in ('.backup', '.tmp', '.deleted'): continue try: note = self._parse_note_file(file_path) # Apply tag filter if specified if tag and tag.lower() not in [t.lower() for t in note.frontmatter.tags]: continue notes.append(note) except StorageError: # Skip files that can't be parsed continue return notes