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

  1. Sign in and open the board. If it is empty, the onboarding wizard seeds a starter ladder with example stages and rungs.
  2. Go to /connect and paste the install snippet for your editor. Ladder's MCP endpoint is:
    https://ladder-decision-log.lovable.app/mcp
  3. Ask your assistant: “show ladder”. It prints the full board verbatim.
  4. 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_projectsList your Ladder projects.
ladder_showPrint the full canonical ladder, verbatim.
ladder_nextRead the highest-priority unblocked open rung.
ladder_listList rungs, filtered by stage or status.
ladder_statusMove a rung to a new status.
ladder_noteAppend a note to a rung.
ladder_addCreate a new rung.
ladder_rulesRead 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"

Team & sharing

Roles
owner manages the project, editor changes rungs, viewer is read-only.
Invite links
Owners generate a tokenised link with an optional expiry and use limit; the invitee signs in and joins.
Share links
Read-only public snapshots of a ladder, resolved through a token-gated lookup so links cannot be enumerated.
Live sync
Board, tree and CLI all read the same rows; realtime pushes changes without a refresh.