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/)
---
type: meeting
project: <project-name>
status: active
date: YYYY-MM-DD
attendees:
- name1
- name2
source: granola
granola-id: <meeting-id>
tags:
- meeting
---
# Meeting Title
**Date**: YYYY-MM-DD
**Attendees**: Name1, Name2
---
## Notes
<notes_markdown content>
</file_format>
<manual_format> When user pastes a transcript without cache data:
Ask for metadata if not obvious:
Structure the content:
---
type: meeting
project: <project>
status: active
date: YYYY-MM-DD
attendees:
- name1
- name2
source: granola-manual
tags:
- meeting
---
# Topic Name
**Date**: YYYY-MM-DD
**Attendees**: Name1, Name2
---
## Summary
<2-3 sentence summary>
## Key Decisions
- Decision 1
- Decision 2
## Discussion Notes
<cleaned transcript, organized by topic>
## Action Items
- [ ] Action 1 (owner)
- [ ] Action 2 (owner)
</manual_format>
When syncing from cache:
📥 **Granola Sync**
Found X meetings with notes:
- YYYY-MM-DD: Meeting Title (XXX chars)
Syncing to `Projects/project/meetings/`...
✓ Created: 2025-01-28-meeting-title.md
When no notes in cache:
📥 **Granola Sync**
Found X meetings but none have local notes cached.
Paste transcript content and I'll format it.
Google Workspace CLI for Gmail, Calendar, Drive, Contacts, Sheets, and Docs.
Manage Apple Notes via the `memo` CLI on macOS (create, view, edit, delete, search, move, and export notes). Use when a user asks OpenClaw to add a note, list notes, search notes, or manage note folders.
Work with Obsidian vaults (plain Markdown notes) and automate via obsidian-cli.
Use when you need to control Slack from OpenClaw via the slack tool, including reacting to messages or pinning/unpinning items in Slack channels or DMs.
Manage Apple Reminders via remindctl CLI (list, add, edit, complete, delete). Supports lists, date filters, and JSON/plain output.
Manage Trello boards, lists, and cards via the Trello REST API.
Category:productivity