@rethunk/mcp-multi-root-git 2.5.0 → 2.8.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.
Files changed (41) hide show
  1. package/AGENTS.md +4 -4
  2. package/CHANGELOG.md +45 -1
  3. package/README.md +1 -1
  4. package/dist/server/batch-commit-tool.js +32 -10
  5. package/dist/server/error-codes.js +95 -0
  6. package/dist/server/git-blame-tool.js +227 -0
  7. package/dist/server/git-branch-list-tool.js +140 -0
  8. package/dist/server/git-cherry-pick-tool.js +11 -10
  9. package/dist/server/git-diff-summary-tool.js +10 -3
  10. package/dist/server/git-diff-tool.js +60 -13
  11. package/dist/server/git-fetch-tool.js +148 -13
  12. package/dist/server/git-inventory-tool.js +7 -6
  13. package/dist/server/git-log-tool.js +14 -4
  14. package/dist/server/git-merge-tool.js +15 -14
  15. package/dist/server/git-parity-tool.js +5 -4
  16. package/dist/server/git-push-tool.js +9 -5
  17. package/dist/server/git-reflog-tool.js +126 -0
  18. package/dist/server/git-refs.js +12 -5
  19. package/dist/server/git-reset-soft-tool.js +4 -3
  20. package/dist/server/git-show-tool.js +96 -22
  21. package/dist/server/git-stash-tool.js +17 -15
  22. package/dist/server/git-tag-tool.js +8 -7
  23. package/dist/server/git-worktree-tool.js +8 -7
  24. package/dist/server/git.js +86 -7
  25. package/dist/server/list-presets-tool.js +2 -1
  26. package/dist/server/presets-resource.js +3 -2
  27. package/dist/server/presets.js +11 -5
  28. package/dist/server/roots.js +11 -10
  29. package/dist/server/tool-parameter-schemas.js +9 -0
  30. package/dist/server/tools.js +6 -0
  31. package/dist/server.js +7 -0
  32. package/docs/mcp-tools.md +134 -12
  33. package/package.json +4 -3
  34. package/schemas/git_blame.json +52 -0
  35. package/schemas/git_branch_list.json +36 -0
  36. package/schemas/git_diff.json +14 -15
  37. package/schemas/git_diff_summary.json +0 -6
  38. package/schemas/git_reflog.json +44 -0
  39. package/schemas/git_show.json +13 -1
  40. package/schemas/index.json +15 -0
  41. package/tool-parameters.schema.json +153 -22
package/docs/mcp-tools.md CHANGED
@@ -17,11 +17,14 @@ MCP clients expose tools as `{serverName}_{toolName}`. With the server registere
17
17
  | `list_presets` | `rethunk-git_list_presets` | List preset names/counts from `.rethunk/git-mcp-presets.json`; invalid JSON/schema surface as errors. Workspace pick + `format` only (includes `absoluteGitRoots`). **Read-only.** |
18
18
  | `git_log` | `rethunk-git_git_log` | Path-filtered, time-windowed `git log` across one or more workspace roots. Returns commit history with author, date, subject, and shortstat. Args: `since`, `paths`, `grep`, `author`, `maxCommits`, `branch`, plus workspace pick args (`absoluteGitRoots` for sibling clones) + `format` (`markdown`/`json`/`oneline`). **Read-only.** |
19
19
  | `git_diff_summary` | `rethunk-git_git_diff_summary` | Structured, token-efficient diff viewer. Returns per-file diffs with additions/deletions counts, truncated to configurable line limits, with lock files/dist/vendor excluded by default. Args: `range`, `fileFilter`, `maxLinesPerFile`, `maxFiles`, `excludePatterns`, plus workspace pick args (optional single-entry `absoluteGitRoots`) + `format`. **Read-only.** |
20
- | `git_diff` | `rethunk-git_git_diff` | Raw diff text for a single repo. Supports unstaged, staged, or `base..head` ranges, optionally scoped to one path. Args: `base?`, `head?`, `path?`, `staged?`, plus single-repo workspace pick + `format`. **Read-only.** |
21
- | `git_show` | `rethunk-git_git_show` | Inspect one commit or ref. Returns commit message plus diff, or file content at `path` for that ref. Args: `ref`, `path?`, plus single-repo workspace pick + `format`. **Read-only.** |
20
+ | `git_diff` | `rethunk-git_git_diff` | Raw diff text for a single repo. Supports unstaged, staged, or `base..head` ranges, scoped to one or more paths with configurable context width. Args: `workspaceRoot`, `rootIndex`, `format`, `base?`, `head?`, `path?`, `paths?`, `unified?`, `staged?`. No `absoluteGitRoots` or `allWorkspaceRoots`. **Read-only.** |
21
+ | `git_show` | `rethunk-git_git_show` | Inspect one commit or ref. Returns commit message plus diff (or `--stat` diffstat), or file content at `path` for that ref. Args: `ref`, `path?`, `paths?`, `stat?`, plus single-repo workspace pick + `format`. **Read-only.** |
22
22
  | `git_worktree_list` | `rethunk-git_git_worktree_list` | List all worktrees (`git worktree list --porcelain`). Workspace pick + `format`. **Read-only.** |
23
23
  | `git_stash_list` | `rethunk-git_git_stash_list` | List `git stash` entries for one repo. Args: single-repo workspace pick + `format`. **Read-only.** |
24
- | `git_fetch` | `rethunk-git_git_fetch` | Fetch from a remote without modifying the working tree. Updates refs only and reports updated/new refs. Args: `remote?`, `branch?`, `prune?`, `tags?`, plus single-repo workspace pick + `format`. **Mutating — refs only.** |
24
+ | `git_blame` | `rethunk-git_git_blame` | Line-by-line authorship for a file: commit SHA, author, date, summary per line. Args: `path` (required), `ref?`, `startLine?`, `endLine?`, plus single-repo workspace pick + `format`. **Read-only.** |
25
+ | `git_branch_list` | `rethunk-git_git_branch_list` | List local branches (sha, current marker, upstream); optional `includeRemotes` adds remote-tracking branches. Args: `includeRemotes?`, plus single-repo workspace pick + `format`. **Read-only.** |
26
+ | `git_reflog` | `rethunk-git_git_reflog` | Show the reflog for a ref (default `HEAD`) — recent HEAD movements with selector, SHA, and message. Args: `ref?`, `maxEntries?`, plus single-repo workspace pick + `format`. **Read-only.** |
27
+ | `git_fetch` | `rethunk-git_git_fetch` | Fetch from a remote without modifying the working tree. Updates refs only and reports updated/new refs, plus structured `updated`/`created`/`pruned` deltas on git ≥ 2.41. Args: `remote?`, `branch?`, `prune?`, `tags?`, plus single-repo workspace pick + `format`. **Mutating — refs only.** |
25
28
  | `git_push` | `rethunk-git_git_push` | Push the current branch to its upstream. Optional `remote`, `branch`, `setUpstream` (passes `-u`). Refuses on detached HEAD; never force-pushes. Workspace pick + `format`. **Mutating.** |
26
29
  | `git_tag` | `rethunk-git_git_tag` | Create/delete annotated or lightweight tags for one repo. Args: `tag`, `message?`, `ref?`, `delete?`, plus single-repo workspace pick + `format`. **Mutating.** |
27
30
  | `git_worktree_add` | `rethunk-git_git_worktree_add` | Create a new linked worktree, creating the branch from `baseRef` if it does not yet exist. Refuses on protected branch names. Args: `path`, `branch`, `baseRef?`, plus workspace pick + `format`. **Mutating.** |
@@ -259,7 +262,7 @@ Path-escape and `rev-parse` failures are reported inline in `pairs[*].error`, no
259
262
 
260
263
  ## JSON responses
261
264
 
262
- Tool JSON bodies are minified and contain only the payload — no `rethunkGitMcp` envelope. Current `MCP_JSON_FORMAT_VERSION` is **`"3"`**; server + format version are discoverable via MCP `initialize`. Payload keys (`groups`, `inventories`, `parity`, `roots`) are stable within a given format version. Preset-related responses may include **`presetSchemaVersion`**.
265
+ Tool JSON bodies are minified and contain only the payload — no `rethunkGitMcp` envelope. Current `MCP_JSON_FORMAT_VERSION` is **`"3"`** (exported constant in `src/server.ts`); the version string is surfaced in the FastMCP `instructions` field and is therefore discoverable via the MCP `initialize` response. Payload keys (`groups`, `inventories`, `parity`, `roots`) are stable within a given format version. Preset-related responses may include **`presetSchemaVersion`**.
263
266
 
264
267
  The package also ships **`tool-parameters.schema.json`**, generated from the registered Zod parameter schemas via `bun run schema:tools`, plus the published **`schemas/`** directory (`schemas/index.json` + one JSON Schema per tool) via `bun run schema:individual`. Connected MCP clients should still prefer live schema discovery from `initialize` / tool listing; the shipped artifacts are for offline inspection, drift checks, and code generation.
265
268
 
@@ -282,7 +285,7 @@ To keep responses compact, **optional fields are omitted when they would be empt
282
285
 
283
286
  - Error payloads carry an `error` code string and any structured context (e.g. `preset`, `presetFile`). The old free-text `message` field is **removed** for self-describing codes (`git_not_found`, `remote_branch_mismatch`, `invalid_remote_or_branch`, `no_pairs`, `preset_not_found` *missing* case). It is retained only where it carries parse output (the `invalid_json` preset branch).
284
287
 
285
- **When to bump `MCP_JSON_FORMAT_VERSION` or change payload shape:** [AGENTS.md](../AGENTS.md) — *Changing contracts*.
288
+ **When to bump `MCP_JSON_FORMAT_VERSION` or change payload shape:** [AGENTS.md](../AGENTS.md) — *Changing contracts*. The constant lives in `src/server.ts` and is surfaced via the server `instructions` field (discoverable from the MCP `initialize` response).
286
289
 
287
290
  ### `git_log` — parameters
288
291
 
@@ -335,6 +338,7 @@ v2 field-omission rules still apply: `filesChanged`, `insertions`, `deletions` o
335
338
  | `not_a_git_repository` | The resolved workspace root is not inside a git repository. |
336
339
  | `invalid_since` | The `since` string contains shell metacharacters and was rejected. |
337
340
  | `invalid_paths` | One of the `paths` entries contains shell metacharacters and was rejected. |
341
+ | `unsafe_ref_token` | `branch` contains characters outside the argv-safe subset. |
338
342
  | `git_log_failed` | `git log` exited non-zero (e.g. unknown branch ref). |
339
343
  | `root_index_out_of_range` | `rootIndex` exceeds the number of MCP file roots. |
340
344
  | `absolute_git_roots_exclusive` | `absoluteGitRoots` was combined with `workspaceRoot`, `rootIndex`, or `allWorkspaceRoots: true`. |
@@ -414,9 +418,15 @@ The response contains one **`parity[]`** entry per resolved git toplevel. `absol
414
418
  |-----------|------|---------|-------|
415
419
  | `base` | string | — | Base ref for a revision diff. When omitted with no `staged`, the tool shows unstaged changes. |
416
420
  | `head` | string | `HEAD` | Head ref for a revision diff. Used only when `base` is provided. |
417
- | `path` | string | — | Optional single file path to scope the diff. |
421
+ | `path` | string | — | Optional single file path to scope the diff. Confined to the repo (`path_escapes_repo` on escape). |
422
+ | `paths` | string[] | — | Multiple file paths to scope the diff; unioned with `path` (deduped). Each confined to the repo. |
423
+ | `unified` | integer | — | Context lines around each change (passed as `-U<n>`, 0–100). Omit for git's default (3). |
418
424
  | `staged` | boolean | `false` | When `true`, runs `git diff --staged`. Ignored when `base` is provided. |
419
- | `workspaceRoot`, `rootIndex`, `format` | — | Standard single-repo workspace pick + output format. |
425
+ | `workspaceRoot` | string | — | Explicit root; highest priority. |
426
+ | `rootIndex` | int | — | Pick one of several MCP roots (0-based). |
427
+ | `format` | `"markdown"` \| `"json"` | `"markdown"` | Output format. |
428
+
429
+ `git_diff` is a single-repo tool. It does not accept `absoluteGitRoots` or `allWorkspaceRoots`; use `workspaceRoot` or `rootIndex` to select the target repo.
420
430
 
421
431
  ### `git_diff` — JSON shape (`format: "json"`)
422
432
 
@@ -432,6 +442,7 @@ The response contains one **`parity[]`** entry per resolved git toplevel. `absol
432
442
  | Code | Meaning |
433
443
  |------|---------|
434
444
  | `unsafe_range_token` | `base` or `head` contains characters outside the argv-safe subset. |
445
+ | `path_escapes_repo` | A `path` / `paths` entry resolves outside the git toplevel. |
435
446
  | `git_diff_failed` | `git diff` exited non-zero. |
436
447
  | `not_a_git_repository` | The resolved workspace root is not inside a git repository. |
437
448
 
@@ -443,6 +454,8 @@ The response contains one **`parity[]`** entry per resolved git toplevel. `absol
443
454
  |-----------|------|-------|
444
455
  | `ref` | string | Commit, branch, tag, or other git rev-spec to inspect. |
445
456
  | `path` | string | Optional single path. When provided, the response shows that path's content at `ref` instead of the full commit diff. |
457
+ | `stat` | boolean | When `true`, runs `git show --stat` — commit message plus per-file diffstat, no full patch (`statOutput` in JSON). |
458
+ | `paths` | string[] | Filter the shown patch/stat to these repo-relative paths; unioned with `path`. Each confined to the repo. |
446
459
  | `workspaceRoot`, `rootIndex`, `format` | — | Standard single-repo workspace pick + output format. |
447
460
 
448
461
  ### `git_show` — JSON shape (`format: "json"`)
@@ -456,12 +469,14 @@ The response contains one **`parity[]`** entry per resolved git toplevel. `absol
456
469
  }
457
470
  ```
458
471
 
459
- `path` is omitted when not requested. `diff` is omitted when `git show` returns only a commit message.
472
+ `path` is omitted when not requested; `paths` is present when multiple paths were given. `diff` is omitted when `git show` returns only a commit message. With `stat: true`, `stat` is `true` and `statOutput` carries the diffstat instead of a full `diff`.
460
473
 
461
474
  ### `git_show` — error codes
462
475
 
463
476
  | Code | Meaning |
464
477
  |------|---------|
478
+ | `unsafe_ref_token` | `ref` contains characters outside the argv-safe subset. |
479
+ | `path_escapes_repo` | `path` resolves outside the git toplevel. |
465
480
  | `git_show_failed` | `git show` exited non-zero (e.g. unknown ref). |
466
481
  | `not_a_git_repository` | The resolved workspace root is not inside a git repository. |
467
482
 
@@ -510,16 +525,116 @@ The response contains one **`parity[]`** entry per resolved git toplevel. `absol
510
525
  "remote": "origin",
511
526
  "updatedRefs": ["abc1234..def5678 main -> origin/main"],
512
527
  "newRefs": ["[new tag] v2.0.0 -> v2.0.0"],
528
+ "updated": [{ "ref": "refs/remotes/origin/main", "oldSha": "abc1234…", "newSha": "def5678…", "flag": " " }],
529
+ "created": [{ "ref": "refs/tags/v2.0.0", "newSha": "0a1b2c3…", "flag": "*" }],
530
+ "pruned": [{ "ref": "refs/remotes/origin/old" }],
513
531
  "output": "From origin\n..."
514
532
  }
515
533
  ```
516
534
 
517
- Fetch failures are reported as `ok: false` with the captured git output in `output`.
535
+ `updated` / `created` / `pruned` are structured ref deltas parsed from `git fetch --porcelain` (git ≥ 2.41), each omitted when empty. On older git the `--porcelain` option is detected as unsupported and the tool falls back to a plain fetch, omitting the structured arrays; the `updatedRefs` / `newRefs` string fields are always present for back-compat. Fetch failures are reported as `ok: false` with the captured git output in `output`.
518
536
 
519
537
  ### `git_fetch` — error codes
520
538
 
521
539
  | Code | Meaning |
522
540
  |------|---------|
541
+ | `unsafe_remote_token` | `remote` contains characters outside the argv-safe subset. |
542
+ | `unsafe_ref_token` | `branch` contains characters outside the argv-safe subset. |
543
+ | `not_a_git_repository` | The resolved workspace root is not inside a git repository. |
544
+
545
+ ---
546
+
547
+ ### `git_blame` — parameters
548
+
549
+ | Parameter | Type | Default | Notes |
550
+ |-----------|------|---------|-------|
551
+ | `path` | string | — | **Required.** Repo-relative file to annotate. Confined to the repo (`path_escapes_repo` on escape). |
552
+ | `ref` | string | working tree | Commit-ish to blame at. Validated as a safe ref token. |
553
+ | `startLine` | int | — | Start of a line range (`-L`). Requires `endLine`. |
554
+ | `endLine` | int | — | End of the line range, inclusive. Requires `startLine`. |
555
+ | `workspaceRoot`, `rootIndex`, `format` | — | Standard single-repo workspace pick + output format. |
556
+
557
+ ### `git_blame` — JSON shape (`format: "json"`)
558
+
559
+ ```json
560
+ {
561
+ "ref": "HEAD",
562
+ "path": "src/server.ts",
563
+ "lines": [
564
+ { "line": 1, "sha": "a1b2c3d4…", "author": "Damon Blais", "date": "2026-04-12T18:32:01-07:00", "summary": "feat: add tool", "content": "import { FastMCP } from \"fastmcp\";" }
565
+ ]
566
+ }
567
+ ```
568
+
569
+ `ref` is omitted when blaming the working tree.
570
+
571
+ ### `git_blame` — error codes
572
+
573
+ | Code | Meaning |
574
+ |------|---------|
575
+ | `path_escapes_repo` | `path` resolves outside the git toplevel. |
576
+ | `unsafe_ref_token` | `ref` contains characters outside the argv-safe subset. |
577
+ | `invalid_line_range` | Only one of `startLine`/`endLine` was given, or `startLine > endLine`. |
578
+ | `git_blame_failed` | `git blame` exited non-zero (unknown path/ref). `detail` carries stderr. |
579
+ | `not_a_git_repository` | The resolved workspace root is not inside a git repository. |
580
+
581
+ ---
582
+
583
+ ### `git_branch_list` — parameters
584
+
585
+ | Parameter | Type | Default | Notes |
586
+ |-----------|------|---------|-------|
587
+ | `includeRemotes` | boolean | `false` | Also list remote-tracking branches (`refs/remotes`); symbolic `origin/HEAD` is skipped. |
588
+ | `workspaceRoot`, `rootIndex`, `format` | — | Standard single-repo workspace pick + output format. |
589
+
590
+ ### `git_branch_list` — JSON shape (`format: "json"`)
591
+
592
+ ```json
593
+ {
594
+ "branches": [
595
+ { "name": "main", "sha": "a1b2c3d4…", "current": true, "upstream": "origin/main" },
596
+ { "name": "feature/x", "sha": "b2c3d4e5…", "current": false }
597
+ ],
598
+ "remotes": [{ "name": "origin/main", "sha": "a1b2c3d4…" }]
599
+ }
600
+ ```
601
+
602
+ `upstream` is omitted when a branch has no upstream. `remotes` is present only when `includeRemotes: true`.
603
+
604
+ ### `git_branch_list` — error codes
605
+
606
+ | Code | Meaning |
607
+ |------|---------|
608
+ | `branch_list_failed` | `git for-each-ref` exited non-zero. `detail` carries stderr. |
609
+ | `not_a_git_repository` | The resolved workspace root is not inside a git repository. |
610
+
611
+ ---
612
+
613
+ ### `git_reflog` — parameters
614
+
615
+ | Parameter | Type | Default | Notes |
616
+ |-----------|------|---------|-------|
617
+ | `ref` | string | `HEAD` | Ref whose reflog to show. Validated as a safe ref token. |
618
+ | `maxEntries` | int | `30` | Max entries to return (1–200). |
619
+ | `workspaceRoot`, `rootIndex`, `format` | — | Standard single-repo workspace pick + output format. |
620
+
621
+ ### `git_reflog` — JSON shape (`format: "json"`)
622
+
623
+ ```json
624
+ {
625
+ "ref": "HEAD",
626
+ "entries": [
627
+ { "sha": "a1b2c3d4…", "selector": "HEAD@{0}", "message": "commit: feat: add tool" }
628
+ ]
629
+ }
630
+ ```
631
+
632
+ ### `git_reflog` — error codes
633
+
634
+ | Code | Meaning |
635
+ |------|---------|
636
+ | `unsafe_ref_token` | `ref` contains characters outside the argv-safe subset. |
637
+ | `reflog_failed` | `git reflog show` exited non-zero. `detail` carries stderr. |
523
638
  | `not_a_git_repository` | The resolved workspace root is not inside a git repository. |
524
639
 
525
640
  ---
@@ -792,9 +907,9 @@ For deletions, `type` is `"deleted"` and `sha` is an empty string.
792
907
 
793
908
  | Code | Meaning |
794
909
  |------|---------|
795
- | `tag_empty` | `tag` trimmed to an empty string. |
796
- | `tag_unsafe` | `tag` contains disallowed characters. |
797
- | `ref_unsafe` | `ref` contains disallowed characters. |
910
+ | `empty_tag_name` | `tag` trimmed to an empty string. |
911
+ | `unsafe_tag_token` | `tag` contains disallowed characters. |
912
+ | `unsafe_ref_token` | `ref` contains disallowed characters. |
798
913
  | `ref_not_found` | `ref` did not resolve to a commit. |
799
914
  | `tag_create_failed` | `git tag` failed while creating the tag. |
800
915
  | `tag_delete_failed` | `git tag -d` failed. |
@@ -908,6 +1023,13 @@ For deletions, `type` is `"deleted"` and `sha` is an empty string.
908
1023
 
909
1024
  ---
910
1025
 
1026
+ ## Environment
1027
+
1028
+ | Variable | Default | Notes |
1029
+ |----------|---------|-------|
1030
+ | `GIT_SUBPROCESS_PARALLELISM` | CPU-based | Max concurrent git subprocesses for multi-root fan-out (`git_inventory`, `git_parity`, multi-root `git_log`). |
1031
+ | `GIT_SUBPROCESS_TIMEOUT_MS` | `120000` | Per-subprocess timeout in ms; on expiry the child is killed (SIGTERM) and the call resolves as failed. Set `0` (or negative) to disable (unbounded). |
1032
+
911
1033
  ## Resource
912
1034
 
913
1035
  | URI | Purpose |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rethunk/mcp-multi-root-git",
3
- "version": "2.5.0",
3
+ "version": "2.8.0",
4
4
  "description": "MCP stdio server: multi-root git status, inventory, and HEAD parity checks. Generic tools usable by any workspace.",
5
5
  "type": "module",
6
6
  "private": false,
@@ -37,6 +37,7 @@
37
37
  "schema:tools": "bun scripts/generate-tool-parameters-schema.ts",
38
38
  "schema:tools:check": "bun scripts/generate-tool-parameters-schema.ts --check",
39
39
  "schema:individual": "bun scripts/generate-individual-schemas.ts",
40
+ "schema:individual:check": "bun scripts/generate-individual-schemas.ts --check",
40
41
  "publish:preflight": "bun scripts/publish-preflight.ts",
41
42
  "test": "bun test src/",
42
43
  "test:coverage": "bun test src/ --coverage",
@@ -68,8 +69,8 @@
68
69
  "zod": "^4.4.3"
69
70
  },
70
71
  "devDependencies": {
71
- "@biomejs/biome": "^2.4.15",
72
- "@types/node": "^25.8.0",
72
+ "@biomejs/biome": "^2.4.16",
73
+ "@types/node": "^25.9.1",
73
74
  "rimraf": "^6.1.3",
74
75
  "typescript": "^6.0.3"
75
76
  },
@@ -0,0 +1,52 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "@rethunk/mcp-multi-root-git: git_blame",
4
+ "description": "Parameter schema for the 'git_blame' MCP tool.",
5
+ "type": "object",
6
+ "properties": {
7
+ "workspaceRoot": {
8
+ "description": "Highest-priority override.",
9
+ "type": "string"
10
+ },
11
+ "rootIndex": {
12
+ "description": "0-based index into the MCP file roots list; ignored when workspaceRoot is set.",
13
+ "type": "integer",
14
+ "minimum": 0,
15
+ "maximum": 9007199254740991
16
+ },
17
+ "format": {
18
+ "default": "markdown",
19
+ "type": "string",
20
+ "enum": [
21
+ "markdown",
22
+ "json"
23
+ ]
24
+ },
25
+ "path": {
26
+ "type": "string",
27
+ "minLength": 1,
28
+ "description": "Repo-relative path to the file to blame."
29
+ },
30
+ "ref": {
31
+ "description": "Optional commit-ish (SHA, branch, tag) to blame at.",
32
+ "type": "string"
33
+ },
34
+ "startLine": {
35
+ "description": "First line of the range to blame (1-based). Requires endLine.",
36
+ "type": "integer",
37
+ "minimum": 1,
38
+ "maximum": 9007199254740991
39
+ },
40
+ "endLine": {
41
+ "description": "Last line of the range to blame (1-based, inclusive). Requires startLine.",
42
+ "type": "integer",
43
+ "minimum": 1,
44
+ "maximum": 9007199254740991
45
+ }
46
+ },
47
+ "required": [
48
+ "format",
49
+ "path"
50
+ ],
51
+ "additionalProperties": false
52
+ }
@@ -0,0 +1,36 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "@rethunk/mcp-multi-root-git: git_branch_list",
4
+ "description": "Parameter schema for the 'git_branch_list' MCP tool.",
5
+ "type": "object",
6
+ "properties": {
7
+ "workspaceRoot": {
8
+ "description": "Highest-priority override.",
9
+ "type": "string"
10
+ },
11
+ "rootIndex": {
12
+ "description": "0-based index into the MCP file roots list; ignored when workspaceRoot is set.",
13
+ "type": "integer",
14
+ "minimum": 0,
15
+ "maximum": 9007199254740991
16
+ },
17
+ "format": {
18
+ "default": "markdown",
19
+ "type": "string",
20
+ "enum": [
21
+ "markdown",
22
+ "json"
23
+ ]
24
+ },
25
+ "includeRemotes": {
26
+ "default": false,
27
+ "description": "When true, also return remote-tracking branches from refs/remotes (excluding symbolic origin/HEAD).",
28
+ "type": "boolean"
29
+ }
30
+ },
31
+ "required": [
32
+ "format",
33
+ "includeRemotes"
34
+ ],
35
+ "additionalProperties": false
36
+ }
@@ -14,19 +14,6 @@
14
14
  "minimum": 0,
15
15
  "maximum": 9007199254740991
16
16
  },
17
- "allWorkspaceRoots": {
18
- "default": false,
19
- "description": "Fan out across all MCP file roots.",
20
- "type": "boolean"
21
- },
22
- "absoluteGitRoots": {
23
- "description": "Absolute paths to git repo roots. Use for many sibling clones under a non-git parent directory.",
24
- "maxItems": 256,
25
- "type": "array",
26
- "items": {
27
- "type": "string"
28
- }
29
- },
30
17
  "format": {
31
18
  "default": "markdown",
32
19
  "type": "string",
@@ -44,17 +31,29 @@
44
31
  "type": "string"
45
32
  },
46
33
  "path": {
47
- "description": "Scope diff to a single file path (e.g. \"src/main.ts\").",
34
+ "description": "Scope diff to a single file path (e.g. \"src/main.ts\"). For multiple files, prefer `paths`. If both `path` and `paths` are given, they are unioned.",
48
35
  "type": "string"
49
36
  },
37
+ "paths": {
38
+ "description": "Scope diff to multiple file paths (e.g. [\"src/a.ts\", \"src/b.ts\"]). Each path is validated and must lie within the repository root. If both `path` and `paths` are given, they are unioned.",
39
+ "type": "array",
40
+ "items": {
41
+ "type": "string"
42
+ }
43
+ },
50
44
  "staged": {
51
45
  "default": false,
52
46
  "description": "If true, show staged changes (git diff --staged). Ignored if `base` is provided.",
53
47
  "type": "boolean"
48
+ },
49
+ "unified": {
50
+ "description": "Number of context lines to show around each change (passed as -U<n> to git diff). Defaults to git's built-in default (3). Use 0 for no context.",
51
+ "type": "integer",
52
+ "minimum": 0,
53
+ "maximum": 100
54
54
  }
55
55
  },
56
56
  "required": [
57
- "allWorkspaceRoots",
58
57
  "format",
59
58
  "staged"
60
59
  ],
@@ -14,11 +14,6 @@
14
14
  "minimum": 0,
15
15
  "maximum": 9007199254740991
16
16
  },
17
- "allWorkspaceRoots": {
18
- "default": false,
19
- "description": "Fan out across all MCP file roots.",
20
- "type": "boolean"
21
- },
22
17
  "absoluteGitRoots": {
23
18
  "description": "Absolute paths to git repo roots. Use for many sibling clones under a non-git parent directory.",
24
19
  "maxItems": 256,
@@ -66,7 +61,6 @@
66
61
  }
67
62
  },
68
63
  "required": [
69
- "allWorkspaceRoots",
70
64
  "format",
71
65
  "maxLinesPerFile",
72
66
  "maxFiles"
@@ -0,0 +1,44 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "@rethunk/mcp-multi-root-git: git_reflog",
4
+ "description": "Parameter schema for the 'git_reflog' MCP tool.",
5
+ "type": "object",
6
+ "properties": {
7
+ "workspaceRoot": {
8
+ "description": "Highest-priority override.",
9
+ "type": "string"
10
+ },
11
+ "rootIndex": {
12
+ "description": "0-based index into the MCP file roots list; ignored when workspaceRoot is set.",
13
+ "type": "integer",
14
+ "minimum": 0,
15
+ "maximum": 9007199254740991
16
+ },
17
+ "format": {
18
+ "default": "markdown",
19
+ "type": "string",
20
+ "enum": [
21
+ "markdown",
22
+ "json"
23
+ ]
24
+ },
25
+ "ref": {
26
+ "default": "HEAD",
27
+ "description": "Ref whose reflog to show (branch name, HEAD, etc.). Default: HEAD.",
28
+ "type": "string"
29
+ },
30
+ "maxEntries": {
31
+ "default": 30,
32
+ "description": "Maximum reflog entries to return (hard cap 200). Default 30.",
33
+ "type": "integer",
34
+ "minimum": 1,
35
+ "maximum": 200
36
+ }
37
+ },
38
+ "required": [
39
+ "format",
40
+ "ref",
41
+ "maxEntries"
42
+ ],
43
+ "additionalProperties": false
44
+ }
@@ -24,11 +24,23 @@
24
24
  },
25
25
  "ref": {
26
26
  "type": "string",
27
+ "minLength": 1,
27
28
  "description": "Commit reference (SHA, branch, tag, or any git rev-spec)."
28
29
  },
29
30
  "path": {
30
- "description": "Optional file path to inspect at the ref. If provided, shows that path's content at the ref instead of the diff.",
31
+ "description": "Optional single file path to inspect at the ref. Merged with `paths` when both are provided.",
31
32
  "type": "string"
33
+ },
34
+ "paths": {
35
+ "description": "Optional list of file paths to filter the shown diff/stat. Merged with `path` when both are provided.",
36
+ "type": "array",
37
+ "items": {
38
+ "type": "string"
39
+ }
40
+ },
41
+ "stat": {
42
+ "description": "When true, show --stat diffstat (files changed summary) instead of the full patch.",
43
+ "type": "boolean"
32
44
  }
33
45
  },
34
46
  "required": [
@@ -54,6 +54,21 @@
54
54
  "file": "git_stash_list.json",
55
55
  "description": "Parameter schema for the 'git_stash_list' MCP tool."
56
56
  },
57
+ {
58
+ "name": "git_blame",
59
+ "file": "git_blame.json",
60
+ "description": "Parameter schema for the 'git_blame' MCP tool."
61
+ },
62
+ {
63
+ "name": "git_branch_list",
64
+ "file": "git_branch_list.json",
65
+ "description": "Parameter schema for the 'git_branch_list' MCP tool."
66
+ },
67
+ {
68
+ "name": "git_reflog",
69
+ "file": "git_reflog.json",
70
+ "description": "Parameter schema for the 'git_reflog' MCP tool."
71
+ },
57
72
  {
58
73
  "name": "git_fetch",
59
74
  "file": "git_fetch.json",