Modo de voz de Claude Code por SSH

Cuando tu servidor no tiene micrófono

08.04.2026 | 20 Shawwal 1447
5 min read

بِسْمِ ٱللَّهِ ٱلرَّحْمَـٰنِ ٱلرَّحِيمِ

Cómo hice funcionar el modo de voz de Claude Code por SSH

He estado ejecutando Claude Code en un servidor Linux remoto por SSH. Es una configuración genial — el servidor tiene más recursos y puedo acceder desde cualquier lugar. Pero cuando intenté usar el modo de voz, me encontré con un muro:

cannot find card '0'

El micrófono no funcionaba. Aquí explico por qué y cómo lo solucioné.

El problema

El modo de voz de Claude Code necesita un micrófono. En tu máquina local es obvio — tienes una tarjeta de sonido, un micrófono y un daemon de audio que lo gestiona todo. Pero mi servidor remoto es exactamente eso: un servidor. Sin tarjeta de sonido, sin micrófono, sin hardware de audio.

Cuando Claude Code intenta acceder al audio, recurre a ALSA (la capa de audio de bajo nivel de Linux), que busca un dispositivo físico. No hay ninguno. De ahí el error.

Por qué esto tiene solución

Lo interesante de Linux es que los sistemas de audio como PipeWire y PulseAudio no están atados al hardware — son daemons que gestionan flujos de audio. Y soportan transparencia de red «de serie». Esto significa que puedes reenviar tu micrófono local a una máquina remota por SSH, de forma limpia y segura.

La solución

La idea es sencilla:

  1. Dile a tu daemon de audio local que acepte conexiones por TCP
  2. Usa la función de túnel inverso de SSH para reenviar ese puerto a la máquina remota
  3. Dile a la máquina remota que use ese túnel como servidor de audio

Vamos paso a paso.

Paso 1: Abre tu servidor de audio local a conexiones TCP

En tu máquina local, copia la configuración predeterminada de PipeWire PulseAudio a tu directorio de usuario:

Terminal window
cp /usr/share/pipewire/pipewire-pulse.conf ~/.config/pipewire/pipewire-pulse.conf

Luego abre ~/.config/pipewire/pipewire-pulse.conf, encuentra el bloque server.address y añade la dirección TCP:

server.address = [
"unix:native"
"tcp:127.0.0.1:4713" # solo localhost — para reenvío de audio por SSH
]

Después reinicia PipeWire:

Terminal window
systemctl --user restart pipewire pipewire-pulse

Esto le dice a PipeWire que escuche en el puerto TCP 4713, pero solo en localhost — así no queda expuesto a la red. Y como está en el archivo de configuración, persiste entre reinicios automáticamente.

Paso 2: SSH con túnel inverso

En lugar de un simple ssh user@server, añade la bandera -R:

Terminal window
ssh -R 4713:127.0.0.1:4713 user@your-server

Esto le dice a SSH: «Todo lo que se conecte al puerto 4713 en la máquina remota, envíalo de vuelta al puerto 4713 de mi máquina local.» El tráfico de audio viaja dentro de la conexión SSH cifrada.

Paso 3: Dile a la máquina remota dónde está el servidor de audio

Una vez conectado al remoto, establece esta variable de entorno:

Terminal window
export PULSE_SERVER="tcp:127.0.0.1:4713"

Ahora cualquier aplicación que use PulseAudio/PipeWire se conectará a ese puerto — que va directo a tu micrófono local.

Paso 4: Arreglar ALSA

Algunas aplicaciones (incluido el fallback de Claude Code) usan ALSA directamente, que no conoce PULSE_SERVER. Crea ~/.asoundrc en la máquina remota:

pcm.!default { type pulse }
ctl.!default { type pulse }

Esto le dice a ALSA: enruta todo a través de PulseAudio en lugar de buscar hardware local. Asegúrate de que el paquete necesario esté instalado:

Terminal window
sudo apt install libasound2-plugins pulseaudio-utils

Paso 5: Probarlo

Aún en el remoto, ejecuta:

Terminal window
pactl info

Si todo funciona, verás la información del servidor de audio de tu máquina local — incluyendo tu micrófono como fuente predeterminada. Esa es la confirmación.

Cómo funciona realmente

Ayuda entender cada pieza por separado antes de ver cómo se conectan.

Cómo funciona PipeWire normalmente

En tu máquina local, PipeWire se ejecuta como un daemon en segundo plano. Posee tu micrófono físico y tus altavoces. Las aplicaciones no hablan directamente con el hardware — se conectan a PipeWire a través de un socket Unix (un archivo como /run/user/1000/pulse/native) y dicen «dame audio». PipeWire se encarga del hardware.

Qué hace el módulo TCP

Normalmente PipeWire solo escucha en ese socket Unix local. Al añadir "tcp:127.0.0.1:4713" a la configuración de PipeWire, le estás diciendo: escucha también en un puerto TCP en localhost. Ahora acepta las mismas peticiones de audio por la red, no solo por el socket local.

Qué hace el túnel SSH

SSH tiene una función llamada reenvío inverso de puertos (-R). Cuando te conectas con:

Terminal window
ssh -R 4713:127.0.0.1:4713 your-server

SSH le dice a la máquina remota: «Todo lo que se conecte a TU puerto 4713, reenvíalo a través de esta conexión SSH a MI puerto 4713.»

Así que el túnel se ve así:

%%{init: {"flowchart": {"useMaxWidth": false}} }%%
graph LR
    A["remote:4713"] ==> B["túnel SSH"] ==> C["localhost:4713 (tu PipeWire)"]

Qué hace PULSE_SERVER

En el remoto, PULSE_SERVER=tcp:127.0.0.1:4713 le dice a cualquier aplicación de audio: «No busques un daemon de audio local — conéctate a esta dirección TCP.»

El panorama completo

Todo junto, la ruta del audio se ve así:

%%{init: {"flowchart": {"useMaxWidth": false}} }%%
graph TD
    A["Claude Code (remoto)"] --> B["tcp:127.0.0.1:4713 en remoto"]
    B --> C["túnel inverso SSH"]
    C --> D["tu PipeWire local en puerto 4713"]
    D --> E["tu micrófono físico"]

Tu voz viaja desde el hardware a PipeWire a socket TCP a túnel SSH a servidor remoto a Claude Code. La máquina remota nunca necesita su propio hardware de audio.

Qué hace .asoundrc

Algunas aplicaciones evitan PulseAudio/PipeWire completamente y hablan con ALSA directamente — la capa de audio de nivel más bajo de Linux. ALSA no sabe de PULSE_SERVER. El archivo ~/.asoundrc soluciona esto diciéndole a ALSA: «Cuando alguien pida el dispositivo de audio predeterminado, enrútalo a través de PulseAudio en lugar de buscar hardware.» Así incluso las aplicaciones basadas en ALSA terminan pasando por el mismo túnel.

Hacerlo permanente

La configuración anterior funciona para una sesión. Para hacerlo permanente:

En el remotoPULSE_SERVER debería estar en ~/.zshrc (o ~/.bashrc):

Terminal window
echo "export PULSE_SERVER='tcp:127.0.0.1:4713'" >> ~/.zshrc

Para SSH — añade RemoteForward a ~/.ssh/config en tu máquina local para no tener que escribir la bandera -R cada vez:

Host your-server
HostName your-server-ip
User your-user
RemoteForward 4713 127.0.0.1:4713

Ahora un simple ssh your-server configura el túnel automáticamente.

Para el módulo TCP local — ya resuelto en el Paso 1. El puerto 4713 se abre automáticamente en cada inicio de sesión.

Resumen

QuéDóndeComando
Módulo TCP (permanente)Local (~/.config/pipewire/pipewire-pulse.conf)Añadir "tcp:127.0.0.1:4713" a server.address
Túnel SSH (permanente)Local (~/.ssh/config)RemoteForward 4713 127.0.0.1:4713 bajo Host your-server
Establecer servidor de audioRemoto (~/.zshrc)export PULSE_SERVER='tcp:127.0.0.1:4713'
Arreglar ALSARemoto (~/.asoundrc)pcm.!default { type pulse }
Instalar pluginsRemotosudo apt install libasound2-plugins pulseaudio-utils

Cinco pasos, sin herramientas de terceros, sin configuración compleja. Simplemente Linux haciendo lo que Linux hace bien.

Ingeniero aeroespacial

Emprendedor ético en público

Tú te ocupas de tu negocio

Yo me encargo del lado digital

Trabaja conmigo
  • IA con honestidad
  • Infraestructura privada
  • Sitios web que rinden

Cuéntame sobre tu situación:

javed@javedab.com Más sobre mí