Brian Webster’s brilliant answer (thank you!) inspired this solution.

I added the demo code to a fully working project on GitHub.
First, we add a custom accessory view to the window’s tab when creating the window. We pass a reference to the NSWindowController so that we can easily notify it whenever something was dropped on the tab item.
window.tab.accessoryView = TabAccessoryView(windowController: windowController)
This custom accessoryView (TabAccessoryView) is not the view that will accept the drops, because the accessory view is confined to an NSStackView, together with the close button and the title label, covering only a portion of the tab next to the title label.
So instead, we use the fact that the accessoryView is part of the NSTabButton’s view hierarchy to inject another custom view (TabDropTargetView) behind the NSStackView …
class TabAccessoryView: NSView {
    weak private(set) var windowController: NSWindowController?
    private let tabDropTargetView: TabDropTargetView
    init(windowController: NSWindowController? = nil) {
        self.windowController = windowController
        self.tabDropTargetView = TabDropTargetView(windowController: windowController)
        super.init(frame: .zero)
    }
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    override func viewDidMoveToWindow() {
        guard tabDropTargetView.superview == nil else { return }
        // DEBUG: Highlight accessory view
        wantsLayer = true
        layer?.backgroundColor = NSColor.red.withAlphaComponent(0.1).cgColor
        // The NSTabButton close button, title, and accessory view are contained in a stack view:
        guard let stackView = superview as? NSStackView,
              let backgroundView = stackView.superview else { return }
        // Add the drop target view behind the NSTabButton’s NSStackView and pin it to the edges
        backgroundView.addSubview(tabDropTargetView, positioned: .below, relativeTo: stackView)
        tabDropTargetView.translatesAutoresizingMaskIntoConstraints = false
        tabDropTargetView.leadingAnchor.constraint(equalTo: backgroundView.leadingAnchor).isActive = true
        tabDropTargetView.trailingAnchor.constraint(equalTo: backgroundView.trailingAnchor).isActive = true
        tabDropTargetView.topAnchor.constraint(equalTo: backgroundView.topAnchor).isActive = true
        tabDropTargetView.bottomAnchor.constraint(equalTo: backgroundView.bottomAnchor).isActive = true
    }
}
… which will handle the dropped item:
class TabDropTargetView: NSView {
    private(set) weak var windowController: NSWindowController?
    let allowedDropTypes: Array<NSPasteboard.PasteboardType> = [.URL, .fileContents, .string, .html, .rtf]
    init(windowController: NSWindowController? = nil) {
        self.windowController = windowController
        super.init(frame: .zero)
        // Tell the system that we accept drops on this view
        registerForDraggedTypes(allowedDropTypes)
    }
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    override func viewDidMoveToWindow() {
        // DEBUG: Highlight drop target view
        wantsLayer = true
        layer?.backgroundColor = NSColor.green.withAlphaComponent(0.05).cgColor
    }
    override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {
        return .copy
    }
    override func draggingUpdated(_ sender: NSDraggingInfo) -> NSDragOperation {
        return .copy
    }
    override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
        // Optional: Ignore drags from the same window
        guard (sender.draggingSource as? NSView)?.window != window else { return false }
        // Check if the dropped item contains text:
        let pasteboard = sender.draggingPasteboard
        guard let availableType = pasteboard.availableType(from: allowedDropTypes),
              let text = pasteboard.string(forType: availableType) else {
            return false
        }
        if let windowController = windowController as? WindowController {
            // Use the reference to the tab’s NSWindowController to pass the dropped item
            windowController.handleDroppedText(text)
        }
        return true
    }
}