peepshow/ sinks/ granola

Reel #78 Meeting notes import

peepshow sink / granola

GranolaDrop a peepshow run straight into Granola as a meeting note.

Write a self-contained markdown bundle (note + frames) into a Granola import directory. Granola's public API is read-only, so peepshow uses a file-drop path the user drags into Granola — no upload, no clipboard juggling.

drop · process · granola

What it does

[Granola](https://granola.ai) is the AI meeting-notes desktop app for macOS and Windows. Its public API (`https://public-api.granola.ai/v1`) is currently read-only — `GET /v1/notes`, `GET /v1/notes/:id`, `GET /v1/folders` and nothing else. This sink takes the practical path: it writes a per-run markdown bundle (`note.md` + a `frames/` folder) into a configurable import directory (`~/Documents/Granola Imports/` by default), pre-formatted with a heading, meeting details, container tags, timestamped transcript segments, and embedded frame thumbnails. Drag the folder into Granola or open `note.md` and paste — the markdown is shaped to render cleanly inside Granola's editor. When Granola ships a write endpoint, the sink will swap the file-drop path for an HTTP POST without touching the markdown formatter.

When to reach for it

  • Pipe meeting recordings (Zoom, Loom, screen captures) through peepshow and into your Granola workspace as native notes
  • Build a paper trail of every video an agent watched alongside your live-attended meetings — same import dir, same review workflow
  • Skip context-switching: drop a video at Claude / Cursor, the agent watches + summarises, Granola gets the structured note for follow-up

Install

npm i -g peepshow

Use it

peepshow ./standup.mp4 --sink granola

Make it automatic

Register the sink once — every run fires it afterward. Scope by --when so it only runs for matching videos.

peepshow sinks add granola
peepshow sinks add granola --when extension=mp4,mov
peepshow sinks add granola --when path=/Volumes/Work/

Configuration

  • GRANOLA_IMPORT_DIR Absolute path to the import directory. Default: `~/Documents/Granola Imports`. Created on first write.
  • GRANOLA_TITLE_PREFIX Prepended to every note title — useful for distinguishing peepshow imports from meetings (e.g. `peepshow: `).
  • GRANOLA_COPY_FRAMES Default `1`; set `0` to embed frames by absolute path instead of copying them into the bundle.
  • GRANOLA_API_KEY Reserved for the future Granola write endpoint. When set, the note records its presence; the sink still uses the file-drop path until the upstream API supports note creation.

Use with an LLM agent

Every peepshow sink reads its config from env vars and receives a single JSON payload on stdin. An LLM agent (Claude Code, Cursor, Windsurf, Gemini, Codex) can drive the Granola sink automatically when three things are true:

  • the env vars below are exported in the agent's shell (or a project .env it can load),
  • the peepshow CLI is on PATH — install with npm i -g peepshow,
  • a peepshow auto-sink is registered for the run (optional but recommended — makes invocation zero-argument).

1. Set the environment

This sink has no required env vars — it writes to a local path. Pass the destination via --sink-arg:

peepshow ./standup.mp4 --sink granola

2. Register as an auto-sink

peepshow sinks add granola
peepshow sinks add granola --when extension=mp4,mov

3. Example LLM session

You → drop a .mov into Claude Code.

Claude → auto-invokes /peepshow:slides ./clip.mov. peepshow extracts frames + audio, the Granola sink forwards the run to a new page in your knowledge base. Claude replies with a summary and a link to the created record.

The transcript text is embedded alongside the frame gallery on the created page.

Write your own

A sink is any executable that reads the --emit json payload on stdin. Shell, Node, Python, Go — the spec's in docs/PLUGINS.md. Register persistent ones with peepshow sinks add-cmd 'your-command'.