handoff-mcp-server 0.10.0 → 0.11.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
@@ -144,7 +144,7 @@ dependencies = [
144
144
 
145
145
  [[package]]
146
146
  name = "handoff-mcp"
147
- version = "0.10.0"
147
+ version = "0.11.0"
148
148
  dependencies = [
149
149
  "anyhow",
150
150
  "chrono",
@@ -153,6 +153,7 @@ dependencies = [
153
153
  "tempfile",
154
154
  "thiserror",
155
155
  "toml",
156
+ "toml_edit",
156
157
  ]
157
158
 
158
159
  [[package]]
package/Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "handoff-mcp"
3
- version = "0.10.0"
3
+ version = "0.11.0"
4
4
  edition = "2021"
5
5
  description = "MCP server that gives AI coding agents persistent memory across sessions"
6
6
  license = "MIT"
@@ -16,6 +16,7 @@ exclude = ["lefthook.yml", "tmp/", "wiki/", "docs/", ".claude/", ".vscode/"]
16
16
  serde = { version = "1", features = ["derive"] }
17
17
  serde_json = "1"
18
18
  toml = "0.8"
19
+ toml_edit = "0.22"
19
20
  chrono = { version = "0.4", features = ["serde"] }
20
21
  anyhow = "1"
21
22
  thiserror = "2"
package/README.md CHANGED
@@ -49,23 +49,17 @@ cargo build --release
49
49
 
50
50
  ## Setup
51
51
 
52
- Add to your Claude Code MCP configuration:
52
+ Register handoff-mcp as an MCP server in Claude Code:
53
53
 
54
- **Global** (`~/.claude/.mcp.json`) available in all projects:
54
+ **Option A** — CLI (recommended):
55
55
 
56
- ```json
57
- {
58
- "mcpServers": {
59
- "handoff": {
60
- "type": "stdio",
61
- "command": "handoff-mcp",
62
- "args": []
63
- }
64
- }
65
- }
56
+ ```bash
57
+ claude mcp add -s user handoff -- handoff-mcp
66
58
  ```
67
59
 
68
- **Per-project** (`.mcp.json` in project root):
60
+ The `-s user` flag registers it globally (available in all projects). Verify with `claude mcp get handoff`.
61
+
62
+ **Option B** — Manual edit of `~/.claude.json`:
69
63
 
70
64
  ```json
71
65
  {
@@ -102,41 +96,95 @@ Add to your Claude Code MCP configuration:
102
96
 
103
97
  ## Tools
104
98
 
99
+ ### Core Session Management
100
+
105
101
  | Tool | Purpose |
106
102
  |------|---------|
107
103
  | `handoff_init` | Initialize `.handoff/` directory for a project |
108
104
  | `handoff_load_context` | Load session context, tasks, and git state at session start |
109
- | `handoff_save_context` | Save session state — establish an active session (`session_status: "active"`) or close it (default) with handoff data |
110
- | `handoff_list_tasks` | List tasks with optional status filter |
105
+ | `handoff_save_context` | Save session state — establish an active session or close it with handoff data |
106
+ | `handoff_update_session` | Incrementally update active session (toggle checklist, add decisions/notes/pointers) |
107
+ | `handoff_list_sessions` | List all sessions (open/active/paused/closed) with summary info |
108
+ | `handoff_get_session` | Get full detail of a specific session by ID |
109
+
110
+ ### Task Management
111
+
112
+ | Tool | Purpose |
113
+ |------|---------|
114
+ | `handoff_list_tasks` | List tasks with filters (status, assignee, milestone, priority, label) |
115
+ | `handoff_get_task` | Get full task details (notes, done_criteria, schedule, etc.) |
111
116
  | `handoff_update_task` | Create, update, or move tasks in a hierarchical tree |
112
- | `handoff_get_config` | Read project configuration |
113
- | `handoff_update_config` | Update project configuration |
117
+ | `handoff_check_criterion` | Toggle a single done_criteria item by index |
118
+ | `handoff_log_time` | Log hours worked — adds to `actual_hours`, deducts from `remaining_hours` |
119
+ | `handoff_bulk_update_tasks` | Update multiple tasks in one call (status, schedule, assignee, priority) |
120
+
121
+ ### Metrics & Scheduling
122
+
123
+ | Tool | Purpose |
124
+ |------|---------|
125
+ | `handoff_get_metrics` | Project metrics: completion %, effort, overdue, budget, milestones |
126
+ | `handoff_get_capacity` | Work capacity for a date range, respecting calendar and assignee config |
127
+ | `handoff_auto_schedule` | Auto-schedule tasks based on dependencies, estimates, and capacity |
128
+
129
+ ### Configuration & Team
130
+
131
+ | Tool | Purpose |
132
+ |------|---------|
133
+ | `handoff_get_config` | Read project configuration (full TOML as JSON) |
134
+ | `handoff_update_config` | Update config: settings, calendar, assignees, effort budget, gantt view |
135
+ | `handoff_list_assignees` | List team members with task counts and effort stats |
136
+ | `handoff_add_assignee` | Add a team member (`[assignees.<key>]`) |
137
+ | `handoff_update_assignee` | Update a team member's fields (partial; null clears a field) |
138
+ | `handoff_remove_assignee` | Remove a team member and unassign them from every task |
139
+ | `handoff_list_milestones` | List milestones (`[milestones.*]`) |
140
+ | `handoff_add_milestone` | Add a milestone (date, color, description) |
141
+ | `handoff_update_milestone` | Update a milestone (partial) |
142
+ | `handoff_remove_milestone` | Remove a milestone |
143
+ | `handoff_update_calendar` | Patch the project `[calendar]` (work hours, closed days, `day_hours`, schedule_mode) |
144
+ | `handoff_update_labels` | Set the project-level label vocabulary |
145
+ | `handoff_start_project` | Set `started_at` and optionally shift all task dates to the project start |
146
+
147
+ These CRUD tools and the VSCode extension write the same `config.toml`, so the
148
+ GUI and the MCP server stay in full parity. All writes are atomic (temp-file +
149
+ rename) so a concurrent reader never sees a partially-written file.
150
+
151
+ ### Cross-Project
152
+
153
+ | Tool | Purpose |
154
+ |------|---------|
114
155
  | `handoff_dashboard` | Overview of all handoff-enabled projects |
156
+ | `handoff_import_context` | Bulk import tasks and session data from documents |
157
+ | `handoff_refer` | Send a cross-project referral (bug, improvement, request) |
158
+ | `handoff_list_referrals` | List incoming referrals from other projects |
159
+ | `handoff_update_referral` | Update referral status (open → acknowledged → resolved) |
115
160
 
116
- ### Task Management
161
+ ### Task Data Model
117
162
 
118
- Tasks are stored as a directory tree, supporting hierarchical structures:
163
+ Tasks are stored as a directory tree with status encoded in filenames:
119
164
 
120
165
  ```
121
166
  tasks/
122
- ├── 01-todo--implement-auth/
123
- │ ├── task.toml
124
- │ ├── 01.1-done--design-schema/
125
- │ │ └── task.toml
126
- │ └── 01.2-in_progress--write-handlers/
127
- │ └── task.toml
128
- └── 02-blocked--deploy-staging/
129
- └── task.toml
167
+ ├── t1-implement-auth/
168
+ │ ├── _task.done.json
169
+ │ ├── t1.1-design-schema/
170
+ │ │ └── _task.done.json
171
+ │ └── t1.2-write-handlers/
172
+ │ └── _task.in_progress.json
173
+ └── t2-deploy-staging/
174
+ └── _task.blocked.json
130
175
  ```
131
176
 
132
177
  Statuses: `todo` | `in_progress` | `review` | `done` | `blocked` | `skipped`
133
178
 
134
179
  Each task can have:
135
- - Priority (`low` / `medium` / `high`)
136
- - Labels
137
- - Done criteria (checklist items)
138
- - Links to issues, MRs, or docs
139
- - Notes
180
+ - **Assignee** — team member key (matches `[assignees.<key>]` in config.toml)
181
+ - **Priority** — `low` / `medium` / `high`
182
+ - **Labels** free-form tags
183
+ - **Done criteria** checklist items (all must be checked before `done` transition)
184
+ - **Links** — URLs to issues, MRs, or docs
185
+ - **Notes** — markdown description
186
+ - **Schedule** — `start_date`, `due_date`, `estimate_hours`, `actual_hours`, `remaining_hours`, `milestone`, `pinned`
187
+ - **Dependencies** — task IDs this task depends on (circular deps rejected)
140
188
 
141
189
  ### Session Context
142
190
 
@@ -181,8 +229,40 @@ auto_git_summary = true # Capture git state automatically
181
229
 
182
230
  [dashboard]
183
231
  scan_dirs = ["~/pro/"] # Directories to scan for dashboard
232
+
233
+ [calendar]
234
+ work_hours_per_day = 8
235
+ closed_weekdays = ["sat", "sun"]
236
+ closed_dates = ["2026-12-25"]
237
+ open_dates = []
238
+ schedule_mode = "auto" # "auto" or "manual"
239
+ overwork_limit_percent = 150
240
+
241
+ [calendar.day_hours]
242
+ fri = 4 # Per-weekday hour overrides
243
+
244
+ [effort_budget]
245
+ total_hours = 500 # Total project effort cap
246
+
247
+ [assignees.alice]
248
+ display_name = "Alice Chen"
249
+ color = "#4A90D9"
250
+ work_hours_per_day = 8
251
+ closed_weekdays = [1, 2] # Per-assignee overrides
252
+
253
+ [assignees.bob]
254
+ display_name = "Bob Martinez"
255
+ color = "#E74C3C"
256
+ work_hours_per_day = 6
257
+
258
+ [gantt_view]
259
+ sort = "start" # start, id, id-desc, status
260
+ zoom = "week" # day, week, month
261
+ mode = "compare" # plan, actual, compare
184
262
  ```
185
263
 
264
+ All configuration sections can be updated via `handoff_update_config` with dot-notation keys (e.g., `"calendar.work_hours_per_day": 7`).
265
+
186
266
  ## MCP Resources
187
267
 
188
268
  | URI | Description |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "handoff-mcp-server",
3
- "version": "0.10.0",
3
+ "version": "0.11.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>",
@@ -26,6 +26,7 @@
26
26
  "files": [
27
27
  "bin/handoff-mcp.js",
28
28
  "scripts/",
29
+ "skills/",
29
30
  "src/",
30
31
  "Cargo.toml",
31
32
  "Cargo.lock",
@@ -0,0 +1,223 @@
1
+ ---
2
+ name: handoff
3
+ description: "Session handoff — load context at start, save at end, track tasks during work. Triggers on session start, session end, task tracking, or when the user says 'handoff', 'save context', 'load context', 'what was I working on', or 'resume'."
4
+ ---
5
+
6
+ # Handoff Skill
7
+
8
+ ## Session Start
9
+
10
+ 1. Call `handoff_load_context` (uses current working directory).
11
+ 2. If the project is not initialized, call `handoff_init` with the project name
12
+ derived from the directory name.
13
+ 3. If `paused_sessions` are returned, show them to the user (ID, summary,
14
+ branch). To resume: `handoff_load_context(session_id: "s-...")`.
15
+ To discard: `handoff_save_context(close_session_id: "s-...")`.
16
+ 4. **Establish an active session immediately** — if `session_guidance` is
17
+ present in the response (meaning no active session exists), call
18
+ `handoff_save_context` with `session_status: "active"` **before starting
19
+ any work**. Include inherited context from the previous session:
20
+ - `summary`: use `session_guidance.suggested_fields.summary` or write
21
+ your own based on the previous session's summary
22
+ - `decisions`, `context_pointers`, `references`: carry forward from
23
+ `session_guidance.suggested_fields` if available
24
+ - `handoff_notes`: at minimum, a `suggestion` noting what you plan to do
25
+ - `checklist`: at minimum, one item noting session establishment
26
+ This ensures that if the conversation is interrupted, the session state
27
+ (what was being worked on, inherited decisions, file pointers) survives.
28
+ 5. Review the returned context:
29
+ - **Suggestions first**: `suggestion` handoff_notes (from current session
30
+ or `previous_session`) are the previous session's recommended next
31
+ actions. Unless the user's request contradicts them, start executing
32
+ from the first suggestion — do NOT re-verify work that the suggestion
33
+ says is already done.
34
+ - **Tasks**: check `in_progress` and `blocked` items first.
35
+ - **Decisions**: note confidence levels — `unverified` items may need revisiting.
36
+ - **Blockers**: address these before starting new work.
37
+ - **Handoff notes**: pay attention to `caution` items.
38
+ - **Context pointers**: read these to rebuild mental context, but do NOT
39
+ re-run tests or checks that the previous session already confirmed
40
+ unless there are new changes since that session's commit.
41
+ 6. Briefly summarize the current state to the user and start working
42
+ immediately from the suggestion — do not repeat completed verification.
43
+
44
+ ## During Work
45
+
46
+ ### Task Status Management
47
+ - When starting a task, call `handoff_update_task` to set status to `in_progress`.
48
+ - When completing a task, update it with all `done_criteria` set to `checked: true`
49
+ and status `done` in a single call. The server enforces that all criteria must be
50
+ checked before accepting a `done` transition — omitting them causes an error.
51
+ - When a task is blocked, set status to `blocked` with notes explaining why.
52
+ - **When work reaches a point requiring user confirmation** (e.g. "push this?",
53
+ "approve this design?"), set the task status to `review`. This signals to the
54
+ user that their input is needed before proceeding.
55
+ - Create new tasks as work is discovered. Always include `done_criteria` with
56
+ verifiable items so completion can be tracked.
57
+
58
+ ### Progressive done_criteria Checking
59
+ - **Check off `done_criteria` immediately as each item is verified** — do not
60
+ wait until the entire task is finished. Use `handoff_check_criterion` to
61
+ toggle individual items:
62
+ - Code written → check the implementation criterion
63
+ - Tests pass → check the test criterion
64
+ - Lint clean → check the lint criterion
65
+ - Real-run verified → check the verification criterion
66
+ - This ensures that if the session is interrupted, the next session knows
67
+ exactly which criteria are already satisfied.
68
+ - **done_criteria must cover the full verification chain**, not just implementation:
69
+ 1. **Implementation**: the code/config/doc changes themselves
70
+ 2. **Automated checks**: tests pass, linter/formatter clean
71
+ 3. **Real-run verification**: the change works in an actual execution
72
+ environment (app runs, endpoint returns expected response, UI renders
73
+ correctly, CLI produces correct output, etc.)
74
+ - A task is not done until verified end-to-end by running the real
75
+ artifact — passing automated checks alone is insufficient.
76
+
77
+ ### Progressive Session Updates
78
+ - Use `handoff_update_session` to incrementally update the active session
79
+ during work — no need to call `save_context` for small updates:
80
+ - **Toggle session checklist items**: `checklist_index` + `checklist_checked`
81
+ - **Add decisions as they happen**: `add_decision`
82
+ - **Add context pointers** to files you've been working on: `add_context_pointer`
83
+ - **Add handoff notes** (cautions, context): `add_handoff_note`
84
+ - Record decisions as they are made, not just at session end.
85
+ - **Before session end, review the overall plan**: call `handoff_list_tasks`
86
+ to see the full picture, then enumerate the next phase's steps as
87
+ `suggestion` handoff_notes. This ensures continuity across sessions.
88
+
89
+ ### Time Tracking
90
+
91
+ Use `handoff_log_time` to record hours worked on a task:
92
+ - Atomically adds to `schedule.actual_hours` and deducts from `schedule.remaining_hours`.
93
+ - Never overwrite `actual_hours` directly — always use the additive `handoff_log_time` tool.
94
+ - Set `schedule.estimate_hours` on task creation so metrics can show estimate vs actual.
95
+ - When the handoff-vscode time tracker is enabled, the extension also logs time
96
+ automatically — the AI does not need to log time manually for extension-tracked tasks.
97
+ - `handoff_update_task`'s `schedule` field **merges** (partial update): passing
98
+ `schedule: { milestone: "v2" }` updates only the milestone and preserves
99
+ `actual_hours`/`remaining_hours`. It never replaces the whole schedule object.
100
+
101
+ ### Metrics & Project Health
102
+
103
+ Check project health with `handoff_get_metrics` at session start:
104
+ - Returns completion %, overdue tasks, budget status, milestone breakdown.
105
+ - Use `assignee` filter to scope metrics to a specific team member.
106
+ - Use metrics to prioritize work: address overdue tasks first, then blocked, then todo.
107
+
108
+ ### Capacity & Scheduling
109
+
110
+ Before assigning dates to tasks, check available capacity:
111
+ - `handoff_get_capacity` — shows hours available per day for a date range, respecting the calendar and assignee configs.
112
+ - `handoff_auto_schedule` — auto-computes optimal start/due dates:
113
+ - Use `dry_run: true` (default) to preview changes without writing.
114
+ - Use `dry_run: false` to apply computed dates to task files.
115
+ - Respects task dependencies, pinned dates, and per-assignee calendars.
116
+ - Respects per-day capacity overrides (`calendar.day_hours`, e.g. a half-day Friday).
117
+ - Use `start_date: "YYYY-MM-DD"` to anchor the earliest task (defaults to today).
118
+ - Returns a change diff showing old vs new dates for each task.
119
+
120
+ ### Team & Assignee Management
121
+
122
+ - `handoff_list_assignees` — lists all team members from config.toml with task counts, active task counts, and effort hours.
123
+ - `handoff_add_assignee` — add a member: `key` (required), `display_name`, `color`, `work_hours_per_day`, `closed_weekdays`, `closed_dates`, `open_dates`, `day_hours`.
124
+ - `handoff_update_assignee` — patch an existing member (only provided fields change; pass `null` to clear a field).
125
+ - `handoff_remove_assignee` — remove a member **and** unassign them from every task automatically.
126
+ - Assign tasks via `handoff_update_task` (single) or `handoff_bulk_update_tasks` (batch).
127
+
128
+ ### Milestone Management
129
+
130
+ - `handoff_list_milestones` — list all milestones (`name → {date, color, description}`).
131
+ - `handoff_add_milestone` — add a milestone: `name` (required), `date`, `color`, `description`.
132
+ - `handoff_update_milestone` — patch an existing milestone (partial).
133
+ - `handoff_remove_milestone` — remove a milestone.
134
+
135
+ ### Project Calendar, Labels & Start
136
+
137
+ - `handoff_update_calendar` — patch `[calendar]` in one call: `work_hours_per_day`, `closed_weekdays`, `closed_dates`, `open_dates`, `day_hours`, `schedule_mode`. Only provided fields change.
138
+ - `handoff_update_labels` — set the project-level label vocabulary (`labels` array).
139
+ - `handoff_start_project` — set `started_at` and, with `shift_dates: true`, move every task's dates so the earliest start lands on the project start date.
140
+
141
+ ### Session Browsing
142
+
143
+ - `handoff_list_sessions` — list all sessions with status filter (open/active/paused/closed) and limit.
144
+ - `handoff_get_session` — get full detail of any session by ID (decisions, checklist, handoff_notes, context_pointers, references).
145
+ - Use these to reference decisions or context from past sessions without needing to re-read the full session file.
146
+
147
+ ### Bulk Operations
148
+
149
+ Use `handoff_bulk_update_tasks` for:
150
+ - Applying auto-schedule results to multiple tasks.
151
+ - Batch status changes (e.g., closing all review tasks).
152
+ - Batch assignee changes (e.g., reassigning a team member's tasks).
153
+ - Each task update is independent — failures on one task don't roll back others.
154
+
155
+ ### Configuration Management
156
+
157
+ Use `handoff_update_config` to manage project settings via dot-notation keys:
158
+ - **Calendar**: `calendar.work_hours_per_day`, `calendar.closed_weekdays`, `calendar.closed_dates`, `calendar.open_dates`, `calendar.schedule_mode`, `calendar.overwork_limit_percent`
159
+ - **Per-weekday hours**: `calendar.day_hours.fri` (number)
160
+ - **Budget**: `effort_budget.total_hours`
161
+ - **Assignees**: `assignees.<key>.display_name`, `assignees.<key>.color`, `assignees.<key>.work_hours_per_day`, `assignees.<key>.closed_weekdays`
162
+ - **Gantt view**: `gantt_view.sort`, `gantt_view.zoom`, `gantt_view.mode`, `gantt_view.group_by_milestone`, `gantt_view.show_workload`
163
+
164
+ ## Session End
165
+
166
+ When the user ends the session (or says "save context", "handoff", etc.):
167
+
168
+ 1. **Review the overall plan** before saving:
169
+ - Call `handoff_list_tasks` to see the current task tree.
170
+ - Identify which tasks were completed, which remain, and what the
171
+ logical next phase of work is.
172
+ - If the original plan needs adjustment based on what was learned,
173
+ note the changes in `decisions`.
174
+
175
+ 2. **Write actionable next-step suggestions**:
176
+ - Add at least one `handoff_notes` entry with `category: "suggestion"`
177
+ that describes a **concrete first action** for the next session
178
+ (not vague guidance like "continue working" — instead: "Run
179
+ `cargo test` on the new validation, then implement the wiki spec
180
+ update per the plan in t7").
181
+ - List the next 2-3 steps the next session should take, in priority
182
+ order, as separate `suggestion` entries.
183
+ - **Do not repeat task completion status** — the task system already
184
+ tracks what is done via `done_criteria`. Reference task IDs instead.
185
+ Bad: "All 138 tests pass and clippy is clean. Next: push branch"
186
+ Good: "Next: push branch and create MR (see t7 done_criteria)"
187
+ - If the next work belongs to a **different project**, say so explicitly
188
+ (e.g. "Next work is in handoff-vscode, not this project").
189
+
190
+ 3. Call `handoff_save_context` with:
191
+ - `summary`: one sentence describing what was accomplished.
192
+ - `decisions`: key decisions made, each with `reason` and `confidence`.
193
+ - `blockers`: anything preventing progress.
194
+ - `checklist`: items for the next session or user to verify. Mark
195
+ completed items as `checked: true` before saving. The server warns
196
+ if unchecked items remain or if checklist is empty.
197
+ - `handoff_notes`: things the next session should know, categorized as
198
+ `caution` (risks), `context` (background), or `suggestion` (next
199
+ actions). **At least one `suggestion` is required** — the server
200
+ warns if none is provided.
201
+ - `context_pointers`: files and line ranges the next session should read.
202
+ Point to files the next session **needs to work on or understand**,
203
+ not files that are already complete. If a file was changed and is done,
204
+ mention it in a `context` handoff_note instead.
205
+ The server warns if empty.
206
+ - `decisions`: the server warns if empty.
207
+ - `references`: relevant docs, issues, MRs. The server warns if empty.
208
+
209
+ By default, `save_context` writes the handoff data into the active
210
+ session and closes it (`.active.json` → `.closed.json`). With
211
+ `session_status: "active"`, it keeps the session active instead of
212
+ closing it — use this at session start to establish a persistent
213
+ session, and omit it (or use the default `"closed"`) at session end.
214
+
215
+ 4. **Review the server response** for warnings:
216
+ - If the server warns about unchecked checklist items, either check
217
+ them (if done) or acknowledge them to the user.
218
+ - If the server warns about missing suggestions, add suggestion notes
219
+ and re-save.
220
+ - If the server warns about missing context_pointers, decisions, or
221
+ references, add them if applicable.
222
+
223
+ 5. Confirm to the user that context has been saved.