Skip to content
Dev ResourcesTested on Busabase 0.95.1, October 9, 2026

Busabase Setup Guide: Let Agents Write, Review Every Change

Run Busabase locally in one command, connect Claude Code, Codex or Cursor over MCP, build your first Base, and decide which agent writes wait for your review. Every step tested on a fresh install.

Busabase · Agent writes, human review
Every change your agent makes, as a diff you approve.
BusabaseAI AgentsMCPClaude CodeCodexCursorHuman in the LoopSelf-HostingOpen SourceTutorial
Cost
$0 (MIT, runs locally)
Time
~20 min
Steps
7
Stack
Node 24 · PGlite · MCP
What you'll get
  • ✓A local Busabase workspace running on your machine, no account and no database to install
  • ✓Claude Code, Codex or Cursor connected to it over MCP
  • ✓A first Base your agents read and write, built in two API calls
  • ✓Agent writes that wait for your approval, with a field-level diff and a history you can audit
Share

Every agent session starts from zero. The useful thing Claude Code worked out on Monday lives in a chat you will never open again, and on Tuesday Codex asks you to explain the project from the top. The fix people reach for is a shared store the agents can read and write. Then the real question shows up: would you let an agent write to your data with nobody looking?

Busabase is an open-source (MIT) database and workspace built around that question. Agents and people share the same records, docs, skills and apps, and every agent write travels as a Change Request: a message, an author, a field-level diff and a history. Your permissions decide whether a change merges on the spot or waits in your inbox.

I installed version 0.95.1 on a Mac with a fresh data directory and ran every command below against it, including the agent writes over MCP. Where the behaviour surprised me, there is a callout.

Step 1 of 7
3 min

Start Busabase

At a glance
Command
npx busabase server
URL
http://localhost:15419
Data
~/.busabase/data (PGlite + files)

One command, no database, no account, no config file. It starts an embedded PGlite database and local file storage:

Terminal
npx busabase server

#   ➜  Server   http://127.0.0.1:15419
#   ➜  Data     ~/.busabase/data
#   ➜  Access   bound to 127.0.0.1, this machine only

Open http://localhost:15419 and you land on the dashboard. The flags you will actually use are --port, --data for a different data folder, and --host. Other ways to run the same thing:

Terminal
# Docker (also on GHCR as ghcr.io/busabase/busabase)
docker run --rm -p 15419:15419 -v ~/.busabase/data:/data busabase/busabase

# Global install
npm i -g busabase && busabase server

# A second, throwaway workspace on another port
npx busabase server --port 15420 --data ~/busabase-sandbox

There is also a desktop app for macOS, Windows and Linux at busabase.com/download, which runs the same local workspace without a terminal.

Node 24.18 or newer
The 0.95.1 packages declare node >=24.18.0. On 24.13 the server still started for me, with a wall of EBADENGINE warnings. Upgrade Node or use Docker so you are not debugging that later.
Why the workspace is empty
A fresh install has no Bases (GET /api/v1/bases returns []). That is on purpose: the first agent you connect builds a starter workspace for you in step 2, or you build one yourself in step 3.
Step 2 of 7
4 min

Connect your agent

At a glance
Easiest
Paste the setup prompt
MCP
POST http://localhost:15419/api/mcp
Scripts
OpenAPI at /api/v1/openapi.json

The easy way: let the agent onboard itself. The server publishes a setup skill at /SETUP_SKILL.md. Paste this into Claude Code, Codex, Cursor, Gemini CLI or anything else that can read a URL:

Prompt for your agent
Read and follow the Busabase Agent Skill, it is the single source of truth:
http://localhost:15419/SETUP_SKILL.md

Follow its onboarding to connect to this workspace. Don't choose a merge policy
yourself unless I ask for one: submit the change and let Busabase apply my
permissions to decide whether it merges now or waits for review.

The skill walks the agent through four milestones: connect, initialize a starter workspace (it offers Content Pipeline, Compliance Checklists, Knowledge Base, CRM Contacts, or a custom one), verify, and install the permanent skills. It asks you one lettered question at a time, so you stay in charge of what gets built.

The MCP way: give the agent typed tools. The local server speaks MCP over Streamable HTTP at /api/mcp. On 0.95.1 it lists 99 tools: bases, records, docs, file trees, search, comments, and the Change Request tools. Add it once per client:

Terminal · Claude Code
claude mcp add --transport http --scope user busabase http://localhost:15419/api/mcp
~/.cursor/mcp.json
{
  "mcpServers": {
    "busabase": { "url": "http://localhost:15419/api/mcp" }
  }
}
~/.codex/config.toml
[mcp_servers.busabase]
url = "http://localhost:15419/api/mcp"

The server's own instructions tell the agent to call auth_verify first and then playbooks_search with your request, so it looks for a saved playbook before it improvises. That is the habit you want.

The script way. Every operation is also a REST endpoint: the spec is at /api/v1/openapi.json and a Swagger page at /api/v1/doc. To save the connection for the CLI and the installed skills, run:

Terminal
npx busabase-cli login --base-url "http://localhost:15419"
A 405 on /api/mcp is fine
Opening /api/mcp in a browser returns 405. MCP clients POST to it. If you want to check it by hand, send an initialize request with curl -X POST and an accept: application/json, text/event-stream header.
Step 3 of 7
4 min

Build your first Base

At a glance
Base
A table of typed fields
Calls
1 folder + 1 Base
Or
busabase-cli install <template>

A Base is a table with typed fields: text, longtext, markdown, number, date, select, multiselect, url, email, attachment, relation and more. You can ask your agent to make one, click it together in the UI, or do it in two calls. Here is a small sales pipeline, folder first so the sidebar is not a flat list:

Terminal
# 1. A folder (structure changes are Change Requests too)
curl -X POST http://localhost:15419/api/v1/nodes/change-requests \
  -H 'content-type: application/json' \
  --data '{"message":"Create the Sales folder","autoMerge":true,
           "operations":[{"kind":"create","nodeType":"folder","slug":"sales","name":"Sales"}]}'
# -> read mergeSummary.mergedNodeIds[0], that is the folder id

# 2. The Base inside it
curl -X POST http://localhost:15419/api/v1/bases \
  -H 'content-type: application/json' \
  --data '{
    "slug": "leads", "name": "Leads", "parentNodeId": "<FOLDER_ID>", "autoMerge": true,
    "fields": [
      { "slug": "name",    "name": "Name",      "type": "text", "required": true },
      { "slug": "company", "name": "Company",   "type": "text" },
      { "slug": "stage",   "name": "Stage",     "type": "select",
        "options": { "choices": [
          { "id": "lead", "name": "Lead", "color": "slate" },
          { "id": "qualified", "name": "Qualified", "color": "amber" },
          { "id": "customer", "name": "Customer", "color": "emerald" } ] } },
      { "slug": "deal",    "name": "Deal size", "type": "number" },
      { "slug": "notes",   "name": "Notes",     "type": "longtext" }
    ]
  }'

Add a few rows the same way, one call per record:

Terminal
curl -X POST http://localhost:15419/api/v1/bases/<BASE_ID>/change-requests \
  -H 'content-type: application/json' \
  --data '{"fields":{"name":"Dana Ortiz","company":"Northwind Labs","stage":"lead","deal":4800},
           "message":"Add Dana Ortiz from the inbound form",
           "idempotencyKey":"seed:v1:dana","autoMerge":true}'
A Busabase Base called Leads with four records: name, company, stage and deal size
The Leads Base after four seed rows. The first field (Name) becomes the record's title everywhere.

Or start from a template. A template is a whole working setup: Bases, views, docs, sample data, apps, and a manual that tells the agent how to use them. The local catalog lists 64 of them at /api/v1/templates, from a CRM to a CMS to a feedback tracker. Install one with the CLI:

Terminal
npx busabase-cli install https://github.com/busabase/templates/tree/main/templates/busa-crm
Pass an idempotencyKey when an agent might retry
Same key, same submitter, same Base: the second call returns the first Change Request instead of a duplicate row. Worth it for any seed script and any agent loop that retries on a timeout.
Step 4 of 7
3 min

Decide which writes wait for you

At a glance
Local default
You own it, so writes merge
Hold an update
requireReview: true
Hold a create
autoMerge: false

This is the step most people skip, and it is the reason to use Busabase at all. Every write is a Change Request, but whether it waits depends on permissions. On a local install you are the owner, so by default an agent's write merges straight away and simply leaves a diff and a history behind. To make writes wait for you, ask for review explicitly:

  • Updating a record over MCP (record_change_request): pass "requireReview": true.
  • Creating a record over MCP (bases_create_change_request): pass "autoMerge": false.
  • Over REST, "autoMerge": false holds both creates and updates.
Update proposed over MCP, held for review
// tools/call record_change_request
{
  "recordId": "<RECORD_ID>",
  "operation": "update",
  "fields": { "stage": "qualified", "deal": 9600,
              "notes": "Signed up from the pricing page. Booked a demo for Thursday, team of 12." },
  "message": "Qualify Dana Ortiz: demo booked, team of 12",
  "requireReview": true
}
// -> "status": "in_review"

Put the rule where the agent reads it every session, in CLAUDE.md or AGENTS.md:

CLAUDE.md
## Busabase
- Every write to Busabase waits for my review.
- Updates: record_change_request with requireReview: true.
- New records: bases_create_change_request with autoMerge: false.
- Write the message as "<verb> <what>: <why>", it is what I read in the inbox.
- Never call change_request_review or change_request_merge. Approving is my job.
requireReview does nothing on a create
On 0.95.1 I sent a new record over MCP with requireReview: true and it merged immediately. The create tool only honours autoMerge: false. If the Home page does not show your agent's new row as pending, this is why.
On a team, the key decides
On Busabase Cloud, a credential capped at the changeRequest level can only propose: nothing it writes lands without a reviewer, whatever flags the agent sends. That is the setting to give agents in a shared workspace.
Step 5 of 7
2 min

Review the diff and merge

At a glance
Where
Home → Waiting for your review
Shows
Before → after, per field
API
approve, then merge (two calls)

Pending changes show up at the top of Home under Waiting for your review and in the Inbox, with a count in the sidebar.

Busabase Home showing two Change Requests waiting for review
Two agent writes waiting: a new lead and an update to an existing one.

Open one and you get What will change: every field the agent touched, old value struck through, new value next to it, with the agent's message above. Approve, or choose Request changes and leave a note the agent can read. You can also edit the proposal before you approve it.

A Busabase Change Request showing deal size 4800 to 9600, new notes, and stage Lead to Qualified
The agent's update to Dana Ortiz: three fields changed, waiting for Approve.

From a script, approving and merging are two separate calls, and that is deliberate: an approved change is not in your data until it is merged.

Terminal
curl -X POST http://localhost:15419/api/v1/change-requests/reviews \
  -H 'content-type: application/json' \
  --data '{"verdict":"approved","reason":"Demo is on the calendar.","changeRequestIds":["<CR_ID>"]}'
# -> "status": "approved"   (not merged yet)

curl -X POST http://localhost:15419/api/v1/change-requests/merge \
  -H 'content-type: application/json' \
  --data '{"changeRequestIds":["<CR_ID>"]}'
# -> "status": "merged"

The MCP versions of those two tools say in their own descriptions that they record a human decision and must not be called unless you asked for that verdict on that change. Keep the line in CLAUDE.md from step 4 anyway. Busabase also has a mobile app for reviewing Change Requests away from the desk.

Step 6 of 7
1 min

Read the history

At a glance
Per record
Lineage, audit, review history
Per workspace
Home → Recent activity
Each change
Message, author, commit

Open the record and the right-hand panel shows who proposed it, the commit author, and the full review history: every Change Request that touched it, with its status and commit id. Home has the same feed for the whole workspace under Recent activity.

A Busabase record with its lineage, audit and review history panel
Dana Ortiz after the merge: the create and the update, each with its commit.

This is what makes the next agent useful. Ask a different agent "What changed on this project this week?" and it answers from these records and their history, not from your clipboard.

Step 7 of 7
3 min

Keep it running, install the skills

At a glance
Skills
busabase, busabase-app-creator
On boot
launchd / systemd --user
Exposure
127.0.0.1 only, keep it that way

Install the two permanent skills so every new agent session knows the workspace without the setup prompt: busabase for everyday reads and writes, busabase-app-creator for building AirApps (dashboards, CRMs, content desks) on live Base data.

Terminal
npx skills add busabase/skills --skill busabase busabase-app-creator

To start the server at login on a Mac, a per-user launchd agent is enough:

~/Library/LaunchAgents/com.busabase.server.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
  <key>Label</key><string>com.busabase.server</string>
  <key>ProgramArguments</key>
  <array><string>/bin/sh</string><string>-lc</string><string>npx -y busabase server</string></array>
  <key>RunAtLoad</key><true/><key>KeepAlive</key><true/>
</dict></plist>
Terminal
launchctl load ~/Library/LaunchAgents/com.busabase.server.plist

# Linux: a user service in ~/.config/systemd/user/busabase.service
#   [Service]
#   ExecStart=/usr/bin/env npx -y busabase server
#   Restart=on-failure
#   [Install]
#   WantedBy=default.target
systemctl --user enable --now busabase.service
loginctl enable-linger "$USER"   # keep it up without a login session
Do not put the open-source server on the internet
The local server has no login. It binds to 127.0.0.1 by default, and --host 0.0.0.0 makes it reachable by anyone on the network. Use it on a trusted machine or private network only. For remote access, the project points to Cloud Connect, an authenticated tunnel from your machine to Busabase Cloud, or put it behind your own auth and reverse proxy.

What it actually costs

  • Busabase open source and the desktop app: $0, MIT licensed, data stays on your machine.
  • Your agents: whatever you already pay for Claude Code, Codex or Cursor. Busabase has no model of its own.
  • Busabase Cloud, if you want a hosted multi-user workspace with roles and web and mobile access: see busabase.com/pricing.

Troubleshooting

  • EBADENGINE warnings on start. Node is older than 24.18. Upgrade, or run the Docker image.
  • Port 15419 already in use. Another Busabase (often the desktop app) is running. Use it, or start a second one with --port and its own --data.
  • Second server will not start on the same data. Only one process can hold a PGlite database at a time. Give each instance its own --data folder.
  • The agent's change merged without asking. Locally you have write access, so writes merge unless the agent sends requireReview: true (updates) or autoMerge: false (creates). See step 4.
  • Approved over the API, but the record did not change. Approval is not a merge. Call /api/v1/change-requests/merge with the same id.
  • Update request rejected with "Invalid discriminator value". POST /api/v1/records/<id>/change-requests needs "operation": "update" (or delete, restore).

You're set

You now have one workspace that every agent on your machine reads from and writes to, and nothing lands in it without a message, a diff and a name attached. Start small: one Base your agents keep current, every write held for review for the first week, then loosen it for the fields you have stopped checking.

Building something on top of it, an AirApp, a template, an agent that keeps a Base current? Launch it on the weekly board: launching is free, every launch is reviewed by a person, and it gets a permanent listing page. Submit it here.

Disclaimer: Nick Launches is not affiliated with Busabase. Tested on Busabase 0.95.1 (npm) on macOS with a fresh data directory on October 9, 2026; the sample leads are made up. Commands and flags may change in later versions, check the README if something does not match.

Share

Get the weekly recap

New dev-resource guides, top launches, and what's worth a look. One email a week.