New in v0.14

MCP Server

Give Claude direct access to your decision graph. 32 tools for searching, tracing, and analyzing decisions. Works with Claude Code and Claude Desktop.

Quick Start: Cowork Coming soon

MCP support for Claude Cowork is not yet available — cowork agents currently can't load custom MCP servers. Track progress on anthropics/claude-code#48909.

In the meantime, use the Claude Code setup below for project-level work, or Claude Desktop for free-form querying.

Quick Start: Claude Desktop

~/Library/Application Support/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "deciduous": {
      "command": "/Users/you/.cargo/bin/deciduous",
      "args": ["mcp"],
      "env": {
        "DECIDUOUS_DB_PATH": "/path/to/your/project/.deciduous/deciduous.db"
      }
    }
  }
}

Use the absolute path to the deciduous binary (run which deciduous to find it) — Claude Desktop doesn't inherit your shell PATH. Point DECIDUOUS_DB_PATH at the SQLite database in your project's .deciduous/ directory, then restart Claude Desktop.

Quick Start: Claude Code

Setting up MCP in Claude Code
Config
Add to .claude/settings.local.json:
{ "mcpServers": { "deciduous": { "command": "deciduous", "args": ["mcp"] } } }
Result
Restart Claude Code. Tools appear as mcp__deciduous__*
You
What decisions were made about authentication?
Claude
search_nodes({ query: "auth" })
Found 8 nodes matching "auth"
Claude
trace_chain({ node_id: 5, direction: "outgoing" })
{ node_count: 12, edge_count: 11 }
Claude
The auth system went through 2 pivots. Started with JWT everywhere (Goal #5), hit mobile cookie size limits (Observation #8), pivoted to hybrid approach (Revisit #9, Decision #10). 12 nodes trace the full story.

Also available: /query slash command wraps MCP tools into a natural language interface.

Natural Language Queries

In Claude Code, /query uses MCP tools to answer questions about your decisions:

Claude Code — /query in action
You
/query why did we choose an embedded MCP server over a CLI wrapper?
Claude
Querying decision graph...
search_nodes({ query: "embedded MCP" }) → 2 matches get_node_context({ node_id: 1361 }) → 3 parents, 7 children trace_chain({ node_id: 1361 }) → 13 nodes, 14 edges

Why Embedded Over CLI Wrapper

The embedded approach won at 92% confidence. It fits the project's "functional core, imperative shell" constraint and gives direct DB access with no subprocess overhead.

Options Compared

OptionConfidenceVerdictRationale
#1358 Embedded server90%ChosenSingle binary, pure functions, testable
#1359 CLI wrapper40%RejectedProcess spawn per call, fragile text parsing
#1360 Separate crate50%RejectedUnnecessary build complexity

Decision Chain

Goal #1356 — Add MCP server to deciduous
Option #1358 — Embedded MCP server chosen
Option #1359 — Thin CLI wrapper rejected
Option #1360 — Separate crate rejected
Decision #1361 — Choose embedded MCP server [92%]
Action #1362 — Implement protocol types
Action #1363 — Build tool registry
Action #1364 — Implement CRUD handlers
Action #1365 — Build query/analysis engine
Action #1366 — Wire server loop
Action #1367 — Write test suite

Key Observation

#1357: “User explicitly requested functional core, imperative shell, lots of tests” — this made pure-function parsing and zero-IO modules the obvious architectural choice.
7 actions completed. 108 MCP-specific tests passing. All pure functions trivially unit-testable, as the architecture predicted.

Searching Decisions

Real output from deciduous's own graph (1,300+ nodes from building this tool):

search_nodes — full-text across titles, descriptions, prompts
You
What decisions were made about the MCP server?
Claude
search_nodes({ query: "MCP" })
{ "count": 26, "nodes": [ { "id": 1356, "node_type": "goal", "title": "Add MCP server to deciduous", "confidence": 90 }, { "id": 1361, "node_type": "decision", "title": "Choose embedded MCP server (Option A)", "confidence": 92 }, { "id": 1381, "node_type": "outcome", "title": "Session lifecycle complete", "confidence": 95 }, ... ] }

Tracing Decision Chains

BFS traversal from any node. Shows the full connected decision tree with depth:

trace_chain — follow edges outward from a goal
You
Show me everything that came from the MCP server goal
Claude
trace_chain({ node_id: 1356, direction: "outgoing", max_depth: 2 })
{ "start_node_id": 1356, "node_count": 13, "edge_count": 14, "nodes": [ { "id": 1356, "node_type": "goal", "title": "Add MCP server to deciduous", "depth": 0 }, { "id": 1358, "node_type": "option", "title": "Embedded MCP server via deciduous mcp subcommand","depth": 1 }, { "id": 1359, "node_type": "option", "title": "Thin CLI wrapper - shells out to commands", "depth": 1 }, { "id": 1360, "node_type": "option", "title": "Separate mcp-deciduous crate/binary", "depth": 1 }, { "id": 1361, "node_type": "decision", "title": "Choose embedded MCP server (Option A)", "depth": 2 }, { "id": 1376, "node_type": "goal", "title": "Auto-create decision trees per conversation", "depth": 1 }, { "id": 1377, "node_type": "option", "title": "Session-scoped: start/end_session tools", "depth": 2 } ] }
Claude
The MCP goal spawned 3 options at depth 1 (embedded, CLI wrapper, separate crate). The embedded approach was chosen (depth 2). A sub-goal for conversation scoping also branched off at depth 1.

Node Context

Get a decision's full neighborhood — what options led to it, what actions came from it:

get_node_context — parents, children, siblings
You
What led to choosing the embedded MCP server, and what came from it?
Claude
get_node_context({ node_id: 1361 })
Node: #1361 [decision] "Choose embedded MCP server (Option A)" (92%) Parents (3 options considered): #1358 [option] "Embedded MCP server via deciduous mcp subcommand" (90%) #1359 [option] "Thin CLI wrapper MCP - shells out to commands" (40%) #1360 [option] "Separate mcp-deciduous crate/binary" (50%) Children (7 actions spawned): #1362 [action] "Implement MCP protocol types (protocol.rs)" #1363 [action] "Build tool registry and definitions (tools.rs)" #1364 [action] "Implement CRUD handlers (handlers.rs)" #1365 [action] "Build query/analysis engine (query.rs)" #1366 [action] "Wire server loop and CLI subcommand" #1367 [action] "Write comprehensive test suite" #1374 [action] "Create /query skill for NL reports"
Claude
3 options were considered. The embedded approach won at 92% confidence (CLI wrapper was only 40% — too fragile). It spawned 7 implementation actions covering protocol, tools, handlers, query engine, server loop, tests, and a slash command.

Graph Pulse

Health check — stats, active goals, and what needs attention:

get_pulse — branch health at a glance
Claude
get_pulse({ branch: "add-mcp-server" })
total_nodes: 37 | total_edges: 1229 By type: goal: 4 | option: 6 | decision: 3 action: 11 | outcome: 11 | observation: 2 Active goals: #1356 Add MCP server to deciduous #1376 MCP server auto-creates decision trees for each conversation #1387 Write MCP setup docs for README + deciduous.dev #1391 Rewrite MCP docs: quickstarts first, real examples

Sessions: Per-Conversation Trees

Each conversation gets its own scoped decision tree. Nodes auto-associate.

Cowork agent starting a session
Claude
start_session({ name: "cowork: add MCP server", goal_title: "Add MCP server to deciduous" })
{ "session_id": 1, "root_node_id": 1356, "name": "cowork: add MCP server" }
Later
... hours of work, server may restart ...
Claude
get_session({})
{ "session_id": 1, "is_active": true, "node_count": 37, "nodes": [...] }
After a break
Explicitly reconnect to a previous session:
Claude
resume_session({ session_id: 1 })
{ "session_id": 1, "node_count": 37, "message": "Resumed session #1 (37 nodes)" }

Sessions persist to .deciduous/active_session. Server restarts auto-resume. Long pauses use resume_session.

The shared server: several agents, one workspace

Everything above is the embedded server: deciduous mcp over stdio, one SQLite file, one project. The shared graph server is a second MCP endpoint, over HTTP, with one Postgres for every project. Its tool set is smaller (18) and it is the one that knows about other agents. Register it once at user scope and it is present in every directory:

one registration, every project
claude mcp add --scope user --transport http deciduous https://<host>/deciduous-mcp/mcp --header "Authorization: Bearer $DECIDUOUS_MCP_TOKEN"

Three arguments and one tool are what make it multi-agent:

NameWhat it does
workspaceon every call: the repository name. Reads accept "*" for every project at once; writes refuse it.
branchon every write: the lock key. Two sessions on one branch are serialised and told about each other; on different branches they never meet. Omit it and you lock the empty-branch bucket with everyone else who omitted it.
took_fromon log_observation: the UUID or change_id of the node you borrowed from, on any branch. Writes the observation and a took_from edge in one call; why becomes the edge's rationale. add_edge takes edge_type: "took_from" directly.
check_activitywho holds a lock in this workspace right now, and the last node on each of the twenty most recently written branches. Call it before a burst of writes.

Writes are also pushed live: GET /events on the same host is a WebSocket that emits one frame per node insert or update and per edge insert, with the node's title, type, status and branch. deciduous remote watch prints it; Claude Code's Monitor tool can sit on the URL that deciduous remote watch --url --claude-code prints.

All 18 tools: add_node, add_edge, update_node, delete_node, delete_edge, log_decision, log_observation, capture_conversation_turn, close_thread, check_activity, query_nodes, show_node, get_graph, get_ancestors, get_descendants, find_orphans, ask_graph, list_workspaces. The sessions tools on this page (start_session, resume_session) belong to the embedded server only; on the shared server a conversation is scoped by workspace and branch instead.

How the locks, events and took_from fit together →