{"slug": "show-hn-hey-spark-open-source-voice-assistant-for-your-laptop-any-llm-brain", "title": "Show HN: Hey Spark – open-source voice assistant for your laptop, any LLM brain", "summary": "ContextuAI released Hey Spark, an open-source always-listening voice assistant for macOS 14+ on Apple Silicon and Windows 11 that runs wake-word detection (openWakeWord), speech-to-text (faster-whisper) and text-to-speech (Piper or Kokoro) locally on the CPU while routing requests to Claude via the Claude Agent SDK, Hermes Agent, or any OpenAI-compatible model including local ones through Ollama. Hey Spark connects to tools such as GitHub, Gmail and Calendar through MCP servers with per-server allowlists, requiring a spoken \"yes\" before any tool that sends, creates or updates, and blocking destructive tools by default. The release requires about 1 GB of disk for models, and audio leaves the machine only if a user selects a cloud STT backend such as Deepgram or ElevenLabs.", "body_md": "*by [ContextuAI](https://contextuai.com)*\n\n**An always-listening voice assistant for your laptop.** Say *\"Hey Spark\"*, ask a question or\ngive a command, and hear the answer. The wake word, speech recognition and voice all run\nlocally on your CPU. The brain is Claude, [Hermes Agent](https://github.com/NousResearch/hermes-agent),\nor any OpenAI-compatible model, including a local one through Ollama. Spark reaches your tools (GitHub, Gmail, Calendar, your own systems) through\n[MCP](https://modelcontextprotocol.io) servers, and it asks out loud before doing anything that\nchanges something.\n\n*\"Hey Spark, what's on my calendar tomorrow?\"*\n*\"Set a pasta timer for ten minutes.\"*\n*\"Summarize the open pull requests on hey-spark.\"*\n*\"Let's start a new project called weather-bot.\"* → *\"I'll create a folder, a git repo and a private GitHub repo called weather-bot. Should I go ahead?\"*\n\n- **Local wake word.** A bundled[openWakeWord](https://github.com/dscripka/openWakeWord) model\nfor \"Hey Spark\".[Train your own wake word](https://github.com/contextuai/hey-spark/blob/main/docs/wakeword.md) for free in Google Colab, or use\nPicovoice Porcupine.\n- **Local speech.**[faster-whisper](https://github.com/SYSTRAN/faster-whisper) speech-to-text and[Piper](https://github.com/rhasspy/piper) or[Kokoro](https://github.com/thewh1teagle/kokoro-onnx) text-to-speech, all CPU-only. Deepgram and ElevenLabs are optional cloud backends.\n- **Your choice of brain.** Claude through the[Claude Agent SDK](https://pypi.org/project/claude-agent-sdk/) , your own[Hermes Agent](https://github.com/NousResearch/hermes-agent) , or any OpenAI-compatible API:\nOpenAI, Azure OpenAI, OpenRouter, Groq, Together, Ollama, LM Studio or vLLM.\n- **Connectors over MCP** , with per-server allowlists. Read-only tools run freely; anything that\nsends, creates or updates needs a**spoken \"yes\"** , and destructive tools are blocked by default.\n- **Conversation that feels natural.** Spark streams its answer sentence by sentence, stays awake\nfor follow-ups without the wake word, ignores speech that isn't meant for it, and can be\ninterrupted by saying the wake word (barge-in).\n- **A personality of your choice.** Plain and brief by default, or a composed British butler\nwith a dry wit who calls you \"sir\", answers the wake word with \"Yes, sir?\" and speaks in a\nBritish voice. See[Personality and voice](https://github.com/contextuai/hey-spark/blob/main/docs/persona.md) .\n- **Memory and shortcuts.** It keeps editable Markdown notes about each connected system, and you\ncan map a short phrase (\"good morning\") to a detailed prompt.\n- **Desktop app** for macOS and Windows: a single Start/Stop button, a light that shows what\nSpark is doing, and windows for Connectors, Shortcuts, the Brain, and Personality & Voice.\n- **Everything is swappable from `config.yaml`** : wake word, VAD, STT, TTS and brain backends,\nwith no code changes.\n\n``` php\nflowchart LR\n    mic[Mic 16 kHz] --> wake[Wake word<br/>openWakeWord]\n    wake --> vad[Record until silence<br/>Silero VAD]\n    vad --> stt[Speech to text<br/>faster-whisper]\n    stt --> brain[Brain<br/>Claude or OpenAI-compatible]\n    brain <--> mcp[MCP connectors<br/>+ spoken confirmation]\n    brain --> split[Sentence splitter]\n    split --> tts[Text to speech<br/>Piper / Kokoro]\n    tts --> spk[Speaker]\n```\n\nNothing leaves your machine before the wake word. After it, only the text of your request goes to the brain you chose. Audio leaves the machine only if you pick a cloud STT backend.\n\n**Requirements:** macOS 14 or later on Apple Silicon, or Windows 11 (see\n[Platform support](#platform-support)), a microphone, about 1 GB of disk for models, and a brain:\n[Claude Code](https://code.claude.com/docs/en/setup) signed in to your Claude account (or with an\n[Anthropic API key](https://console.anthropic.com/)), an OpenAI-compatible key, or\n[Ollama](https://ollama.com) running locally. A USB speakerphone with echo cancellation works\nbest.\n\nGet the latest build from [Releases](https://github.com/contextuai/hey-spark/releases). Each file\nhas a `.sha256` checksum next to it.\n\n**macOS** (Apple Silicon, macOS 14+)\n\n1. Download `HeySpark-<version>-macos-arm64.dmg` , open it and drag**HeySpark** into**Applications** .\n2. Open it from Applications. If macOS says it can't verify the app, open\n*System Settings → Privacy & Security* , scroll down and click**Open Anyway** . (Or run`xattr -dr com.apple.quarantine /Applications/HeySpark.app` once in Terminal.)\n3. Allow microphone access when macOS asks.\n\nSettings, logs, models and your `.env` live in `~/Library/Application Support/HeySpark`.\n\n**Windows** (Windows 11)\n\n1. Download and run `HeySpark-Setup-<version>.exe` . It installs per-user and needs no admin\nrights. The installer isn't code-signed yet, so Windows SmartScreen may warn you: choose*More info → Run anyway* .\n2. Open **Hey Spark** from the Start menu.\n\nSettings, logs, models and your `.env` live in `%LOCALAPPDATA%\\HeySpark`.\n\n**Then, on either platform:**\n\n1. Click the **brain** button, pick a provider and enter\nyour key (or pick Ollama).\n2. Press **Start** . The first start downloads the speech models (about 200 MB). Then say*\"Hey Spark\"* .\n\n```\n# 1. Install uv (https://docs.astral.sh/uv/); it manages Python 3.11 for you\ngit clone https://github.com/contextuai/hey-spark.git\ncd hey-spark\nuv sync --all-extras                 # plain `uv sync` skips the optional backends\n\n# 2. Download the speech models into ./.models (about 200 MB)\nuv run spark models download\n\n# 3. Add your brain's key\ncp .env.example .env                 # (Windows: copy) then set your key; see \"Choose a brain\"\n\n# 4. Check everything, then talk to it\nuv run spark doctor                  # every required check should show ✔\nuv run spark                         # say \"Hey Spark, what's the capital of Japan?\"\n```\n\nNo microphone handy? `uv run spark --text` lets you type questions and read answers, and\n`uv run spark --brain mock --text` runs fully offline with no key at all.\n\n| Brain | Set up | Good for | \n|---|---|---|\n| **Claude** (default) | [Claude Code](https://code.claude.com/docs/en/setup) installed and signed in (or`ANTHROPIC_API_KEY` in`.env` ) | The best tool use and connector work. Supports the researcher sub-agent and fast/deep model routing | \n| **Hermes Agent** | [Hermes Agent](https://github.com/NousResearch/hermes-agent) with its API server on, and its`API_SERVER_KEY` | Giving your Hermes agent a voice: it answers with its own model, tools, memory and skills | \n| **OpenAI-compatible cloud** (OpenAI, Azure, OpenRouter, Groq, Together) | The provider's key in `.env` , and`brain.backend: openai_compat` | Using a model or account you already have | \n| **Local** (Ollama, LM Studio, vLLM) | Run the server, pull a tool-capable model (e.g. `qwen2.5:7b` ) | **Fully local** : with faster-whisper and Piper, nothing leaves your machine | \n\nThe easiest way to switch is the desktop app's **Brain** window, which also tests the connection\nand checks that the model can call tools. See [docs/openai_brain.md](https://github.com/contextuai/hey-spark/blob/main/docs/openai_brain.md) for the\nprovider presets and the `config.yaml` settings.\n\nWith Claude, `brain.mode` picks the models: `auto` (default) sends quick requests to\n`brain.fast_model` and bigger ones to `brain.deep_model`; `deep` answers everything with\n`brain.deep_model` and hands tool-heavy lookups to a researcher on a faster model (the best\nanswers, and the highest API cost). You can also switch by voice\n(\"use the deep model\", \"back to auto\").\n\nThe default `config.yaml` uses the bundled model `assets/wakewords/hey_spark.onnx`. Nothing to set\nup. If it misses you or wakes on its own, tune `wakeword.options.openwakeword.threshold`.\n\n**Want your own wake word?** [`tools/wakeword_trainer.ipynb`](https://github.com/contextuai/hey-spark/blob/main/tools/wakeword_trainer.ipynb) trains\none for any phrase on a free Colab GPU in about an hour, with no recordings needed.\n[docs/wakeword.md](https://github.com/contextuai/hey-spark/blob/main/docs/wakeword.md) walks through it step by step, plus the Porcupine\nalternative.\n\n- **Follow-ups:** after a reply, Spark stays awake for 3 minutes (`attention.awake_s` ), so you can\nkeep talking without the wake word. It answers only speech that's meant for it, then plays a\nsoft chime when it falls asleep.\n- **Commands:** \"new topic\" (fresh conversation), \"go to sleep\", \"never mind\", and \"mute\nyourself\" (it then stops listening until you click the mic button in the window). Film-style\nones work too: \"stand down\", \"belay that\", \"clean slate protocol\", \"full power\", \"go dark\".\n- **Timers and time:** \"set a pasta timer for 10 minutes\", \"what timers do I have\", \"what time is it\".\n- **New projects:** \"let's start a new project called weather-bot\". After your*yes* , Spark creates`projects.root_dir/weather-bot` with git and a first commit, a private GitHub repo and a tracking\nissue through your`gh` login (it never pushes), and can open Claude Code in the folder.\n- **Shortcuts:** map a phrase like \"good morning\" to a detailed prompt in the Shortcuts window\n(or`shortcuts.json` ). Fifteen come built in: \"rise and shine\" for the morning briefing,\n\"what's next?\", \"sitrep\", \"check the post\", \"run a diagnostic\", \"house party protocol\" and more.\nSee[docs/commands.md](https://github.com/contextuai/hey-spark/blob/main/docs/commands.md) .\n- **Barge-in:** with`app.barge_in: true` , saying the wake word while Spark is talking stops it.\nTurn this on only with an echo-cancelling speakerphone.\n- **Earcons:** a chime on wake, a tick while thinking, a low tone on errors.\n- **Personality and voice:** pick the butler personality and a British voice in the Personality &\nVoice window (or`app.persona: butler` in`config.yaml` ). See[docs/persona.md](https://github.com/contextuai/hey-spark/blob/main/docs/persona.md) .\n\nConnectors are MCP servers defined in `mcp_servers.json` (with `${VAR}` placeholders only; the\nvalues come from `.env`). Add them by hand or in the desktop app's **Connectors** window. Each\nserver's tool policy lives in `config.yaml` under `connectors:`:\n\n- `allowed_tools` are read-only and pre-approved.\n- `side_effecting` tools (send, create, update) need a**spoken \"yes\"** every time. Spark says one\nline about what it will do and waits. Silence, an unclear answer or \"no\" means it doesn't happen.\n- `destructive` tools are blocked unless you set`allow_destructive: true` for that server.\n- Any tool on none of these lists is denied.\n\n1. \nCreate a [fine-grained token](https://github.com/settings/personal-access-tokens/new) for the\nrepos Spark may see:*Issues: Read and write* ,*Pull requests: Read* and*Contents: Read* .\n2. \nIn the **Connectors** window, open**github** (under*From config files* ) and click**Edit\nconfig** . Replace`${SPARK_GITHUB_PAT}` with your token and press**Save and test** . Spark\nmoves the token to`.env` .\n\n```\n{\n  \"github\": {\n    \"type\": \"http\",\n    \"url\": \"https://api.githubcopilot.com/mcp/\",\n    \"headers\": { \"Authorization\": \"Bearer YOUR_TOKEN\" }\n  }\n}\n```\n\n3. \nSwitch it on. Spark uses GitHub's own labels for the tools: reading runs freely, creating an issue asks you first, and deleting is off. Try *\"What are the open issues in my-repo?\"*\n\nThis is GitHub's official [github-mcp-server](https://github.com/github/github-mcp-server),\nhosted by GitHub. GitHub's docs list Copilot access as a prerequisite for the hosted server\n(Copilot has a free plan); if your account is refused, or you'd rather run it on your own\ncomputer, see\n[docs/connectors.md](https://github.com/contextuai/hey-spark/blob/main/docs/connectors.md). Paste the token itself: GitHub's VS Code example uses\n`${input:...}`, a VS Code prompt that Spark can't show.\n\nChoose **Add connectors** in the Connectors window and paste any MCP server's JSON (the\n`mcpServers` block from its README or from Claude Desktop), or import Claude Desktop's servers in\none click. [docs/connectors.md](https://github.com/contextuai/hey-spark/blob/main/docs/connectors.md) covers servers set up by hand in\n`mcp_servers.json` and `config.yaml`, including Gmail, Google Calendar and Outlook through\nComposio. The claude.ai Gmail and Calendar connectors are off by default: they work only through\na claude.ai login in your own Claude CLI, so they're for personal setups.\n\n- Before the wake word, audio never leaves the wake-word detector, and no audio is stored unless\nyou run with `--debug-audio` .\n- After the wake word, your words are transcribed locally (unless you choose Deepgram) and the text goes to the brain you chose.\n- Secrets live only in `.env` or the environment. A redaction filter masks them, and common token\nshapes, in every log line.\n- Spark keeps local logs you can read and delete: transcripts (`logs/transcripts.log` , turn off\nwith`logging.transcripts: false` ) and an activity history (`history/` , see`activity:` in`config.yaml` ). They never leave your machine.\n\nEverything is in [`config.yaml`](https://github.com/contextuai/hey-spark/blob/main/config.yaml), and every key has a comment. Override any key per run\nwith an environment variable (`SPARK_<SECTION>__<KEY>`) or a CLI flag:\n\n```\nwakeword: { backend: openwakeword }   # openwakeword | porcupine\nstt:      { backend: faster_whisper } # faster_whisper | deepgram\ntts:      { backend: kokoro }         # kokoro | piper | elevenlabs | print\nbrain:    { backend: claude_agent }   # claude_agent | openai_compat | mock\n$env:SPARK_STT__BACKEND = \"deepgram\"; uv run spark\nuv run spark --stt deepgram --tts kokoro\n```\n\n## All commands\n\n```\nuv run spark                         # voice mode\nuv run spark --text                  # type questions, print answers (no audio devices)\nuv run spark --text --speak          # type questions, hear answers\nuv run spark --no-tts                # voice in, printed answers out\nuv run spark --debug-audio           # also save the last utterance to debug_audio/\nuv run spark -v                      # debug logging (shows tool calls by name)\nuv run spark desktop                 # the desktop window\nuv run spark doctor                  # environment checks, each with a fix\nuv run spark models download         # whisper + the configured voice (Kokoro George by default)\nuv run spark bench stt|tts|brain     # latency benchmarks (median / p90)\nuv run spark bench latency           # live: wake word to first audio, end to end\nuv run spark bench false-wake --minutes 30   # live: count false wakes on background audio\n```\n\nPer-turn latency breakdowns are appended to `logs/latency.jsonl`.\n\n| Platform | Status | \n|---|---|\n| **macOS 14+, Apple Silicon** | Desktop app ( `.dmg` ) and source. Every build is self-tested in CI. New in 0.1.0, so please report anything odd. | \n| **Windows 11** | Desktop app (installer) and source. The platform Hey Spark was developed on (WASAPI audio). | \n| Intel Macs, Linux | From source only, untested. The code is cross-platform Python; reports and pull requests are welcome. | \n\nEverything runs on the CPU; no GPU is needed.\n\n**macOS** (on a Mac with the Xcode command-line tools):\n\n```\nbash scripts/build_macos.sh\n```\n\nThis freezes the app into `build/dist/HeySpark.app`, signs it ad hoc, runs its self-test and\nwrites `build/installer/HeySpark-<version>-macos-arm64.dmg`. Set `MACOS_SIGN_IDENTITY` (plus\n`APPLE_ID`, `APPLE_TEAM_ID` and `APPLE_APP_PASSWORD`) to sign with a Developer ID and notarize.\n\n**Windows:**\n\n```\npowershell -ExecutionPolicy Bypass -File scripts\\build_windows.ps1\n```\n\nThis freezes the app into `build\\dist\\HeySpark\\HeySpark.exe`. With\n[Inno Setup 6](https://jrsoftware.org/isinfo.php) installed (`winget install JRSoftware.InnoSetup`),\nit also writes `build\\installer\\HeySpark-Setup-<version>.exe`.\n\nReleases are built by GitHub Actions ([`build-apps.yml`](https://github.com/contextuai/hey-spark/blob/main/.github/workflows/build-apps.yml)), which\nalso builds both apps for pull requests that touch packaging or the desktop app.\n\n```\nuv run pytest -q                     # offline suite: fakes and synthesized audio, about a minute\nuv run pytest -q -m live             # hits real Claude / cloud APIs (needs keys)\nuv run ruff check . && uv run ruff format --check .\n```\n\nThe architecture in one line: every component is an abstract class in `spark/interfaces.py`, and\n`spark/registry.py` maps the backend names in `config.yaml` to implementations. `spark/app.py`\nis the state machine. [CONTRIBUTING.md](https://github.com/contextuai/hey-spark/blob/main/CONTRIBUTING.md) explains how to add a backend, run the\ntests and send a pull request, and [docs/design/SPEC.md](https://github.com/contextuai/hey-spark/blob/main/docs/design/SPEC.md) is the original\ndesign spec. Hardware checks that need a real mic are in\n[docs/dev/MANUAL_QA.md](https://github.com/contextuai/hey-spark/blob/main/docs/dev/MANUAL_QA.md).\n\nHey Spark was built with [Claude Code](https://claude.com/claude-code). The project's agents and\nskills are in [`.claude/`](https://github.com/contextuai/hey-spark/blob/main/.claude), and the original phase plans and reports are in\n[docs/dev/history](https://github.com/contextuai/hey-spark/blob/main/docs/dev/history).\n\nContributions are welcome: see [CONTRIBUTING.md](https://github.com/contextuai/hey-spark/blob/main/CONTRIBUTING.md) and the\n[Code of Conduct](https://github.com/contextuai/hey-spark/blob/main/CODE_OF_CONDUCT.md). Please report vulnerabilities privately as described in\n[SECURITY.md](https://github.com/contextuai/hey-spark/blob/main/SECURITY.md). Release notes are in [CHANGELOG.md](https://github.com/contextuai/hey-spark/blob/main/CHANGELOG.md).\n\nThe code is [MIT](https://github.com/contextuai/hey-spark/blob/main/LICENSE) © 2026 Nagendra Rao Jogi.\n\nThe bundled wake-word model (`assets/wakewords/hey_spark.onnx`) is licensed separately under\n**CC BY-NC-SA 4.0** (non-commercial), because its training data has mixed licenses. See\n[assets/wakewords/LICENSE](https://github.com/contextuai/hey-spark/blob/main/assets/wakewords/LICENSE). For commercial use, train your own model on\ndata you're licensed to use, or use Porcupine. Licenses for the dependencies and the downloaded\nspeech models are listed in [THIRD_PARTY_NOTICES.md](https://github.com/contextuai/hey-spark/blob/main/THIRD_PARTY_NOTICES.md).\n\nHey Spark is an open-source project from [ContextuAI](https://contextuai.com), makers of\n[ContextuAI Solo](https://contextuai.com/solo).", "url": "https://wpnews.pro/news/show-hn-hey-spark-open-source-voice-assistant-for-your-laptop-any-llm-brain", "canonical_source": "https://github.com/contextuai/hey-spark", "published_at": "2026-10-31 18:09:19+00:00", "updated_at": "2026-10-31 18:20:59.197563+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "agent-protocols", "large-language-models", "ai-products"], "entities": ["ContextuAI", "Hey Spark", "Claude", "Hermes Agent", "OpenAI", "Ollama", "openWakeWord", "faster-whisper"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/show-hn-hey-spark-open-source-voice-assistant-for-your-laptop-any-llm-brain", "markdown": "https://wpnews.pro/news/show-hn-hey-spark-open-source-voice-assistant-for-your-laptop-any-llm-brain.md", "text": "https://wpnews.pro/news/show-hn-hey-spark-open-source-voice-assistant-for-your-laptop-any-llm-brain.txt", "jsonld": "https://wpnews.pro/news/show-hn-hey-spark-open-source-voice-assistant-for-your-laptop-any-llm-brain.jsonld"}}