Oatmeal

A native Mac meeting notetaker that's invisible to screen sharing

not yet reviewed by publik

How to install Oatmeal

Every step written out, for people who have never opened a terminal. Pick the setup you have.

🥣 Oatmeal

A native Mac meeting notetaker that's invisible to screen sharing.

License: MIT Local First No Cloud Platform PRs Welcome

Mic + system audio, transcribed on-device with Whisper, written up by a local language model — all inside a small floating window that never appears in Zoom, Meet, or any screen share. No bots joining calls. No accounts. No API keys. No cloud.


How it works

you, in a meeting ──►  Oatmeal.app  (invisible to screen share)
                        mic + system audio
                             │
                             ▼
                whisper.cpp transcribes live, on-device
                             │
                             ▼
                llama.cpp writes notes, on-device
                             │
                             ▼
        ~/Library/Application Support/dev.oatmeal.app/recordings/

The recorder is a native window — NSWindow.sharingType = NSWindowSharingNone — so it's excluded from every screen/window capture (Zoom, Discord, Loom, QuickTime…) while staying fully visible on your own display. A title-bar pill lets you flip it visible again when you actually want to share it. Nothing about the meeting — audio, transcript, or notes — ever leaves the machine except the one-time model downloads on first launch.

What it does

LaneHow
Invisible windowNSWindow.sharingType = NSWindowSharingNone, flippable back to visible from the title bar.
Microphone + system audiocpal for the mic, ScreenCaptureKit for a system-audio tap — no BlackHole or virtual driver.
Live transcriptwhisper-rs (whisper.cpp, Metal GPU) streams lines into a floating window while you record.
NotesA local instruct model (llama.cpp, Metal GPU) writes a summary once the meeting ends; you can also type your own notes as you go.
CalendarReads Apple Calendar (EventKit — iCloud, Google, Exchange, whatever your Mac already has) so upcoming meetings show on the home screen.

Meetings are saved to ~/Library/Application Support/dev.oatmeal.app/recordings/<date>-<title>/ as plain transcript.md and notes.md files next to the audio — nothing is locked in a database.

Updating

Your meetings are not inside the app. They live under ~/Library/Application Support/dev.oatmeal.app/, so replacing Oatmeal in /Applications never touches a recording, a transcript, or a note. Every write to those files is atomic — a crash, or quitting the app to install a new version, cannot leave a half-written note behind.

Oatmeal checks this repository's releases when it starts. A newer version shows a strip you can dismiss; occasionally a release is marked required, and then the app asks you to update before continuing (In app updates). If it can't reach GitHub it says nothing and carries on — you can always record offline.

One wrinkle worth knowing: builds are ad-hoc signed, so macOS treats each release as a new app identity and will ask for Microphone and Screen Recording again after an update.

Privacy

  • Transcription and note-writing both run on-device — Whisper and the local language model, via whisper.cpp/llama.cpp on the Metal GPU. Audio is never stored or uploaded anywhere.
  • The only network calls Oatmeal makes are the one-time model downloads — the Whisper and note-writing models on first launch — an update check that asks GitHub for this repository's release list when the app starts, and — if you're using the Calendar features — EventKit itself running in-process. The update check sends nothing but the request.
  • Attaching a YouTube video to a note reaches the network twice more, and both are worth knowing about. Pasting the link already contacts YouTube — Oatmeal looks the video up to read its title and length before you press Transcribe, so the request goes out as soon as you paste, not when you confirm. And the first time you do this, Oatmeal downloads a third-party helper program, yt-dlp, from github.com and runs it on your machine; nothing else in Oatmeal does that. The version is pinned in the source, so the app never fetches whatever build happens to be newest. These requests tell Google which video you asked for and the IP address you're asking from, but send nothing about your meetings, notes, or transcripts, and none of it happens unless you paste a link.
  • Recording people has consent rules that vary by place. Tell attendees you're taking notes.

Alternative: browser recorder + your coding agent

This repo also ships a second, older way to run Oatmeal — a zero-dependency local web server instead of a native app, meant to be driven by a coding agent (Claude Code, Cursor, Codex…) rather than the app's own local model. Transcripts land as plain Markdown in a meetings/ folder that your agent reads, writes notes into, and can commit to git as a shared team knowledge base. Cross-platform, but the window is not hidden from screen sharing.

git clone https://github.com/Cujoqt/oatmeal.git
cd oatmeal
npm install
npm start          # recorder at http://localhost:4123

Then paste one line into your coding agent:

Read SKILL.md and set up Oatmeal for me.

The agent starts the recorder, opens http://localhost:4123, and tells you how to record. (Claude Code auto-discovers the skill via .claude/skills/ — mentioning meetings is enough.) When a meeting starts: hit Record, share Entire screen with "share system audio" checked (window shares carry no audio). When it ends, tell your agent:

write up my meeting

You get summary, key points, decisions, and action items — committed to git if the repo has a remote.

Claude Code superpowers for this path
You typeWhat happens
/meetingRecorder starts (if needed) and opens in your browser
/writeupLatest transcript becomes polished notes: summary, decisions, action items — committed & pushed
/recall what did we tell Acme about pricing?Grounded answer from every meeting in the knowledge base, with file citations
/prep akritPre-meeting brief: what you discussed last time, open action items, promises made, suggested agenda
  • It notices unwritten meetings. A SessionStart hook checks for transcripts with no notes — open Claude Code after a call and it offers the write-up before you ask.
  • MCP auto-registers. .mcp.json exposes list_meetings / search_meetings / get_meeting to any MCP client the moment you open the repo.

Other agents: the same flows work by asking in plain English — the commands are just markdown files in .claude/commands/, readable by anything.

Running as a background service (no agent, no terminal open)
node scripts/install-autostart.mjs

Registers the recorder as a real background service — a Startup-folder entry on Windows, a LaunchAgent on macOS, systemd --user on Linux — with no admin rights and no permission prompts. Starts at every login, keeps running. Uninstall with node scripts/install-autostart.mjs --uninstall.

If your coding agent has (or can add) a Google/Outlook Calendar connector, just ask it to wire your calendar into Oatmeal. No connector? Copy oatmeal.config.example.json to oatmeal.config.json, paste your calendar's ICS feed URL, and re-run the install script — it also installs a calendar watcher that opens the recorder ~7 minutes before each meeting.

What's in the repo

PathWhat it is
app/The native macOS app (Tauri + Rust) — invisible recorder window, on-device Whisper + local LLM
SKILL.mdThe product spec your coding agent follows for the browser-recorder path — setup, notes flow, knowledge base rules, calendar automation
capture/Zero-dependency local server + recorder page for the browser-recorder path
meetings/Transcripts + notes written by the browser-recorder path. Plain Markdown.
scripts/mcp-server.mjsOptional MCP server — expose meetings/ to any MCP client
scripts/install-autostart.mjsRegisters the browser recorder (+ calendar watcher) as a background OS service
scripts/calendar-watch.mjsStandalone ICS calendar poller for the browser-recorder path
.claude/skills/Auto-discovery so Claude Code picks up the skill on clone

Contributing

PRs welcome.

Good first issues:

  • Smarter meeting-title detection (from calendar or first few words)
  • Calendar connector recipes for the browser-recorder path (Google, Outlook, Slack integration guides)
  • Full multi-person diarization (mic vs system audio are already tagged "You"/"Room" — telling apart two+ people on the other end of the call would need Pyannote or similar)
  • Better error messages (when Whisper fails, when git push fails, etc.)

Not in scope: cloud sync, accounts, compliance features (fine-grained audit logs), multi-language models beyond Whisper's baseline. Those belong in derivatives, not core.

License

MIT © Vedant Soni — free forever.