graindrop
README.md
# graindrop
Audio capture pipeline. Listens for audio files, transcribes via whisper.cpp, and serves audio + transcript through an MCP server.
```
Audio file → graindrop → whisper.cpp → manifest.json → MCP server (:8648)
```
Any MCP-compatible agent (Hermes, Claude Code, Cursor, etc.) connects to the graindrop MCP and discovers new recordings as they land.
## One-sentence pitch
A self-contained daemon that watches a directory, transcribes anything that lands in it, and presents the results to any AI agent through a standard protocol — no cloud, no subscriptions, no vendor lock-in.
## How it works
1. Drop an audio file (`.m4a`, `.wav`, `.mp3`) into the watched directory
2. graindrop copies it to `audio/`, transcribes via whisper.cpp to `transcripts/`, archives the original to `_archive/`, and logs it in `manifest.json`
3. The MCP server exposes the recording to any connected agent through tools and resources
4. The agent reads the transcript, fetches the audio, and does what it does
## Quick start
```bash
# Install
pip install graindrop
# or from source:
git clone https://github.com/stuartmhannon/graindrop
cd graindrop
pip install -e .
# Start the MCP server
graindrop-mcp --port 8648
# The server watches ~/Dropbox/graindrop/ by default
# Drop an .m4a in there and the MCP server picks it up
```
## MCP Tools
| Tool | Purpose |
|---|---|
| `graindrop_list` | List all recordings, newest first |
| `graindrop_list_unread` | List only unacknowledged recordings |
| `graindrop_get_transcript` | Full transcript text for a recording |
| `graindrop_get_audio` | Audio file path for a recording |
| `graindrop_ack` | Mark a recording as read |
| `graindrop_stats` | Summary counts |
## MCP Resources
| URI | Content |
|---|---|
| `graindrop://recording/{id}/transcript` | Plain text transcript |
| `graindrop://recording/{id}/audio` | Binary audio (m4a/wav) |
## Configuration
```bash
graindrop-mcp --port 8648 --dir ~/grain/reference/graindrop
```
- `--port`: HTTP SSE port (default: 8648)
- `--dir`: Data directory (default: `~/grain/reference/graindrop`)
The watched directory defaults to `~/Dropbox/graindrop/`. Override by editing `WATCH_DIR` in `graindrop_mcp.py`.
## Storage layout
```
~/grain/reference/graindrop/
├── audio/{slug}.{ext} ← canonical audio copy
├── transcripts/{slug}.txt ← whisper transcript
├── _archive/{original} ← source file backup
├── manifest.json ← searchable index
├── graindrop_mcp.py ← MCP server
├── graindrop_watcher.py ← processing script
```
## Requirements
- Python 3.10+
- [whisper.cpp](https://github.com/ggerganov/whisper.cpp) (for transcription)
- ffmpeg (for audio conversion)
- `mcp[cli]` (installed automatically)
## Agent integration
### Hermes Agent
Add to `~/.hermes/config.yaml`:
```yaml
mcp_servers:
graindrop:
url: http://127.0.0.1:8648/sse
transport: sse
```
### Any MCP client
Connect to `http://127.0.0.1:8648/sse` using the MCP protocol's HTTP SSE transport. Call `tools/list` to discover available tools, then `tools/call` to invoke them.
## License
MIT — do what you want, just don't blame us.
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues