@rethunk/mcp-multi-root-git 2.8.1 → 2.9.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/AGENTS.md +1 -1
- package/CHANGELOG.md +8 -0
- package/dist/server/tools.js +66 -25
- package/docs/install.md +1 -0
- package/docs/mcp-tools.md +1 -0
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -23,7 +23,7 @@ IDEs injecting this as context: do not re-link from rules.
|
|
|
23
23
|
| [`src/server/schemas.ts`](src/server/schemas.ts) | `WorkspacePickSchema`, `MAX_INVENTORY_ROOTS_DEFAULT`, **`MAX_ABSOLUTE_GIT_ROOTS`** (256), optional **`absoluteGitRoots`** on workspace pick |
|
|
24
24
|
| [`src/server/inventory.ts`](src/server/inventory.ts) | `InventoryEntryJson`, `validateRepoPath`, `makeSkipEntry`, `buildInventorySectionMarkdown`, `collectInventoryEntry` |
|
|
25
25
|
| [`src/server/git-refs.ts`](src/server/git-refs.ts) | `isProtectedBranch`, `isSafeGitRefToken`, `isSafeGitRangeToken`, `isSafeGitAncestorRef`; `getCurrentBranch`, `resolveRef`, `isWorkingTreeClean`, `isFullyMergedInto`, `isContentEquivalentlyMergedInto`, `commitListBetween`; `listWorktrees`, `worktreeForBranch`; `inferRemoteFromUpstream`; `conflictPaths` |
|
|
26
|
-
| [`src/server/tools.ts`](src/server/tools.ts) | `registerRethunkGitTools` — dispatches to `register*` below |
|
|
26
|
+
| [`src/server/tools.ts`](src/server/tools.ts) | `registerRethunkGitTools` — dispatches to `register*` below; `selectToolRegistrars(envValue, registrars)` — pure parse/filter fn for `RETHUNK_GIT_TOOLS` (reads env inside `registerRethunkGitTools`, not at module scope); `TOOL_REGISTRARS` ordered array |
|
|
27
27
|
| [`src/server/git-status-tool.ts`](src/server/git-status-tool.ts) | `git_status` |
|
|
28
28
|
| [`src/server/git-inventory-tool.ts`](src/server/git-inventory-tool.ts) | `git_inventory` |
|
|
29
29
|
| [`src/server/git-parity-tool.ts`](src/server/git-parity-tool.ts) | `git_parity` |
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@rethunk/mcp-multi-root-git` are documented here. Format loosely follows [Keep a Changelog](https://keepachangelog.com); the project uses [Semantic Versioning](https://semver.org).
|
|
4
4
|
|
|
5
|
+
## [2.9.0] — 2026-06-05
|
|
6
|
+
|
|
7
|
+
Feature release: `RETHUNK_GIT_TOOLS` allowlist env var. Additive — no JSON format-version bump.
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **`RETHUNK_GIT_TOOLS`** — comma-separated allowlist of exact tool names. When set to a non-empty value, only the listed tools are registered; unknown names are warned to stderr and ignored. When unset or empty (default), all 23 tools are registered — zero behavioral change for existing consumers. If every name in the list is unrecognized, zero tools are registered and a loud warning is emitted (the restriction is honored literally rather than falling back to all tools). The presets resource (`rethunk-git://presets`) is always registered regardless of this setting. Cuts MCP token cost for agents that only need a small subset of tools. Example: `RETHUNK_GIT_TOOLS=git_status,git_diff_summary,git_diff,git_log,batch_commit,git_push`.
|
|
12
|
+
|
|
5
13
|
## [2.8.0] — 2026-05-29
|
|
6
14
|
|
|
7
15
|
Feature release: three new read-only inspection tools (tool count 20 → 23). Additive — no JSON format-version bump.
|
package/dist/server/tools.js
CHANGED
|
@@ -19,32 +19,73 @@ import { registerGitTagTool } from "./git-tag-tool.js";
|
|
|
19
19
|
import { registerGitWorktreeAddTool, registerGitWorktreeListTool, registerGitWorktreeRemoveTool, } from "./git-worktree-tool.js";
|
|
20
20
|
import { registerListPresetsTool } from "./list-presets-tool.js";
|
|
21
21
|
import { registerPresetsResource } from "./presets-resource.js";
|
|
22
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Ordered registry of all 23 MCP tools. Registration order is preserved for
|
|
24
|
+
* both full and filtered (RETHUNK_GIT_TOOLS) subsets.
|
|
25
|
+
*/
|
|
26
|
+
const TOOL_REGISTRARS = [
|
|
23
27
|
// Read-only tools
|
|
24
|
-
registerGitStatusTool
|
|
25
|
-
registerGitInventoryTool
|
|
26
|
-
registerGitParityTool
|
|
27
|
-
registerListPresetsTool
|
|
28
|
-
registerGitLogTool
|
|
29
|
-
registerGitDiffSummaryTool
|
|
30
|
-
registerGitDiffTool
|
|
31
|
-
registerGitShowTool
|
|
32
|
-
registerGitWorktreeListTool
|
|
33
|
-
registerGitStashListTool
|
|
34
|
-
registerGitFetchTool
|
|
35
|
-
registerGitBlameTool
|
|
36
|
-
registerGitBranchListTool
|
|
37
|
-
registerGitReflogTool
|
|
28
|
+
{ name: "git_status", register: registerGitStatusTool },
|
|
29
|
+
{ name: "git_inventory", register: registerGitInventoryTool },
|
|
30
|
+
{ name: "git_parity", register: registerGitParityTool },
|
|
31
|
+
{ name: "list_presets", register: registerListPresetsTool },
|
|
32
|
+
{ name: "git_log", register: registerGitLogTool },
|
|
33
|
+
{ name: "git_diff_summary", register: registerGitDiffSummaryTool },
|
|
34
|
+
{ name: "git_diff", register: registerGitDiffTool },
|
|
35
|
+
{ name: "git_show", register: registerGitShowTool },
|
|
36
|
+
{ name: "git_worktree_list", register: registerGitWorktreeListTool },
|
|
37
|
+
{ name: "git_stash_list", register: registerGitStashListTool },
|
|
38
|
+
{ name: "git_fetch", register: registerGitFetchTool },
|
|
39
|
+
{ name: "git_blame", register: registerGitBlameTool },
|
|
40
|
+
{ name: "git_branch_list", register: registerGitBranchListTool },
|
|
41
|
+
{ name: "git_reflog", register: registerGitReflogTool },
|
|
38
42
|
// Mutating tools
|
|
39
|
-
registerBatchCommitTool
|
|
40
|
-
registerGitPushTool
|
|
41
|
-
registerGitMergeTool
|
|
42
|
-
registerGitCherryPickTool
|
|
43
|
-
registerGitResetSoftTool
|
|
44
|
-
registerGitTagTool
|
|
45
|
-
registerGitWorktreeAddTool
|
|
46
|
-
registerGitWorktreeRemoveTool
|
|
47
|
-
registerGitStashApplyTool
|
|
48
|
-
|
|
43
|
+
{ name: "batch_commit", register: registerBatchCommitTool },
|
|
44
|
+
{ name: "git_push", register: registerGitPushTool },
|
|
45
|
+
{ name: "git_merge", register: registerGitMergeTool },
|
|
46
|
+
{ name: "git_cherry_pick", register: registerGitCherryPickTool },
|
|
47
|
+
{ name: "git_reset_soft", register: registerGitResetSoftTool },
|
|
48
|
+
{ name: "git_tag", register: registerGitTagTool },
|
|
49
|
+
{ name: "git_worktree_add", register: registerGitWorktreeAddTool },
|
|
50
|
+
{ name: "git_worktree_remove", register: registerGitWorktreeRemoveTool },
|
|
51
|
+
{ name: "git_stash_apply", register: registerGitStashApplyTool },
|
|
52
|
+
];
|
|
53
|
+
/**
|
|
54
|
+
* Parse the RETHUNK_GIT_TOOLS env var and return the matching subset of
|
|
55
|
+
* registrars plus any unrecognized token names.
|
|
56
|
+
*
|
|
57
|
+
* @param envValue Raw value of process.env.RETHUNK_GIT_TOOLS (may be undefined).
|
|
58
|
+
* @param registrars Full ordered registrar list (injectable for tests).
|
|
59
|
+
*/
|
|
60
|
+
export function selectToolRegistrars(envValue, registrars) {
|
|
61
|
+
const tokens = (envValue ?? "")
|
|
62
|
+
.split(",")
|
|
63
|
+
.map((t) => t.trim())
|
|
64
|
+
.filter((t) => t.length > 0);
|
|
65
|
+
// Unset, empty, or whitespace-only → register all tools.
|
|
66
|
+
if (tokens.length === 0) {
|
|
67
|
+
return { selected: registrars, unknown: [] };
|
|
68
|
+
}
|
|
69
|
+
const knownNames = new Set(registrars.map((r) => r.name));
|
|
70
|
+
const requested = new Set(tokens);
|
|
71
|
+
const unknown = tokens.filter((t) => !knownNames.has(t));
|
|
72
|
+
// Preserve canonical order; deduplicate duplicate tokens automatically.
|
|
73
|
+
const selected = registrars.filter((r) => requested.has(r.name));
|
|
74
|
+
return { selected, unknown };
|
|
75
|
+
}
|
|
76
|
+
export function registerRethunkGitTools(server) {
|
|
77
|
+
const env = process.env.RETHUNK_GIT_TOOLS;
|
|
78
|
+
const { selected, unknown } = selectToolRegistrars(env, TOOL_REGISTRARS);
|
|
79
|
+
if (unknown.length > 0) {
|
|
80
|
+
process.stderr.write(`[rethunk-git] RETHUNK_GIT_TOOLS: unknown tool name(s) ignored: ${unknown.map((n) => JSON.stringify(n)).join(", ")}\n`);
|
|
81
|
+
}
|
|
82
|
+
if (selected.length === 0 && (env ?? "").trim().length > 0) {
|
|
83
|
+
process.stderr.write(`[rethunk-git] RETHUNK_GIT_TOOLS: every listed name was unrecognized — registering NO tools. ` +
|
|
84
|
+
`Set RETHUNK_GIT_TOOLS to a comma-separated list of valid tool names, or unset it to register all tools.\n`);
|
|
85
|
+
}
|
|
86
|
+
for (const { register } of selected) {
|
|
87
|
+
register(server);
|
|
88
|
+
}
|
|
89
|
+
// The presets RESOURCE is always registered, regardless of the tool allowlist.
|
|
49
90
|
registerPresetsResource(server);
|
|
50
91
|
}
|
package/docs/install.md
CHANGED
|
@@ -92,6 +92,7 @@ Omit any `cwd` / `workingDirectory` field unless your client requires it for unr
|
|
|
92
92
|
| Variable | Default | Purpose |
|
|
93
93
|
|----------|---------|---------|
|
|
94
94
|
| `GIT_SUBPROCESS_PARALLELISM` | `4` | Number of parallel git subprocesses for inventory operations and `git_status` submodule rows. Valid range: 1 to 2×CPU count (auto-clamped to prevent runaway spawning). Increase on high-core machines to accelerate large fleet scans; decrease if system resources are constrained. |
|
|
95
|
+
| `RETHUNK_GIT_TOOLS` | _(unset)_ | Comma-separated list of tool names to register. When unset or empty, all 23 tools are registered (default). When set, only the listed tools are exposed — unknown names are warned and ignored. If every name is unknown, **zero** tools are registered and a loud warning is emitted (the restriction is honored literally). The presets resource (`rethunk-git://presets`) is always registered regardless of this setting. Example: `RETHUNK_GIT_TOOLS=git_status,git_diff_summary,git_diff,git_log,batch_commit,git_push`. Full tool-name list: `git_status`, `git_inventory`, `git_parity`, `list_presets`, `git_log`, `git_diff_summary`, `git_diff`, `git_show`, `git_worktree_list`, `git_stash_list`, `git_fetch`, `git_blame`, `git_branch_list`, `git_reflog`, `batch_commit`, `git_push`, `git_merge`, `git_cherry_pick`, `git_reset_soft`, `git_tag`, `git_worktree_add`, `git_worktree_remove`, `git_stash_apply`. |
|
|
95
96
|
|
|
96
97
|
Set these in the environment where the MCP client launches the server (e.g. in your shell, in the MCP client config as `env`, or in a startup script).
|
|
97
98
|
|
package/docs/mcp-tools.md
CHANGED
|
@@ -1029,6 +1029,7 @@ For deletions, `type` is `"deleted"` and `sha` is an empty string.
|
|
|
1029
1029
|
|----------|---------|-------|
|
|
1030
1030
|
| `GIT_SUBPROCESS_PARALLELISM` | CPU-based | Max concurrent git subprocesses for multi-root fan-out (`git_inventory`, `git_parity`, multi-root `git_log`). |
|
|
1031
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
|
+
| `RETHUNK_GIT_TOOLS` | _(unset — all)_ | Comma-separated allowlist of exact tool names. Unset or empty → all 23 tools registered. Non-empty → only the listed tools; unknown names warned to stderr. If every listed name is unknown, zero tools are registered (restriction honored literally). The presets resource is always available. Example: `RETHUNK_GIT_TOOLS=git_status,git_diff_summary,git_diff,git_log,batch_commit,git_push`. |
|
|
1032
1033
|
|
|
1033
1034
|
## Resource
|
|
1034
1035
|
|
package/package.json
CHANGED