handoff-mcp-server 0.15.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Cargo.lock CHANGED
@@ -136,7 +136,7 @@ dependencies = [
136
136
 
137
137
  [[package]]
138
138
  name = "handoff-mcp"
139
- version = "0.15.0"
139
+ version = "0.16.0"
140
140
  dependencies = [
141
141
  "anyhow",
142
142
  "chrono",
package/Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "handoff-mcp"
3
- version = "0.15.0"
3
+ version = "0.16.0"
4
4
  edition = "2021"
5
5
  description = "MCP server that gives AI coding agents persistent memory across sessions"
6
6
  license = "MIT"
package/README.md CHANGED
@@ -33,7 +33,37 @@ At session start, the agent calls `handoff_load_context` to pick up where things
33
33
 
34
34
  ## Installation
35
35
 
36
- ### cargo (recommended if you have Rust)
36
+ ### Claude Code Plugin (recommended)
37
+
38
+ The easiest way to install handoff-mcp is as a Claude Code plugin:
39
+
40
+ ```bash
41
+ # 1. Install the binary (required — the plugin calls it)
42
+ npm install -g handoff-mcp-server
43
+ # or: cargo install handoff-mcp
44
+
45
+ # 2. Add the marketplace
46
+ /plugin marketplace add alphaelements/handoff-mcp
47
+
48
+ # 3. Install the plugin (MCP server + skills)
49
+ /plugin install handoff-mcp@handoff-mcp-marketplace
50
+ ```
51
+
52
+ This registers the MCP server and all skills automatically — no manual
53
+ `.mcp.json` or skill file setup needed.
54
+
55
+ **Optional: memory auto-injection hooks**
56
+
57
+ ```bash
58
+ /plugin install handoff-mcp-hooks@handoff-mcp-marketplace
59
+ /plugin enable handoff-mcp-hooks
60
+ ```
61
+
62
+ This adds hooks that inject relevant project memories on every prompt and file
63
+ edit. Disable anytime with `/plugin disable handoff-mcp-hooks` — the MCP server
64
+ and skills remain active.
65
+
66
+ ### cargo
37
67
 
38
68
  ```bash
39
69
  cargo install handoff-mcp
@@ -58,9 +88,10 @@ cd handoff-mcp
58
88
  cargo build --release
59
89
  ```
60
90
 
61
- ## Setup
91
+ ## Setup (non-plugin)
62
92
 
63
- Register handoff-mcp as an MCP server in Claude Code:
93
+ If you installed via cargo/npm (without the plugin), register handoff-mcp as an
94
+ MCP server in Claude Code manually:
64
95
 
65
96
  **Option A** — CLI (recommended):
66
97
 
@@ -86,8 +117,9 @@ The `-s user` flag registers it globally (available in all projects). Verify wit
86
117
 
87
118
  ### Enable automatic memory injection (optional)
88
119
 
89
- If you want project memories to be automatically injected into your context
90
- (instead of calling `handoff_memory_query` manually every time), run:
120
+ If you installed via the plugin, use `handoff-mcp-hooks` instead (see above).
121
+
122
+ For non-plugin installs, run:
91
123
 
92
124
  ```bash
93
125
  handoff-mcp setup
@@ -215,6 +247,7 @@ rename) so a concurrent reader never sees a partially-written file.
215
247
  | `handoff_memory_delete` | Delete a memory by id (full id or unique prefix) |
216
248
  | `handoff_memory_cleanup` | Housekeeping (for SessionStart): silently merge exact duplicates, return near-duplicate/stale recommendations, gc old injection sidecars |
217
249
 
250
+ For usage best practices (granularity, scope_paths, conflict handling, cleanup), see `skills/handoff-memory/SKILL.md`.
218
251
  See [Project Memory](#project-memory-1) below for what it is and how to wire automatic injection.
219
252
 
220
253
  ### Task Data Model
@@ -549,16 +582,26 @@ This project uses handoff-mcp for session continuity.
549
582
  surfaced as conflicts for you to merge or force-save — never merged silently.
550
583
  ```
551
584
 
552
- ## Skill File (Optional)
585
+ ## Skills
553
586
 
554
- This repository includes a skill file at [`skills/handoff/SKILL.md`](skills/handoff/SKILL.md) that makes handoff behavior automatic in Claude Code. Copy it to your user skills directory:
587
+ This repository includes skill files that make handoff behavior automatic in Claude Code:
588
+
589
+ | Skill | Purpose |
590
+ |-------|---------|
591
+ | `handoff` | Core session lifecycle, task management, metrics, scheduling |
592
+ | `handoff-load` | Quick session-start procedure |
593
+ | `handoff-memory` | Memory CRUD, conflict handling, cleanup |
594
+ | `handoff-refer` | Cross-project referrals |
595
+ | `handoff-import` | Bulk import from documents |
596
+
597
+ **Plugin users**: all skills are included automatically.
598
+
599
+ **Manual setup**: copy the skills to your user skills directory:
555
600
 
556
601
  ```bash
557
- cp -r skills/handoff ~/.claude/skills/
602
+ cp -r skills/* ~/.claude/skills/
558
603
  ```
559
604
 
560
- This teaches the agent to automatically load context at session start, track tasks during work, and save context at session end.
561
-
562
605
  ## Compatibility
563
606
 
564
607
  - **Claude Code** — fully supported (stdio transport)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "handoff-mcp-server",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "description": "MCP server that gives AI coding agents persistent memory across sessions",
5
5
  "license": "MIT",
6
6
  "author": "AlphaElements <66808803+alphaelements@users.noreply.github.com>",
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env bash
2
+ # Sync skills/ -> plugin/skills/ for plugin distribution.
3
+ # Run before release to ensure the plugin has the latest skills.
4
+ set -euo pipefail
5
+
6
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
7
+ ROOT="$(dirname "$SCRIPT_DIR")"
8
+
9
+ rm -rf "$ROOT/plugin/skills"
10
+ cp -a "$ROOT/skills" "$ROOT/plugin/skills"
11
+
12
+ echo "Synced skills/ -> plugin/skills/"
13
+ diff -rq "$ROOT/skills/" "$ROOT/plugin/skills/" && echo "No differences." || echo "WARNING: differences remain after sync."
@@ -0,0 +1,139 @@
1
+ ---
2
+ name: handoff-memory
3
+ description: "Project memory — save, query, merge, and clean up durable project knowledge (lessons, rules, conventions, gotchas). Triggers on 'メモリ保存', 'これ覚えて', '知見を残して', '過去の知見', 'memory save', 'memory query', 'remember this', 'recall', 'cleanup memories', or when recording post-incident learnings, recurring NG patterns, or project-specific conventions."
4
+ ---
5
+
6
+ # Handoff Memory Skill
7
+
8
+ ## When to use
9
+
10
+ - The user says "メモリ保存", "これ覚えて", "知見を残して", "remember this", "save this as a memory"
11
+ - The user asks "過去の知見を確認", "recall", "what do we know about X"
12
+ - You discover a reusable lesson, recurring NG pattern, or project-specific convention worth persisting across sessions
13
+ - Post-incident feedback or investigation results should be captured
14
+ - Existing memories need merging, updating, or pruning
15
+ - Session start — run cleanup to keep the memory store healthy
16
+
17
+ ## Granularity Rule
18
+
19
+ **One memory = one piece of knowledge.** Do not bundle multiple unrelated lessons
20
+ into a single memory. Each memory should be independently searchable and
21
+ independently deletable. If two ideas always travel together, save them together;
22
+ if they could be relevant in different contexts, split them.
23
+
24
+ ## Saving a Memory
25
+
26
+ Call `handoff_memory_save` with:
27
+
28
+ | Param | Required | Description |
29
+ |---|---|---|
30
+ | `text` | yes | The memory content. Be specific and actionable — "always use X because Y", not "X is important" |
31
+ | `kind` | no (default: `lesson`) | One of: `lesson` (something learned), `rule` (a mandated practice), `convention` (an agreed pattern), `gotcha` (a non-obvious trap) |
32
+ | `scope_paths` | no | Path prefixes this memory applies to (e.g. `["src/storage/", "src/mcp/handlers/"]`). Memories with matching scope_paths get a relevance boost when the user edits files under those paths |
33
+ | `tags` | no | Free-form tags for searchability (e.g. `["atomic-write", "config"]`). Tags are included in the similarity index |
34
+ | `force` | no | `true` to skip near-duplicate detection and save unconditionally |
35
+ | `merge_into` | no | ID of an existing memory to overwrite with merged content (see Merging below) |
36
+ | `absorb_ids` | no | IDs of memories to delete after merging into the target |
37
+
38
+ ### scope_paths Best Practices
39
+
40
+ - Use directory-level substrings, not full file paths: `"src/storage/"` not `"src/storage/config.rs"`. The matching is substring-based (`file_path.contains(scope)`), so `"storage/"` will match any file whose path contains that segment
41
+ - Scope broadly enough to catch related files, narrowly enough to avoid noise
42
+ - A memory with no scope_paths relies purely on text similarity for injection — fine for project-wide rules, but file-specific gotchas benefit from scoping
43
+
44
+ ### tags Best Practices
45
+
46
+ - Use lowercase, hyphenated terms: `"atomic-write"`, `"json-rpc"`, `"config-toml"`
47
+ - Tags supplement the body text for search — add tags for synonyms or concepts not explicitly mentioned in the body
48
+
49
+ ## Handling Near-Duplicate Conflicts
50
+
51
+ When `handoff_memory_save` returns `status: "conflict"`, it means the new memory
52
+ is similar to one or more existing memories (Jaccard similarity >= threshold). The
53
+ response includes both the new text and the similar existing memories.
54
+
55
+ **Decision flow:**
56
+
57
+ 1. **Read both texts carefully.** Are they expressing the same knowledge?
58
+ 2. **If yes — merge:** Write a combined text that captures both perspectives, then call `handoff_memory_save` again with:
59
+ - `text`: the merged content
60
+ - `merge_into`: ID of the existing memory to keep
61
+ - `absorb_ids`: IDs of any other similar memories to absorb
62
+ - Update `kind`, `tags`, `scope_paths` as needed
63
+ 3. **If no — force-save:** The memories are genuinely distinct despite textual similarity. Call `handoff_memory_save` with `force: true` to save the new one separately.
64
+
65
+ Do not ignore conflicts — they indicate the memory store may have redundancy that degrades injection quality.
66
+
67
+ ## Querying Memories
68
+
69
+ Call `handoff_memory_query` with:
70
+
71
+ | Param | Description |
72
+ |---|---|
73
+ | `text` | The prompt or question to match against (BM25 relevance ranking) |
74
+ | `file_paths` | Files being worked on — memories scoped to these paths get a boost |
75
+ | `session_id` | Current session ID — suppresses re-injection of memories already seen this session |
76
+ | `limit` | Max memories to return (default from config, typically 5) |
77
+ | `tool_name` | Tool being used (adds context tokens for matching) |
78
+ | `mark_injected` | Whether to record injection for dedup (default: true) |
79
+
80
+ The query engine uses BM25 text similarity plus a scope_path bonus. Passing
81
+ `session_id` enables per-session diff injection: a memory already injected this
82
+ session (same content hash) is filtered out, but an edited memory (new hash) is
83
+ re-injected.
84
+
85
+ ## Cleanup
86
+
87
+ ### When to Run
88
+
89
+ Run `handoff_memory_cleanup` at the start of each session (the SessionStart hook
90
+ does this automatically if configured). Optional arguments:
91
+
92
+ | Param | Default | Description |
93
+ |---|---|---|
94
+ | `apply_exact_merges` | `true` | Set `false` to skip auto-merging and only return recommendations |
95
+ | `stale_days` | from config (default 60) | Override the staleness threshold in days |
96
+
97
+ It performs three passes:
98
+
99
+ 1. **Exact duplicates** — silently auto-merged (lossless; oldest entry kept, others absorbed). Skipped when `apply_exact_merges` is `false`
100
+ 2. **Near-duplicate clusters** — returned as recommendations for AI-driven merge
101
+ 3. **Stale memories** — memories not referenced for `stale_days`, returned as recommendations
102
+
103
+ ### Acting on Cleanup Recommendations
104
+
105
+ - **similar_clusters**: Review each cluster. If the memories are truly redundant, merge them with `handoff_memory_save(merge_into=..., absorb_ids=[...])`. If distinct, leave them.
106
+ - **stale**: Consider whether the memory is obsolete (delete with `handoff_memory_delete`) or simply rarely triggered (leave it — low hit_count doesn't mean low value).
107
+
108
+ ### Manual Deletion
109
+
110
+ Call `handoff_memory_delete` with the memory `id` (full ID or unique prefix). Use
111
+ this for memories that are confirmed obsolete, wrong, or superseded by a code
112
+ change.
113
+
114
+ ## Memory Hooks (Optional Auto-Injection)
115
+
116
+ Memory tools can be called manually, but for automatic injection without AI
117
+ initiative, configure Claude Code hooks:
118
+
119
+ | Hook | Tool Call | Purpose |
120
+ |---|---|---|
121
+ | `UserPromptSubmit` | `handoff_memory_query` (prompt text) | Inject memories relevant to each user prompt |
122
+ | `PreToolUse` (`Edit\|Write\|MultiEdit`) | `handoff_memory_query` (file path) | Inject memories scoped to the file being edited |
123
+ | `SessionStart` | `handoff_memory_cleanup` | Auto-merge exact duplicates, surface recommendations |
124
+
125
+ Run `handoff-mcp setup` to install these hooks automatically, or
126
+ `handoff-mcp setup --uninstall` to remove them. See the README for the full hook
127
+ JSON configuration.
128
+
129
+ ## Memory vs Session vs CLAUDE.md
130
+
131
+ | Layer | Lifespan | Purpose |
132
+ |---|---|---|
133
+ | Sessions (`.handoff/sessions/`) | Per-conversation | "What was I doing last time?" |
134
+ | Memory (`.handoff/memory/`) | Cross-session, long-lived | "What has this project learned?" |
135
+ | `CLAUDE.md` | Permanent | Foundational rules, build commands, repo structure |
136
+ | `.claude/skills/` | Permanent | Operational procedures triggered by intent |
137
+
138
+ Rule changes: discover via memory → codify in skills/CLAUDE.md. Memory is the
139
+ source of evidence; skills and CLAUDE.md are the source of authority.