Metadata-Version: 2.4
Name: glados-voice-mcp
Version: 0.1.0
Summary: Warm, shared GLaDOS text-to-speech server with an MCP interface for agents
Author: Bruno Meneguello
License-Expression: MIT
Project-URL: Homepage, https://github.com/bkmeneguello/glados-voice-mcp
Project-URL: Repository, https://github.com/bkmeneguello/glados-voice-mcp
Project-URL: Issues, https://github.com/bkmeneguello/glados-voice-mcp/issues
Keywords: mcp,model-context-protocol,tts,text-to-speech,glados,voice,agents
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE.md
Requires-Dist: numpy<3,>=1.26
Requires-Dist: sounddevice<1,>=0.5
Requires-Dist: num2words<1,>=0.5
Requires-Dist: platformdirs<5,>=4
Requires-Dist: mcp<3,>=2
Provides-Extra: cpu
Requires-Dist: onnxruntime; extra == "cpu"
Provides-Extra: cuda
Requires-Dist: onnxruntime-gpu<2,>=1.31.1; extra == "cuda"
Requires-Dist: nvidia-cuda-runtime; extra == "cuda"
Requires-Dist: nvidia-cublas; extra == "cuda"
Requires-Dist: nvidia-cudnn-cu13; extra == "cuda"
Requires-Dist: nvidia-cufft; extra == "cuda"
Requires-Dist: nvidia-curand; extra == "cuda"
Dynamic: license-file

# glados-voice-mcp

A warm, shared GLaDOS text-to-speech server for agents, exposed as an [MCP](https://modelcontextprotocol.io) tool.
It builds on [nimaid/GLaDOS-TTS](https://github.com/nimaid/GLaDOS-TTS), included unmodified as a git submodule.

> **Using an AI agent?** Point it at this repository and ask it to follow [`AGENTS.md`](AGENTS.md); it contains every step to install, register and verify the server.

- **Fast:** about 100 ms to first audio once the models are loaded; text is split into sentences and the first one plays while the rest is still being synthesized.
- **Lazy and shared:** the MCP process is a thin proxy. The first `speak` starts one shared daemon (`127.0.0.1:18765`) that loads the models, serves every agent on one audio device, and exits after 10 minutes without requests or speech.
- **In character:** the persona is part of the tool description and `speak` rejects calls with `in_character=false`. The server cannot verify the style of the text itself.
- **One voice at a time:** if a message is loading or playing, `speak` returns `BUSY ... Retry in about N seconds` so agents never talk over each other. `speak` with empty text cuts speech for everyone.

## Install

No clone or project directory is needed: [uv](https://docs.astral.sh/uv/) installs the [`glados-voice-mcp`](https://pypi.org/project/glados-voice-mcp/) package from PyPI. Pick exactly one onnxruntime extra: `cpu` or `cuda` (NVIDIA, CUDA 13 wheels).

```bash
# 1. Build the environment and download the models once (about 125 MB, stored in your user data dir)
uvx --from "glados-voice-mcp[cpu]@latest" glados-voice download-models

# 2. Try it (plays audio)
uvx --from "glados-voice-mcp[cpu]@latest" glados-voice say "Hello, test subject."
```

Prefer a persistent command? `uv tool install "glados-voice-mcp[cpu]"` or `pipx install "glados-voice-mcp[cpu]"` puts `glados-voice-mcp` on your `PATH`. To develop, clone with `git clone --recurse-submodules https://github.com/bkmeneguello/glados-voice-mcp` and run `uv pip install ".[cpu]"` in a venv.

## Register the MCP server

```bash
claude mcp add glados-voice -- uvx --from "glados-voice-mcp[cpu]@latest" glados-voice-mcp
```

For other clients use the command `uvx` with the arguments `--from "glados-voice-mcp[cpu]@latest" glados-voice-mcp`; [`AGENTS.md`](AGENTS.md) has Codex, Gemini and JSON examples.

Tool: `speak(text, in_character, wait=false)`. Empty `text` stops the current speech.

## Configuration (environment variables)

| Variable | Default | Meaning |
|---|---|---|
| `GLADOS_IDLE_SECONDS` | `600` | Idle time before the daemon exits and unloads the models |
| `GLADOS_PORT` | `18765` | Localhost port of the shared daemon |
| `GLADOS_BACKEND` | `cpu` | `cpu` (lowest latency for sentences), `cuda`, or `auto` (CPU for short chunks, CUDA for long) |
| `GLADOS_MODELS_DIR` | OS user data dir | Model files, e.g. `%LOCALAPPDATA%\glados-voice\models` on Windows, `~/.local/share/glados-voice/models` on Linux |

The daemon log is `glados_voice_daemon.log` in the system temp directory. The daemon accepts requests from any local process and has no authentication, but it rejects browser requests (`Origin` header, non-JSON `Content-Type`, foreign `Host`).

## Python use

```python
from glados_voice import VoiceEngine

engine = VoiceEngine().start()   # loads in the background
engine.speak("Hello. This is a test.")
engine.wait_idle()
```

## Credits and license

The code is MIT, see `LICENSE` and `NOTICE.md` for third-party notices.

- **Voice models:** they come from [dnhkng/GlaDOS](https://github.com/dnhkng/GlaDOS) and are downloaded at first use. They are not stored or distributed in this repository and are not covered by its MIT license. The voice imitates a character and recordings owned by Valve Corporation, so it is for personal, non-commercial fan use only.
- **Unofficial:** GLaDOS and Portal belong to Valve Corporation; this project is not affiliated with or endorsed by Valve.
- **`cuda` extra:** it installs proprietary NVIDIA libraries from PyPI under NVIDIA's license terms. The `cpu` extra does not.
