Preface

DeepSeek Harness (DSH) binds its Web GUI to 127.0.0.1 by default, making it accessible only through a browser on the same machine. To view conversation progress or continue sessions from a phone or another computer on the same Wi-Fi, common approaches involve SSH port forwarding or NAT traversal—complex steps requiring extra tunnel maintenance.

dsh-lan-access is a DSH networking tool plugin maintained by Leon0555. Installed via a single npm command, it binds the web service to 0.0.0.0 and resolves the issue where browsers on a local network lack the crypto.randomUUID API, which causes RPC failures in HTTP. Starting from v0.1.2, it also includes automatic layout adaptation for narrow-screen mobile devices. Below, we introduce its capabilities, installation methods, and security boundaries.

What Is This

dsh-lan-access is designed for “trusted intranet” scenarios: devices on the same local network—phones, tablets, or other computers—can access the Web GUI via http://<IP of the DSH host>:3080 in a browser, without needing SSH or NAT traversal.

  • Maintainer: Leon0555
  • Category: Networking Tool
  • License: MIT
  • Current Version: 0.1.3 (npm / GitHub)
  • Catalog Page: https://www.skillhub.cn/plugins/Leon0555/dsh-lan-access
  • Source Code: https://github.com/Leon0555/dsh-lan-access

Core Features

1. Local Network Binding

The plugin overrides the webserver configuration with a bundle patch, changing the host to 0.0.0.0 while keeping the port based on DSH’s default logic (ctx.webStartup.port ?? 3080). After binding, other devices on the local network can access the Web GUI via http://<IP of the DSH host>:3080.

Example to find the local IP (macOS):

ipconfig getifaddr en0

2. crypto.randomUUID Polyfill

Browsers only expose crypto.randomUUID in secure contexts like HTTPS or localhost. In plain HTTP on a local network, this API is absent, causing all of DSH’s RPC calls to fail—project/session lists won’t load, and workspaces cannot be added.

This plugin uses the webServer’s tapIndex hook to inject a fallback implementation (standard UUID v4, generated by crypto.getRandomValues) into the <head> of each returned index.html. It includes an idempotency guard, only activating in non-secure contexts, and does not affect access via localhost on the same machine.

3. Mobile/Narrow Screen Auto-Adaptation (v0.1.2+)

When the screen width is ≤820px, it automatically switches to a compact mobile layout without requiring configuration. Key adaptations include:

  • Reduced font size and tightened layout (message flow, code blocks, heading hierarchy)
  • Input field font-size: 16px to prevent automatic zoom on iOS focus
  • Larger touch targets for buttons and removal of click delay (touch-action: manipulation)
  • Full-screen modals/dialogs (100dvh + safe area adaptation), with floating panels like model selection fixed to prevent obstruction
  • Effective in both dark and light themes (following DSH’s own theme)

The narrow-screen adaptation CSS is ported from dsh-lan-gate (MIT License), including only the layout layer and not the gateway/approval functions.

Installation & Enabling

Method 1: Let DSH Install It

Simply paste the plugin link to DSH and let it install itself (Catalog page: https://www.skillhub.cn/plugins/Leon0555/dsh-lan-access).

Method 2: Install from npm

Requires pnpm (npm i -g pnpm). Run:

dsh plugin --profile web add dsh-lan-access

For local development installation, use:

dsh plugin --profile web add file:/path/to/dsh-lan-access

Restart the service after installation. If using launchd for persistence:

launchctl kickstart -k gui/$(id -u)/com.dsh.web

Uninstallation

dsh plugin --profile web remove dsh-lan-access

After uninstallation, the webserver reverts to default binding to 127.0.0.1 only, and the polyfill is no longer injected.

Typical Usage

  1. Install the plugin locally and restart the DSH web service.
  2. Find the local network IP of the DSH host (e.g., on macOS: ipconfig getifaddr en0).
  3. On a phone or another computer on the same Wi-Fi, open http://<IP>:3080 in a browser.
  4. Configure models, providers, credentials, etc., at http://127.0.0.1:3080 on the local machine; remote devices are primarily for conversations, viewing progress, and selecting models within sessions.

If remote full access to the configuration plane is also needed, the compliant solution provided in the README is SSH local port forwarding:

ssh -L 3080:127.0.0.1:3080 user@MacIP

Then access http://127.0.0.1:3080 from the client. From the server’s perspective, it remains loopback access, does not bypass DSH’s security barriers, and includes SSH authentication. Requires enabling “Remote Login” on the Mac, and you should assess the command-line access risks introduced by SSH.

Use Cases & Notes

Who Is It For

  • Trusted home or company intranets, where you want to continue DSH conversations or view real-time progress on a phone/tablet
  • Avoiding the need to set up separate SSH forwarding or NAT traversal for routine local network access
  • Requiring a readable, clickable Web GUI layout on narrow-screen devices

Security Reminders

After binding to 0.0.0.0, any device on the same network can connect to DSH, with no authentication, meaning the entire network can reach the command execution capabilities of the local DSH process. Use only on trusted home/company intranets; do not enable on public Wi-Fi.

Recommendation: Restrict source IPs via router/firewall; for internet access, overlay with tunnels like Tailscale.

The plugin runs with the current DSH process permissions. Before installation, review the source code and MIT license to ensure its behavior aligns with your security expectations.

Remote Access Restrictions (Intentionally Not Bypassed by This Plugin)

DSH strictly limits the “configuration plane”—settings page, model/provider management, credentials, Agent Presets, directory selection, llm.discoverModels, etc.—to loopback access (127.0.0.1) only. Even with this plugin binding the web service to 0.0.0.0, accessing these endpoints from a local network IP still returns HTTP 403. This is DSH’s official security boundary (PRIVILEGED_METHODS in dsh-client-connection); the trustedHosts whitelist is merely a DNS rebinding barrier, not authentication.

This plugin does not bypass this barrier, nor does it provide proxies to rewrite request headers.

Accessible Remotely (LAN) HTTP 403 (Loopback Only)
Conversations, real-time progress Settings page (model, provider configuration)
Model selection within sessions (llm.providers / llm.models) Credential management (credentials.*)
Session history, workspace browsing Agent Preset management
Other normal APIs Directory selection (host.pickDirectory), llm.discoverModels

Technical Notes

  • Binding: Bundle patch overrides the webserver line (host: 0.0.0.0, port remains ctx.webStartup.port ?? 3080).
  • Polyfill: tapIndex injects inline scripts into the <head> of index.html; only active in non-secure contexts.
  • Mobile Adaptation: Uses the same tapIndex to inject <style> (@media (max-width: 820px)), targeting stable structural attributes like DSH’s data-slot, data-chat-flow, data-composer-card, and role="dialog".

Conclusion

dsh-lan-access addresses the practical barriers to accessing DSH on a local network with three changes: binding to 0.0.0.0, patching crypto.randomUUID, and narrow-screen layout adaptation. It explicitly does not open the configuration and credential domains, making it suitable for “remote conversations, local configuration management” in trusted intranets.

  • Community Catalog: https://www.skillhub.cn/plugins/Leon0555/dsh-lan-access
  • GitHub: https://github.com/Leon0555/dsh-lan-access
  • npm: https://www.npmjs.com/package/dsh-lan-access