Cuando tu servidor no tiene micrófono
بِسْمِ ٱللَّهِ ٱلرَّحْمَـٰنِ ٱلرَّحِيمِ
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:
- Dile a tu daemon de audio local que acepte conexiones por TCP
- Usa la función de túnel inverso de SSH para reenviar ese puerto a la máquina remota
- 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:
cp /usr/share/pipewire/pipewire-pulse.conf ~/.config/pipewire/pipewire-pulse.confLuego 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:
systemctl --user restart pipewire pipewire-pulseEsto 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:
ssh -R 4713:127.0.0.1:4713 user@your-serverEsto 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:
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:
sudo apt install libasound2-plugins pulseaudio-utilsPaso 5: Probarlo
Aún en el remoto, ejecuta:
pactl infoSi 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:
ssh -R 4713:127.0.0.1:4713 your-serverSSH 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 remoto — PULSE_SERVER debería estar en ~/.zshrc (o ~/.bashrc):
echo "export PULSE_SERVER='tcp:127.0.0.1:4713'" >> ~/.zshrcPara 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:4713Ahora 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ónde | Comando |
|---|---|---|
| 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 audio | Remoto (~/.zshrc) | export PULSE_SERVER='tcp:127.0.0.1:4713' |
| Arreglar ALSA | Remoto (~/.asoundrc) | pcm.!default { type pulse } |
| Instalar plugins | Remoto | sudo 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í