How to sync Granola notes into Lightfield
Last updated: April 28, 2026
How to sync Granola notes into Lightfield
Lightfield doesn't pull in Granola notes automatically — they need to be connected via a workflow. Once set up, the workflow runs hourly, matches your Granola meetings to CRM meetings, and loads the notes in as transcripts. From there, the AI can reference them across your opportunities and accounts.
Step 1: Create a time-based workflow
Go to Workflows and create a new workflow
Set the trigger to Time-based
Switch to Advanced and enter
0 * * * *as the cron expression (runs every hour)
Step 2: Add an Agent step
Add an Agent step to the workflow
Step 3: Paste in the sync prompt
In the Agent step prompt, paste the following:
Granola → Lightfield CRM Sync
Context
Granola tool output contains timestamps in UTC timezone. Internal CRM tool outputs contain timestamps in the timezone specified in the system prompt.
Extract the timezone from the system prompt line:
All timestamps are listed in the user's timezone, {timezone}.Match meetings using attendee email overlap + title similarity + time alignment after timezone conversion.
Granola MCP tool outputs are saved to workspace files — read them with bashExecutor (
cat /workspace/.mcp_results/<filename>.json).
Step 1: Fetch data (parallel calls)
Make these calls simultaneously and wait for all results.
1a. Granola meetings
tool: mcp_granola_list_meetings
text
{ "time_range": "custom", "custom_start": "<ISO date: 1 days ago>", "custom_end": "<ISO date: today>"}1b. CRM meetings
tool: getMeetings
text
{ "description": "meetings from the past 1 days", "filterExpression": "startDate:>=<1 days ago ISO> && startDate:<=<now ISO>", "offset": 0, "sortExpression": ["startDate:desc"]}Step 2: Fetch Granola meeting details (one at a time)
For each meeting ID from Step 1a, fetch details individually so each result is saved to its own workspace file:
tool: mcp_granola_get_meetings
text
{ "meeting_ids": ["<single_meeting_id>"]}Each call produces a separate /workspace/.mcp_results/<filename>.json file. Track the mapping of granola_id → file_path for use in Step 4.
Before syncing, extract just the <summary> content into a clean text file (e.g., /workspace/.mcp_results/notes_<granola_id>.txt) using bashExecutor. Only pass the clean file to upsertMeetingTranscript.
Step 3: Match meetings
Use pythonExecutor to match programmatically. Do not match by hand.
Extract the workspace timezone from the system prompt.
Convert Granola UTC timestamps to the workspace timezone using
zoneinfo(never hardcode offsets — handle DST correctly):
python
from datetime import datetimefrom zoneinfo import ZoneInfoorg_tz = ZoneInfo(org_timezone) # from system promptgranola_utc = datetime.fromisoformat(granola_timestamp).replace(tzinfo=ZoneInfo("UTC"))granola_local = granola_utc.astimezone(org_tz)For each Granola meeting, find the CRM meeting where:
Start times are within 30 minutes after timezone conversion, and
Attendee emails overlap, and
Title is similar (fuzzy match — check if titles share key words, ignoring case and filler words)
Only accept a match when at least two of these three signals are strong (e.g., exact title + time match, or 2+ email overlaps + time match). A single shared attendee with a completely different title is not a valid match.
Output matched rows with:
granola_id,granola_file_path,crm_meeting_id,crm_meeting_title,account_name,hasTranscript.
hasTranscript and attendee emails come from the getMeetings output (Step 1b). Skip unmatched meetings on either side.
Step 4: Sync transcripts
For each matched meeting:
If
hasTranscriptistrue: do nothing. Log: "Transcript preserved for [title]."If
hasTranscriptisfalse: upsert the Granola notes as the CRM transcript using the clean file from Step 2.
tool: upsertMeetingTranscript
text
{ "meetingId": "<crm_meeting_id>", "meetingTitle": "<meeting title>", "workspaceFilePath": "<clean notes file from Step 2>", "fileUrl": null, "transcriptText": null}Do not reason about transcript contents. The hasTranscript boolean is the only signal — if it's true, the meeting already has a transcript and you must do nothing.
Step 5: Summarize
Return:
Matched: each Granola → CRM match with meeting title and account name
Synced: which meetings had Granola notes loaded as transcripts
Preserved: which meetings already had transcripts (skipped)
Unmatched: any Granola or CRM meetings that couldn't be matched
Where to find the notes after setup
Once the workflow runs, Granola notes will appear as meeting transcripts on the matching CRM meetings. From there, the AI can surface them when you ask questions about an account or opportunity — you won't need to search for them separately.