Releases: jej2k5/meetey
Release list
v2.0.0 — Recording you can rely on
The first version I'd trust with a meeting that matters.
1.4 and 1.5 lost recordings — repeatedly, in ways that were hard to see. This release fixes the cause and removes the conditions that let it hide.
What was wrong
The meeting watcher checked for windows every ten seconds, including while a recording was running. macOS treats a second look at the screen as a competing capture and terminates the live one, so recordings died a few seconds after starting.
It arrived as an improvement: keep reporting whether the watcher can see your screen, even mid-recording. It destroyed the thing it was reporting on.
The timeline was plain in the logs — a recording made before that check was introduced ran 34 minutes; every recording after it died in seconds.
Why it survived being fixed
Two reasons, both fixed here:
- Updating didn't restart the watcher. macOS keeps running whatever it loaded at login, so the old code kept running and kept killing recordings while the update appeared to have worked.
- The self-check passed while the bug happened in front of it. It reported "0.3 seconds written" of a six-second test as a tick, because it only asked whether any audio arrived. A capture that stops early is exactly the fault it exists to catch.
Nothing is lost any more
The audio file is valid at every moment while it's being written, not only once it finishes cleanly. Lose power, kill the process, close the laptop — whatever is on disk plays and transcribes up to that second.
Earlier versions wrote the file's header only at the end, so any interruption in an hour-long meeting destroyed all of it.
Transcripts arrive on their own
Within about a minute of a meeting ending, a readable timestamped transcript appears in ~/.meetey/recordings/. No Claude Code, no sign-in, nothing to remember — transcription runs locally.
Notes still need Claude, so they wait for you. /meetey writeup writes them for everything that piled up while you were away.
Also
- Screen capture covers the whole app. Narrowing it to a single window cost four recordings — Google Meet replaces its window when you join a call, and a capture aimed at the old one dies, taking the audio with it. Close or mute anything sensitive before opting in.
- A second meeting in the same window gets offered. Previously an instant Meet started after an earlier call was silently never suggested.
npx jej2k5/meetey verifyproves the machine can record and transcribe, by doing both. Install and update run it and decline to claim success when it fails.
Upgrade
npx jej2k5/meetey updateThen restart Claude Code. Grant Screen Recording permission if macOS asks — the binary is re-signed on every update, so it's treated as new.
If you had recordings that never produced notes, they're still there: /meetey writeup.
v1.5.2 — A closing window no longer ends the audio
A 32-minute meeting recorded six seconds. If you record with screen capture on, upgrade.
What happened
macOS captures audio and video through a single stream with a single scope. So narrowing screen capture to one window — the feature that keeps your other tabs and notification banners out of frame — narrowed the audio to that window's lifetime too.
Google Meet replaces its window when you join a call. The window chosen at the prompt stopped existing a few seconds later, and the entire recording stopped with it. Six seconds of audio, no screen content, and 32 minutes of nothing.
The fix
Audio and screen are now captured separately. Audio follows the app and cannot be ended by a window closing. Screen capture keeps its window narrowing, so nothing is lost on the privacy side.
A stopped capture is also acted on rather than quietly logged:
- Screen capture stops — survivable. It says so and keeps recording audio.
- Audio stops — the recording ends and saves what it has, instead of running on for half an hour writing nothing.
If a recording came out short
Nothing can be recovered from a recording that was already truncated; the audio was never written. Recordings made from here on are unaffected by this.
Upgrade
npx jej2k5/meetey updateThen restart Claude Code, and grant Screen Recording permission if macOS asks — the binary is re-signed on every update, so it is treated as new.
v1.5.1 — The watcher's recordings actually work
If you use the watcher, upgrade. Three bugs, all of which failed silently, and one of which meant no recording the watcher made was ever transcribed.
Nothing the watcher recorded was transcribed
whisper-cli was called by name. That works from Claude Code, which inherits your shell's PATH, and never worked from the watcher — a background agent gets /usr/bin:/bin:/usr/sbin:/sbin and Homebrew installs elsewhere. Every attempt failed with ENOENT into a log file, so recordings simply appeared never to be written up.
Your existing recordings are fine. The audio was captured correctly; only transcription failed. Run /meetey stop in Claude Code, or ask it to transcribe the WAV in ~/.meetey/recordings/ directly.
A recording could hang and capture nothing
Asking macOS what's on screen doesn't reliably fail when Screen Recording permission is unresolved — it can simply never return. A capture would sit indefinitely: no audio, no file, no error, and nothing in the log to distinguish it from a recording that was working. One 35-minute meeting was lost this way.
That call is now bounded and says what a timeout means. The capture also reports each setup step, so a stall is visible rather than looking like success.
This is most likely to bite right after an upgrade: the binary is rebuilt and re-signed, macOS treats it as a new program, and a background agent can't put the permission prompt in front of you. Grant Screen Recording after upgrading.
Stopping the watcher killed a recording in progress
Stopping the watcher tears down everything it started, including a running capture — mid-write, with nothing saved and nothing queued. It now finishes the recording properly first.
An interrupted recording is also no longer lost: the audio is all there behind an unwritten header, and transcribing repairs it automatically.
Upgrade
npx jej2k5/meetey update
npx jej2k5/meetey watch enableRe-running watch enable is worth it — it verifies the watcher can actually see your screen and tells you if permission is missing, rather than letting it fail quietly.
There is no bare meetey command; installing through npx puts nothing on your PATH.
v1.5.0 — You can see the watcher working
The watcher used to be invisible. Enabled or not, working or blind, there was no way to tell without running a command. Now it's in the menu bar for as long as it's on.
A presence, not a notification
watching ◌ quiet dotted circle, sitting still
recording ◉ red — this one steps aside for it
It's deliberately unlike the recording dot. Watching and recording are different things to be told, and a second attention-seeking icon would have weakened the only continuously-visible sign that a recording is happening. So while you're recording, the watcher's icon gets out of the way entirely and gives the red dot the bar.
It sits still. No pulse, no breathing, no heartbeat. It moves when something actually changes — settling in when the watcher starts, standing aside when a recording begins, coming back when it ends — and not otherwise. An icon that animates for hours in your peripheral vision is noise, not craft. macOS's Reduce Motion setting is respected.
Its menu tells you what it's doing, and stops the watcher if you want.
Turning it on tells you whether it worked
watch enable verifies it can actually see your windows before reporting success, which takes a moment. That moment now shows progress instead of appearing to hang.
Upgrade
npx jej2k5/meetey updateThen restart Claude Code. If the watcher is already enabled, the icon appears the next time the watcher restarts — or run npx jej2k5/meetey watch enable to get it immediately.
There is no bare meetey command; installing through npx puts nothing on your PATH.
v1.4.2 — The watcher can tell you it's working
If you use the watcher, upgrade. It could previously run without seeing anything, and say nothing about it.
The watcher could be on and blind
macOS grants Screen Recording permission per process, so the watcher needs its own — separately from the one meetey-capture already has. Nothing asked for it, so most people wouldn't have granted it.
Turning the watcher on reported success regardless. It would then look for meetings, see nothing, write one line to a log nobody was pointed at, and repeat every ten seconds. No error, no prompt — just a watcher that never noticed a meeting, with no way to tell whether it was broken or you simply hadn't had one.
Enabling now checks before it congratulates itself, and if it can't see your windows it says so and names exactly what to switch on. Nothing is left installed that looks on but isn't.
The check runs from the agent itself rather than the installer, because permission is attributed to whichever process asks — a check run from the terminal would pass while the thing it just installed stayed blind.
Back-to-back meetings were missed
When a recording ended, the watcher transcribed it — and froze completely while doing so. On an hour of audio that's several minutes of being switched off, so a meeting starting right after one ended was missed entirely. Transcription now runs alongside the watcher rather than in front of it.
Status commands were quietly wrong
/meetey statussaid nothing was happening while a finished recording sat waiting to be written up — right after a notification told you to go collect it./meetey doctor, whose whole job is answering "is meetey working?", couldn't see the watcher at all. Now it reports whether the watcher is on and whether it can actually see anything.
Update checking
npx jej2k5/meetey status
now reports whether a newer version has been released.
This is the only part of Meetey that contacts a server. It's an anonymous request for the repository's latest release tag — nothing about you or your machine is sent. Cached for a day, two second timeout, skipped silently when offline. MEETEY_NO_UPDATE_CHECK=1 turns it off. /meetey doctor reports the same figure but never makes the request itself; it reads what the CLI last found.
Also
- Enabling stopped claiming "audio only", which stopped being true when the prompt gained an audio + screen option.
- A meeting you skipped stays skipped across a restart.
npx jej2k5/meetey watch logand... watch logsboth work.
Upgrade
npx jej2k5/meetey updateThen restart Claude Code. If you had the watcher enabled, run npx jej2k5/meetey watch enable again — it will now tell you whether it can actually see your screen.
(There is no bare meetey command: installing through npx runs the package from its cache and puts nothing on your PATH. Earlier notes said otherwise — that was wrong.)
v1.4.1 — Recordings the watcher finished are no longer stranded
Fixes a bug in v1.4.0. If you used the watcher, upgrade.
The bug
Stopping a watch-agent recording from the menu bar left /meetey stop reporting "No active recording" — with the audio sitting on disk and no obvious way to reach it. The post-stop notification tells you to run /meetey stop, so it pointed straight at the dead end.
A recording started by the watcher ends in a different process from the MCP server. That process clears the "something is recording" state, which is correct, but nothing was left behind for /meetey stop to collect. Recordings started from /meetey start were unaffected.
The fix
Finished-but-uncollected recordings are now recorded on disk, so they survive the process that made them — and a Claude Code restart between stopping and writing up.
When there is genuinely nothing to collect, /meetey stop no longer dead-ends: it names the recordings that have audio but no notes, and offers to write the most recent one up.
Nothing was lost
Recordings affected by this are still in ~/.meetey/recordings/, and the watcher had already transcribed them. After upgrading, /meetey stop will point you at them.
Upgrade
npx jej2k5/meetey updateThen restart Claude Code so the MCP server reconnects.
v1.4.0 — Recordings that start on offer and end by themselves
Meetey no longer needs you to think about it during a meeting. It can notice a call starting and ask, it shows what it is capturing while it runs, and it stops on its own when the call ends.
Upgrade
npx jej2k5/meetey updateThen restart Claude Code so the MCP server reconnects. New installs: npx jej2k5/meetey install.
Changed behaviour
Existing recordings work differently after this upgrade, without you asking:
- Recordings end themselves — when the app quits, when the captured window closes, or when the call itself ends. The last of those trims the file back to when the call ended, so the waiting never reaches your transcript.
- A menu bar item appears while recording, showing what is being captured and for how long, with Stop Recording.
Both are on by default. autoStop: false, stopWhenCallEnds: false, and menuBar: false on start_recording turn them off individually.
Far fewer keyframe files
Screen capture used to write a JPEG whenever the picture differed from the last one. In the standard slide-plus-speaker-tile layout the moving tile always qualified, so a one-hour call filled its 200-frame budget in the first few minutes and recorded nothing after.
Two rules replace that:
- A keyframe is written when the screen stops moving, not when it starts, so a slide transition collapses to the one settled frame — which also reads far better than anything caught mid-fade.
- Regions that are always moving stop counting. A speaker tile, a progress bar, a clock.
Revisiting a slide you already showed no longer writes it twice; the manifest records that it came back.
Watch for meetings
npx jej2k5/meetey watch enableNotices meetings in Chrome, Zoom, and Teams and asks before recording — naming the window, offering audio only or audio + screen. Off until you enable it, and it never starts a recording on its own. Also drivable from /meetey watch inside Claude Code.
Narrow what gets captured
Screen capture can now target a single window rather than everything an app displays, which keeps its other windows and notification banners out of frame. On a multi-monitor setup the display is chosen by where the meeting actually is, rather than whichever display came first.
macOS has no tab-level capture, so a window is as fine as it goes — to isolate one tab, drag it into its own window.
Also
- Transcripts are produced as soon as a watched recording ends, so they are ready before you ask.
Ctrl+Shift+R/Ctrl+Shift+Sare documented as what they are: shortcuts inside Claude Code, not system-wide hotkeys. Stopping from anywhere is what the menu bar is for.sceneThresholdis reachable fromstart_recording; it was previously documented but not wired up.
Requires macOS 13+. After upgrading, macOS may ask for Screen Recording permission again — the capture binary is rebuilt and re-signed. Enabling the watcher asks separately for Node.
v1.2.0 — Admin tools for the meeting library
Your meeting archive is now answerable. Ask Claude Code about it instead of navigating it with ls and grep.
Upgrade
npx jej2k5/meetey updateThen restart Claude Code so the MCP server reconnects with the new tools. New installs: npx jej2k5/meetey install.
Ask about your meetings
"what meetings do I have this week?"
"what did we decide about the API cutover?"
"show me the standup from Thursday"
"how much disk are my recordings using?"
"is meetey working? screen recording seems broken"
"delete the test recording from yesterday but keep the notes"
There is no separate app, dashboard, or web UI — the terminal you already work in is the admin surface.
What's new
| Tool | What it does |
|---|---|
list_recordings |
The library — title, date, duration, transcript quality, keyframe count, size. Filter by date range, quality, or whether screen capture was on |
get_recording |
One meeting in full, notes included, plus paths to its audio, transcript, and keyframes. By session ID or by date |
search_recordings |
Search every meeting's notes and transcripts, returning the matching line with its [mm:ss] offset |
delete_recording |
Removes a session's files. Shows what it would delete and frees nothing until you confirm; keepNotes drops the audio and keyframes but keeps the writing |
system_status |
Install health, Screen Recording permission, active model, disk used — the first thing to check when something isn't working |
Search is the one worth knowing about
Asking "what did we decide about the API cutover?" returns the decision, which meeting it was in, and the timestamp:
2026-08-01 [28:51] (notes) Move the API cutover to next sprint
2026-08-01 [28:51] (transcript) Lets move the API cutover to next sprint then.
You land on the second it was said, rather than opening a transcript and reading. This is what the timestamps introduced in v1.1.0 were for.
Scope it with scope: "notes" to search only decisions and action items, or scope: "transcripts" for everything that was actually said.
Deletion describes before it acts
delete_recording is a dry run unless you pass confirm: true. The first call returns the exact file list and frees nothing, so you always see what's going before anything goes. It also refuses to touch a session that's still recording.
keepNotes is the option you'll probably want: it reclaims the audio and keyframes — which are nearly all of the disk — while keeping the notes and transcript, which are small and are the part worth keeping.
Health in one place
system_status reports the capture binary and its code signature, whisper-cli, the model, MCP registration, the skill, hotkeys, Screen Recording permission, and the disk used by your library. Permission is the most common thing to go wrong and the hardest to diagnose from an error message, so it's checked directly rather than inferred.
Compatibility
No breaking changes. All six capture tools from v1.1.0 behave exactly as before; these five are additions.
Recordings made with earlier versions are picked up automatically, including notes from before v1.1.0 that used the old meetey-<epoch>.md filename. A transcript whose notes file has been deleted still appears in search rather than silently vanishing.
Requirements
macOS 13+, Node.js 18+, Xcode Command Line Tools, Claude Code, Homebrew.
Source-only release. The Swift capture binary is compiled and ad-hoc signed on your machine at install time, which is what lets it hold the ScreenCaptureKit entitlement without notarization.
Licensed under the Apache License 2.0.
v1.1.0 — Screen capture and verifiable notes
Meetey now captures what was on screen, and its notes tell you where every claim came from.
Upgrade
npx jej2k5/meetey updateThen restart Claude Code so the MCP server reconnects. New installs: npx jej2k5/meetey install.
No new permissions. Screen capture uses the Screen Recording access you already granted for audio.
Screen capture — opt-in, per meeting
Meetey can capture slides, screen shares, code, and diagrams alongside the audio, and fold them into the notes.
/meetey start --video Audio + screen keyframes
/meetey start --audio-only Audio only
It is off by default and asked for every time. There is no setting that turns it on permanently — that's deliberate, because screen capture records everything the target app displays, including other tabs, other windows, and notification banners.
It doesn't record video. It samples once a second and keeps a frame only when the picture materially changes, so an hour-long meeting produces a few dozen keyframes rather than 3,600:
| Storage/hr | Sent to Claude | |
|---|---|---|
| Audio | ~115 MB | ~12K tokens (transcript) |
| Screen keyframes | ~10 MB | ~5K tokens (recognized text) |
Text is recognized on-device with the macOS Vision framework, so the default path sends only text. Claude opens an actual keyframe image only when the text isn't enough — a diagram, a chart, a UI screenshot.
Tuning: --fps, --scene-threshold, --max-frames, --no-ocr. See the README.
Notes you can actually check
The output format was rebuilt around one question: if you doubt a line, how fast can you confirm it?
Every claim carries its timestamp.
### Key Decisions
- **[12:04]** Ship v1.1 without the motion heuristic; revisit next cycle
### Action Items
- [ ] **[31:17]** Draft the migration doc — Priya · due FridayThe transcript moved out of the way. It lives in a sibling -transcript.md as timestamped lines, instead of nine thousand unattributed words buried under your action items. It's no longer printed into chat either.
Bad audio announces itself. Transcript quality is now measured — fragment rate, whisper looping, speech pace against spoken time — and a poor transcript says so instead of being summarized in the same confident voice as a clean one:
> ⚠️ Transcription quality: poor — 80% of segments were silence markers,
> fragments, or repeats. Summary may be incomplete; ggml-base.en.bin was used.
Empty states diagnose. "No decisions recorded" means something different when the transcript was too poor to find any — and only that case is fixable, so the notes tell you how.
Filenames are browsable. 2026-08-01-1402-q3-roadmap.md instead of meetey-1754049600.md. ls is now a meeting history.
Everything else
| v1.0.0 | v1.1.0 | |
|---|---|---|
| Decisions | - [decision] |
- **[12:04]** [decision] |
| Transcript | inline, also printed to chat | sibling file, path only in chat |
| Header | 2026-08-01T14:02:11.123Z → … |
Fri 1 Aug 2026, 2:02–2:47 PM · 45 min |
| Bad audio | silently summarized | quality callout + how to fix |
| Filename | epoch integer | date + slug |
| Screen content | — | opt-in keyframes with on-device OCR |
New MCP tool get_keyframes. transcribe now returns timestamped segments, exact duration read from the WAV header, the model used, and a quality assessment.
What stays local
Recording, transcription, and OCR all run on your machine. The summary is written by Claude, so transcript and OCR text goes to the API — keyframe images only when the text isn't enough to read a diagram. Audio never leaves. No meeting bot joins your call. Full breakdown in the README.
Known limitations
- Camera-heavy calls are a poor fit for screen capture. A moving video tile changes the picture constantly and burns through the frame budget. Use it for slides and screen shares; stay on audio for faces-only discussions.
- Capture is process-level, not tab-level. Targeting Chrome captures all Chrome audio, and with
--video, everything Chrome displays. - English-only by default. The bundled model is
base.enand transcription runs with-l en. - No speaker diarization. The transcript is a single stream with no per-speaker attribution.
Requirements
macOS 13+, Node.js 18+, Xcode Command Line Tools, Claude Code, Homebrew.
Source-only release, as with v1.0.0. The Swift capture binary is compiled and ad-hoc signed on your machine at install time, which is what lets it hold the ScreenCaptureKit entitlement without notarization.
Licensed under the Apache License 2.0.
v1.0.0 — Meetey
Meetey captures meeting audio on your Mac, transcribes it locally, and turns it into structured notes — entirely inside Claude Code. No cloud service, no subscription, no audio leaving your machine.
Install
npx jej2k5/meetey installThen open System Settings → Privacy & Security → Screen Recording, enable your terminal app, and start a new Claude Code session.
Usage
| Command | Hotkey | What it does |
|---|---|---|
/meetey start |
Ctrl+Shift+R |
Detects the running meeting app and starts recording |
/meetey stop |
Ctrl+Shift+S |
Stops, transcribes, and writes notes |
/meetey status |
— | Reports whether a recording is active |
/meetey stop produces a summary, key decisions, and action items alongside the full transcript, saved as a .md file next to the WAV in ~/.meetey/recordings/.
What's in this release
- Swift capture binary using ScreenCaptureKit — records app audio as 16-bit PCM WAV at 16 kHz mono, stops on SIGTERM/SIGINT or an optional
--stop-aftertimer. - MCP server exposing five tools:
list_apps,start_recording,stop_recording,transcribe,get_status. Registered globally in~/.claude.json, so it's available in every Claude Code session. /meeteyskill withstart,stop, andstatussubcommands.meeteyCLI withinstall,update, andstatuscommands.statusreports exactly which pieces are wired up and what to run to fix the ones that aren't.- Local transcription via whisper.cpp, defaulting to
ggml-base.en.bin(~142 MB). Swap insmall.enorlarge-v3-turbo-q5_0for better accuracy by settingMEETEY_MODEL.
Supported meeting apps
| App | Bundle ID |
|---|---|
| Chrome (Google Meet / Teams web) | com.google.Chrome |
| Zoom | us.zoom.xos |
| Microsoft Teams (desktop) | com.microsoft.teams |
Requirements
- macOS 13 (Ventura) or later
- Node.js 18+
- Xcode Command Line Tools (
xcode-select --install) - Claude Code
- Homebrew (installed automatically if missing)
Known limitations
- Chrome capture is process-wide. ScreenCaptureKit captures at the process level, not the tab level, so targeting Chrome records all Chrome audio. Mute other tabs before recording.
- No speaker diarization. The transcript is a single stream of text with no per-speaker attribution.
- English-only by default. The bundled model is
base.en, and transcription is invoked with-l en. - Screen Recording permission is required and must be granted to your terminal app, not to Meetey itself.
Source-only release
No prebuilt binary is attached. The Swift capture binary is compiled and ad-hoc code-signed on your machine at install time, which is what lets it hold the ScreenCaptureKit entitlement without notarization.
Licensed under the Apache License 2.0.