Cómo ejecutar DeepSeek Harness en un VPS privado
Instala DeepSeek Harness en un VPS Linux, fija la versión de npm, revisa qué puede hacer un plugin y accede a la interfaz del puerto 3080 mediante un túnel SSH.
Qué es DeepSeek Harness
DeepSeek Harness (dsh) es un entorno de ejecución de agentes para Node.js que puede ejecutarse en un VPS (servidor privado virtual). La forma segura de ejecutarlo es vincularlo a 127.0.0.1 y acceder desde el navegador mediante un túnel SSH (secure shell). Sirve una interfaz web (user interface) en el puerto 3080 en lugar de funcionar en un terminal. Ese servidor web no solicita ninguna contraseña propia. Por tanto, publicar el puerto 3080 proporciona a cualquiera que lo encuentre un agente que puede leer sus archivos y ejecutar comandos con la cuenta de usuario de Linux.
DeepSeek lo publicó el 13 August 2026 con licencia MIT, como el paquete npm @deepseek-ai/dsh. El proyecto se describe como una versión preliminar para desarrolladores e indica que se esperan cambios incompatibles. Todos los números de versión que aparecen a continuación corresponden a una instantánea de August 2026. Consulte el repositorio antes de copiar cualquiera de ellos en un sistema importante.
Una idea recorre todo el diseño: todo es un plugin. El adaptador del modelo, el registro de herramientas, el registro de sesión, el sandbox, el planificador y el propio bucle del agente son plugins cargados en un contexto compartido, y cualquiera de ellos puede sustituirse. No existe un núcleo privilegiado que los plugins se limiten a ampliar. Esto es lo que hace que merezca la pena probar el harness, y también es donde reside el único riesgo real. La conveniencia de esa contrapartida depende del punto de comparación, y cómo se compara con Claude Code y Omnigent sitúa el diseño basado completamente en plugins junto a otras dos alternativas en cuanto al acoplamiento al modelo, la licencia y la cantidad de recursos de un VPS que requiere cada una.
Un arnés no es un modelo
El arnés ejecuta el ciclo del agente. El razonamiento ocurre en un modelo externo, por lo que nada funciona hasta que se proporciona una clave de API (interfaz de programación de aplicaciones) o la dirección de un endpoint de modelo alojado por usted. Todo lo descrito en esta publicación corresponde a la configuración del arnés, no al comportamiento del modelo, y conviene tener clara la diferencia entre ambos antes de pasar una tarde averiguando de qué lado procede un problema.
La configuración se realiza en la interfaz de usuario, en Settings y después en Models. El catálogo incluye tarjetas preparadas para los principales proveedores de API (DeepSeek, OpenAI y Anthropic), donde se pega una clave. La opción interesante es "Add a custom provider": solicita un ID de proveedor, un nombre visible, una URL base, un protocolo de API y una credencial. Utiliza el protocolo compatible con OpenAI, por lo que funciona con cualquier gateway o servidor local que implemente ese protocolo. Los proveedores personalizados también pueden consultar el endpoint compatible con OpenAI GET /models para completar automáticamente la lista de modelos.
Así se apunta el arnés a un modelo del mismo VPS. Ollama expone una API compatible con OpenAI en http://127.0.0.1:11434/v1/. El campo de clave de API debe contener cualquier cadena, ollama por convención, porque el campo es obligatorio y después se ignora. La cuestión más difícil es si un modelo lo bastante pequeño para ejecutarse en su VPS tiene capacidad suficiente para controlar un agente. La diferencia entre Ollama y vLLM como servidor local de modelos determina cuánta RAM requiere esa decisión.
Las claves introducidas en la interfaz de usuario son de solo escritura. El arnés las almacena en $DSH_HOME/.credentials.yaml y conserva únicamente una referencia a la credencial en settings.yaml. $DSH_HOME tiene ~/.dsh de forma predeterminada. Trate ese archivo como un archivo de contraseñas, porque lo es: cualquiera que pueda leerlo puede gastar su presupuesto de API. Si prefiere editar directamente esos archivos en lugar de hacerlo desde Settings, el recorrido por los archivos de configuración, las claves y los endpoints de modelo de dsh explica la función de cada clave y qué datos salen de su equipo en cada modo.
Qué necesita antes de la instalación
- un VPS con Ubuntu 24.04 u otra distribución Linux actual, con acceso SSH
- Node.js 22.19 o una versión posterior de la serie 22.x, o Node.js 24 o posterior, que son las versiones con las que el proyecto se compila y prueba
- una cuenta de usuario normal, no
root, porque el agente ejecuta comandos de shell con la cuenta que inició el proceso pnpmen el PATH si planea instalar plugins, ya que el comando del plugin lo ejecuta mediante un shell- el puerto 3080 cerrado en el firewall y en el firewall de red independiente de su proveedor
El paquete nodejs de Ubuntu es más antiguo de lo que necesita el entorno de pruebas, así que instale Node desde NodeSource o nvm en lugar de usar apt install nodejs. Si el VPS es nuevo, reforzar SSH antes de cualquier otra tarea merece diez minutos, porque el túnel del que está a punto de depender sólo es tan seguro como el servidor SSH que lo sustenta.
Instalar DeepSeek Harness en un VPS con una versión fijada
node --version
npx @deepseek-ai/dsh@0.1.0-rc.6 webnpx descarga el paquete y ejecuta su binario dsh. web es un alias de --profile web, que inicia la aplicación del navegador, y el proceso muestra la dirección en la que está escuchando. El valor predeterminado es http://127.0.0.1:3080. Esos números determinan el enlace de red, no son un valor predeterminado meramente estético, y por qué dsh muestra una dirección de loopback explica qué responderá y qué no responderá el harness antes de intentar acceder a él desde el portátil.
Fije la versión. npx @deepseek-ai/dsh web resuelve la referencia a la que apunta la etiqueta latest en el momento de ejecutarlo, y el proyecto ya ha publicado varias versiones candidatas y advierte de que habrá cambios incompatibles. 0.1.0-rc.6 es la referencia a la que apuntaba latest el 13 de agosto de 2026. Una versión fijada garantiza que el sistema que configura hoy se comporte igual el mes que viene. Así, una actualización pasa a ser una decisión que toma, no un cambio accidental que descubre. Si un comando con la versión fijada inicia una compilación incorrecta o se niega a instalarse, los errores habituales de instalación y versión de dsh explican cómo vaciar la caché de npx y comprobar qué npm incluye su Node.
Para el uso diario, instálelo una vez en lugar de resolver la versión de nuevo cada vez que lo inicia.
npm install -g @deepseek-ai/dsh@0.1.0-rc.6
dsh --profile web --helpConviene ejecutar esa segunda línea, porque el lanzador y la aplicación web tienen conjuntos de opciones independientes. dsh --help muestra las opciones propias del lanzador. dsh --profile web --help muestra las opciones que acepta la aplicación web. Ahí se encuentran --port, --host y --trusted-host, que puede repetirse.
Ahora confirme en qué dirección está escuchando.
ss -tlnp | grep 3080La columna de dirección local debe mostrar 127.0.0.1:3080. Si muestra 0.0.0.0:3080, la interfaz está accesible desde Internet. Detenga el proceso antes de hacer cualquier otra cosa.
Por qué nunca debe publicar el puerto 3080
El servidor web no tiene ninguna capa de autenticación. Su configuración expone un host de escucha y un puerto de escucha. Esa es toda la superficie. El control de acceso para implementaciones que no usan loopback se configura aparte mediante un ajuste de host de confianza. No es una pantalla de inicio de sesión.
Ahora tenga en cuenta qué hay detrás de ese puerto. El agente edita archivos del espacio de trabajo y ejecuta comandos de shell. Además, las credenciales del proveedor están almacenadas en disco junto al agente. Por tanto, un puerto 3080 abierto equivale a un shell remoto con una interfaz de chat, ejecutándose con el usuario que lo inició y con su clave de API asociada. No hace falta ningún exploit. Basta con conocer el número de puerto. Los escáneres encuentran los puertos a las pocas horas de que un host se conecte a Internet.
La CLI (interfaz de línea de comandos) confirma este comportamiento. Desde 0.1.0-rc.6, no admite deliberadamente --host 0.0.0.0 y termina con un error de uso en lugar de iniciarse. Esta negativa es una medida de seguridad. No busque un parche para eliminarla.
Hay otras dos implementaciones razonables cuando un túnel no resulta adecuado. Coloque el equipo en una red superpuesta privada para que tenga una dirección a la que sólo puedan enrutar sus propios dispositivos. Eso es lo que proporciona un servidor de control Headscale autohospedado. Otra opción es situar delante un reverse proxy que autentique la petición antes de que llegue al puerto 3080, por ejemplo un servidor de inicio de sesión único Authentik que realice autenticación delegada. Un reverse proxy sin autenticación delante no es un control de seguridad. Es una URL más larga.
Acceda a la interfaz web mediante un túnel SSH
Ejecute esto en su portátil, no en el servidor.
ssh -N -L 3080:127.0.0.1:3080 you@your-server-L abre el puerto 3080 en su portátil y reenvía todo lo que se conecte a él a través de la sesión SSH cifrada. La parte 127.0.0.1:3080 se resuelve en el servidor, por lo que la conexión llega al harness desde loopback, exactamente como si estuviera en la máquina. -N indica que no se debe iniciar un shell remoto, porque sólo necesita el reenvío.
A continuación, abra http://127.0.0.1:3080 en el navegador local. Si el puerto 3080 ya está ocupado en su portátil, cambie el número de la izquierda: ssh -N -L 3180:127.0.0.1:3080 you@your-server y, después, vaya a http://127.0.0.1:3180. El número de la izquierda es local y el de la derecha corresponde al servidor, por lo que sólo cambia el de la izquierda.
Guárdelo en ~/.ssh/config y deje de escribirlo.
Host dsh
HostName 203.0.113.10
User deploy
IdentityFile ~/.ssh/id_ed25519
LocalForward 3080 127.0.0.1:3080Después, ssh -N dsh inicia el túnel. Si el navegador informa de que se rechazó la conexión, normalmente significa que el túnel está activo, pero que no hay nada escuchando en el extremo remoto, porque SSH reenvía el puerto independientemente de que el harness esté en ejecución. Compruebe el servidor con el comando ss anterior.
Mantenga el harness en ejecución después de cerrar la sesión
Un comando npx termina junto con el shell. Un servicio de usuario de systemd sobrevive y vuelve a iniciar el harness después de un error o un reinicio. La unidad de esta sección es deliberadamente mínima. Si quiere ejecutar el harness con una cuenta propia restringida, fijar la versión dentro de la unidad y disponer de registros que se puedan buscar, la configuración de systemd sin interfaz de dsh lo explica en detalle.
loginctl enable-linger $USER
mkdir -p ~/.config/systemd/user
command -v dshenable-linger es importante porque los servicios de usuario normalmente se detienen cuando termina la última sesión. Sin esta opción, el harness termina en cuanto se cierra el túnel. Tome la ruta absoluta que muestra command -v dsh e inclúyala en la unidad, porque systemd no busca en el PATH que construye el shell de inicio de sesión.
[Unit]
Description=DeepSeek Harness web UI
After=network-online.target
[Service]
Type=simple
WorkingDirectory=%h/projects/site
ExecStart=/usr/local/bin/dsh web
Restart=on-failure
RestartSec=5
[Install]
WantedBy=default.targetWorkingDirectory no es un detalle estético. El proceso dsh usa el directorio desde el que se inicia como ubicación predeterminada del sistema de archivos. Por tanto, un servicio iniciado en el directorio incorrecto proporciona al agente un espacio de trabajo predeterminado equivocado. Aun así, puede seleccionar el espacio de trabajo en la interfaz de usuario.
systemctl --user daemon-reload
systemctl --user enable --now dsh
systemctl --user status dshUna unidad que no se inicia casi siempre tiene una ruta ExecStart incorrecta o una versión de Node que el binario rechaza. journalctl --user -u dsh -n 50 indica cuál es el problema. El mismo patrón sirve para mantener cualquier agente de programación en ejecución en un VPS, y los modos de fallo son idénticos.
Qué puede hacer un plugin
Un plugin es un módulo que aporta servicios, eventos tipados y efectos reversibles a un contexto compartido. Conviene revisar con atención los puntos de extensión:
- registrar un proveedor de modelos en
ctx.llm - añadir herramientas orientadas al modelo en
ctx.tools - proporcionar el backend de shell detrás de
ctx.shell - proporcionar acceso al sistema de archivos o aplicar políticas detrás de
ctx.fs - registrar comandos para usuarios en
ctx.commands - ejecutar tareas en segundo plano mediante
ctx.jobs - envolver los procesos iniciados con un backend
ctx.sandbox - interceptar solicitudes y llamadas a herramientas mediante los eventos
agent/*ytools/* - ampliar el estado persistente de la sesión
- controlar la interfaz de usuario mediante
ctx.agents
Lea esa lista como lo haría un atacante. Un plugin puede proporcionar la capa del sistema de archivos y la capa de shell, y puede situarse entre el modelo y cada llamada a herramienta que este realice. Ningún cuadro de diálogo de permisos se interpone entre un plugin y esos puntos de extensión, porque un plugin es código Node normal que se carga en el mismo proceso que todo lo demás. Instalar un plugin equivale a ejecutar código de un tercero con los permisos de su agente, y los permisos del agente son los permisos de su usuario de Unix.
Esta es la misma decisión de confianza que toma al conectar un servidor MCP a un agente en un VPS, donde MCP significa protocolo de contexto del modelo. Por eso ejecutar un agente de programación de forma segura en un VPS empieza por la cuenta con la que se ejecuta, no por el modelo. También explica por qué los ataques a la cadena de suministro de npm afectan tanto a los servidores: el paso de instalación es la intrusión y no aparece ninguna solicitud de confirmación.
De dónde proceden los plugins
Los plugins se almacenan en perfiles. Un perfil es una composición con nombre que se guarda en $DSH_HOME, cuyo valor predeterminado es ~/.dsh, y cada directorio de perfil contiene los plugins externos que instala. La CLI los gestiona reenviando los argumentos directamente a pnpm y usando el directorio del perfil como directorio de trabajo.
dsh plugin --profile web add github:deepseek-harness/turtle-ui
dsh plugin --profile web remove turtle-uiComo los argumentos llegan a pnpm sin cambios, add, remove, update y why funcionan igual que en cualquier proyecto de pnpm, y un plugin puede ser un paquete de npm o una referencia de GitHub. pnpm debe estar primero disponible en PATH. En Node 22 y versiones posteriores, corepack enable pnpm lo coloca allí.
La búsqueda se realiza mediante un topic de GitHub. Los autores de plugins añaden el topic dsh-plugin a su repositorio, y consultar ese topic es la forma de encontrar los plugins disponibles. Un topic es una etiqueta que el autor aplica a su propio repositorio. Nadie lo revisa ni lo firma, y la página del topic ordena los repositorios por estrellas, que miden la popularidad, no la seguridad.
Cuatro prácticas ayudan a mantener esto bajo control. Lea el código fuente antes de instalar un plugin, porque la mayoría son lo bastante pequeños como para leerlos en diez minutos. Fije la versión o el commit exactos en lugar de seguir una rama. Ejecute el harness con un usuario que no sea propietario de ningún otro recurso, en un VPS que esté dispuesto a reconstruir. Proporcione al agente su propia clave de API y su propio límite de gasto, separados de la clave que usan los servicios de producción. Si va a leer un plugin y quiere saber qué archivos contienen el riesgo, el recorrido para revisar un plugin de dsh explica el manifiesto, el punto de entrada y los puntos de extensión que registra un plugin.
Si prefiere comparar los diseños antes de decidirse por uno, el arnés multiagente de Omnigent resuelve el mismo problema con una estructura diferente. Las ventajas y desventajas se hacen evidentes cuando entran en juego los plugins. Si termina manteniendo dos o tres en el mismo equipo en lugar de elegir uno, poner todos los arneses detrás de una API autoalojada evita necesitar un túnel por puerto, a cambio de añadir otro servicio que debe enlazarse a loopback y configurarse con una contraseña real desde el primer día.
Qué falla primero
Node es demasiado antiguo. El proyecto requiere Node 22.19 y versiones posteriores de la línea 22.x, o Node 24 y posteriores, y su CI prueba esas versiones. Un entorno de ejecución más antiguo falla al iniciar porque el código usa sintaxis y API que no están disponibles en él. Ejecute node --version antes de cualquier otra cosa.
El puerto 3080 ya está ocupado. Puede haber un segundo harness, un proceso antiguo o una aplicación no relacionada que también use 3080. Búsquelo con ss -tlnp | grep 3080. Después, deténgalo o inicie el harness en otro puerto con dsh web --port 3180. --port corresponde a la aplicación web, por lo que debe ejecutarse después de web.
El navegador no puede conectarse a través del túnel. Confirme que accedió a 127.0.0.1 y no a la dirección pública del servidor, porque el puerto reenviado sólo existe en su portátil. Después, confirme que el harness está escuchando en el servidor, ya que SSH establece el reenvío aunque no haya ningún proceso respondiendo en el extremo remoto.
dsh plugin falla inmediatamente. El comando es un envoltorio de pnpm, por lo que la ausencia del binario pnpm lo detiene antes de que comience cualquier trabajo de los plugins.
El agente no puede ver su proyecto. El espacio de trabajo usa por defecto el directorio desde el que se inició el proceso. Por tanto, una unidad cuyo WorkingDirectory sea su directorio personal proporciona al agente ese directorio. Seleccione el espacio de trabajo en la interfaz o corrija la unidad y vuelva a cargarla.
FAQ
¿Es seguro exponer la interfaz web de DeepSeek Harness en el puerto 3080?
No. El servidor web no tiene autenticación propia, y el agente que se ejecuta detrás edita archivos y ejecuta comandos de shell como el usuario que inició el proceso. La clave de API del proveedor también se almacena en el mismo disco. Mantenga el listener en 127.0.0.1 y acceda a él mediante un túnel SSH. También puede usar una red overlay privada o un reverse proxy que autentique cada petición antes de que llegue al puerto. Desde la versión 0.1.0-rc.6, la CLI rechaza --host 0.0.0.0 y termina con un error de uso. Esto indica lo que los autores piensan de esa configuración.
¿Necesito una clave de API de DeepSeek o puedo usar un modelo local?
Ambas opciones funcionan porque el harness es un runtime, no un modelo. En Settings y después en Models, puede pegar una clave en la tarjeta de un proveedor del catálogo. También puede elegir "Add a custom provider" e indicar una URL base que use el protocolo compatible con OpenAI. Un servidor local de Ollama responde en http://127.0.0.1:11434/v1/ y acepta cualquier cadena en el campo de la clave de API. Las claves se guardan en $DSH_HOME/.credentials.yaml, cuyo valor predeterminado es ~/.dsh/.credentials.yaml.
¿Qué permisos obtiene realmente un plugin de DeepSeek Harness al instalarlo?
Obtiene los permisos de la cuenta que ejecuta el harness. Un plugin es código Node cargado en el mismo proceso. Sus puntos de extensión incluyen el backend de shell, la capa del sistema de archivos, el registro de herramientas y los eventos que envuelven cada llamada a una herramienta. Nada aísla un plugin de esas interfaces, a menos que el propio plugin proporcione el aislamiento. Lea el código fuente antes de instalarlo y ejecute el harness con un usuario que no sea propietario de nada importante.
¿Qué versión debo instalar y seguirá funcionando?
Instale una versión exacta, por ejemplo npx @deepseek-ai/dsh@0.1.0-rc.6 web. Esa es la versión a la que apuntaba la etiqueta latest el 13 de agosto de 2026. El proyecto se describe como una versión preliminar para desarrolladores y advierte que se esperan cambios incompatibles. Por tanto, un comando sin versión fijada puede comportarse de forma distinta de un día para otro. Revise el repositorio antes de actualizar y espere cambios en las claves de configuración y en las interfaces de los plugins mientras la versión siga comenzando por 0.