Quickstart
LeftFold connects to your AI through MCP (Model Context Protocol). Setup takes under a minute:
- Create an account and choose your handle
- Copy your MCP URL:
https://leftfold.io/your-handle - Add the URL to your AI client (see guides below)
- Start talking — your AI handles the rest
No SDK. No database provisioning. No configuration files. One URL is the entire integration.
Connect Claude (claude.ai)
Claude supports MCP servers through Connectors (formerly Integrations).
- Open claude.ai and go to Settings
- Navigate to Connectors
- Click Add Connector and enter your MCP URL
- Authorize LeftFold when prompted
Connect ChatGPT
ChatGPT supports MCP servers as tool connectors.
- Open ChatGPT
- Go to Settings → Connectors (or Tools & Connectors)
- Add a new MCP connector with your LeftFold URL
- Authorize when prompted
Connect Cursor
Cursor supports MCP servers in its settings.
- Open Cursor Settings (
Cmd+,) - Navigate to MCP Servers
- Click Add Server
- Set type to
sseand URL to your LeftFold endpoint
{
"mcpServers": {
"leftfold": {
"url": "https://leftfold.io/your-handle"
}
}
}Connect Claude Code
Claude Code (CLI) supports MCP servers via its settings file.
{
"mcpServers": {
"leftfold": {
"url": "https://leftfold.io/your-handle"
}
}
}Or add it via the CLI:
claude mcp add leftfold https://leftfold.io/your-handle
How it works
LeftFold is an event-sourced domain modeling system. Instead of storing current state (like a key-value store), it stores an immutable sequence of events — facts about what happened. Current state is derived by "folding" (replaying) events in order.
Your AI is simultaneously the client, the domain expert, and the decision-maker. It follows a decision cycle for every conversation:
- Orient — call
list_aggregatesto see what domain concepts exist - Analyze — does the new information fit an existing aggregate?
- Decide — use an existing event type, evolve a schema, or define a new aggregate
- Record — call
append_eventswith validated data - Query — use the
querytool to answer questions from folded state - Reflect — did any facts emerge that should be recorded?
Aggregates & events
An aggregate is a domain concept with a distinct lifecycle — Contact, Order, Project, Decision. Each aggregate is a consistency boundary: events within it are ordered and atomic.
An event is an immutable fact — ContactCreated, OrderShipped, DecisionAccepted. Events are past-tense, self-describing, and timestamped.
Design principles
- Prefer fewer, well-defined aggregates (3–7 serves most domains)
- Aggregates are singular PascalCase nouns:
Contact, notContacts - Events are past-tense:
OrderShipped, notShipOrder - Cross-aggregate relationships use ID references, resolved at query time via
$lookup - Aggregate IDs should be descriptive:
contact-jane-smith, not a random UUID
Schema evolution
Schemas evolve over time via revise_event_definition. New fields must be optional or have defaults. Existing events automatically receive defaults when folded. Migration reasoning is stored permanently.
Queries
Queries use a MongoDB-style aggregation pipeline. The AI formulates the query; LeftFold executes it server-side and caches the results.
[
{ "$match": { "aggregate_type": "Contact" } },
{ "$fold": {} }
][
{ "$match": { "aggregate_type": "Contact" } },
{ "$fold": {} },
{ "$match": { "status": "active" } }
][
{ "$match": { "aggregate_type": "Order" } },
{ "$fold": {} },
{ "$lookup": {
"from": "Contact",
"localField": "contact_id",
"foreignField": "_instance",
"as": "contact"
}}
][
{ "$match": { "aggregate_type": "Order" } },
{ "$fold": {} },
{ "$group": { "_id": "status", "count": { "$count": {} } } },
{ "$sort": { "count": -1 } }
]Scopes
Scopes are optional isolated domains within your account. Each scope has its own aggregate types, events, schemas, and query cache. Data in one scope is invisible to other scopes.
When to use scopes: When you have multiple independent domains — a business AND a side project, or separate client engagements.
When not to use scopes: When you have one purpose. The unscoped general space is simpler. Your AI won't suggest scopes until you mention a second domain.
MCP tools reference
ORIENTATION
guide — Returns the usage guide. Call at the start of your first conversation.
list_scopes — Returns all scopes. Called first in every conversation.
list_aggregates — Returns the current world model summary.
get_aggregate_detail — Full schema history and instance list for an aggregate type.
SCHEMA MANAGEMENT
create_scope — Create a new isolated domain.
define_aggregate — Register a new aggregate type with initial event definitions.
revise_event_definition — Add new fields to an event type (backward-compatible).
DATA OPERATIONS
append_events — The only write operation. Records events atomically.
query — Primary read path. MongoDB-style aggregation pipeline with caching.
get_events — Raw event retrieval for debugging and audit trails.
audit — Complete event history for a specific aggregate instance.
Query pipeline stages
$match — Filter events (pre-fold) or documents (post-fold). Supports $eq, $ne, $gt, $gte, $lt, $lte, $in, $nin, $exists.
$fold — Core operation. Replays events per instance, producing current state via last-write-wins merge.
$lookup — Join across aggregates. Target aggregate is auto-folded.
$group — Aggregate with accumulators: $sum, $count, $avg, $min, $max, $push.
$project — Select, exclude, or rename fields. Supports dot-notation.
$sort — Order results. 1 for ascending, -1 for descending.
$limit — Cap result count.