sbeardsley/dev-say
If you are the rightful owner of dev-say and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
The macOS Say MCP Server is a text-to-speech server that leverages the macOS 'say' command to provide speech synthesis capabilities, allowing integration with Claude Code in devcontainers.
@squirrelsoft/dev-say
An MCP (Model Context Protocol) server that provides text-to-speech functionality using the macOS say command. This allows Claude Code running in a devcontainer to trigger speech synthesis on your Mac host.
Features
- Convert text to speech using macOS native
saycommand - Choose from available system voices
- Adjust speech rate
- Save audio to file (AIFF format)
- Works seamlessly with Claude Code in devcontainers
Prerequisites
- macOS (required - uses the native
saycommand) - Node.js 16+
- npm or yarn
Installation
Global Installation via npm
npm install -g @squirrelsoft/dev-say
Local Installation from Source
- Clone this repository on your Mac host:
git clone https://github.com/sbeardsley/dev-say.git
cd dev-say
- Install dependencies:
npm install
- Build the TypeScript code:
npm run build
- Link globally (optional):
npm link
Quick Start
After installing globally with npm, you can manage the server with these simple commands:
# Start the server (runs in background on port 8837)
dev-say start
# Stop the server
dev-say stop
# Check if server is running
dev-say status
# Restart the server
dev-say restart
# View server logs
dev-say logs
The server will run in the background and automatically log to ~/.dev-say.log.
Usage
Running the Server
Using the CLI (Recommended)
Once installed globally via npm install -g @squirrelsoft/dev-say:
# Start the server in the background
dev-say start
# Stop the server
dev-say stop
# Check server status
dev-say status
# Restart the server
dev-say restart
# View logs
dev-say logs
Manual Mode
The server supports two transport modes:
HTTP Mode (for Devcontainer/Remote Access)
# Default mode - runs HTTP server on port 8837
npm start
# Or explicitly set HTTP mode
MCP_TRANSPORT=http PORT=8837 npm start
Stdio Mode (Legacy)
MCP_TRANSPORT=stdio npm start
For development with hot reload:
npm run dev
Configuration
For Claude Code in Devcontainer
- Start the server on your Mac host:
If installed globally:
dev-say start
Or manually:
cd /path/to/dev-say
npm install
npm run build
npm start # Runs HTTP server on port 8837
- Configure Claude Code inside the devcontainer:
Use the Claude Code CLI to add the MCP server:
claude mcp add --transport http dev-say http://host.docker.internal:8837/mcp
Alternatively, you can manually add to your MCP settings (typically ~/.config/claude/settings.json in the container):
{
"mcpServers": {
"dev-say": {
"url": "http://host.docker.internal:8837/mcp",
"transport": "http"
}
}
}
Important: The server uses the MCP Streamable HTTP transport which requires:
- Proper Accept headers (
application/json, text/event-stream) - Session management via
Mcp-Session-Idheader - Initialize request to start a session
Claude Code should handle this automatically when configured with "transport": "http".
The host.docker.internal hostname automatically resolves to your Mac host from within the Docker container.
For Local Claude Code on Mac
- Start the server on your Mac:
If installed globally:
dev-say start
Or manually:
cd /path/to/dev-say
npm install
npm run build
npm start # Runs HTTP server on port 8837
- Configure Claude Code:
Use the Claude Code CLI to add the MCP server:
claude mcp add --transport http dev-say http://localhost:8837/mcp
Alternatively, you can manually add to your Claude Code MCP settings (~/Library/Application Support/Claude/claude_code_config.json):
{
"mcpServers": {
"dev-say": {
"url": "http://localhost:8837/mcp",
"transport": "http"
}
}
}
Available Tools
The server exposes a single speak tool with the following parameters:
- text (required): The text to speak
- voice (optional): The voice to use (run
say -v ?in terminal to see available voices) - rate (optional): Speech rate in words per minute (default: 175)
- outputFile (optional): Path to save audio file instead of playing
Example Usage in Claude Code
Once configured, you can use the speak tool in Claude Code:
Use the speak tool to say "Hello, world!"
With options:
Use the speak tool to say "Hello" with voice "Samantha" at rate 200
Save to file:
Use the speak tool to save "This is a test" to output.aiff
Available Voices
To see all available voices on your system, run:
say -v ?
Popular voices include:
- Alex (US English)
- Samantha (US English)
- Daniel (British English)
- Karen (Australian English)
- Tessa (South African English)
Troubleshooting
Devcontainer Connection Issues
Server not accessible from container
- Ensure the server is running on your Mac:
npm start - Check the server is listening on all interfaces: should show
0.0.0.0:8837 - Test connectivity from container:
curl http://host.docker.internal:8837/health - Verify Docker Desktop settings allow host networking
MCP configuration not working
- Check Claude Code settings location in your container
- Verify the curl command can reach the server
- Look for error messages in Claude Code logs
General Issues
Server not connecting
- Ensure the path in your MCP config is absolute and correct
- Check that the server builds successfully with
npm run build - Verify Node.js is in your PATH
No sound output
- Check your Mac's volume settings
- Ensure the
saycommand works in terminal:say "test" - Verify you're running on macOS (not Linux/Windows)
Voice not found
- Use
say -v ?to list available voices - Voice names are case-sensitive
Testing the Server
Test HTTP endpoint directly:
# From your Mac
curl -X POST http://localhost:8837/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/list","params":{},"id":1}'
# From devcontainer
curl -X POST http://host.docker.internal:8837/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/list","params":{},"id":1}'
Test health endpoint:
curl http://localhost:8837/health
Development
Project Structure
dev-say/
├── bin/
│ └── cli.js # CLI commands (start/stop/status)
├── src/
│ └── server.ts # MCP server implementation
├── dist/ # Compiled JavaScript (generated)
├── package.json # Dependencies and scripts
├── tsconfig.json # TypeScript configuration
└── README.md # This file
Building
npm run build
Testing Locally
You can test the say command directly:
say "Hello, world!"
say -v Samantha "Hello"
say -r 300 "Fast speech"
say -o output.aiff "Save to file"
License
MIT