Syncs Granola meeting notes to Obsidian vault. Reads from Granola's local cache to extract meeting metadata and notes, then creates properly formatted markdown files with frontmatter. Also handles manual transcript formatting when cache doesn't have content.
Manual formatting:
When local cache has no notes, ask user to copy from Granola app. </limitation>
~/Library/Application Support/Granola/cache-v3.json
{
"cache": "{\"state\":{\"documents\":{...}}}" // nested JSON string
}
Each document contains:
id - unique meeting IDtitle - meeting titlenotes_markdown - notes content (often empty)notes_plain - plain text versiongoogle_calendar_event.start.dateTime - meeting timegoogle_calendar_event.attendees - list with email fields<read_cache>
cat ~/Library/Application\ Support/Granola/cache-v3.json | python3 -c "
import json,sys
d=json.load(sys.stdin)
cache=json.loads(d['cache'])
docs=cache['state']['documents']
# List meetings with notes
for doc in docs.values():
md = doc.get('notes_markdown', '')
if md and len(md) > 50:
title = doc.get('title', 'Untitled')
cal = doc.get('google_calendar_event') or {}
start = cal.get('start') or {}
dt = start.get('dateTime', '')[:10]
print(f'{dt} | {title[:40]} | {len(md)} chars')
"
</read_cache>
<file_format>
Filename: YYYY-MM-DD-kebab-case-title.md
Location: Project meetings folder (e.g., Projects/project-name/meetings/)
---