Skip to content

Granola (notes source)

@notewright/granola-notes-provider is the built-in notes source. It syncs meeting notes and transcripts from Granola into D1. It contributes a sync Durable Object (GranolaSyncAgent) that runs on a cron and on demand.

Terminal window
bun add @notewright/granola-notes-provider
import { defineApp } from "@notewright/core";
import { granola } from "@notewright/granola-notes-provider";
const app = defineApp({ notes: granola, followUp: /* your sink */ });
export default app;
export const { FollowUpAgent, SpeakerContextAgent } = app.durableObjects;
export { GranolaSyncAgent } from "@notewright/granola-notes-provider";

The provider exports the granola extension and the GranolaSyncAgent Durable Object class. You must re-export GranolaSyncAgent from your entry so Cloudflare can resolve it by class_name.

The granola provider declares this configSchema:

KeyKindRequiredPurpose
GRANOLA_API_KEYsecretYesGranola API key, used to authenticate sync.
GRANOLA_API_BASE_URLvarNoOverride the Granola API base URL.
GRANOLA_PAGE_SIZEvarNoPage size for listing updated notes.
GRANOLA_REQUESTS_PER_SECONDvarNoClient-side rate limit for outbound requests.

Put GRANOLA_API_KEY in your deploy secrets (.env, applied with --secrets-file), and the optional vars in the vars block of wrangler.jsonc if you need to override the defaults.

  • Cron. GranolaSyncAgent registers the schedule 0 0 * * 2-6 (weekday evenings) on first start. Wake it after deploy with notewright start so the schedule registers. (/health is a core-owned Worker route; it does not reach the provider Durable Object, so it never registers the cron.)
  • On demand. notewright sync (or POST /sync) triggers a sync immediately. Because the Granola extension declares a sync binding, the /sync route forwards to the GranolaSyncAgent rather than running inline.

See Syncing & backfill for running and observing syncs.

The Granola extension contributes the following through its runtime fragment, so you do not hand-write them beyond the canonical wrangler.jsonc:

  • Durable Object binding GRANOLA_SYNC_AGENT → class GranolaSyncAgent.
  • DO migration granola-v1 for the GranolaSyncAgent SQLite class.