The manual for building on durable state.
OpenLotus keeps your project state in one live record — plans, decisions, evidence, and drift your agent can read over MCP. Your agent remembers what you decided, where reality drifted, and what to do next — without you re-explaining. This guide explains everything in plain language, with code you can copy.
No jargon, no theory — just how to use it today.
With the skill: say “set up OpenLotus” and it does the three files. Without it: copy the three blocks below — same result, one time. Pick one.
What is OpenLotus
Durable project state, independent of your agent. Not a chatbot, not a dashboard — the state layer that keeps work coherent.
The skill works great on its own — it organizes work so your agent can handle more at once. Paired with OpenLotus state, every plan it makes is anchored in your real project and every result lands where you can see it.
- Progress map — the state tree
- Dashboard — your week, verified
- Workspace — talk with the map loaded
Connecting your agent
Two ways to get connected. Let your agent configure itself, or set it up by hand in 2 minutes.
OpenLotus connects your local agent to your cloud project state through the Model Context Protocol (MCP).
Just paste this prompt into your agent:
Your agent reads the full specification from llms.txt, registers the MCP server in your config, adds the memory rules to your repository, and helps you complete pairing.
Run in your terminal at your repo root. Opens your browser to select or create a project.
Add to your MCP config file (.mcp.json, .cursor/mcp.json, or opencode.json), then restart your agent.
{
"mcpServers": {
"openlotus": {
"command": "npx",
"args": ["openlotus", "agent"]
}
}
}Paste into AGENTS.md or CLAUDE.md in your repo root so your agent records decisions and monitors drift.
## OpenLotus loop (standing rules) Shared memory lives in OpenLotus via MCP tools: get_memory, get_reality, get_drift, record_decision, record_constraint, report_failure, record_lesson, write_scratchpad, read_scratchpad, manage_tasks, dismiss_drift, resolve_failure, resolve_risk. The founder sees the same data on the web dashboard. These rules apply to EVERY action and every prompt, not just session start. CLI commands (local, run in your repo): - npx openlotus pair one-time: link this repo to a cloud project - npx openlotus bootstrap one-time: seed the map from README/PROGRESS/AGENTS - npx openlotus sync push a fresh reality snapshot to the dashboard - npx openlotus status print latest observed state + drift - npx openlotus agent MCP server over stdio (what your harness launches) - npx openlotus version print the installed CLI version 1. Boot: at the START of any work session or non-trivial prompt, call get_memory + get_drift before planning anything. If findings exist, fix blockers and risks before new work. Then run npx openlotus sync and call get_drift again to confirm the finding cleared. Do not dismiss reality-derived findings; dismiss only findings reality cannot clear, such as an unsupported claim you have now backed with evidence. If the map has no goal yet, set one first. A project without a goal is not set up. 2. Decisions: whenever a direction choice is made (stack, scope, schema, tradeoff), call record_decision immediately with a title and why. Do not batch. 3. Founder notes: whenever the founder says something worth keeping that is not yet a decision, task, or constraint (a stray idea, a preference, something to check later), call write_scratchpad immediately. Check read_scratchpad before asking the founder something they may already have answered. 4. Tasks: track real work with manage_tasks. Create on starting, update status as it moves (queued/running/done/failed/pending), set due dates, mark done the moment it is done. Never leave a finished task open. 5. Reality check: after completing meaningful work, call get_reality and mention surprises (unexpected dirty files, TODO spikes). npx openlotus sync pushes the same snapshot to the dashboard. 6. Close the loop: after a fix, run npx openlotus sync and call get_drift; a reality-derived finding clears itself. Call dismiss_drift only for findings reality cannot clear. When a recorded failure is fixed, call resolve_failure. When a risk is handled, resolve it. Fixed items must disappear from the record. Never leave solved problems looking open. 7. PROGRESS.md: update after each milestone or plan change so the file matches the map. If they disagree, the map wins and the file gets fixed. 8. Failures and constraints: when an approach fails, call report_failure (never retry the same strategy silently). When a boundary is set, call record_constraint. Never bury constraints or failures in decision prose. 9. Stale over silent: if context is missing, call get_memory again instead of guessing. Never invent project state from chat history alone.
Append this to AGENTS.md at the repo root. Claude Code also reads it via @AGENTS.md in CLAUDE.md.
llms.txt is a plain-language primer on OpenLotus — what the loop is, how supervision works, how to pair and use MCP. Paste it to any agent and it understands OpenLotus without you explaining anything.
- One prompt does it all with the vibe-to-ship skill
- One command pairing with browser auth
- Standard MCP config works across Cursor, Claude Code, & OpenCode
- Permanent memory via repo markdown rules
Pairing a project
Browser-based, no flags. Run one command, pick a project on the web.
Run npx openlotus pair — it opens your browser to /pair. Log in — or create an account if you don’t have one — then pick a project.
No --email --password flags. The browser handles auth; the CLI just waits for your pick.
- Auth URL opens in your browser
- Creates a new project if you need one
- Links this local repo to your choice
What is mcp.json?
A small config file that tells your agent how to start OpenLotus.
Think of it as a launcher. It says: “when you start, run this command to talk to OpenLotus.” You create it once. After that the agent has the tools in every session.
The same snippet lives in the homepage “Connect your agent” section. The skill writes the file for you if it's missing.
Append these standing memory rules to your repo rules file so your agent records decisions and monitors drift automatically:
## OpenLotus loop (standing rules) Shared memory lives in OpenLotus via MCP tools: get_memory, get_reality, get_drift, record_decision, record_constraint, report_failure, record_lesson, write_scratchpad, read_scratchpad, manage_tasks, dismiss_drift, resolve_failure, resolve_risk. The founder sees the same data on the web dashboard. These rules apply to EVERY action and every prompt, not just session start. CLI commands (local, run in your repo): - npx openlotus pair one-time: link this repo to a cloud project - npx openlotus bootstrap one-time: seed the map from README/PROGRESS/AGENTS - npx openlotus sync push a fresh reality snapshot to the dashboard - npx openlotus status print latest observed state + drift - npx openlotus agent MCP server over stdio (what your harness launches) - npx openlotus version print the installed CLI version 1. Boot: at the START of any work session or non-trivial prompt, call get_memory + get_drift before planning anything. If findings exist, fix blockers and risks before new work. Then run npx openlotus sync and call get_drift again to confirm the finding cleared. Do not dismiss reality-derived findings; dismiss only findings reality cannot clear, such as an unsupported claim you have now backed with evidence. If the map has no goal yet, set one first. A project without a goal is not set up. 2. Decisions: whenever a direction choice is made (stack, scope, schema, tradeoff), call record_decision immediately with a title and why. Do not batch. 3. Founder notes: whenever the founder says something worth keeping that is not yet a decision, task, or constraint (a stray idea, a preference, something to check later), call write_scratchpad immediately. Check read_scratchpad before asking the founder something they may already have answered. 4. Tasks: track real work with manage_tasks. Create on starting, update status as it moves (queued/running/done/failed/pending), set due dates, mark done the moment it is done. Never leave a finished task open. 5. Reality check: after completing meaningful work, call get_reality and mention surprises (unexpected dirty files, TODO spikes). npx openlotus sync pushes the same snapshot to the dashboard. 6. Close the loop: after a fix, run npx openlotus sync and call get_drift; a reality-derived finding clears itself. Call dismiss_drift only for findings reality cannot clear. When a recorded failure is fixed, call resolve_failure. When a risk is handled, resolve it. Fixed items must disappear from the record. Never leave solved problems looking open. 7. PROGRESS.md: update after each milestone or plan change so the file matches the map. If they disagree, the map wins and the file gets fixed. 8. Failures and constraints: when an approach fails, call report_failure (never retry the same strategy silently). When a boundary is set, call record_constraint. Never bury constraints or failures in decision prose. 9. Stale over silent: if context is missing, call get_memory again instead of guessing. Never invent project state from chat history alone.
Append this to AGENTS.md at the repo root. Claude Code also reads it via @AGENTS.md in CLAUDE.md.
- One JSON snippet, one path to fix
- Makes the tool catalog appear in every session
- Skill writes it if it’s missing
{
"mcpServers": {
"openlotus": {
"command": "npx",
"args": ["openlotus", "agent"]
}
}
}Save it at the path your harness reads (.mcp.json, .cursor/mcp.json, or opencode.json), then restart the agent.
The vibe-to-ship skill
A 5-step routine your agent follows to ship without drift — built from real shipping expertise, packaged as graph engineering.
If a triage shows nothing actionable, the skill stops in ~5k tokens — it doesn’t burn credits running nothing.
Read the full skill guide →- Open-source, drop-in for Claude Code & OpenCode
- If setup missing, Beat 1 finishes pairing first
- Manual or agent-driven — your choice
What triage does & why
Triage is the honest check before your agent moves.
It compares what you said you’d do (the tree) to what actually happened (git, dirty files, TODOs) and outputs a High / Watch / Noise list.
Without triage, agents invent a plan. With it, they start from the last verified reality.
Run with: “Run vibe-to-ship triage” or let the Beat 1 auto-check run.
- Catches drift before acting
- Early exit when nothing actionable
- Reconciles declared vs observed
Hooks & safety net
Hooks enforce the loop even when the agent forgets.
Optional safety net: your agent automatically checks for drift when it starts, so it flags problems before it acts. No extra cost, works even if the agent ignored the earlier rules.
There’s also a built-in safety net without hooks: if the map drifts from git (e.g., 12 uncommitted files while the milestone claims done), the next get_drift flags it as risk. Drift is information, not failure.
- SessionStart: prints drift at boot
- Budget cap: switches to report-only at 80%
- Max 3 fix attempts, then escalate
CLI reference
Six commands, one binary. Everything the agent needs, plus the two one-time setup commands.
Run any of them with npx openlotus <command> inside a paired repo. Environment overrides: OPENLOTUS_EMAIL, OPENLOTUS_PASSWORD, OPENLOTUS_BASE_URL.
Agent contract on every prompt: read state first, set the project goal if blank, write founder notes to the scratchpad, track work as tasks with statuses and due dates, and close addressed drift plus fixed failures and risks so solved items disappear.
- Same binary serves CLI and MCP
- sync/status never block your agent
- bootstrap makes the map useful on day one
Timestamps
Every action is stamped. No anonymous edits.
Milestones, decisions, risks, evidence, milestones — each carries createdAt. Snapshots carry capturedAt + syncCount. Reviews carry lastReviewAt.
You see them as relative times in the dashboard and absolute times when you expand a node.
- Milestones · decisions · evidence: createdAt
- Snapshots: capturedAt + syncCount
- Reviews: lastReviewAt, trajectory
Permanent history
Your full history, in full detail. Forever.
Every decision, constraint, and lesson stays exactly as recorded — on every plan, including Free. No event budgets, no expiry, no summarizing old entries away to fit a tier. We never punish persistence.
- Full detail forever, on every plan
- No event budgets, no expiry
- Search your whole record
Same detail on day 1 and day 1,000 — nothing expires, nothing compacts.
Security
Your code never leaves your machine.
OpenLotus reads your work’s shape — what changed, what you decided, where things drift — not your files. get_reality sends counts and branch names, never file bodies. Tools are capability-scoped (e.g., github.read), never “all access.”
- Never reads file contents
- Per-tool capability checks
- Pairs are per-project, not per-org