Isimud
Haz que tu agente te hable (solo OSX)
Documentación
isimud
isimud es una app de la barra de menús de macOS y un servidor MCP de HTTP transmisible que permite hablar a los agentes de IA. Un agente envía texto a una herramienta MCP; isimud resuelve una voz con nombre, sintetiza el habla mediante Apple, OpenAI o Google, y luego la reproduce a través de una única cola de habla serializada.
isimud es la contraparte de texto a voz de muninn, que convierte el habla en texto para los agentes.
Usa isimud cuando quieras:
- Una app local de bandeja de macOS que pulse mientras un agente está hablando.
- Un servidor MCP sin interfaz gráfica para uso mediante scripts o en segundo plano.
- Texto a voz local primero, con proveedores en la nube opcionales con tu propia clave.
- Voces con nombre que ocultan los ID de voz específicos del proveedor a los agentes.
- Cola, cancelación, estado y notificaciones del ciclo de vida del habla a través de MCP.
Inicio rápido
Completa esta ruta para ejecutar isimud con el proveedor local de texto a voz de Apple. El TTS de Apple no requiere una clave de API.
Requisitos previos
- macOS. El proyecto es solo para macOS; la app empaquetada declara macOS 12.0 o posterior.
- Rust 1.89 o posterior y Cargo.
- Un cliente MCP que admita HTTP transmisible.
Instalar
Instala el crate binario publicado:
cargo install isimud-text-to-speech
Verifica que Cargo haya instalado el binario isimud:
isimud --version
O compila desde este repositorio:
cargo build --release --bin isimud
./target/release/isimud --version
Configurar
isimud crea una configuración predeterminada ejecutable en el primer arranque si no existe ningún archivo de configuración. Esa configuración generada contiene una única voz default respaldada por Apple. Para comenzar con la configuración de muestra completa, crea el directorio de configuración y copia la muestra:
mkdir -p ~/.config/isimud
cp configs/config.sample.toml ~/.config/isimud/config.toml
La precedencia de la ruta de configuración es:
ISIMUD_CONFIG$XDG_CONFIG_HOME/isimud/config.toml~/.config/isimud/config.toml
Ejecutar
Inicia la app de la barra de menús y el servidor MCP:
isimud
Para operación solo de servidor:
isimud --headless
Opciones de CLI:
--headless Run only the MCP server
-h, --help Print help
-V, --version Print the version
Resultado esperado:
- En el modo de barra de menús, aparece un pequeño indicador de isimud en la barra de menús de macOS.
- El servidor MCP escucha en
http://127.0.0.1:3654/mcp. - Llamar a
isimud.statusdesde tu cliente MCP devuelvestate: "idle"cuando no se está hablando.
Conectar un cliente MCP
Configura tu cliente MCP con transporte HTTP transmisible:
URL: http://127.0.0.1:3654/mcp
Si estableces ISIMUD_AUTH_TOKEN o [server].auth_token, agrega este encabezado de solicitud:
Authorization: Bearer <TOKEN>
El servidor solo se vincula a direcciones IP de bucle local. Se aceptan 127.0.0.1 y ::1; los nombres de host como localhost y las direcciones que no son de bucle local como 0.0.0.0 se rechazan al inicio.
Cuando la autenticación está configurada, las solicitudes sin el token de portador exacto devuelven HTTP 401.
Hablar desde un agente
Llama a isimud.speak con texto:
{
"text": "Build finished.",
"voice": "default",
"rate": 1.0
}
La llamada regresa inmediatamente de forma predeterminada:
{
"job_id": "00000000-0000-0000-0000-000000000000",
"queue_depth": 0
}
Establece wait en true cuando el llamador MCP deba bloquearse hasta que la emisión se complete, falle, se cancele o alcance [tts].wait_timeout_secs:
{
"text": "Deployment complete.",
"wait": true
}
Con wait=true, la respuesta incluye outcome:
{
"job_id": "00000000-0000-0000-0000-000000000000",
"queue_depth": 0,
"outcome": "completed"
}
Configurar voces y proveedores
Las voces con nombre son el contrato de voz público para los agentes. El argumento voice de isimud.speak y [tts].default_voice debe coincidir con una clave de [voices.<name>].
[tts]
providers = ["apple", "openai", "google"]
default_voice = "default"
rate = 1.0
max_queue_depth = 64
wait_timeout_secs = 0
[voices.default]
provider = "apple"
voice = "Samantha"
[voices.narrator]
provider = "openai"
voice = "onyx"
[voices.googler]
provider = "google"
voice = "en-US-Neural2-C"
language = "en-US"
Importante: default_voice es un nombre de voz, no un nombre de proveedor. Para hacer de OpenAI el predeterminado, establece default_voice = "narrator" o crea otro bloque [voices.<name>] cuyo provider = "openai".
Los campos opcionales por voz son language, rate, pitch y volume. Una solicitud rate anula la rate de la voz, que a su vez anula [tts].rate; la volume de la voz tiene como valor predeterminado 1.0.
La disponibilidad de proveedores sigue a [tts].providers. Si el proveedor de la voz solicitada no está disponible, isimud selecciona el primer proveedor de respaldo disponible y descarta el ID de voz específico del proveedor para esa emisión de respaldo. Si no hay ningún proveedor disponible, el trabajo falla y emite un evento failed.
Configuración de proveedores
| Proveedor | Credenciales | Comportamiento |
|---|---|---|
| Apple | Ninguna | Usa el comando say de macOS, reproduce en línea y enumera las voces instaladas con AVSpeechSynthesisVoice. |
| OpenAI | OPENAI_API_KEY o [providers.openai].api_key | Llama a POST /v1/audio/speech, solicita el formato de respuesta configurado y reproduce el audio devuelto mediante rodio. |
GOOGLE_API_KEY o [providers.google].api_key | Llama a Google Cloud Text-to-Speech text:synthesize, decodifica audioContent y reproduce el audio devuelto mediante rodio. |
OpenAI y Google envían un valor de velocidad/ritmo solo cuando la velocidad resuelta está dentro de 0.25..=4.0. Google envía el tono solo cuando el tono resuelto está dentro de -20..=20.
ID de voz integrados de OpenAI expuestos por isimud.list_voices:
alloy ash ballad cedar coral echo fable marin nova onyx sage shimmer verse
El listado de voces de Google es intencionalmente de mejor esfuerzo y actualmente devuelve un catálogo de proveedores vacío; las voces de Google configuradas con nombre siguen funcionando.
Referencia de configuración
Consulta configs/config.sample.toml para ver la muestra completa.
| Configuración | Predeterminado | Descripción |
|---|---|---|
[app].menubar | true | Ejecuta la app de bandeja de macOS. --headless desactiva la bandeja para ese proceso. |
[app].autostart | false | Sincroniza un LaunchAgent de macOS por usuario que inicia el ejecutable actual al iniciar sesión. |
[server].host | "127.0.0.1" | Host de enlace de bucle local. Debe analizarse como una dirección IP. |
[server].port | 3654 | Puerto HTTP de MCP. |
[server].path | "/mcp" | Ruta HTTP transmisible de MCP. |
[server].auth_token | sin establecer | Token de portador opcional. ISIMUD_AUTH_TOKEN tiene prioridad. |
[tts].providers | ["apple", "openai", "google"] | Orden de respaldo de proveedores. |
[tts].default_voice | "default" | Nombre de la entrada [voices.<name>] predeterminada. |
[tts].rate | 1.0 | Multiplicador de velocidad de habla neutro. |
[tts].max_queue_depth | 64 | Número de trabajos permitidos detrás de la emisión activa. 0 desactiva el límite. |
[tts].wait_timeout_secs | 0 | Tiempo de espera para llamadas a wait=true. 0 espera para siempre. |
[indicator.colors.*] | Paleta gris/verde del sistema de Apple | Colores del indicador de la barra de menús. Los valores deben ser cadenas hexadecimales #RRGGBB. |
El esquema TOML es estricto. Los campos desconocidos hacen fallar el análisis de configuración; la recarga en caliente mantiene la configuración anterior cuando un archivo modificado no se analiza o valida.
Variables de entorno:
| Variable | Propósito |
|---|---|
ISIMUD_CONFIG | Anula la resolución de la ruta de configuración. |
ISIMUD_AUTH_TOKEN | Anula [server].auth_token. |
ISIMUD_LOAD_DOTENV=0 | Desactiva la carga de inicio de ./.env desde el directorio de trabajo actual. También acepta false o no. |
OPENAI_API_KEY | Habilita el proveedor de OpenAI. |
GOOGLE_API_KEY | Habilita el proveedor de Google. |
RUST_LOG | Anula [logging].level; los objetivos útiles son runtime, server, provider, config y speech. |
Las variables de entorno del shell tienen prioridad sobre .env y los secretos del archivo de configuración.
Referencia de herramientas MCP
| Herramienta | Parámetros | Resultado |
|---|---|---|
isimud.speak | text obligatorio; opcionales voice, rate, wait | job_id, queue_depth; con wait=true, también outcome y error opcional. |
isimud.stop | ninguno | Cancela el trabajo activo si existe y limpia los trabajos en cola. Devuelve cancelled_job y cleared. |
isimud.list_voices | ninguno | Enumera las voces con nombre configuradas y los catálogos de voces de los proveedores. |
isimud.status | ninguno | Devuelve state, job_id activo, voice, provider, queue_depth y degraded. |
isimud.speak rechaza texto vacío y voces con nombre desconocidas como parámetros no válidos. Cuando la cola está llena, devuelve el código de error JSON-RPC -32010 con esta carga útil de datos:
{
"queue_depth": 64,
"capacity": 64
}
Los pares MCP conectados reciben notificaciones personalizadas isimud/speech_event para estos eventos del ciclo de vida:
enqueued started finished failed stopped degraded
Las solicitudes MCP personalizadas denominadas isimud/quit o isimud/exit activan un apagado ordenado.
Comportamiento en tiempo de ejecución
isimud ejecuta un único trabajador de habla. Los trabajos nunca se superponen; cada emisión aceptada espera a que la emisión actual termine o se cancele.
El trabajo activo no cuenta para [tts].max_queue_depth. Esa configuración solo limita los trabajos que esperan detrás de la emisión activa.
Guardar el archivo de configuración recarga en caliente el motor de habla y la paleta de la bandeja. Los cambios válidos actualizan voces, credenciales de proveedores, velocidades de habla, configuración de cola y colores de la bandeja sin reiniciar. Las ediciones no válidas se registran y la configuración anterior permanece activa.
La configuración de enlace del servidor ([server].host, [server].port, [server].path y autenticación) y la sincronización de inicio automático del LaunchAgent se aplican al inicio. Reinicia isimud después de cambiar esas configuraciones.
El icono de la bandeja de macOS es gris cuando está inactivo y pulsa en verde mientras habla. Si el trabajador de habla sale inesperadamente o un trabajo entra en pánico, isimud.status informa degraded: true y se transmite un evento degraded.
Funciones de la app de macOS
Esquema de URL
La app empaquetada registra el esquema de URL isimud://. Úsalo para poner en cola el habla desde enlaces de macOS o automatización:
isimud://speak/Hello%20world
isimud://speak?text=Hello%20world&voice=narrator&rate=1.25
El texto de la ruta tiene prioridad sobre el parámetro de consulta text cuando ambos están presentes. El esquema de URL está disponible al ejecutar el .app empaquetado que incluye la entrada CFBundleURLTypes.
Clic en la bandeja
En el modo de barra de menús, un clic izquierdo en el icono de la bandeja intenta ejecutar el comando opcional fortune y hablar su salida. Si fortune no está instalado o no devuelve texto, el clic se ignora y se registra una advertencia.
Inicio automático
Establece [app].autostart = true para sincronizar un LaunchAgent por usuario en ~/Library/LaunchAgents/com.bnomei.isimud.plist. El LaunchAgent usa la ruta del ejecutable actual y establece ISIMUD_CONFIG en la ruta de configuración resuelta.
Al ejecutar el .app empaquetado, prefiere los elementos de inicio de sesión de macOS si deseas un comportamiento de inicio tipo app.
Empaquetado
Compila un binario de lanzamiento para un objetivo:
TARGET=aarch64-apple-darwin scripts/build-release.sh
Compila un paquete de app de macOS y un archivo zip a partir de un binario de lanzamiento existente:
TARGET=aarch64-apple-darwin scripts/package-macos-app.sh
Si compilaste el objetivo host predeterminado con cargo build --release --bin isimud, ejecuta scripts/package-macos-app.sh sin TARGET.
Variables de empaquetado útiles:
| Variable | Predeterminado | Descripción |
|---|---|---|
BIN_NAME | isimud | Nombre del binario copiado en el paquete de la app. |
PRODUCT_NAME | Isimud | Nombre del producto del paquete de la app. |
BUNDLE_IDENTIFIER | com.bnomei.isimud | Identificador de paquete de macOS. |
TARGET | sin establecer | Selecciona target/<TARGET>/release/isimud como ruta del binario. |
BIN_PATH | sin establecer | Ruta explícita del binario. Anula TARGET. |
ICON_PATH | packaging/macos/Isimud.icns | Icono opcional copiado en el paquete de la app cuando está presente. |
CODESIGN_APP | 1 | Firma ad-hoc con codesign --sign -. Establécelo en 0 si codesign no está disponible. |
ZIP_APP | 1 | Establécelo en 0 para omitir la creación del zip. |
Crea un archivo de lanzamiento tar a partir de un objetivo compilado:
VERSION=$(scripts/resolve-version.sh) TARGET=aarch64-apple-darwin scripts/package-release.sh
Desarrollo
Ejecuta las comprobaciones principales:
cargo test
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
Este repositorio también incluye hooks de prek:
prek install
prek run --all-files
Limitaciones actuales
- macOS es la única plataforma compatible.
- El servidor MCP solo admite HTTP transmisible; no hay transporte stdio.
- El servidor se vincula únicamente a direcciones de loopback.
- Apple
sayrespetaratepero no aplicavolumenipitch. - Los tiempos de espera de solicitudes de OpenAI y Google se dejan al cliente HTTP y al comportamiento del proveedor/red.
[tts].wait_timeout_secssolo limita cuánto tiempo espera una llamada MCPwait=truepor el resultado del trabajo; no cancela la síntesis. - isimud valida que
textno esté vacío, pero no impone un límite fijo de caracteres, bytes, tokens o tamaño de respuesta del proveedor. - El audio del proveedor de nube se decodifica y reproduce en memoria, por lo que expresiones muy largas pueden aumentar el uso de memoria y la latencia de reproducción.
Mapa de fuentes
- Carga de configuración y valores predeterminados: src/config.rs
- Herramientas MCP y distribución de notificaciones: src/mcp.rs
- Servidor HTTP y aplicación de loopback/autenticación: src/server.rs
- Resolución de voces nombradas: src/voices.rs
- Cola de voz y trabajador: src/worker.rs
- Registro de proveedores y respaldo: src/providers/mod.rs
- Comportamiento de la bandeja de macOS: src/runtime_tray.rs
- Análisis de esquema de URL: src/url_scheme.rs
- Plantilla de paquete de aplicación macOS: packaging/macos/Info.plist.template
Licencia
MIT. Ver LICENSE.