delete_category
Remove a category from your knowledge base, including its subcategories and notes when specified, with a safety confirmation for non-empty categories.
Instructions
Delete a category and optionally all its contents
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| category_path | Yes | Category path to delete (e.g., 'work/clients/acme') | |
| confirm | No | Must be true to delete non-empty category (safety check) | |
| recursive | No | If true, delete all subcategories and notes (default: true) |
Implementation Reference
- Core handler method that performs the actual category deletion logic, including recursive deletion, confirmation checks, and counting deleted items.def delete_category( self, category_path: str, recursive: bool = True, confirm: bool = False ) -> Dict[str, int]: """ Delete a category. Args: category_path: Category path to delete recursive: If True, delete subcategories and notes confirm: Must be True to delete non-empty category Returns: Dictionary with counts of deleted items Raises: CategoryNotFoundError: If category doesn't exist StorageError: If deletion fails or confirmation not provided """ normalized = normalize_path(category_path) if not normalized: raise InvalidPathError("Category path cannot be empty") if not self._category_exists(normalized): raise CategoryNotFoundError( f"❌ Error: Category '{normalized}' not found\n" f"💡 Tip: Use list_categories to see available categories" ) cat_path = self._get_category_path(normalized) # Count what will be deleted notes_count = self._count_notes_in_category(normalized, recursive=True) subcats = [d for d in cat_path.rglob("*") if d.is_dir()] if recursive else [] subcats_count = len(subcats) # Check if confirmation needed if (notes_count > 0 or subcats_count > 0) and not confirm: raise StorageError( f"❌ Error: Category '{normalized}' is not empty " f"({notes_count} notes, {subcats_count} subcategories)\n" f"💡 Tip: Set confirm=True to delete non-empty category" ) # Perform deletion try: if recursive: shutil.rmtree(cat_path) else: # Only delete if empty cat_path.rmdir() except OSError as e: raise StorageError(f"Failed to delete category '{normalized}': {e}") return { "notes_deleted": notes_count, "subcategories_deleted": subcats_count }
- src/knowledge_base_mcp/server.py:344-369 (handler)MCP tool handler wrapper that extracts arguments, calls the storage layer's delete_category, formats the response, and handles errors.async def handle_delete_category(arguments: dict) -> list[TextContent]: """Handle delete_category tool call.""" try: category_path = arguments["category_path"] confirm = arguments.get("confirm", False) recursive = arguments.get("recursive", True) result = storage.delete_category( category_path=category_path, recursive=recursive, confirm=confirm ) notes_deleted = result["notes_deleted"] subcats_deleted = result["subcategories_deleted"] msg = f"✓ Category '{category_path}' deleted successfully\n" msg += f" Notes deleted: {notes_deleted}\n" msg += f" Subcategories deleted: {subcats_deleted}" return [TextContent(type="text", text=msg)] except (CategoryNotFoundError, StorageError) as e: return [TextContent(type="text", text=str(e))] except Exception as e: return [TextContent(type="text", text=f"❌ Error: {str(e)}")]
- src/knowledge_base_mcp/server.py:64-87 (registration)Registration of the delete_category tool in the MCP server, including name, description, and input schema.Tool( name="delete_category", description="Delete a category and optionally all its contents", inputSchema={ "type": "object", "properties": { "category_path": { "type": "string", "description": "Category path to delete (e.g., 'work/clients/acme')", }, "confirm": { "type": "boolean", "description": "Must be true to delete non-empty category (safety check)", "default": False, }, "recursive": { "type": "boolean", "description": "If true, delete all subcategories and notes (default: true)", "default": True, }, }, "required": ["category_path"], }, ),
- src/knowledge_base_mcp/server.py:291-292 (handler)Dispatch logic in the main call_tool handler that routes to handle_delete_category.elif name == "delete_category": return await handle_delete_category(arguments)