Skip to content

Commit eeb6a81

Browse files
committed
feat: initial scaffold of @rethunk/mcp-multi-root-git v1.0.0
Generic MCP stdio server with three read-only git tools (git_status, git_inventory, git_parity). Workspace root resolved from MCP roots, not cwd. Named presets from .rethunk/git-mcp-presets.json. TypeScript, Biome, Node >=22, CI on Node 24 + 22.
0 parents  commit eeb6a81

9 files changed

Lines changed: 3133 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
ci:
11+
name: Node ${{ matrix.node }}
12+
runs-on: ubuntu-latest
13+
strategy:
14+
matrix:
15+
node: [24, 22]
16+
steps:
17+
- uses: actions/checkout@v4
18+
- uses: actions/setup-node@v4
19+
with:
20+
node-version: ${{ matrix.node }}
21+
cache: npm
22+
- run: npm ci
23+
- run: npm run check
24+
- run: npm run build

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
node_modules/
2+
dist/
3+
*.tsbuildinfo
4+
.env
5+
*.log

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Rethunk-AI
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# @rethunk/mcp-multi-root-git
2+
3+
MCP stdio server providing three read-only git tools for any workspace. No `cwd` in MCP config — workspace root comes from the client's MCP roots (provided at `initialize`).
4+
5+
## Tools
6+
7+
MCP clients expose these as `{serverName}_{toolName}` (e.g. `rethunk-git_git_status`). Register the server with name `rethunk-git` (or any name you choose); the tools' registered short ids are:
8+
9+
| Registered id | Purpose |
10+
|-----------------|---------|
11+
| `git_status` | `git status --short -b` for workspace root + optional submodules |
12+
| `git_inventory` | Status + ahead/behind per listed root; ordered for push prep |
13+
| `git_parity` | Compare `git rev-parse HEAD` for left/right path pairs |
14+
15+
## Workspace preset file
16+
17+
For multi-root repos, commit a file at **`.rethunk/git-mcp-presets.json`** in your workspace root:
18+
19+
```json
20+
{
21+
"push-prep": {
22+
"nestedRoots": ["path/to/package-a", "path/to/package-b"],
23+
"parityPairs": [
24+
{ "left": "core/packages/shared", "right": "edge/packages/shared", "label": "shared" }
25+
]
26+
}
27+
}
28+
```
29+
30+
Then call tools with `"preset": "push-prep"` instead of passing paths inline.
31+
32+
**This file is not part of the npm package.** Each repo that needs named presets commits its own file.
33+
34+
### Schema
35+
36+
```jsonc
37+
// .rethunk/git-mcp-presets.json
38+
{
39+
"<preset-name>": {
40+
"nestedRoots": ["<relative-path>", ...], // for git_inventory
41+
"parityPairs": [ // for git_parity
42+
{ "left": "<rel>", "right": "<rel>", "label": "<display>" }
43+
]
44+
}
45+
}
46+
```
47+
48+
## Installation
49+
50+
```bash
51+
npm install -g @rethunk/mcp-multi-root-git
52+
# or use via npx (no install required):
53+
npx -y @rethunk/mcp-multi-root-git
54+
```
55+
56+
## Cursor user-level MCP config
57+
58+
Add to `~/.cursor/mcp.json` (no `cwd` needed — Cursor supplies workspace roots automatically):
59+
60+
```json
61+
{
62+
"mcpServers": {
63+
"rethunk-git": {
64+
"command": "npx",
65+
"args": ["-y", "@rethunk/mcp-multi-root-git"]
66+
}
67+
}
68+
}
69+
```
70+
71+
## Workspace root resolution
72+
73+
1. Explicit `workspaceRoot` arg in the tool call (overrides everything).
74+
2. First `file://` root from the MCP `initialize` / `roots/list_changed` (Cursor, Claude Desktop, etc. send these automatically).
75+
3. `process.cwd()` as a last resort (useful in CI and test harnesses that pass explicit `workspaceRoot`).
76+
77+
When a client sends multiple roots, the first valid `file://` root wins. Document tie-breaking in your own skill if you need a different policy.
78+
79+
## Development
80+
81+
Requires **Node ≥ 22**. Develop on **Node 24**.
82+
83+
```bash
84+
npm install
85+
npm run build # tsc → dist/
86+
npm run check # Biome lint + format check
87+
npm run check:fix # Auto-fix Biome issues
88+
```
89+
90+
## Publishing
91+
92+
```bash
93+
npm run prepublishOnly # build + check
94+
npm publish # publishes @rethunk/mcp-multi-root-git@1.0.0
95+
```

biome.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"$schema": "https://biomejs.dev/schemas/2.4.10/schema.json",
3+
"linter": {
4+
"enabled": true,
5+
"rules": {
6+
"recommended": true
7+
}
8+
},
9+
"formatter": {
10+
"enabled": true,
11+
"indentStyle": "space",
12+
"indentWidth": 2,
13+
"lineWidth": 100,
14+
"lineEnding": "lf"
15+
},
16+
"javascript": {
17+
"formatter": {
18+
"quoteStyle": "double",
19+
"semicolons": "always",
20+
"trailingCommas": "all",
21+
"bracketSpacing": true,
22+
"arrowParentheses": "always"
23+
}
24+
},
25+
"files": {
26+
"includes": ["src/**/*", "*.json", "*.md"]
27+
}
28+
}

0 commit comments

Comments
 (0)