Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Conversational Memory

Every conversation with Claude gets its own decision tree. When a session starts, a root goal node is created. Every node added during that conversation is automatically associated with the session – no manual bookkeeping. When the conversation ends, an optional summary captures what was accomplished.

The result: each conversation produces a self-contained, queryable record of what was discussed, decided, and built.

Session Lifecycle

A session has three phases:

  1. Startstart_session creates a root goal node and returns a session ID
  2. Work – all add_node calls auto-associate with the active session
  3. Endend_session marks the session complete with an optional summary
Session lifecycle
Claude
start_session({ name: "auth refactor", goal_title: "Refactor authentication to use OAuth2", goal_prompt: "I need to replace our custom JWT auth with OAuth2..." })
{ "session_id": 3, "root_node_id": 42, "name": "auth refactor" }
During conversation
Every add_node call auto-associates with session #3
Claude
add_node({ node_type: "option", title: "Use Auth0 as provider" })
Node #43 created -- automatically part of session #3
Claude
add_node({ node_type: "option", title: "Self-hosted Keycloak" })
Node #44 created -- automatically part of session #3
Claude
link_nodes({ from_id: 42, to_id: 43, rationale: "possible approach" })
Claude
link_nodes({ from_id: 42, to_id: 44, rationale: "possible approach" })
Claude
add_node({ node_type: "decision", title: "Choose Auth0 - managed service, faster to ship" })
Node #45 created
Claude
end_session({ summary: "Chose Auth0, implemented OAuth2 flow, tests passing" })
{ "session_id": 3, "node_count": 11, "message": "Ended session #3 (11 nodes)" }

Resuming Sessions

Pick up where you left off. Use list_sessions to find previous conversations, then resume_session to reconnect. New nodes continue building on the same decision tree.

Resuming a previous conversation
You
What sessions do I have?
Claude
list_sessions({})
{ "count": 3, "sessions": [ { "session_id": 1, "name": "initial setup", "is_active": false, "node_count": 14 }, { "session_id": 2, "name": "add caching", "is_active": false, "node_count": 8 }, { "session_id": 3, "name": "auth refactor", "is_active": false, "node_count": 11 } ]}
You
Resume the auth refactor
Claude
resume_session({ session_id: 3 })
{ "session_id": 3, "name": "auth refactor", "node_count": 11, "message": "Resumed session #3 (11 nodes)" }
Claude
get_session({ session_id: 3 })
Returns all 11 nodes from the previous conversation for full context
Claude
I can see the previous session chose Auth0 and implemented the OAuth2 flow. Let me continue from where we left off.

Persistence Across Restarts

The active session ID is written to .deciduous/active_session on disk. When the MCP server starts (or restarts – Claude Desktop and Claude Code may kill and re-spawn the server process), it reads this file and automatically resumes the active session. No manual intervention needed.

If the session was already ended, the stale file is cleaned up automatically.

Master Memory

Claude Desktop users get a persistent decision graph across every conversation. The MCP config points DECIDUOUS_DB_PATH at a single .deciduous/deciduous.db file. Every conversation – whether it runs for five minutes or five hours – writes to the same database.

This means you can ask Claude in a new conversation about decisions made in previous ones. The graph is the memory layer that outlasts any single chat.

Conversation 1 (Jan)  --> .deciduous/deciduous.db  <-- Session #1 (14 nodes)
Conversation 2 (Feb)  --> .deciduous/deciduous.db  <-- Session #2 (8 nodes)
Conversation 3 (Mar)  --> .deciduous/deciduous.db  <-- Session #3 (11 nodes)

In a brand new conversation, you can query the entire history:

New conversation querying past decisions
You
Why did we choose Auth0 over Keycloak?
Claude
search_nodes({ query: "Auth0" })
Found 4 nodes matching "Auth0"
Claude
trace_chain({ node_id: 42, direction: "outgoing" })
{ "node_count": 11, "edge_count": 12 }
Claude
The auth refactor (Session #3) considered two options: Auth0 and self-hosted Keycloak. Auth0 was chosen at 85% confidence because it's a managed service and faster to ship. The implementation included OAuth2 flow with PKCE, and all tests are passing.

The database is the single source of truth. Sessions organize it by conversation. Search and trace work across all of them.

Multi-Session Workflow Example

Here is a realistic workflow spanning two sessions days apart, showing how memory persists:

Session 1 -- Monday: starting the auth work
You
I need to add user authentication to the app. Users should sign up with email/password, and we need OAuth support for Google and GitHub.
Claude
start_session({ name: "auth implementation", goal_title: "Add user authentication with email + OAuth" })
{ "session_id": 1, "root_node_id": 1, "name": "auth implementation" }
Claude
add_node({ node_type: "option", title: "NextAuth.js - handles OAuth providers out of the box" })
Node #2 created
Claude
add_node({ node_type: "option", title: "Custom auth with Passport.js" })
Node #3 created
Claude
add_node({ node_type: "decision", title: "Use NextAuth.js - built-in Google/GitHub, less code" })
Node #4 created
Claude
add_node({ node_type: "action", title: "Implement NextAuth with Google + GitHub providers" })
Node #5 created
Claude
add_node({ node_type: "outcome", title: "OAuth working for Google, GitHub provider hitting rate limits in dev" })
Node #6 created
Claude
add_node({ node_type: "observation", title: "GitHub OAuth rate limits are per-app in dev mode, need to register a proper OAuth app" })
Node #7 created
Claude
end_session({ summary: "NextAuth chosen and implemented. Google OAuth working. GitHub needs a registered OAuth app to avoid dev rate limits." })
{ "session_id": 1, "node_count": 7, "message": "Ended session #1 (7 nodes)" }
Session 2 -- Thursday: picking up where we left off
You
I registered the GitHub OAuth app. Let's fix the auth and add email/password signup.
Claude
list_sessions({})
{ "count": 1, "sessions": [ { "session_id": 1, "name": "auth implementation", "is_active": false, "node_count": 7 } ]}
Claude
resume_session({ session_id: 1 })
{ "session_id": 1, "node_count": 7, "message": "Resumed session #1 (7 nodes)" }
Claude
get_session({})
Returns all 7 nodes -- I can see the GitHub rate limit observation from Monday
Claude
I can see from the previous session that NextAuth is set up with Google working, and there was a GitHub OAuth rate limit issue. Now that you've registered the app, let me update the config and add email/password support.
Claude
add_node({ node_type: "action", title: "Configure registered GitHub OAuth app credentials" })
Node #8 created -- automatically part of session #1
Claude
add_node({ node_type: "action", title: "Add NextAuth CredentialsProvider for email/password" })
Node #9 created
Claude
add_node({ node_type: "outcome", title: "All three auth methods working - Google, GitHub, email/password" })
Node #10 created
Claude
end_session({ summary: "GitHub OAuth fixed with registered app. Email/password added via CredentialsProvider. All three auth methods tested and working." })
{ "session_id": 1, "node_count": 10, "message": "Ended session #1 (10 nodes)" }

The decision tree now contains the full story: what was tried, what worked, what needed a second pass, and why. Any future session can query this history without having been part of either conversation.