WebSocket Configuration Issue with Tailscale Network Access
● WebSocket Configuration Issue with Tailscale Network Access
Issue Summary
The Claude Code UI WebSocket backend failed to work when accessed via Tailscale network (100.x IP addresses), despite HTTP API calls functioning correctly. This affected AI chat functionality for users accessing the service through Tailscale VPN.
Root Cause
The /api/config endpoint in server/index.js was hardcoding the WebSocket URL using a static IP detection method:
// PROBLEMATIC CODE (Lines 192-201)
const serverIP = getServerIP(); // Returns first non-localhost IP
(192.168.1.146)
const host = ${serverIP}:${PORT};
const wsUrl = ${protocol}://${host}; // Always returned
ws://192.168.1.146:3008
Problem: When users accessed via Tailscale (http://100.117.241.55:3009), the frontend received a WebSocket URL pointing to the local network IP (ws://192.168.1.146:3008) instead of the Tailscale IP (ws://100.117.241.55:3008), causing WebSocket connections to fail.
Impact
- ✅ Working: HTTP API calls, file operations, authentication
- ❌ Broken: Real-time chat, AI interactions, live updates
- Affected Networks: Tailscale, remote access, any non-local-network access
Solution
Modified the /api/config endpoint to dynamically determine the WebSocket URL based on the client's request host:
// FIXED CODE app.get('/api/config', authenticateToken, (req, res) => { const requestHost = req.get('host'); // Get host from request header const protocol = req.protocol === 'https' || req.get('x-forwarded-proto') === 'https' ? 'wss' : 'ws';
const hostname = requestHost.split(':')[0]; // Extract hostname
const wsHost = `${hostname}:${PORT}`; // Use same hostname with backend
port
res.json({
serverPort: PORT,
wsUrl: `${protocol}://${wsHost}` // Dynamic WebSocket URL
});
});
Fix Results
Before: WebSocket URL was always ws://192.168.1.146:3008After: WebSocket URL adapts to request:
- Local: ws://localhost:3008
- WiFi: ws://192.168.1.146:3008
- Tailscale: ws://100.117.241.55:3008
Files Modified
- File: /server/index.js
- Lines: 190-205 (API config endpoint)
- Change: Dynamic host detection instead of static IP resolution
Testing Verified
- ✅ WebSocket connections via Tailscale network
- ✅ AI chat functionality working
- ✅ Backward compatibility with local/WiFi access
- ✅ Service auto-restart on boot maintained
Recommendation
This fix should be applied to the upstream codebase to support multi-network deployments including VPN access, Docker containers, and cloud deployments where the service may be accessed through different network interfaces.
save in md file in the claudecodeui folder
● Write(claudecodeui/claudecodeui/WEBSOCKET_TAILSCALE_FIX.md)
⎿ Wrote 91 lines to claudecodeui/claudecodeui/WEBSOCKET_TAILSCALE_FIX.md
# WebSocket Configuration Issue with Tailscale Network Access
## Issue Summary
The Claude Code UI WebSocket backend failed to work when accessed via
Tailscale network (100.x IP addresses), despite HTTP API calls
functioning correctly. This affected AI chat functionality for users
accessing the service through Tailscale VPN.
## Root Cause
The /api/config endpoint in server/index.js was hardcoding the
WebSocket URL using a static IP detection method:
… +81 lines (ctrl+r to expand)
This is now fixed in the latest commit. Can you check?