Gran 👵🏻

SDK

Use Gran's Node and TypeScript SDK to load config, create the local app core, connect to a running service, and export archives from code.

@kkarimi/gran-sdk is the Node-first package for people who want Gran's local-first core without shelling out to CLI commands.

Install it alongside @kkarimi/gran when you want to embed Gran in scripts, local apps, or agent workflows:

npm install @kkarimi/gran-sdk

Create The App Core

import { createGranSdk } from "@kkarimi/gran-sdk";

const { app, config } = await createGranSdk({
  apiKey: process.env.GRAN_API_KEY,
});

console.log(config.notes.output);
const meetings = await app.listMeetings({ limit: 10 });

If you want config loading separated from app creation:

import { createGranApp, loadGranConfig } from "@kkarimi/gran-sdk";

const config = await loadGranConfig({ config: `${process.env.HOME}/.config/gran/config.json` });
const app = await createGranApp(config, { surface: "server" });

Connect To A Running Local Service

If gran service start or gran web already has the shared runtime running, you can connect to it over the existing local transport:

import { connectGranService } from "@kkarimi/gran-sdk";

const client = await connectGranService("http://127.0.0.1:5051");

console.log(client.getState().sync.lastCompletedAt);
const folders = await client.listFolders();
await client.close();

This is the easiest path for browser-side tooling, agent integrations, or other local processes that should reuse the existing Gran runtime instead of spinning up another app instance.

Export An Archive

The SDK exposes the same bundled export shape as the CLI:

import { createGranSdk, exportGranArchive } from "@kkarimi/gran-sdk";

const { app } = await createGranSdk({
  apiKey: process.env.GRAN_API_KEY,
});

await exportGranArchive(app, {
  folder: "Team",
  outputRoot: "./gran-exports",
});

By default that writes:

  • notes to ./gran-exports/notes
  • transcripts to ./gran-exports/transcripts

You can also use includeNotes: false or includeTranscripts: false when you only want one side.

Save Knowledge Base Profiles

import { createGranExportTarget, createGranSdk, saveGranExportTarget } from "@kkarimi/gran-sdk";

const { app } = await createGranSdk({
  apiKey: process.env.GRAN_API_KEY,
});

await saveGranExportTarget(
  app,
  createGranExportTarget("obsidian-vault", {
    dailyNotesDir: "Daily",
    id: "obsidian",
    name: "My Obsidian Vault",
    outputDir: "/Users/you/Documents/Obsidian",
  }),
);

The helper fills in sensible defaults for folder and Obsidian-friendly knowledge-base profiles, so user code does not need to know the internal default subdirectory or format rules.

For API-backed destinations like Notion, Capacities, or Tana, keep Gran as the source-side SDK and let Yazd own the actual knowledge-base plugin and remote publish flow.

Build Obsidian Open URLs

import { buildObsidianOpenFileUri } from "@kkarimi/gran-sdk";

const noteUrl = buildObsidianOpenFileUri({
  filePath: "Meetings/Team/Launch Review-notes.md",
  target: {
    outputDir: "/Users/you/Documents/Obsidian",
    vaultName: "Work",
  },
});

On this page