The Simplest Integration Possible
Most integrations require API keys, tokens, webhooks, and authentication. Obsidian is different. It's just markdown files in a folder.
SpeechButton can write files. That's it. That's the integration.
Hold Command+8.
"Meeting with the design team. We agreed on the new landing page layout. Hero section keeps the 7ms headline, comparison table moves above the fold, FAQ gets accordion treatment. Maria sends mockups by Monday."
Release. A markdown file appears in your vault:
~/Documents/Obsidian/2026-04-04.md
## Meeting with Design Team — April 4, 2026
- - Agreed on new landing page layout
- - Hero section: keep 7ms headline
- - Comparison table: move above the fold
- - FAQ: accordion treatment
- - Action: Maria sends mockups by Monday
Obsidian picks it up instantly. Searchable, linkable, yours forever. No API key. No cloud service. No account. Nothing left your Mac.
Setup: 3 Minutes
Four steps. Two hotkeys. No API keys anywhere. Fully working voice-to-vault in under three minutes.
Step 1: Know your vault path
Obsidian vaults are just folders. Set the path once as an environment variable — that's the only configuration you need.
# Common locations
~/Documents/Obsidian/
~/Obsidian/MyVault/
~/vaults/notes/
export OBSIDIAN_VAULT="$HOME/Documents/Obsidian"
Step 2: SpeechButton config.toml
Two hotkeys: ⌘8 appends to today's daily note, ⌘9 drops into a quick inbox. The transform is a local prompt file — no API call, no internet.
# ~/.config/speechbutton/config.toml [general] scope = "global" platform = "macos15" # Daily journal — append timestamped entry [[hotkey]] key = "RightCommand+8" channel = "8" name = "obsidian" transform = "prompts/obsidian_note.md" exec = "OBSIDIAN_VAULT=~/Documents/Obsidian integrations/send_obsidian.py" # Quick inbox — drop a thought into inbox.md [[hotkey]] key = "RightCommand+9" channel = "9" name = "obsidian-inbox" transform = "prompts/obsidian_note.md" exec = "OBSIDIAN_VAULT=~/Documents/Obsidian integrations/send_obsidian.py --inbox"
Step 3: Local AI transform prompt
SpeechButton runs this prompt through the on-device model. No network request. No API key. Plain text file you can edit anytime.
You are a note formatter for Obsidian. Convert the following spoken text into clean markdown suitable for an Obsidian vault. Rules: - Use ## headings to separate topics if there are multiple - Use bullet points for lists and decisions - Use **bold** for names, key terms, and action items - Format action items as: - [ ] Task description - Keep it concise — remove filler words - Do NOT add a title heading (the filename serves as title) - Output ONLY the markdown content, nothing else
File lives at ~/.config/speechbutton/prompts/obsidian_note.md. Edit to taste — the model runs locally, so no costs, no rate limits.
Step 4: The Python script
One script handles all three modes. Reads from stdin, writes to vault. Pure stdlib — no dependencies to install.
#!/usr/bin/env python3 """Append text to Obsidian vault. 100% local.""" import os, sys from datetime import datetime from pathlib import Path def main(): text = sys.stdin.read().strip() if not text: sys.exit(0) vault = Path(os.environ.get("OBSIDIAN_VAULT", "~/Documents/Obsidian")).expanduser() # Default: daily note if "--file" in sys.argv: target = vault / sys.argv[sys.argv.index("--file") + 1] elif "--inbox" in sys.argv: target = vault / "inbox.md" else: target = vault / f"{datetime.now():%Y-%m-%d}.md" target.parent.mkdir(parents=True, exist_ok=True) timestamp = datetime.now().strftime("%H:%M") sep = "\n\n---\n\n" if target.exists() and target.stat().st_size > 0 else "" with open(target, "a") as f: f.write(f"{sep}**{timestamp}** — {text}\n") print(f"Obsidian: → {target.relative_to(vault)}") if __name__ == "__main__": main()
Save and make executable:
mkdir -p ~/.config/speechbutton/integrations ~/.config/speechbutton/prompts
# save script to: ~/.config/speechbutton/integrations/send_obsidian.py
chmod +x ~/.config/speechbutton/integrations/send_obsidian.py
Three modes
send_obsidian.py— append to today's daily note (2026-04-03.md)send_obsidian.py --inbox— append toinbox.mdsend_obsidian.py --file "Projects/MyProject.md"— append to any file
Real Workflows
Meeting notes
"Sprint planning April 4th. We committed to three stories: the payment webhook refactor, the CSV export fix, and the onboarding animation. Velocity was 21 points last sprint, we're taking 24 this time. Risk: the webhook refactor depends on the Stripe API migration which hasn't been tested yet. Action: James tests Stripe migration by Tuesday."
Result: appended to 2026-04-04.md with a timestamp entry — formatted markdown with decisions, velocity, risks, and action items. Transformed locally on device, nothing left your Mac.
Daily journal — append all day
"Started with code review, found a memory leak in the WebSocket handler"
"Good lunch conversation with Alex about the pricing strategy, he thinks we should test 9.99 before committing"
"Wrapped up the CSV fix, PR submitted, heading out"
Your daily note at end of day:
# 2026-04-04 - **09:00** — Started with code review, found a memory leak in the WebSocket handler - **12:30** — Good lunch conversation with Alex about the pricing strategy, he thinks we should test 9.99 before committing - **17:00** — Wrapped up the CSV fix, PR submitted, heading out
Zero friction. You never opened Obsidian. Nothing went to a cloud. Just files.
Quick capture — ideas, thoughts, references
"Idea: what if SpeechButton channels could chain? Output of one transform feeds into the next. Voice → transcribe → summarize → translate → post to Slack. Pipeline of transforms. Like Unix pipes but for voice."
Result: appended to inbox.md with a timestamp. Captured in 10 seconds. Available next time you search your vault. 100% local.
Research notes with Obsidian links
"Research on push-to-talk latency. Key finding: SuperWhisper doesn't publish capture latency numbers. Wispr Flow mentions 'fast' but no millisecond claims. We're the only tool citing 7ms with a technical explanation. Related to the comparison page task, link to SpeechButton pricing research."
The transform can include [[wikilinks]] if you configure it to recognize note references. Add to the transform prompt: "If the speaker mentions linking to another note, include an Obsidian wikilink [[Note Name]]."
100% Local: The Entire Pipeline
Every step happens on your Mac. No step touches the internet. This is the key difference from Notion or Linear integrations:
| Component | Where it runs |
|---|---|
| Voice capture | Your Mac — microphone buffer only |
| Speech-to-text | Apple Neural Engine — on-device |
| Transform | On-device AI model — no API call |
| File write | Your Mac filesystem — direct write |
| Obsidian sync | Local vault (or your own sync) |
The entire pipeline is local. Voice → on-device STT → on-device AI transform → file on disk. Zero network requests. Zero API tokens. Zero accounts. Zero servers.
No API key for the transform. The prompt file (prompts/obsidian_note.md) runs through the on-device model. Your notes, your hardware, your data — entirely.
- ✓ No API keys — not one
- ✓ Works offline — airplane mode, field notes, air-gapped
- ✓ Private by default — journal, medical, legal notes
- ✓ Only env var needed:
OBSIDIAN_VAULT
- × API tokens
- × OAuth credentials
- × Webhook endpoints
- × Cloud round-trips for every note
Obsidian Plugins That Enhance Voice Notes
Once your voice notes land in the vault, Obsidian's plugin ecosystem adds superpowers:
- [ ] action items across all voice notes into a unified task listSpeechButton gets the notes into Obsidian. The plugin ecosystem makes them useful.
Get Started
- 1 Download SpeechButton — free 15 minutes/day, no account needed
-
2
Set your vault path —
export OBSIDIAN_VAULT="$HOME/Documents/Obsidian" -
3
Copy the config, prompt, and script from this article into
~/.config/speechbutton/— no API keys, no accounts - 4 Hold RightCommand+8, speak, release. Your first voice note appears in Obsidian. Everything ran locally on your Mac.
Start building your voice-powered vault today
Free 15 min/day · No account needed · No API keys · macOS 15+ · Apple Silicon
Download for macOS — FreePro ($7.99/mo) removes the daily limit. Requires macOS 15+ and Apple Silicon.