- RDP — Phase 3
+
+
+ handleRdpClipboard(session.id, text)"
+ />
diff --git a/frontend/composables/useRdp.ts b/frontend/composables/useRdp.ts
new file mode 100644
index 0000000..ef18582
--- /dev/null
+++ b/frontend/composables/useRdp.ts
@@ -0,0 +1,243 @@
+import Guacamole from 'guacamole-common-js'
+import { useAuthStore } from '~/stores/auth.store'
+import { useSessionStore } from '~/stores/session.store'
+
+/**
+ * Custom Guacamole Tunnel that speaks JSON over WebSocket.
+ *
+ * Why custom instead of Guacamole.WebSocketTunnel:
+ * - The standard WebSocketTunnel expects raw Guacamole protocol over WS.
+ * - Our /ws/rdp gateway wraps all messages in JSON envelopes (same pattern
+ * as /ws/terminal and /ws/sftp) for auth, connect handshake, and error
+ * signaling.
+ * - This tunnel bridges the two: guacamole-common-js sees raw Guacamole
+ * instructions while our gateway sees consistent JSON messages.
+ *
+ * Protocol:
+ * Browser → Gateway: { type: 'connect', hostId, width, height, ... }
+ * Browser → Gateway: { type: 'guac', instruction: '