delete_category
Remove a category and optionally all its contents from the knowledge base. Specify the category path and confirm deletion 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
- src/knowledge_base_mcp/server.py:344-369 (handler)MCP tool handler that extracts arguments, calls the storage delete_category method, formats success/error messages with deletion stats.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)}")]
- JSON input schema for the delete_category tool, defining category_path as required, with optional confirm and recursive flags.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 (registration)Dispatch logic in the main @app.call_tool() function that routes 'delete_category' calls to the handler.elif name == "delete_category": return await handle_delete_category(arguments)
- src/knowledge_base_mcp/server.py:64-87 (registration)Tool object registration in @app.list_tools(), defining name, description, and schema for delete_category.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"], }, ),
- Core storage helper that performs the filesystem deletion: validates path, checks confirmation for non-empty dirs, counts items, uses shutil.rmtree for recursive delete.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 }