Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mamerto — Voice Narrator for Claude Code

Mamerto

Give Claude Code a voice. Hear what it did, not what it wrote.
A Stop hook that synthesizes Claude's response into a short, human summary and speaks it aloud via ElevenLabs TTS. Like a colleague telling you "he's fixed the login bug" while you keep coding.

Quickstart · How it works · Usage · Troubleshooting


Why?

Claude Code writes walls of text. You already have eyes for that. What you don't have is someone telling you what just happened while you keep coding.

Before: Claude responds. You stop what you're doing. You read 40 lines. You go back to coding.

After: Claude responds. You hear "Fixed the login bug and updated the tests". Your eyes never leave the code.

Mamerto doesn't read Claude's output — it synthesizes it. Claude itself distills the response into 1-2 sentences, the way a human would summarize it out loud. Then ElevenLabs speaks it.

How it works

Claude responds
      |
      v
  Stop hook fires --> narrator.py
      |
      |-- 1. Extract final assistant text from the transcript
      |-- 2. Strip markdown (code blocks, links, headers...)
      |-- 3. Synthesize via claude -p --bare (1-2 sentence human summary)
      '-- 4. Send to ElevenLabs TTS --> play audio

The synthesis step calls claude -p --bare to distill the response into what a person would actually say:

  • 40-line explanation becomes "Refactored the auth service, pulled token validation into its own module"
  • Long debugging session becomes "Found the bug — circular import between user service and auth middleware"
  • Code generation becomes "Built the payment component with all three variants you asked for"

Zero extra API cost — it runs through your existing Claude Code plan.

Quickstart

5 minutes. No dependencies. Just Python and Claude Code.

1. Clone and configure

git clone https://github.com/jlcases/mamerto.git
cd mamerto
chmod +x narrator.py narrator

Create a .env file with your ElevenLabs credentials:

ELEVENLABS_API_KEY=your_api_key_here
ELEVENLABS_VOICE_ID=your_voice_id_here

Get your API key at elevenlabs.io. Find the voice ID in the URL when you select a voice in the dashboard.

2. Register the Stop hook

Add this to ~/.claude/settings.json:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "/absolute/path/to/mamerto/narrator.py"
          }
        ]
      }
    ]
  }
}

If you already have other settings in that file, just merge the hooks section.

3. Install the Skill (optional)

The skill lets you toggle narration with /narrator on and /narrator off inside Claude Code.

mkdir -p ~/.claude/skills/narrator
cat > ~/.claude/skills/narrator/SKILL.md << 'SKILL'
---
name: narrator
description: Toggle voice narration on or off. Use when the user says "narrator on", "narrator off", "turn narration on/off", or any request to enable/disable voice narration.
---

# Narrator Toggle

Run the toggle script and report the result:

| Intent  | Command                            |
| ------- | ---------------------------------- |
| Enable  | `/path/to/mamerto/narrator on`     |
| Disable | `/path/to/mamerto/narrator off`    |
| Toggle  | `/path/to/mamerto/narrator toggle` |
| Status  | `/path/to/mamerto/narrator status` |

Reply with one line confirming the new state.
SKILL

Replace /path/to/mamerto with your actual path.

4. Try it

You: /narrator on
Claude: Narrator: ON

You: explain how the auth middleware works
Claude: [text response + you hear a spoken summary]

You: /narrator off
Claude: Narrator: OFF

How it's built

Built entirely with Claude Code primitives — no framework, no external orchestrator:

File What it does
narrator.py Stop hook — extracts text, synthesizes via Claude, sends to TTS
narrator Bash toggle — creates/removes the flag file ~/.claude/narrator_enabled
.env ElevenLabs credentials (gitignored)

Anti-recursion guard

The synthesis step calls claude -p, which could trigger the Stop hook again. A lock file (/tmp/narrator_humanizing.lock) prevents the loop: the hook checks for it on startup and exits immediately if present.

Graceful fallback

If claude -p fails (timeout, CLI not found), narration falls back to the cleaned text directly.

Requirements

  • macOS — uses afplay for audio playback
  • Claude Code CLI — installed and authenticated
  • ElevenLabs account — free tier works fine
  • Python 3.10+ — zero pip dependencies, stdlib only

Troubleshooting

tail -20 /path/to/mamerto/narrator.log
Symptom Fix
No audio after enabling Check .env has valid ELEVENLABS_API_KEY and ELEVENLABS_VOICE_ID
Hook not firing Verify path in settings.json is absolute and narrator.py is executable
Narration says unrelated things Make sure you have the latest narrator.py with --bare in the synthesis call
Slow narration Normal — synthesis adds ~3s. If too slow, it falls back to raw text

License

MIT


"I don't just read code... I narrate brilliance." — Mamerto

About

Give Claude Code a voice. Stop hook that synthesizes every response into a human summary and speaks it via ElevenLabs TTS. Zero dependencies.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages