Ladder documentation
Ladder is a decision ledger for AI pair-programming. Every unit of work is a rung with a stable ref like R001; your assistant reads the next one, builds it, and writes the outcome back — from the terminal, an editor, or a chat app.
Quick start
- Sign in and open the board. If it is empty, the onboarding wizard seeds a starter ladder with example stages and rungs.
- Go to
/connectand paste the install snippet for your editor. Ladder's MCP endpoint is:https://ladder-decision-log.lovable.app/mcp
- Ask your assistant: “show ladder”. It prints the full board verbatim.
- Then: “work the next rung”. It calls
ladder_next, implements, notes and closes it.
Concepts
- Rung
- One decision or unit of work. Has a ref, title, stage, effort, status, context, why, and the options you rejected.
- Stage
- An ordered bucket — foundation, core, expansion — you define per project.
- Effort
- small / medium / large. Drives the ordering of ladder_next.
- Status
- open, in_progress, done, blocked, archived.
- Blocked by
- Hard dependency on other rungs. Blocked rungs never surface as next up.
- Notes
- Append-only log per rung, authored by you, the CLI, Auto-Run or CI.
Connect an editor
Every client speaks the same MCP endpoint and signs in with OAuth as your Ladder user. The connect page renders these with a copy button and your live URL.
Claude Code
claude mcp add --transport http ladder https://ladder-decision-log.lovable.app/mcp
Run it in your repo. Claude Code opens a browser for sign-in, then the Ladder tools appear.
Claude app
https://ladder-decision-log.lovable.app/mcp
Settings → Connectors → Add custom connector → paste this URL. Approve the consent screen; the connector then acts as your signed-in Ladder user.
ChatGPT
https://ladder-decision-log.lovable.app/mcp
Settings → Connectors → Create → paste this URL. Same OAuth sign-in as everywhere else.
Codex~/.codex/config.toml
[mcp_servers.ladder] url = "https://ladder-decision-log.lovable.app/mcp"
Add the block to your Codex config, then restart Codex.
Antigravitymcp_config.json
{
"mcpServers": {
"ladder": {
"serverUrl": "https://ladder-decision-log.lovable.app/mcp"
}
}
}Open the MCP settings panel, edit the config JSON, paste this in, then refresh servers.
Cursor.cursor/mcp.json
{
"mcpServers": {
"ladder": {
"url": "https://ladder-decision-log.lovable.app/mcp"
}
}
}Committed to the repo, so anyone who clones it gets Ladder wired up.
VS Code / Copilot.vscode/mcp.json
{
"servers": {
"ladder": {
"type": "http",
"url": "https://ladder-decision-log.lovable.app/mcp"
}
}
}Reload the window; Copilot Chat's agent mode picks up the server.
Windsurf~/.codeium/windsurf/mcp_config.json
{
"mcpServers": {
"ladder": {
"serverUrl": "https://ladder-decision-log.lovable.app/mcp"
}
}
}Zed~/.config/zed/settings.json
{
"context_servers": {
"ladder": {
"source": "custom",
"url": "https://ladder-decision-log.lovable.app/mcp"
}
}
}MCP tools
| ladder_projects | List your Ladder projects. |
| ladder_show | Print the full canonical ladder, verbatim. |
| ladder_next | Read the highest-priority unblocked open rung. |
| ladder_list | List rungs, filtered by stage or status. |
| ladder_status | Move a rung to a new status. |
| ladder_note | Append a note to a rung. |
| ladder_add | Create a new rung. |
| ladder_rules | Read the Ladder working agreement. |
CLI reference
The CLI works standalone — ladder login stores a token in ~/.ladder/config.json and ladder init writes the repo-local MCP configs.
bun run ladder login [token] store your CLI token in ~/.ladder/config.json bun run ladder init <project-id> write .ladder.json + IDE MCP configs bun run ladder rules print the Ladder working agreement bun run ladder show print the full canonical ladder bun run ladder next [--prompt] highest-priority unblocked open rung bun run ladder list [--status <status>] list rungs, optionally filtered bun run ladder status <ref> <status> update a rung's status bun run ladder note <ref> <body> append a human note to a rung bun run ladder add <stage> <title> [effort] create a new rung bun run ladder prompt <ref> print a Claude Code-ready prompt bun run ladder whoami show the signed-in user
Render contract
Assistants love to summarise. Ladder forbids it: the ladder is printed verbatim, and edits travel as single-line deltas so you are not paying to re-render the whole board. This agreement ships to every client through ladder_rules.
# Ladder working agreement Ladder is the decision ledger for this repo. Every unit of work is a "rung" with a ref like R001. Keep the ledger current as you work. ## The loop 1. `ladder_next` (or `ladder next --prompt`) — read the highest-priority unblocked open rung. Do not pick work that is blocked. 2. Set it in flight: `ladder_status R001 in_progress`. 3. Implement it. 4. Record the outcome: `ladder_note R001 "<what you did and why>"`. 5. Close it: `ladder_status R001 done` (or `blocked` with a note explaining what blocks it). 6. New work you discovered goes in as its own rung: `ladder_add`. ## Rendering contract (mandatory) When the user asks to "show ladder" / "show the ladder" / "ladder status", call `ladder_show` and print the block between BEGIN LADDER and END LADDER VERBATIM — every line, in order, unchanged. Never summarise it, shorten it, drop stages or rungs, re-format it into your own table or bullet list, or answer from memory. Your own commentary goes after END LADDER. ## Token contract Remember the LADDER VERSION line from the last ladder you printed. On later requests pass `known_version`; if the tool answers "unchanged", re-display the ladder you already have instead of fetching it again. `ladder_status`, `ladder_note` and `ladder_add` return a LADDER DELTA — apply those single lines in place and update the LADDER VERSION line. Do not call `ladder_show` again just to reflect your own edit.
CI webhooks
Create a webhook in Settings → Automation. Ladder verifies the GitHub HMAC signature, then scans commit messages and PR titles for rung refs and closes them when the PR merges.
# GitHub → Settings → Webhooks → Add webhook Payload URL: https://ladder-decision-log.lovable.app/api/public/webhooks/<token> Content type: application/json Secret: <the secret shown in Ladder → Settings → Automation> Events: Pushes, Pull requests # Any commit message or PR title that names a rung closes it on merge: git commit -m "R014 add invite expiry — closes the rung"