readless
Claude Code plugin (MCP-based) that speaks status, summaries, and blocker questions out loud — so you can walk away from a long task and still know what's happening.
Three agent-callable tools:
| Tool | When the agent calls it | Spoken length |
|---|---|---|
speak_summary(headline, details="") |
End of every turn, or when a user-visible task finishes | ≤ 50 words |
speak_status(message) |
Mid-task heartbeat during work expected to run > 2 min (server throttles to 1/min) | ≤ 10 words |
speak_blocker(question) |
Agent is stuck and needs your input. Bypasses quiet hours, interrupts current speech. | ≤ 20 words |
Default TTS backend is edge-tts — Microsoft's free online TTS endpoint. No API key, no signup, no model download, and the default voice zh-CN-XiaoxiaoNeural handles Chinese + English code-switching naturally. Falls back to your OS's built-in voice if the network is unreachable. Optional OpenAI / ElevenLabs backends are available if you want your own voice — keys are entered through a separate CLI so they never touch the Claude conversation.
Install
You need uv (Astral's Python launcher) on PATH — that's it. uv provisions Python automatically, so you do not need to install Python 3.10+ yourself or manage virtualenvs.
# 1. Install uv (skip if you already have it)
curl -LsSf https://astral.sh/uv/install.sh | sh # macOS / Linux
# brew install uv # macOS via Homebrew
# irm https://astral.sh/uv/install.ps1 | iex # Windows PowerShell
Then in Claude Code:
/plugin marketplace add hwjustin/readless
/plugin install readless
/readless:setup
/readless:setup:
- Verifies
uvis on PATH (re-prompts if not) and pre-warmsuvx --from readless-mcp readlessso the first MCP startup is instant. - Asks whether you want the Chinese or English instruction block, then appends it to
~/.claude/CLAUDE.md(marker-bounded, idempotent) so the agent knows to callspeak_summaryat the end of every turn.
After setup, fully restart Claude Code (not just a new chat — close the CLI / IDE host so the new PATH is picked up). /mcp should show readless ✓ Connected.
Why uv? The MCP SDK requires Python ≥3.10. macOS ships 3.9 system-wide, and asking users to install Homebrew Python or manage a venv was the #1 source of "it doesn't work."
uvdownloads a suitable Python on demand into its own cache (~/.cache/uv/), runsreadless-mcpfrom PyPI in isolation, and leaves the system Python untouched. This is the pattern recommended by the official MCP servers repo.
Switching to OpenAI / ElevenLabs (optional)
The default edge-tts backend is good enough for most people. If you want OpenAI or ElevenLabs voices, set the key in your own terminal — don't paste the key into Claude:
# OpenAI
uvx --from 'readless-mcp[openai]' readless-setkey openai # prompts for key, input hidden
# ElevenLabs
uvx --from 'readless-mcp[elevenlabs]' readless-setkey elevenlabs
readless-setkey uses getpass to read the key without echoing it, writes it to ~/.readless/config.yaml (chmod 600), and flips tts_provider for you. Use readless-setkey clear openai (or elevenlabs) to wipe a saved key.
Env vars OPENAI_API_KEY / ELEVENLABS_API_KEY always override the config file if you prefer shell-rc-managed secrets.
Configure
~/.readless/config.yaml is auto-created from defaults on first run. Common edits:
edge_voice: en-US-AriaNeural— pick a different edge-tts voice (edge-tts --list-voicesto list)edge_rate: "+20%"— speed up the default voicetts_provider: system— force OS-native TTS (useful for fully offline machines)system_voice: Tingting— pick a macOS voice (say -v '?'to list)quiet_hours.start / end— opt-in night-silencing forspeak_summary/speak_status(off by default;speak_blockerstill plays even if enabled)tools.speak_status: false(etc.) — disable individual toolsstatus_throttle_seconds: 60— limitspeak_statusrate
See config.example.yaml.
Tune the agent
CLAUDE_EXAMPLE.md is the source of truth for "when should the agent call which tool." Edit your ~/.claude/CLAUDE.md block to make the agent more or less chatty — that's the lever, not the code.
Logs
All tool calls append to ~/.readless/log.jsonl:
{"ts": "2026-05-14T22:30:00+08:00", "kind": "summary", "headline": "构建通过,3 个测试都过了", "details": ""}
License
Apache 2.0 — see LICENSE.
Structure
.claude-plugin/
plugin.json plugin metadata (name, version, description)
marketplace.json /plugin marketplace add metadata
.mcp.json MCP server declaration (uvx --from readless-mcp readless)
commands/
setup.md /readless:setup — ensure `uv` is installed + CLAUDE.md append
src/readless/
server.py FastMCP entry + tool definitions
tts.py edge / system / openai / elevenlabs backends
setkey.py readless-setkey CLI — secure API-key entry
config.py YAML loading + quiet-hours math (built-in YAML fallback)
throttle.py StatusThrottle (1 call/min default)
logger.py JSONL append-only log
CLAUDE_EXAMPLE.md agent instruction blocks (Chinese + English)
Metadata
Release files for readless-mcp 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| readless_mcp-1.1.0.tar.gz | 18.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| readless_mcp-1.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 36.3 kB
Release files / readless_mcp-1.1.0.tar.gz
| Download URL | readless_mcp-1.1.0.tar.gz |
|---|---|
| Size | 18.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
13a8b860a133b6af7d3d7af6210f704047e7d2f643939e02cce2c04f9d10f887
|
|
BLAKE2b-256 checksum How to use checksums |
6f3cf533f11eb8121144d8cda1e42dda5e93fcb41459e39d99cc34f402b9c138
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.20
|
Release files / readless_mcp-1.1.0-py3-none-any.whl
| Download URL | readless_mcp-1.1.0-py3-none-any.whl |
|---|---|
| Size | 17.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a0bf6cbe2986d7d358894a00376bda6c6f8e3a86177b6cdd8517fcc420b6942c
|
|
BLAKE2b-256 checksum How to use checksums |
7df408eed9d52390bf71592e4447d4b6cab82b29ad26cf03e365ae9239afb255
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.20
|