{"slug": "show-hn-meeting-notes-sync-import-transcripts-and-ai-summaries-into-obsidian", "title": "Show HN: Meeting Notes Sync – import transcripts and AI summaries into Obsidian", "summary": "Developer Andrea Grandi released an Obsidian plugin that syncs meeting transcripts, notes, and AI summaries from MacParakeet and Fellow into a user's vault, merging recordings from both sources into a single folder. The plugin is pending community-store review and can be installed via BRAT or manually.", "body_md": "Sync meeting transcripts, notes, and AI summaries from MacParakeet and Fellow into your vault.\n\nObsidian plugin that syncs your meeting transcripts, notes, and AI summaries into your vault — from [MacParakeet](https://macparakeet.com) and [Fellow](https://fellow.app), one folder per meeting. A meeting recorded by both sources merges into a single folder instead of duplicating.\n\n`Summary (MacParakeet).md`\n\n, `Summary (Fellow).md`\n\n), so a meeting captured by both stays unambiguous.`merge-confidence: low`\n\nfor review.\n\n```\nMeetings/2026/06 - June/2 - Weekly Standup - Jun 11th/\n  2 - Weekly Standup - Jun 11th.md     ← index: macparakeet-id + fellow-id + interval\n  Summary (MacParakeet).md\n  Transcript (MacParakeet).md\n  Notes.md\n  Summary (Fellow).md\n  Action Items (Fellow).md\n  Transcript (Fellow).md\n```\n\nEach source is toggled independently; a disabled source is completely inert — no requests, writes, or notices.\n\nReads meetings from `macparakeet-cli`\n\n(no network, no accounts, no database access). Requires macOS with [MacParakeet](https://macparakeet.com) installed (the CLI ships inside the app) or the standalone CLI (`brew install moona3k/tap/macparakeet-cli`\n\n), and Obsidian desktop. The plugin auto-detects the CLI (Homebrew paths, then the app bundle); override the path in settings if needed, and the health check confirms it. Enable it in *Settings → Meeting Notes Sync*.\n\nPolls Fellow's REST Developer API for cloud AI recaps. Setup:\n\n`acme`\n\nin `acme.fellow.app`\n\n) and ⚠️ The Fellow key is stored in plaintext in\n\n`data.json`\n\n(standard for API-backed plugins). If your vault is in git or a synced folder, exclude that file and treat the key as a secret; revoke it in Fellow if it leaks.\n\nPending community-store review — until it lands there, install via [BRAT](https://github.com/TfTHacker/obsidian42-brat) (*Add beta plugin* → `andreagrandi/obsidian-meeting-notes-sync`\n\n), or manually drop `main.js`\n\n+ `manifest.json`\n\nfrom a [release](https://github.com/andreagrandi/obsidian-meeting-notes-sync/releases) into `<vault>/.obsidian/plugins/meeting-notes-sync/`\n\nand enable the plugin. To build from source:\n\n```\ngit clone https://github.com/andreagrandi/obsidian-meeting-notes-sync\ncd obsidian-meeting-notes-sync && npm install && npm run build\n# copy main.js + manifest.json into <vault>/.obsidian/plugins/meeting-notes-sync/\n```\n\nIf you used an earlier build under the `macparakeet-sync`\n\nid: quit Obsidian, rename `<vault>/.obsidian/plugins/macparakeet-sync/`\n\n→ `meeting-notes-sync/`\n\n, reopen, and re-enable. This keeps `data.json`\n\n(numbering, snapshots, file ownership) so the next sync is a no-op instead of re-importing. Existing folders keep their names; only new artifacts get the source suffix.\n\nSync runs shortly after launch and every 30 minutes (configurable; `0`\n\ndisables), or on demand via the ribbon icon / **Sync now**. The main settings:\n\n`Meetings/…`\n\nis the root).`{year}`\n\n· `{month}`\n\n· `{monthName}`\n\n(June) · `{monthShort}`\n\n(Jun) · `{day}`\n\n· `{dayOrdinal}`\n\n(2nd) · `{date}`\n\n(YYYY-MM-DD) · `{n}`\n\n(per-month number) · `{title}`\n\n. Unknown tokens are left as-is.\n\nDefault: `Meetings/{year}/{month} - {monthName}/{n} - {title} - {monthShort} {dayOrdinal}`\n\n→ `Meetings/2026/06 - June/4 - Core sync-discovery - Jun 2nd`\n\n. The trailing date disambiguates recurring meetings that share a title.\n\n**Overlap threshold** (fraction of the shorter meeting, default 0.5) and **minimum overlap (minutes)** govern when two sources' meetings are treated as one. Raise them to merge more conservatively.\n\n| Command | What it does |\n|---|---|\n`Sync now` |\nSync enabled sources; reports `X new, Y updated, Z unchanged` |\n`Check connection` |\nVerify `macparakeet-cli` is reachable (Fellow's check lives in settings) |\n`Force re-sync` |\nRe-process all in-scope meetings (picks up in-place regenerated summaries) |\n\n`{n}`\n\n) and the folder name are frozen on first import and never change — a later source merges in without renumbering.Each source sits behind a common adapter and a source-agnostic engine: MacParakeet via `macparakeet-cli`\n\n(`meetings list/show/results list --json`\n\n), Fellow via its REST API (`/me`\n\n, `/recordings`\n\n, `/recording/{id}`\n\n, `/note/{id}`\n\n) with `updated_at`\n\nchange detection. Meetings are merged across sources by interval overlap, and sync state (numbering, per-file ownership, per-source snapshots) lives in `data.json`\n\n. Details in [PLAN.md](PLAN.md).\n\n```\nnpm install\nnpm run dev     # esbuild watch\nnpm test        # vitest\nnpm run build   # typecheck + production bundle\n```\n\nCI runs build + tests on every push and PR.\n\n**Live Fellow test** — `npx -y tsx scripts/fellow-live-test.mts`\n\nruns the real engine (local CLI + live Fellow API) into a temp vault. It reads `FELLOW_SUBDOMAIN`\n\n/ `FELLOW_API_KEY`\n\nfrom `.env`\n\n(see `.env.example`\n\n) for the harness only; the plugin itself never reads the environment — end users configure the subdomain and key in the settings UI.\n\n**Releasing** — `npm run release <major.minor.patch>`\n\n(e.g. `npm run release 0.3.1`\n\n) bumps `package.json`\n\n, `manifest.json`\n\n, `versions.json`\n\n, and the lockfile, then commits and creates the unprefixed `X.Y.Z`\n\ntag. Push it (`git push origin master && git push origin <version>`\n\n) to trigger `.github/workflows/release.yml`\n\n, which attests `main.js`\n\n's build provenance and attaches `main.js`\n\n+ `manifest.json`\n\nto a GitHub release (Obsidian downloads only those two; `versions.json`\n\nis read from the repo). A plain `npm run`\n\nscript is used (not the `npm version`\n\nlifecycle hook) so it works regardless of a global `ignore-scripts=true`\n\n. Community-store submission to [ obsidianmd/obsidian-releases](https://github.com/obsidianmd/obsidian-releases) is a one-time manual step after the first release.", "url": "https://wpnews.pro/news/show-hn-meeting-notes-sync-import-transcripts-and-ai-summaries-into-obsidian", "canonical_source": "https://community.obsidian.md/plugins/meeting-notes-sync", "published_at": "2026-06-18 08:34:11+00:00", "updated_at": "2026-06-18 08:53:26.235926+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools"], "entities": ["Andrea Grandi", "Obsidian", "MacParakeet", "Fellow", "BRAT"], "alternates": {"html": "https://wpnews.pro/news/show-hn-meeting-notes-sync-import-transcripts-and-ai-summaries-into-obsidian", "markdown": "https://wpnews.pro/news/show-hn-meeting-notes-sync-import-transcripts-and-ai-summaries-into-obsidian.md", "text": "https://wpnews.pro/news/show-hn-meeting-notes-sync-import-transcripts-and-ai-summaries-into-obsidian.txt", "jsonld": "https://wpnews.pro/news/show-hn-meeting-notes-sync-import-transcripts-and-ai-summaries-into-obsidian.jsonld"}}