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 +1 -1
- package/Cargo.toml +1 -1
- package/README.md +53 -10
- package/package.json +1 -1
- package/scripts/sync-plugin-skills.sh +13 -0
- package/skills/handoff-memory/SKILL.md +139 -0
package/Cargo.lock
CHANGED
package/Cargo.toml
CHANGED
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
|
-
###
|
|
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
|
-
|
|
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
|
|
90
|
-
|
|
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
|
-
##
|
|
585
|
+
## Skills
|
|
553
586
|
|
|
554
|
-
This repository includes
|
|
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
|
|
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.
|
|
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.
|