MCPProxy uses platform-specific local IPC for secure, low-latency communication between the tray application and core server.
- Dual Listener Design: Core server accepts connections on both TCP (for browsers/remote) and socket/pipe (for tray)
- Unified Socket Transport: Tray uses socket/pipe for ALL communication - both API calls AND Server-Sent Events (SSE)
- No Hybrid Mode: All HTTP traffic (including persistent SSE connection) is routed through the socket - no TCP fallback
- Automatic Detection: Tray auto-detects socket path from data directory configuration
- Zero Configuration: Works out-of-the-box with no manual setup required
- Platform-Specific: Unix sockets (macOS/Linux), Named pipes (Windows)
- Data Directory Permissions: Must be
0700(user-only access) or server refuses to start (exit code 5) - Socket File Permissions: Created with
0600(user read/write only) - UID Verification: Server verifies connecting process belongs to same user
- GID Verification: Group ownership validated on macOS/Linux
- SID/ACL Verification: Windows ACLs ensure current user-only access
- Stale Socket Cleanup: Automatic removal of leftover socket files from crashed processes
- Ownership Validation: Socket file ownership verified before use
- Connection Source Tagging: Middleware distinguishes socket vs TCP connections
- Socket/Pipe connections: Trusted by default (skip API key validation)
- TCP connections: Require API key authentication
- Middleware:
internal/httpapi/server.gochecks connection source via context
- macOS/Linux:
<data-dir>/mcpproxy.sock(default:~/.mcpproxy/mcpproxy.sock) - Windows:
\\.\pipe\mcpproxy-<username>(or hashed for custom data-dir) - Override:
--tray-endpointflag orMCPPROXY_TRAY_ENDPOINTenvironment variable
internal/server/listener.go- Listener manager and abstraction layerinternal/server/listener_unix.go- Unix socket implementation (macOS/Linux)internal/server/listener_darwin.go- macOS-specific peer credential verificationinternal/server/listener_linux.go- Linux-specific peer credential verificationinternal/server/listener_windows.go- Windows named pipe implementationinternal/server/listener_mux.go- Multiplexing listener combining TCP + socket/pipecmd/mcpproxy-tray/internal/api/dialer.go- Tray client socket dialer with auto-detectioncmd/mcpproxy-tray/internal/api/dialer_unix.go- Unix socket dialer (macOS/Linux)cmd/mcpproxy-tray/internal/api/dialer_windows.go- Named pipe dialer (Windows)cmd/mcpproxy-tray/internal/api/client.go- HTTP client with socket transport (lines 100-118, 318-377)
The tray application uses a unified HTTP client that routes all traffic through the socket:
- Custom HTTP Transport: Creates
http.Transportwith socket-basedDialContextfunction - API Calls: Standard HTTP requests (
GET /api/v1/info,POST /api/v1/servers/{name}/enable) use socket transport - SSE Connection: Persistent HTTP connection to
/eventsendpoint also uses socket transport - Real-time Updates: Core sends
event: statusmessages withlisten_addrfield for tray UI updates - Single Source of Truth: Tray UI reads
listen_addrexclusively from SSE status events (no local fallbacks)
Socket/pipe communication is enabled by default. You can disable it using:
# Disable socket communication (clients will use TCP + API key)
./mcpproxy serve --enable-socket=false
# Explicitly enable (default behavior)
./mcpproxy serve --enable-socket=true{
"listen": "127.0.0.1:8080",
"enable_socket": false,
"mcpServers": [...]
}If you're running the core server via the tray application (e.g., automatically at startup), and want to disable socket communication:
- Edit your config file at
~/.mcpproxy/mcp_config.json - Add or update:
"enable_socket": false - Restart the core server (via tray menu: "Stop Core" → "Start Core")
When socket communication is disabled, the tray application will fall back to TCP connections using the auto-generated API key.
# Default: Socket auto-created in data directory
./mcpproxy serve
# Disable socket, use TCP only
./mcpproxy serve --enable-socket=false
# Custom socket path
./mcpproxy serve --tray-endpoint=unix:///tmp/custom.sock
# Windows named pipe
mcpproxy.exe serve --tray-endpoint=npipe:////./pipe/mycustompipe
# Verify socket creation
ls -la ~/.mcpproxy/mcpproxy.sock
# Should show: srw------- (socket, user-only permissions)
# Tray automatically connects via socket (no API key needed)
./mcpproxy-tray- Unit tests:
internal/server/listener_test.go(13 tests covering TCP, Unix socket, permissions, multiplexing) - Dialer tests:
cmd/mcpproxy-tray/internal/api/dialer_test.go(14 tests covering dialers, auto-detection, URL parsing) - E2E tests:
internal/server/socket_e2e_test.go(3 scenarios: socket without API key, TCP with/without API key, concurrent requests)