Skip to main content
Glama

delete

Permanently remove a database record by its ID, including related graph edges and triggering deletion events. This irreversible operation fails if foreign key constraints exist.

Instructions

Delete a specific record from the database by its ID.

This tool permanently removes a record from the database. Use with caution as this operation cannot be undone. The deletion will also:

  • Remove any graph edges (relations) connected to this record

  • Trigger any defined deletion events/hooks

  • Fail if the record is referenced by FOREIGN KEY constraints

Args: thing: The full record ID to delete in format "table:id" (e.g., "user:john", "product:laptop-123") namespace: Optional SurrealDB namespace override. If not provided, uses SURREAL_NAMESPACE env var. database: Optional SurrealDB database override. If not provided, uses SURREAL_DATABASE env var.

Returns: A dictionary containing: - success: Boolean indicating if deletion was successful - deleted: The ID of the deleted record - data: The deleted record data (if available) - error: Error message if deletion failed (only present on failure)

Examples: >>> await delete("user:john") {"success": true, "deleted": "user:john", "data": {"id": "user:john", "name": "John Doe"}}

>>> await delete("product:nonexistent")
{"success": true, "deleted": "product:nonexistent", "data": null}  # No error even if record didn't exist

Note: This operation is irreversible. Consider using soft deletes (status fields) for recoverable deletions.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
thingYes
namespaceNo
databaseNo

Implementation Reference

  • The primary handler for the 'delete' tool, registered via @mcp.tool(). Handles input validation, fetches deleted record data, calls repo_delete, and formats the response.
    async def delete(
        thing: str,
        namespace: Optional[str] = None,
        database: Optional[str] = None,
    ) -> Dict[str, Any]:
        """
        Delete a specific record from the database by its ID.
    
        This tool permanently removes a record from the database. Use with caution as this operation
        cannot be undone. The deletion will also:
        - Remove any graph edges (relations) connected to this record
        - Trigger any defined deletion events/hooks
        - Fail if the record is referenced by FOREIGN KEY constraints
    
        Args:
            thing: The full record ID to delete in format "table:id" (e.g., "user:john", "product:laptop-123")
            namespace: Optional SurrealDB namespace override. If not provided, uses SURREAL_NAMESPACE env var.
            database: Optional SurrealDB database override. If not provided, uses SURREAL_DATABASE env var.
    
        Returns:
            A dictionary containing:
            - success: Boolean indicating if deletion was successful
            - deleted: The ID of the deleted record
            - data: The deleted record data (if available)
            - error: Error message if deletion failed (only present on failure)
    
        Examples:
            >>> await delete("user:john")
            {"success": true, "deleted": "user:john", "data": {"id": "user:john", "name": "John Doe"}}
    
            >>> await delete("product:nonexistent")
            {"success": true, "deleted": "product:nonexistent", "data": null}  # No error even if record didn't exist
    
        Note: This operation is irreversible. Consider using soft deletes (status fields) for recoverable deletions.
        """
        try:
            ns, db = resolve_namespace_database(namespace, database)
    
            # Validate thing format
            if ":" not in thing:
                raise ValueError(f"Invalid record ID format: {thing}. Must be 'table:id'")
    
            logger.info(f"Deleting record {thing}")
    
            # Try to get the record first (optional, for returning deleted data)
            try:
                select_result = await repo_query(f"SELECT * FROM {thing}", namespace=ns, database=db)
                deleted_data = select_result[0] if select_result else None
            except Exception:
                deleted_data = None
    
            # Perform the deletion
            record_id = ensure_record_id(thing)
            await repo_delete(record_id, namespace=ns, database=db)
    
            return {
                "success": True,
                "deleted": thing,
                "data": deleted_data
            }
        except Exception as e:
            logger.error(f"Delete failed for {thing}: {str(e)}")
            raise Exception(f"Failed to delete {thing}: {str(e)}")
  • Helper function repo_delete that executes the actual DELETE operation on the SurrealDB connection.
    async def repo_delete(
        record_id: Union[str, RecordID],
        namespace: Optional[str] = None,
        database: Optional[str] = None,
    ):
        """Delete a record by record id.
    
        Args:
            record_id: The record ID to delete
            namespace: Optional namespace override (uses env var if not provided)
            database: Optional database override (uses env var if not provided)
    
        Returns:
            The deletion result
        """
        try:
            async with db_connection(namespace, database) as connection:
                return await connection.delete(record_id)
        except Exception as e:
            logger.exception(e)
            raise RuntimeError(f"Failed to delete record: {str(e)}")
  • Utility function to resolve namespace and database from tool parameters or environment variables, used by all tools including delete.
    def resolve_namespace_database(
        namespace: Optional[str] = None,
        database: Optional[str] = None,
    ) -> Tuple[Optional[str], Optional[str]]:
        """
        Resolve namespace and database values from parameters or environment variables.
    
        Args:
            namespace: Optional namespace parameter from tool call
            database: Optional database parameter from tool call
    
        Returns:
            Tuple of (resolved_namespace, resolved_database). Both will be None if using
            default pooled connection, or both will be strings if using override connection.
    
        Raises:
            ValueError: If namespace/database cannot be determined from either source
        """
        # Get values from env vars as fallback
        env_namespace = os.environ.get("SURREAL_NAMESPACE")
        env_database = os.environ.get("SURREAL_DATABASE")
    
        # Resolve final values
        final_namespace = namespace if namespace is not None else env_namespace
        final_database = database if database is not None else env_database
    
        # If both are from env vars (or both params are None), use pooled connection
        if namespace is None and database is None and env_namespace and env_database:
            return None, None  # Signal to use pooled connection
    
        # If either param is provided, we need both values resolved
        if final_namespace is None or final_database is None:
            missing = []
            if final_namespace is None:
                missing.append("namespace")
            if final_database is None:
                missing.append("database")
            raise ValueError(
                f"Missing required database configuration: {', '.join(missing)}. "
                "Either set SURREAL_NAMESPACE/SURREAL_DATABASE environment variables "
                "or provide namespace/database parameters in the tool call."
            )
    
        return final_namespace, final_database

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/lfnovo/surreal-mcp'

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