docs / guides
Using with agents
Give agents persistent SQL tables through the botdb skill, the MCP server, or the CLI in headless environments.
Agents already know SQL. botdb gives them tables that persist across sessions, survive machine changes, and sync between agents, with output and errors designed to be read by a model.
There are three ways to connect an agent, and they combine:
| Method | Best for |
|---|---|
| Skill | Agents with a shell. Teaches them when and how to call botdb. |
| MCP | Agents that prefer tools over shell commands. |
| Env | Containers, CI and servers: BOTDB_INVITE, or BOTDB_PHRASE + BOTDB_REMOTE. |
Skill
The skill is a SKILL.md file that tells an agent when to reach for botdb (structured information that should outlast the session) and how to use it: commands, output format, table rules, history and sharing. It’s embedded in the binary.
botdb skill # print SKILL.md
botdb skill install # install for every detected client
botdb skill install --client claude # one client: claude, opencode, codex, cursor, agents
botdb skill install --dir .claude/skills # a project: writes .claude/skills/botdb/SKILL.md
| Client | Installed to |
|---|---|
claude |
~/.claude/skills/botdb/SKILL.md |
opencode |
~/.config/opencode/skills/botdb/SKILL.md |
codex |
~/.codex/skills/botdb/SKILL.md |
agents |
~/.agents/skills/botdb/SKILL.md |
cursor |
Not automatic: add the output of botdb skill to a project rule. |
The default, --client all, only installs for clients whose config directory (~/.claude, ~/.config/opencode, ~/.codex, ~/.agents) already exists. Re-running it updates the file.
The same file is published at /skill.md and rendered on the For agents page.
MCP server
botdb mcp runs a Model Context Protocol server on stdio.
botdb mcp install # register with every detected client
botdb mcp install --client cursor # one client: claude, opencode, codex, cursor, agents
| Client | What install does |
|---|---|
claude |
Runs claude mcp add --scope user botdb -- <botdb path> mcp, or prints that command if it fails. |
opencode |
Adds "mcp": {"botdb": {"type": "local", "command": ["<botdb path>", "mcp"], "enabled": true}} to ~/.config/opencode/opencode.json. If only opencode.jsonc exists, it prints the snippet to add. |
codex |
Appends a [mcp_servers.botdb] entry to ~/.codex/config.toml. |
cursor |
Adds botdb to mcpServers in ~/.cursor/mcp.json. |
agents |
Prints the command to configure by hand. |
As with the skill, --client all only touches clients whose config directory exists (~/.claude, ~/.config/opencode, ~/.codex, ~/.cursor). The installed command uses the absolute path of the botdb binary. To configure any other client, run botdb mcp over stdio:
{
"mcpServers": {
"botdb": { "command": "botdb", "args": ["mcp"] }
}
}
Tools:
| Tool | Arguments | Description |
|---|---|---|
list_databases |
Databases on this device: name, id, read-only, synced, default. | |
create_database |
name |
Create a database. It syncs to the default remotes. |
schema |
database, table |
Tables with columns and row counts, indexes and views. |
query |
database, sql, params |
Read-only SQL (SELECT, WITH, informational pragmas). Returns row objects. |
execute |
database, sql, params |
Writes and schema changes; several statements run atomically. Returns {"ok", "changes"}, plus rows if a statement returned any. |
history |
database, table, pk, since, limit |
Recent changes, newest first (default 50, at most 1000). |
sync |
database |
Sync now; without a database, syncs everything. |
params is an array for ? placeholders or an object for :name. database is optional when there’s a default or only one database. query is annotated read-only and execute destructive, so clients can allow reads without confirmation while still asking before writes.
Errors come back as tool results with isError: true and the same {"error": {"code", "message", "hint"}} body as the CLI. The server pulls before reads like the CLI, and pushes in-process shortly after writes and every 30 seconds.
Output contract
When stdout is not a terminal, botdb prints JSON:
- A
SELECTprints an array of row objects:[{"title":"Dune: Part Two","rating":5}]. - A write prints
{"ok":true,"changes":N}. - An error prints
{"error":{"code":"...","message":"...","hint":"..."}}to stderr and exits with status 1. Thecodeis stable and thehintsays how to fix the problem, for example which table rule was broken and what to write instead.
Force a format with -F json|table|csv (or BOTDB_FORMAT).
Headless agents, containers and CI
Agents that run without a person at the keyboard can’t answer prompts or reach a desktop keychain. Configure them through the environment.
One database (preferred): create an invite and pass it as BOTDB_INVITE. botdb joins that database on first use, no vault needed, and uses it whenever no other database is selected. The agent gets access to that database only, and with --read-only, can’t change it.
botdb invite movies --read-only # on your machine
docker run -e BOTDB_INVITE=bdb1_... -v agent-botdb:/root/.botdb my-agent
# GitHub Actions
env:
BOTDB_INVITE: ${{ secrets.BOTDB_INVITE }}
steps:
- run: botdb sql "SELECT count(*) AS n FROM watched"
Mount a volume at the botdb home directory (~/.botdb, or BOTDB_HOME) if the container should keep its local copy between runs. Otherwise it downloads the database again on each start (the first read waits up to 20 seconds for it).
Everything: BOTDB_PHRASE opens the full vault from the recovery phrase without storing a key anywhere. On a fresh home, also set BOTDB_REMOTE (comma-separated) to where your vault syncs, and run botdb sync once to pull the catalog and every database:
export BOTDB_PHRASE="..." BOTDB_REMOTE="https://relay.example.com"
botdb sync
botdb ls
Only use this on machines you trust as much as your laptop: the phrase grants access to every database.
Other useful variables:
| Variable | Use |
|---|---|
BOTDB_DB |
Default database, so the agent can omit -d. |
BOTDB_HOME |
Where local copies and state live. |
BOTDB_KEYSTORE |
file keeps the vault key in <home>/vault.key instead of the OS keychain. |
BOTDB_NO_AUTOSYNC |
1 disables automatic sync. Call botdb sync explicitly. |
BOTDB_RELAY_TOKEN |
Needed if the agent creates databases on a relay with a token. |
See Configuration for the full list.
Patterns
- Prefer natural keys when the same thing might be added from two places, such as a movie’s IMDb id. Rows with the same primary key merge instead of duplicating.
- One invite per agent. Each agent becomes its own replica. Revoking one is a
rotate-keyplus re-inviting the others. - Local-only scratch tables. Tables whose name starts with
_never sync and skip the table rules. Use them for caches and intermediate results. - Undo is cheap. If an agent makes a mess,
botdb historyshows exactly what changed andbotdb revert --at 10mputs it back. - Don’t keep secrets. If botdb reports
not_logged_in, the user can runbotdb loginthemselves, or ask the agent to. An agent that runs it gets the recovery phrase in the JSON output: it should show it to the user once and never save it in files, notes or memory. The same goes for invites.