This page is the full reference for using Morph in Claude Code. For a single canonical installation flow (binaries, init, then IDE), see Installation.
What you get: Rich structured traces of every agent interaction -- tool calls, file reads/edits, prompts, and responses -- stored as Runs with Traces in the Morph object store. Always-on recording via hooks (no need for the agent to call a tool). File tree commits via MCP tools or CLI, independent of Git.
- Install the Morph binaries -- see Installation: Install the Morph binaries.
- Initialize a Morph repo inside an existing git repo:
morph init-- see Installation: Initialize a Morph repo. (If your project is not a git repo yet,morph initwill offer to rungit initfor you.) - Run setup to install MCP config + hooks + the recording scripts:
morph setup claude-codeThis writes (or merges into) .claude/settings.json in your project, drops two recording scripts under .claude/hooks/, and marks them executable. Then open the project in Claude Code; ensure morph and morph-mcp are on your PATH. No manual MCP or hook configuration needed.
If you would rather wire it by hand (CI, custom layouts, restricted writes), Sections 1 and 2 below describe the full hand-roll. morph setup claude-code writes exactly the same artifacts, idempotently, while preserving any pre-existing model, mcpServers, or hooks entries.
Claude Code connects to tools via MCP. Add the Morph server so the agent can use morph_record_session, morph_stage, morph_commit, etc.
If morph-mcp is on your PATH, add it in your MCP configuration (e.g. via claude mcp add or your settings file). Example for a project-level config:
Project: .claude/settings.json (or merge into existing):
{
"mcpServers": {
"morph": {
"command": "morph-mcp",
"args": []
}
}
}If Claude Code can't find the binary, use the full path (e.g. "/usr/local/bin/morph-mcp" or "$HOME/.cargo/bin/morph-mcp"). Restart or reload Claude Code after changing MCP config.
If the MCP server's working directory isn't your project root, set MORPH_WORKSPACE in the server config so Morph finds the repo:
{
"mcpServers": {
"morph": {
"command": "morph-mcp",
"args": [],
"env": {
"MORPH_WORKSPACE": "/absolute/path/to/your/project"
}
}
}
}Claude Code hooks run on lifecycle events. Use UserPromptSubmit and Stop so every prompt and full response is recorded without the agent calling a tool.
- UserPromptSubmit -- Fires when you submit a prompt; payload includes
promptandsession_id. - Stop -- Fires when Claude finishes responding; payload includes structured data (transcript or conversation) and
last_assistant_messageas a fallback.
Copy the Morph hook scripts into your project so Claude Code can run them:
- From the Morph repo, copy the contents of
claude-code/hooks/into your project's.claude/hooks/directory (e.g.morph-record-prompt.sh,morph-record-stop.sh). - Make the scripts executable:
chmod +x .claude/hooks/morph-record-prompt.sh .claude/hooks/morph-record-stop.sh.
The stop hook checks for structured data in the Claude Code payload:
transcript_path-- JSONL file containing the full conversation. Parsed fortool_use(file reads, file edits, shell commands) andtool_resultitems, producing rich structured trace events.conversation-- Array of message objects withtool_useandtool_resultcontent blocks; parsed similarly whentranscript_pathis unavailable.- Token usage (
input_tokens,output_tokens,total_tokens) -- captured intorun.environment.parameters. - Fallback -- If neither
transcript_pathnorconversationis available, the hook recordslast_assistant_messageas a plain response.
In .claude/settings.json (or ~/.claude/settings.json), add a hooks section. Paths are relative to the project root:
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": ".claude/hooks/morph-record-prompt.sh"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": ".claude/hooks/morph-record-stop.sh"
}
]
}
]
}
}If you already have other hooks, merge these entries into the existing UserPromptSubmit and Stop arrays.
- UserPromptSubmit appends the prompt to
.morph/hooks/pending-<session_id>.jsonl. - Stop reads that file, parses structured events from the payload, builds a Run + Trace, runs
morph session import(wasmorph run recordpre-v0.48), then deletes the pending file.
Hook output and logs go under .morph/hooks/logs/ and .morph/hooks/debug/ (see Debugging below).
In your project root:
morph initThis creates .morph/ (objects, refs, config, prompts, runs, traces, etc.). No other directories are modified.
- In Claude Code, confirm the Morph MCP server is connected (per your MCP setup).
- Submit a prompt and let Claude respond; then check that a new run appears, e.g.
ls .morph/objects/or inspect.morph/runs/and.morph/hooks/logs/morph-record.log.
Same as with Cursor:
- Stage:
morph add .(CLI) ormorph_stage(MCP) - Commit:
morph commit -m "message"(CLI) ormorph_commit(MCP)
When hooks run, they write under .morph/hooks/:
| File | Purpose |
|---|---|
.morph/hooks/logs/claude-invoke.log |
Claude Code invoked the hook (one line per event) |
.morph/hooks/logs/morph-record.log |
Morph stored a run (one line per successful record, with run hash) |
.morph/hooks/debug/last-UserPromptSubmit.json |
Last UserPromptSubmit payload (prompt may be truncated) |
.morph/hooks/debug/last-Stop.json |
Last Stop payload (response may be truncated) |
If recording doesn't happen, ensure:
morphandmorph-mcpare on PATH (or use full paths in config).- The project has been initialized with
morph init(.morph/exists). - Hook script paths in
.claude/settings.jsonare correct and the scripts are executable. - Claude Code was restarted or hooks were reloaded after config changes (Claude Code snapshots hooks at startup; some changes require a new session).
- Hooks reference -- Event list, input schemas, and config.
- Connect Claude Code to tools via MCP -- MCP setup.
- Installation -- Canonical install flow for all IDEs.
- CURSOR-SETUP.md -- Cursor-specific setup (same binaries and MCP server).
- OPENCODE-SETUP.md -- OpenCode-specific setup.