Skip to main content
Glama
cwente25

Knowledge Base MCP Server

by cwente25

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
NameRequiredDescriptionDefault
category_pathYesCategory path to delete (e.g., 'work/clients/acme')
confirmNoMust be true to delete non-empty category (safety check)
recursiveNoIf true, delete all subcategories and notes (default: true)

Implementation Reference

  • 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"],
    },
  • 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)
  • 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
        }

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