/substrate
Use when the user wants to read/write their Butterbase substrate — the per-user agent-memory backend that holds entities, business state, institutional memory, and an append-only action ledger. Use for: founder copilots, AI agents that need memory across sessions, anything that
$ npx -y skills add butterbase-ai/butterbase-skills --skill substrate --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/substrate
Context preview
The summary Claude sees to decide when to auto-load this skill.
Use when the user wants to read/write their Butterbase substrate — the per-user agent-memory backend that holds entities, business state, institutional memory, and an append-only action ledger. Use for: founder copilots, AI agents that need memory across sessions, anything that
SKILL.md
substrate.SKILL.mdname: substrate
description: Use when the user wants to read/write their Butterbase substrate — the per-user agent-memory backend that holds entities, business state, institutional memory, and an append-only action ledger. Use for: founder copilots, AI agents that need memory across sessions, anything that proposes actions on the user's behalf.
Butterbase Substrate
Substrate is an **optional, per-user** add-on backend. One substrate per Butterbase account, lazily provisioned on first use, queryable from local Claude Code (via MCP), from any opted-in Butterbase app (via `ctx.substrate` inside functions), and from external systems (via HTTP).
Four stores
| Store | What lives there | Tools | |---|---|---| | Entities | People, companies, projects you transact with | `get_entity`, `find_entities` | | Business state | Numeric facts that change over time (MRR, headcount) | `find_entities` with type filter | | Institutional memory | Decisions, commitments, learnings | `search_memory` | | Action ledger | Append-only log of every proposed/executed action | `list_outbox`, `propose_action` history |
The propose → policy → execute → log loop
Every write goes through this loop. Agents NEVER touch the substrate database directly.
1. **Propose** — `propose_action` with `capability` + `args`. Returns an action ID. 2. **Policy** — substrate-core evaluates per-capability rules. Verdicts: `auto_execute`, `require_approval`, `deny`. 3. **Approval (if needed)** — human calls `approve_action(action_id)` or `reject_action(action_id)`. If `yolo_mode=true` for this user, approvals are auto-granted for capabilities marked yolo-safe. 4. **Execute + log** — substrate-core runs the action in a transaction and appends to the ledger.
For external side effects (sending email, calling an API), substrate writes to the **outbox** instead of executing inline. The cron-scheduler drains it. Use `list_outbox`, `retry_outbox`, `cancel_outbox` to manage it.
Reads
- `get_entity(id)` — fetch by ID.
- `find_entities(type, query, limit)` — typed search; `query` is full-text + structured.
- `search_memory(query, kind?)` — semantic + keyword search across decisions/commitments/learnings.
When to use
- ✅ Founder copilot ("what did I decide about pricing last quarter?")
- ✅ AI agent that should remember a customer across conversations
- ✅ Any app where you want a single source of truth for entities the agent operates on
- ❌ Plain CRUD app (use regular Butterbase tables)
- ❌ Pure analytics / read-only dashboard (substrate is action-oriented)
Linking an app
When `apps.substrate_user_id` is set to the app owner's `platform_user.id`, functions in that app get `ctx.substrate` injected at cold start, with reader and proposer methods. Use `/butterbase-skills:journey-substrate` to enable this for an app.
API keys
For agent access from local Claude Code, generate a `scope='both'` API key via `manage_auth_config` `action: "generate_service_key"` with `substrate_access: true`. The same `bb_sk_` key works on both app and substrate endpoints.
Anti-patterns
- ❌ Calling substrate MCP tools without first checking whether the user has substrate provisioned. `find_entities` returns 401 if there's no substrate — handle gracefully and suggest provisioning.
- ❌ Treating the action ledger as mutable. It's append-only; "undo" is a new compensating action, not a delete.
- ❌ Storing transient state in entities. Entities are durable nouns; use the app's runtime tables for ephemeral state.
- ❌ Calling `upsert_entity` without `canonical_keys` or `primary_email` and expecting dedup. Provide one or the other so substrate can match an existing row. Without them, every call mints a new entity.
- ❌ Calling `update_entity` for a partial update. It replaces `attrs` wholesale and will drop every key you didn't include. Use `patch_entity` (RFC 7396 merge-patch) instead.
- ❌ Storing entity IDs in app data and skipping alias resolution after `merge_entities`. The merged-away ID stops resolving to an entity; look up `substrate.entity_aliases` to find the survivor.
Read more
name: substrate description: Use when the user wants to read/write their Butterbase substrate — the per-user agent-memory backend that holds entities, business state, institutional memory, and an append-only action ledger. Use for: founder copilots, AI agents that need memory across sessions, anything that proposes actions on the user's behalf.
Butterbase Substrate
Substrate is an **optional, per-user** add-on backend. One substrate per Butterbase account, lazily provisioned on first use, queryable from local Claude Code (via MCP), from any opted-in Butterbase app (via `ctx.substrate` inside functions), and from external systems (via HTTP).
Four stores
| Store | What lives there | Tools | |---|---|---| | Entities | People, companies, projects you transact with | `get_entity`, `find_entities` | | Business state | Numeric facts that change over time (MRR, headcount) | `find_entities` with type filter | | Institutional memory | Decisions, commitments, learnings | `search_memory` | | Action ledger | Append-only log of every proposed/executed action | `list_outbox`, `propose_action` history |
The propose → policy → execute → log loop
Every write goes through this loop. Agents NEVER touch the substrate database directly.
1. **Propose** — `propose_action` with `capability` + `args`. Returns an action ID. 2. **Policy** — substrate-core evaluates per-capability rules. Verdicts: `auto_execute`, `require_approval`, `deny`. 3. **Approval (if needed)** — human calls `approve_action(action_id)` or `reject_action(action_id)`. If `yolo_mode=true` for this user, approvals are auto-granted for capabilities marked yolo-safe. 4. **Execute + log** — substrate-core runs the action in a transaction and appends to the ledger.
For external side effects (sending email, calling an API), substrate writes to the **outbox** instead of executing inline. The cron-scheduler drains it. Use `list_outbox`, `retry_outbox`, `cancel_outbox` to manage it.
Reads
- `get_entity(id)` — fetch by ID.
- `find_entities(type, query, limit)` — typed search; `query` is full-text + structured.
- `search_memory(query, kind?)` — semantic + keyword search across decisions/commitments/learnings.
When to use
- ✅ Founder copilot ("what did I decide about pricing last quarter?")
- ✅ AI agent that should remember a customer across conversations
- ✅ Any app where you want a single source of truth for entities the agent operates on
- ❌ Plain CRUD app (use regular Butterbase tables)
- ❌ Pure analytics / read-only dashboard (substrate is action-oriented)
Linking an app
When `apps.substrate_user_id` is set to the app owner's `platform_user.id`, functions in that app get `ctx.substrate` injected at cold start, with reader and proposer methods. Use `/butterbase-skills:journey-substrate` to enable this for an app.
API keys
For agent access from local Claude Code, generate a `scope='both'` API key via `manage_auth_config` `action: "generate_service_key"` with `substrate_access: true`. The same `bb_sk_` key works on both app and substrate endpoints.
Anti-patterns
- ❌ Calling substrate MCP tools without first checking whether the user has substrate provisioned. `find_entities` returns 401 if there's no substrate — handle gracefully and suggest provisioning.
- ❌ Treating the action ledger as mutable. It's append-only; "undo" is a new compensating action, not a delete.
- ❌ Storing transient state in entities. Entities are durable nouns; use the app's runtime tables for ephemeral state.
- ❌ Calling `upsert_entity` without `canonical_keys` or `primary_email` and expecting dedup. Provide one or the other so substrate can match an existing row. Without them, every call mints a new entity.
- ❌ Calling `update_entity` for a partial update. It replaces `attrs` wholesale and will drop every key you didn't include. Use `patch_entity` (RFC 7396 merge-patch) instead.
- ❌ Storing entity IDs in app data and skipping alias resolution after `merge_entities`. The merged-away ID stops resolving to an entity; look up `substrate.entity_aliases` to find the survivor.
Claude Code plugin for Butterbase — the AI-Native Backend-as-a-Service. This plugin gives Claude deep knowledge of Butterbase's 42+ MCP tools, guides you through common workflows, and auto-configures the MCP server connection.
Repo: butterbase-ai/butterbase-skills
Other skills on butterbase-skills.
- /agents
Use when designing, deploying, or debugging a Butterbase Agent (declarative LLM/tool graph), registering an MCP server for tool use, or wiring access controls and rate limits. Agents are first-class app resources defined by a `graph_spec` and invoked over
Open skill - /ai
Use when calling the app's AI gateway from agent tools — chat completions, embeddings, listing models, configuring defaults or BYOK, reading token/cost usage
Open skill - /auth-setup
Use when configuring OAuth providers (Google/GitHub/Apple/X/etc.), setting up post-login auth hooks, tuning JWT lifetimes, or generating service API keys
Open skill - /build-app
Use when building a new Butterbase app from scratch, creating a full-stack application, or when the user asks to set up a complete backend with database, auth, and deployment
Open skill - /contributing
Use when contributing to the Butterbase codebase, adding new MCP tools, creating API routes, writing migrations, or understanding the monorepo architecture
Open skill - /debug-rls
Use when users report access denied errors, see wrong data, RLS policies are not working, or when troubleshooting Row-Level Security issues in Butterbase
Open skill

