self._hostname = hostname
         self._socket: Optional[socket] = None
         self._recv_loop: Optional[Loop] = None
-        self._caps_available: list[str] = []
-        self._caps_enabled: list[str] = []
+        self._caps: dict[str, set[str]] = {
+                'available': set(), 'enabled': set(), 'finished': set()}
         self.id_ = uuid4()
         self.assumed_open = False
         self.realname = realname
 
         Thread(target=connect, daemon=True, args=(self,)).start()
 
-    def set_caps(self,
-                 caps: list[str],
-                 final_line: bool,
-                 enabled: bool = False
+    def set_caps(self, caps: set[str], final_line: bool, enabled: bool
                  ) -> None:
         'Record available or enabled server capabilities.'
-        finished_marker = '\0'
-        caps_list = self._caps_enabled if enabled else self._caps_available
-        if caps_list[-1:] == [finished_marker]:
-            caps_list.clear()
-        caps_list += caps
+        category = 'enabled' if enabled else 'available'
+        if category in self._caps['finished']:
+            self._caps[category].clear()
+            self._caps['finished'].remove(category)
+        self._caps[category] |= caps
         if final_line:
-            caps_list += [finished_marker]
-            self.log(f'# server caps {"enabled" if enabled else "available"}'
-                     f': {caps_list[:-1]}')
+            self._caps['finished'].add(category)
+            self.log(f'# server caps {category}: {self._caps[category]}')
 
     @abstractmethod
     def log(self, msg: str, chat: str = '') -> None:
             if subverb in {'LS', 'LIST'}:
                 target.set_caps(final_line=msg.params[2] != '*',
                                 enabled=subverb == 'LIST',
-                                caps=msg.params[-1].strip().split())
+                                caps=set(msg.params[-1].strip().split()))