handoff-mcp-server 0.13.1 → 0.15.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
@@ -13,9 +13,9 @@ dependencies = [
13
13
 
14
14
  [[package]]
15
15
  name = "anyhow"
16
- version = "1.0.102"
16
+ version = "1.0.103"
17
17
  source = "registry+https://github.com/rust-lang/crates.io-index"
18
- checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
18
+ checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3"
19
19
 
20
20
  [[package]]
21
21
  name = "autocfg"
@@ -37,9 +37,9 @@ checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
37
37
 
38
38
  [[package]]
39
39
  name = "cc"
40
- version = "1.2.64"
40
+ version = "1.2.65"
41
41
  source = "registry+https://github.com/rust-lang/crates.io-index"
42
- checksum = "dad887fd958be91b5098c0248def011f4523ab786cd411be668777e55063501f"
42
+ checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96"
43
43
  dependencies = [
44
44
  "find-msvc-tools",
45
45
  "shlex",
@@ -99,12 +99,6 @@ version = "0.1.9"
99
99
  source = "registry+https://github.com/rust-lang/crates.io-index"
100
100
  checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
101
101
 
102
- [[package]]
103
- name = "foldhash"
104
- version = "0.1.5"
105
- source = "registry+https://github.com/rust-lang/crates.io-index"
106
- checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
107
-
108
102
  [[package]]
109
103
  name = "futures-core"
110
104
  version = "0.3.32"
@@ -131,20 +125,18 @@ dependencies = [
131
125
 
132
126
  [[package]]
133
127
  name = "getrandom"
134
- version = "0.4.2"
128
+ version = "0.4.3"
135
129
  source = "registry+https://github.com/rust-lang/crates.io-index"
136
- checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
130
+ checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099"
137
131
  dependencies = [
138
132
  "cfg-if",
139
133
  "libc",
140
134
  "r-efi",
141
- "wasip2",
142
- "wasip3",
143
135
  ]
144
136
 
145
137
  [[package]]
146
138
  name = "handoff-mcp"
147
- version = "0.13.1"
139
+ version = "0.15.0"
148
140
  dependencies = [
149
141
  "anyhow",
150
142
  "chrono",
@@ -157,27 +149,12 @@ dependencies = [
157
149
  "toml_edit",
158
150
  ]
159
151
 
160
- [[package]]
161
- name = "hashbrown"
162
- version = "0.15.5"
163
- source = "registry+https://github.com/rust-lang/crates.io-index"
164
- checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
165
- dependencies = [
166
- "foldhash",
167
- ]
168
-
169
152
  [[package]]
170
153
  name = "hashbrown"
171
154
  version = "0.17.1"
172
155
  source = "registry+https://github.com/rust-lang/crates.io-index"
173
156
  checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
174
157
 
175
- [[package]]
176
- name = "heck"
177
- version = "0.5.0"
178
- source = "registry+https://github.com/rust-lang/crates.io-index"
179
- checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
180
-
181
158
  [[package]]
182
159
  name = "iana-time-zone"
183
160
  version = "0.1.65"
@@ -202,12 +179,6 @@ dependencies = [
202
179
  "cc",
203
180
  ]
204
181
 
205
- [[package]]
206
- name = "id-arena"
207
- version = "2.3.0"
208
- source = "registry+https://github.com/rust-lang/crates.io-index"
209
- checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
210
-
211
182
  [[package]]
212
183
  name = "indexmap"
213
184
  version = "2.14.0"
@@ -215,9 +186,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
215
186
  checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
216
187
  dependencies = [
217
188
  "equivalent",
218
- "hashbrown 0.17.1",
219
- "serde",
220
- "serde_core",
189
+ "hashbrown",
221
190
  ]
222
191
 
223
192
  [[package]]
@@ -228,21 +197,15 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
228
197
 
229
198
  [[package]]
230
199
  name = "js-sys"
231
- version = "0.3.102"
200
+ version = "0.3.103"
232
201
  source = "registry+https://github.com/rust-lang/crates.io-index"
233
- checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31"
202
+ checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102"
234
203
  dependencies = [
235
204
  "cfg-if",
236
205
  "futures-util",
237
206
  "wasm-bindgen",
238
207
  ]
239
208
 
240
- [[package]]
241
- name = "leb128fmt"
242
- version = "0.1.0"
243
- source = "registry+https://github.com/rust-lang/crates.io-index"
244
- checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
245
-
246
209
  [[package]]
247
210
  name = "lexsim"
248
211
  version = "0.1.0"
@@ -267,9 +230,9 @@ checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
267
230
 
268
231
  [[package]]
269
232
  name = "log"
270
- version = "0.4.32"
233
+ version = "0.4.33"
271
234
  source = "registry+https://github.com/rust-lang/crates.io-index"
272
- checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a"
235
+ checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad"
273
236
 
274
237
  [[package]]
275
238
  name = "memchr"
@@ -298,16 +261,6 @@ version = "0.2.17"
298
261
  source = "registry+https://github.com/rust-lang/crates.io-index"
299
262
  checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
300
263
 
301
- [[package]]
302
- name = "prettyplease"
303
- version = "0.2.37"
304
- source = "registry+https://github.com/rust-lang/crates.io-index"
305
- checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
306
- dependencies = [
307
- "proc-macro2",
308
- "syn",
309
- ]
310
-
311
264
  [[package]]
312
265
  name = "proc-macro2"
313
266
  version = "1.0.106"
@@ -319,9 +272,9 @@ dependencies = [
319
272
 
320
273
  [[package]]
321
274
  name = "quote"
322
- version = "1.0.45"
275
+ version = "1.0.46"
323
276
  source = "registry+https://github.com/rust-lang/crates.io-index"
324
- checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
277
+ checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368"
325
278
  dependencies = [
326
279
  "proc-macro2",
327
280
  ]
@@ -351,12 +304,6 @@ version = "1.0.22"
351
304
  source = "registry+https://github.com/rust-lang/crates.io-index"
352
305
  checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
353
306
 
354
- [[package]]
355
- name = "semver"
356
- version = "1.0.28"
357
- source = "registry+https://github.com/rust-lang/crates.io-index"
358
- checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
359
-
360
307
  [[package]]
361
308
  name = "serde"
362
309
  version = "1.0.228"
@@ -424,9 +371,9 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
424
371
 
425
372
  [[package]]
426
373
  name = "syn"
427
- version = "2.0.117"
374
+ version = "2.0.118"
428
375
  source = "registry+https://github.com/rust-lang/crates.io-index"
429
- checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
376
+ checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
430
377
  dependencies = [
431
378
  "proc-macro2",
432
379
  "quote",
@@ -543,35 +490,11 @@ version = "1.13.3"
543
490
  source = "registry+https://github.com/rust-lang/crates.io-index"
544
491
  checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8"
545
492
 
546
- [[package]]
547
- name = "unicode-xid"
548
- version = "0.2.6"
549
- source = "registry+https://github.com/rust-lang/crates.io-index"
550
- checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
551
-
552
- [[package]]
553
- name = "wasip2"
554
- version = "1.0.4+wasi-0.2.12"
555
- source = "registry+https://github.com/rust-lang/crates.io-index"
556
- checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487"
557
- dependencies = [
558
- "wit-bindgen 0.57.1",
559
- ]
560
-
561
- [[package]]
562
- name = "wasip3"
563
- version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
564
- source = "registry+https://github.com/rust-lang/crates.io-index"
565
- checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
566
- dependencies = [
567
- "wit-bindgen 0.51.0",
568
- ]
569
-
570
493
  [[package]]
571
494
  name = "wasm-bindgen"
572
- version = "0.2.125"
495
+ version = "0.2.126"
573
496
  source = "registry+https://github.com/rust-lang/crates.io-index"
574
- checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a"
497
+ checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4"
575
498
  dependencies = [
576
499
  "cfg-if",
577
500
  "once_cell",
@@ -582,9 +505,9 @@ dependencies = [
582
505
 
583
506
  [[package]]
584
507
  name = "wasm-bindgen-macro"
585
- version = "0.2.125"
508
+ version = "0.2.126"
586
509
  source = "registry+https://github.com/rust-lang/crates.io-index"
587
- checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d"
510
+ checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1"
588
511
  dependencies = [
589
512
  "quote",
590
513
  "wasm-bindgen-macro-support",
@@ -592,9 +515,9 @@ dependencies = [
592
515
 
593
516
  [[package]]
594
517
  name = "wasm-bindgen-macro-support"
595
- version = "0.2.125"
518
+ version = "0.2.126"
596
519
  source = "registry+https://github.com/rust-lang/crates.io-index"
597
- checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd"
520
+ checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e"
598
521
  dependencies = [
599
522
  "bumpalo",
600
523
  "proc-macro2",
@@ -605,47 +528,13 @@ dependencies = [
605
528
 
606
529
  [[package]]
607
530
  name = "wasm-bindgen-shared"
608
- version = "0.2.125"
531
+ version = "0.2.126"
609
532
  source = "registry+https://github.com/rust-lang/crates.io-index"
610
- checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f"
533
+ checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24"
611
534
  dependencies = [
612
535
  "unicode-ident",
613
536
  ]
614
537
 
615
- [[package]]
616
- name = "wasm-encoder"
617
- version = "0.244.0"
618
- source = "registry+https://github.com/rust-lang/crates.io-index"
619
- checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
620
- dependencies = [
621
- "leb128fmt",
622
- "wasmparser",
623
- ]
624
-
625
- [[package]]
626
- name = "wasm-metadata"
627
- version = "0.244.0"
628
- source = "registry+https://github.com/rust-lang/crates.io-index"
629
- checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
630
- dependencies = [
631
- "anyhow",
632
- "indexmap",
633
- "wasm-encoder",
634
- "wasmparser",
635
- ]
636
-
637
- [[package]]
638
- name = "wasmparser"
639
- version = "0.244.0"
640
- source = "registry+https://github.com/rust-lang/crates.io-index"
641
- checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
642
- dependencies = [
643
- "bitflags",
644
- "hashbrown 0.15.5",
645
- "indexmap",
646
- "semver",
647
- ]
648
-
649
538
  [[package]]
650
539
  name = "windows-core"
651
540
  version = "0.62.2"
@@ -723,100 +612,6 @@ dependencies = [
723
612
  "memchr",
724
613
  ]
725
614
 
726
- [[package]]
727
- name = "wit-bindgen"
728
- version = "0.51.0"
729
- source = "registry+https://github.com/rust-lang/crates.io-index"
730
- checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
731
- dependencies = [
732
- "wit-bindgen-rust-macro",
733
- ]
734
-
735
- [[package]]
736
- name = "wit-bindgen"
737
- version = "0.57.1"
738
- source = "registry+https://github.com/rust-lang/crates.io-index"
739
- checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
740
-
741
- [[package]]
742
- name = "wit-bindgen-core"
743
- version = "0.51.0"
744
- source = "registry+https://github.com/rust-lang/crates.io-index"
745
- checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
746
- dependencies = [
747
- "anyhow",
748
- "heck",
749
- "wit-parser",
750
- ]
751
-
752
- [[package]]
753
- name = "wit-bindgen-rust"
754
- version = "0.51.0"
755
- source = "registry+https://github.com/rust-lang/crates.io-index"
756
- checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
757
- dependencies = [
758
- "anyhow",
759
- "heck",
760
- "indexmap",
761
- "prettyplease",
762
- "syn",
763
- "wasm-metadata",
764
- "wit-bindgen-core",
765
- "wit-component",
766
- ]
767
-
768
- [[package]]
769
- name = "wit-bindgen-rust-macro"
770
- version = "0.51.0"
771
- source = "registry+https://github.com/rust-lang/crates.io-index"
772
- checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
773
- dependencies = [
774
- "anyhow",
775
- "prettyplease",
776
- "proc-macro2",
777
- "quote",
778
- "syn",
779
- "wit-bindgen-core",
780
- "wit-bindgen-rust",
781
- ]
782
-
783
- [[package]]
784
- name = "wit-component"
785
- version = "0.244.0"
786
- source = "registry+https://github.com/rust-lang/crates.io-index"
787
- checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
788
- dependencies = [
789
- "anyhow",
790
- "bitflags",
791
- "indexmap",
792
- "log",
793
- "serde",
794
- "serde_derive",
795
- "serde_json",
796
- "wasm-encoder",
797
- "wasm-metadata",
798
- "wasmparser",
799
- "wit-parser",
800
- ]
801
-
802
- [[package]]
803
- name = "wit-parser"
804
- version = "0.244.0"
805
- source = "registry+https://github.com/rust-lang/crates.io-index"
806
- checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
807
- dependencies = [
808
- "anyhow",
809
- "id-arena",
810
- "indexmap",
811
- "log",
812
- "semver",
813
- "serde",
814
- "serde_derive",
815
- "serde_json",
816
- "unicode-xid",
817
- "wasmparser",
818
- ]
819
-
820
615
  [[package]]
821
616
  name = "zmij"
822
617
  version = "1.0.21"
package/Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "handoff-mcp"
3
- version = "0.13.1"
3
+ version = "0.15.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
@@ -198,6 +198,14 @@ rename) so a concurrent reader never sees a partially-written file.
198
198
  | `handoff_get_referral` | Fetch one incoming referral in full — details, suggested tasks, done_criteria, context |
199
199
  | `handoff_update_referral` | Update referral status (open → acknowledged → resolved) |
200
200
 
201
+ ### Timer Coordination
202
+
203
+ | Tool | Purpose |
204
+ |------|---------|
205
+ | `handoff_timer_start` | Start tracking time for a task — delegates to VSCode extension if alive, otherwise starts MCP fallback timer |
206
+ | `handoff_timer_stop` | Stop the timer and log elapsed hours to `actual_hours` — delegates to VSCode if alive |
207
+ | `handoff_timer_get_time` | Get current timer state (elapsed, authority, projected total) without stopping |
208
+
201
209
  ### Project Memory
202
210
 
203
211
  | Tool | Purpose |
@@ -279,6 +287,9 @@ done_task_limit = 10 # Max completed tasks to show
279
287
  auto_git_summary = true # Capture git state automatically
280
288
  require_estimate_hours = true # Require estimate_hours on leaf tasks (default true)
281
289
  ai_estimate_multiplier = 0.2 # Multiplier turning human estimates into AI-effort hours
290
+ timer_provider = "auto" # "auto" | "vscode" | "mcp" | "off"
291
+ timer_authority_ttl_secs = 30 # Heartbeat freshness TTL for authority.json
292
+ timer_idle_timeout_minutes = 10 # Idle pause threshold for MCP fallback timer
282
293
 
283
294
  [dashboard]
284
295
  scan_dirs = ["~/pro/"] # Directories to scan for dashboard
@@ -462,6 +473,45 @@ All under `[settings]` in `.handoff/config.toml`, all with safe defaults
462
473
  | `memory_stale_days` | `60` | Days without a reference before a memory is flagged stale |
463
474
  | `memory_injected_gc_days` | `14` | Age at which per-session injection sidecars are garbage-collected |
464
475
 
476
+ ## CLI API
477
+
478
+ Since v0.15.0, every MCP tool is also callable directly from the shell:
479
+
480
+ ```bash
481
+ handoff-mcp <group> <action> [--key value ...]
482
+ ```
483
+
484
+ All output is JSON on stdout, suitable for scripting and programmatic use
485
+ (e.g. `child_process.execFile` from a VSCode extension).
486
+
487
+ **Examples:**
488
+
489
+ ```bash
490
+ # Memory operations
491
+ handoff-mcp memory save --text "Always use atomic_write" --kind lesson --tags safety,io
492
+ handoff-mcp memory query --text "atomic" --limit 5
493
+ handoff-mcp memory delete --id m-20260630-...
494
+
495
+ # Task management
496
+ handoff-mcp task list --status-filter todo
497
+ handoff-mcp task update --id t1 --title "New task" --status todo --estimate-hours 2
498
+ handoff-mcp task log-time --task-id t1 --hours 0.5
499
+
500
+ # Session and metrics
501
+ handoff-mcp session load
502
+ handoff-mcp metrics
503
+ handoff-mcp dashboard
504
+ ```
505
+
506
+ **Available groups:** `init`, `task`, `session`, `config`, `memory`,
507
+ `referral`, `assignee`, `milestone`, `calendar`, `labels`, `project`,
508
+ `metrics`, `capacity`, `schedule`, `dashboard`, `timer`.
509
+
510
+ Run `handoff-mcp --help` to see all groups, or `handoff-mcp <group> --help`
511
+ for actions within a group. See the
512
+ [CLI API Reference](https://github.com/alphaelements/handoff-mcp/wiki/CLI-API-Reference)
513
+ on the wiki for the full command list.
514
+
465
515
  ## MCP Resources
466
516
 
467
517
  | URI | Description |
@@ -489,6 +539,10 @@ This project uses handoff-mcp for session continuity.
489
539
  - **Decisions**: Record decisions with confidence levels as they are made,
490
540
  not just at session end. Use `confirmed` for verified facts, `estimated`
491
541
  for reasonable assumptions, `unverified` for unknowns.
542
+ - **Timer**: Use `handoff_timer_start` / `handoff_timer_stop` to track task time.
543
+ When the VSCode extension is running, the timer delegates to it automatically.
544
+ When the extension is absent, MCP runs a fallback timer and logs hours on stop.
545
+ Use `handoff_timer_get_time` to check elapsed time without stopping.
492
546
  - **Project memory**: Use `handoff_memory_save` to record durable lessons, rules,
493
547
  conventions, and gotchas that every future session should know. Use
494
548
  `handoff_memory_query` to retrieve relevant memories. Near-duplicate memories are
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "handoff-mcp-server",
3
- "version": "0.13.1",
3
+ "version": "0.15.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>",
@@ -105,6 +105,23 @@ Use `handoff_log_time` to record hours worked on a task:
105
105
  `schedule: { milestone: "v2" }` updates only the milestone and preserves
106
106
  `actual_hours`/`remaining_hours`. It never replaces the whole schedule object.
107
107
 
108
+ ### Timer Coordination (MCP ⇄ VSCode)
109
+
110
+ Use `handoff_timer_start` / `handoff_timer_stop` / `handoff_timer_get_time` to
111
+ track task time with automatic VSCode extension coordination:
112
+
113
+ - **`handoff_timer_start`** — if the VSCode extension is running (live authority
114
+ heartbeat), the request is delegated via `.handoff/timer/requests/`. If absent,
115
+ MCP starts a fallback internal timer.
116
+ - **`handoff_timer_stop`** — if delegated, creates a stop request for the extension.
117
+ If MCP is the fallback, stops the timer and atomically logs elapsed hours to
118
+ `actual_hours` (same as `handoff_log_time`).
119
+ - **`handoff_timer_get_time`** — reads `.handoff/timer/state.json` to show
120
+ elapsed time, state (tracking/paused/stopped), and current authority (vscode/mcp).
121
+ - The `timer_provider` config setting controls behavior: `"auto"` (default) uses
122
+ the authority protocol, `"vscode"` always delegates, `"mcp"` always uses
123
+ fallback, `"off"` disables timer tools entirely.
124
+
108
125
  ### Metrics & Project Health
109
126
 
110
127
  Check project health with `handoff_get_metrics` at session start: