Skip to main content

GranolaDB

The database that runs on your meeting notes.

Stop paying for S3, CloudWatch, and Datadog. GranolaDB stores your logs and agent traces in Granola — the AI meeting-notes app — as meeting notes. Infinitely scalable*. Fully searchable**. Your traces finally get an AI summary.

Install

pip install granoladb            # core
pip install granoladb[otel]      # + OpenTelemetry span exporter
pip install granoladb[capture]   # + `granoladb login --capture` (macOS)

Then get your Granola access token. On macOS, GranolaDB grabs it for you:

granoladb login --capture

This intercepts your own Granola app's traffic (via mitmproxy's local mode) and lifts the Authorization: Bearer token out of it — because Granola encrypts the token on disk and its network client ignores every proxy, so there's genuinely no politer way to get it. You'll approve a one-time macOS network-extension prompt, then click around a couple of notes so the app makes a request. Yes: GranolaDB MITMs your own Granola to obtain a token Granola won't hand out. That is the joke, and it is load-bearing.

The token is a short-lived session JWT (expires in a few hours) — rerun --capture when it does. Or, if you have a token another way, cache it directly:

granoladb login <YOUR_TOKEN>     # store it (OS keychain)
export GRANOLA_TOKEN="..."       # or per-shell, nothing stored
granoladb logout                 # forget the stored token

(There's also an experimental granoladb login --auto that tries to decrypt the token straight from the app's local store, but Granola's on-disk crypto changes often, so don't count on it.)

Exactly how --capture works (no hidden magic)

We think you should know precisely what this does before running it:

  1. It launches mitmproxy in "local mode" pointed at the Granola process only. mitmproxy installs a macOS network extension ("Mitmproxy Redirector") that you approve once — it reroutes only Granola's traffic through mitmproxy.
  2. Why intercept at all: Granola encrypts the token on disk and its API client ignores every proxy (system, env, VPN), so there is no file to read or setting to flip. Intercepting the app's own traffic is the only way to obtain it.
  3. What it reads: when Granola calls api.granola.ai, the request carries an Authorization: Bearer <token> header. --capture extracts only that value.
  4. Where it goes: stored locally only — in your OS keychain (macOS Keychain / Windows Credential Manager / Freedesktop Secret Service) via the keyring library. If no keychain backend exists, it falls back to a 0600 file at ~/.granoladb/token and tells you it did so. Nothing is sent anywhere. The mitmproxy process and its temporary capture file are torn down immediately.
  5. What the token is: your own short-lived Granola session JWT — not your password, not a refresh token. granoladb logout deletes it.

The whole capture flow is in src/granoladb/capture_macos.py and storage is in src/granoladb/auth.py — read them.

Quickstart

import logging, granoladb

logging.getLogger().addHandler(granoladb.GranolaHandler())
logging.error("payment failed")   # this is now a meeting
from granoladb import Client
db = Client()
db.put({"level": "ERROR", "msg": "payment failed", "svc": "api"})
print(db.query(contains="payment"))

vs. legacy databases

Feature Postgres S3 GranolaDB
Durability Yes Yes "probably"
Query latency ms ms one flush interval
AI summary of rows No No Yes
Retention policy You set You when Granola archives it
Production ready Yes Yes absolutely not

* limited by Granola's rate limits, which we call horizontal scaling. ** limited by Granola's search bar.

How it works

Records are batched into "meetings." Each batch becomes one Granola document — JSON lines under a GRANOLADB v1 marker, written via Granola's internal /v1/create-document endpoint and read back via /v1/get-documents. Reads decode the records out. This is a joke. Do not put anything real in it.

Auth: granoladb login --capture (see above) stores your token in the OS keychain, or set GRANOLA_TOKEN. Set GRANOLADB_DRY_RUN=1 to print calls instead of writing to Granola.

License

MIT

Metadata

Release files for granoladb 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for granoladb 0.1.0
File Size Uploaded
granoladb-0.1.0.tar.gz 22.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for granoladb 0.1.0
File Interpreter ABI Platform
granoladb-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 40.4 kB

Release files / granoladb-0.1.0.tar.gz

Download URL granoladb-0.1.0.tar.gz
Size 22.6 kB
Tags Source
SHA-256 checksum
How to use checksums
fdf01faeb63a7c46973fd10e9f553fddc1f9fa1c8221a71d5d8e20830c5ce09b
BLAKE2b-256 checksum
How to use checksums
e189d83a7836ed3527b8cfb2dbb3dbdb1b3618d66e240582a98b2ff555b86265
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.12

Release files / granoladb-0.1.0-py3-none-any.whl

Download URL granoladb-0.1.0-py3-none-any.whl
Size 17.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1d1d76537dde9d18b23d2bc36b2f96c24e71a894f732ca5b7ede72eb49d764d4
BLAKE2b-256 checksum
How to use checksums
2f3cb4201a92f5d41293ccf0bd8ec678aef2fdd9e88a9fc94e43f39787b90b71
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.12

Release history Release notifications | RSS feed

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page