Working across sessions

Your AI agent forgets when the session ends. Backlog doesn't. Here's a three-day walkthrough: start a task in Claude Code, pick it up the next morning in Cursor, finish it overnight via an unattended agent, review the activity log in the morning.

Before you start: install Backlog (go install) and add the MCP server to whichever clients you use (MCP guide). Point every client at the same BACKLOG_DB. That's the shared brain.

The scenario

You're a solo developer shipping a small SaaS. You use Claude Code at your desk, Cursor on your laptop, and you sometimes leave an agent running overnight on a remote machine. Without persistent state, every session starts cold: the AI re-reads the codebase, re-plans the work, and forgets what you decided yesterday.

With Backlog, the state moves with the work, not with the AI session. One database, every client reading and writing it, and a complete audit trail when you check in.

The example feature: "Fix unsigned JWT rejection in auth middleware", a TASK-1 you'll spread across three days and three sessions.

Day 1, evening: start in Claude Code

You sit down at your desk, open Claude Code, and create the task. The agent drafts the initial plan based on its understanding of the codebase.

Claude Code session, Tuesday 9:47pm
# You create the task
backlog task add -p api \
  -t "Fix unsigned JWT rejection in auth middleware" \
  --type vulnerability --priority P1 \
  --as human:mazin

# Claude drafts the plan
backlog plan add --task TASK-1 \
  --title "JWT verification implementation" \
  --content "1. Extract Authorization header
2. Verify RS256 signature against JWKS endpoint
3. Return 401 on missing/malformed/unsigned tokens
4. Add unit tests with forged tokens" \
  --as ai:claude-code

# You move it to doing (the agent is working)
backlog task move TASK-1 --status doing --as ai:claude-code

Before bed, Claude leaves a progress comment:

backlog comment add --task TASK-1 \
  "Stubbed the JWKS fetcher. Tests pending, out of context window." \
  --as ai:claude-code

You close the laptop. Claude Code is gone. Its context, its plan, its reasoning. All of it would normally evaporate. But every write went into backlog.db.

Day 2, morning: switch to Cursor

You're on the couch with your other laptop. Cursor is your editor here. You don't want to re-explain the JWT task. Cursor has never seen it.

Cursor session, Wednesday 8:12am
# What was I working on?
backlog task list --status doing --as human:mazin
Output
 REF    │ P  │ TYPE          │ STATUS │ TITLE                                       │ ACTOR
────────┼────┼───────────────┼────────┼─────────────────────────────────────────────┼───────────────
 TASK-1 │ P1 │ vulnerability │ doing  │ Fix unsigned JWT rejection in auth middl…   │ claude-code

One command. The task is there. The plan is there. Claude's comment is there.

backlog task show TASK-1 --with-plans --with-comments

Now you tell Cursor "continue TASK-1." It reads the plan, sees Claude already stubbed the JWKS fetcher, sees the open work item ("Tests pending"), and picks up exactly there. It doesn't need to re-onboard, ask what the codebase does, or rewrite the plan from scratch.

Cursor finishes the tests, leaves its own comment, and writes a memory entry so the next session doesn't repeat its work:

backlog comment add --task TASK-1 \
  "Tests pass. JWKS keys cached with 1h TTL, re-fetched on key-ID miss." \
  --as ai:cursor

backlog memory add --project api \
  --body "JWKS endpoint: /auth/.well-known/jwks.json. Cache TTL 1h." \
  --tags "auth,decision" \
  --as ai:cursor

Day 2, night: unattended agent run

You want PR creation and a final security review done before you wake up. You SSH into a remote machine and start an agent that pulls tasks from the same Backlog (via BACKLOG_DB=/path/to/backlog.db) and finishes them autonomously.

Remote machine, Wednesday 11:30pm
# Set the env var so the agent reads your laptop's backlog
export BACKLOG_DB=/Volumes/sync/backlog/backlog.db

# Run an overnight loop: pick any P1 todo task, ship it, repeat
backlog mcp serve --as ai:claude-code &
# (claude-code or your script picks up TASK-1, opens the PR,
#  runs the security scan, posts the verdict comment, marks done)

While you sleep, the agent reads the plan, the existing comments, and the memory entry. It uses all of that as context. No human-in-the-loop needed because the context is in the database, not in some chat history that disappeared at 9pm.

Day 3: review the trail in the web UI

Morning. Coffee. You open backlog web and check Activity.

backlog web

You see, in chronological order:

  • human:mazin created TASK-1 at 9:47pm Tuesday
  • ai:claude-code attached plan v1 at 9:48pm Tuesday
  • ai:claude-code commented "Stubbed JWKS fetcher" at 10:15pm Tuesday
  • ai:cursor commented "Tests pass" at 8:34am Wednesday
  • ai:cursor added memory entry on JWKS caching at 8:35am Wednesday
  • ai:claude-code opened PR #1247 at 2:18am Thursday
  • ai:claude-code commented "Security scan clean, ready for review" at 2:31am Thursday
  • ai:claude-code moved TASK-1 to done at 2:32am Thursday

The PR is up. The reasoning behind every decision is in the plan and the comments. The architectural choice (cached JWKS, 1h TTL) is in memory where the next task on this codebase will read it. You merge the PR and pick the next task.

You didn't onboard the AI three times. You didn't re-explain the codebase. You didn't lose Claude's stub work when you switched to Cursor. The state moved with the work.

What's actually happening

The mechanics are unglamorous, which is the point:

  • One database file. Every MCP client and CLI invocation talks to the same backlog.db. Set BACKLOG_DB in each client's MCP config and they're pointing at the same brain.
  • Typed actors on every row. human:mazin, ai:claude-code, ai:cursor: stored as columns on every task, plan version, comment, and memory entry. Auditable forever.
  • Immutable plan versions. Claude's v1 plan stays readable even after Cursor writes v2. Nothing is overwritten silently.
  • Memory is the AI's scratchpad. Tagged free-form notes that survive every session. Architectural decisions, gotchas, "we tried this and it didn't work" notes, all queryable.
  • Activity log is the audit trail. Every write across the workspace lands in activity_log. Filter by project, entity, or actor. The morning standup writes itself.

That's it. There's no clever protocol behind it: the state lives in a file, the clients read and write it, and your work survives the session.

Where to go from here