Define a tool. Get a backend.

LocalFirst turns tool definitions into SQLite persistence, auto-migrations, CRUD, and AI-ready adapters — all from a single schema.

$bunx localfirstdotsh init
index.ts
1const createReminder = defineTool({
2 name: "create_reminder",
3 input: z.object({
4 title: z.string(),
5 dueAt: z.string(),
6 }),
7 persist: { entity: "reminders", indexes: ["dueAt"] },
8});
9
10const app = createLocalFirst({ dbPath: "./app.db", tools: [createReminder] });
11await app.migrate();
12await app.execute("create_reminder", { title: "Ship v1", dueAt: "2026-04-01" });

Tool → database

The schema is your migration

CRUD generated

List, get, update, delete. Zero boilerplate

Works with any LLM

OpenAI, Anthropic, Gemini, Ollama, MCP

Local-first by default

SQLite, no network, no backend

Approval flows built in

Gate any tool behind a human-in-the-loop check

The magic in one file

Define. Wire. Execute.

That's the entire backend. No database schema to design, no migrations to write, no API to build.

The tool definition is the schema. LocalFirst derives everything else.

decisions.ts
1import { z } from "zod";
2import { defineTool, createLocalFirst } from "@localfirstdotsh/core";
3
4// 1. Define the tool
5const logDecision = defineTool({
6 name: "log_decision",
7 description: "Record a decision with context and rationale",
8 input: z.object({
9 title: z.string(),
10 context: z.string(),
11 decision: z.string(),
12 }),
13 persist: { entity: "decisions" },
14});
15
16// 2. Wire up the runtime
17const app = createLocalFirst({
18 dbPath: "./decisions.db",
19 tools: [logDecision],
20});
21await app.migrate(); // table + indexes created automatically
22
23// 3. Execute — from your code or an AI model
24await app.execute("log_decision", {
25 title: "Hire contract vs full-time",
26 context: "Q2 headcount tight",
27 decision: "Contract for 3 months, revisit in June",
28});
How it works

Three steps. Zero boilerplate.

01

Define a tool

Zod schema, persist config, optional handler

02

LocalFirst generates

SQLite table, migrations, CRUD API, AI-compatible descriptor

03

Execute from anywhere

Your app, an AI model, the CLI, or an MCP client

Philosophy

The database is a detail

Most stacks start with a database schema. You design tables, write migrations, build an API, then wire up your app.

LocalFirst starts with tools — the things your system can do. The database is derived from those definitions, not designed upfront.

When the tool changes, the migration is automatic. When you add a field, no schema file to update. No API layer to maintain.

You describe behavior. LocalFirst handles persistence.

Before vs After

Skip the ceremony.

Without LocalFirst

  • Design database schema
  • Write and manage migrations
  • Build CRUD API
  • Write validation layer
  • Wire to AI tool format
  • Handle approval logic separately

With LocalFirst

  • Define tool
  • Done
Integrations

Works with your stack.

First-class adapters for the tools you already use.

OpenAIadapter-model serializes tools for the OpenAI tool-calling format
AnthropicNative tool-use format out of the box
MCPExpose any tool over the Model Context Protocol in one line
Gemini / OllamaGeneric adapter covers any provider
Claude Codebunx localfirstdotsh install claude generates the MCP config
CLI

Everything from the terminal.

The dev command boots a full inspect workbench — browse tools, entities, data, tasks, migrations, approvals, and audit logs.

terminal
$
bunx localfirstdotsh init --example

# Scaffold a working instance

$
bunx localfirstdotsh dev

# Open inspect UI against your local db

$
bunx localfirstdotsh serve

# Start an MCP server

$
bunx localfirstdotsh install claude

# Wire into Claude Code

The Inspect Workbench

LocalFirst Inspect UI — browse tools, entities, capabilities, migrations, and data
Use cases

Built for real workflows.

AI memory

Persist everything an agent learns or decides, automatically

Decision logs

Build a searchable record of AI-assisted decisions

Research store

Structure and query notes, sources, and findings from any LLM session

CRM without a backend

Contacts, interactions, and follow-ups driven entirely by tools

Agent action history

Every tool call logged, indexed, queryable

Approval-gated automation

Let the model suggest, let the human confirm

Advanced

For when you need more.

Production-grade features that grow with your use case.

Durable tasks

Queue long-running tool executions with retries, checkpoints, and cancellation

Approval workflows

manual, auto, or always_allow per tool or globally

Workflow graph

Resource links with cascade policies between entities

Schema migrations

Safe vs risky change detection, migration preview before apply

Audit logging

Every execution, approval, and rejection is recorded

Inspect UI

Full workbench bundled with the CLI

Start building local-first tools today.

No database setup. No API boilerplate. No backend.

$bunx localfirstdotsh init --example
bun add @localfirstdotsh/core zod