lazy-cherry-pick-mcp 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/README.md +53 -0
- package/bin/cli.js +95 -0
- package/package.json +37 -0
package/README.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# lazy-cherry-pick-mcp
|
|
2
|
+
|
|
3
|
+
A [Model Context Protocol](https://modelcontextprotocol.io) server exposing **22 git
|
|
4
|
+
tools** (status, branches, commits, diffs, cherry-pick, fetch/pull/push, conflict
|
|
5
|
+
resolution) so AI clients — Claude Desktop, Cursor, VS Code, etc. — can drive real
|
|
6
|
+
git workflows on a repo on your machine, including an AI-driven conflict-resolution
|
|
7
|
+
loop.
|
|
8
|
+
|
|
9
|
+
This package is a thin launcher: on first run it downloads the matching
|
|
10
|
+
[`sidecar`](https://github.com/tentaikhoan24/lazy-cherry-pick) binary from the
|
|
11
|
+
project's GitHub Releases, caches it locally, and execs it with `--mcp`. No Tauri /
|
|
12
|
+
desktop app install required.
|
|
13
|
+
|
|
14
|
+
> **Platform support**: Windows x64 only for now. Other platforms exit with an error
|
|
15
|
+
> pointing to build-from-source instructions.
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
Add to your MCP client config (e.g. Claude Desktop's `claude_desktop_config.json`):
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"mcpServers": {
|
|
24
|
+
"lazy-cherry-pick": {
|
|
25
|
+
"command": "npx",
|
|
26
|
+
"args": ["-y", "lazy-cherry-pick-mcp"],
|
|
27
|
+
"env": {
|
|
28
|
+
"LCP_DEFAULT_REPO": "D:\\path\\to\\your\\repo"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
- `LCP_DEFAULT_REPO` is optional. Without it, the model must pass an absolute `repo`
|
|
36
|
+
path on every tool call.
|
|
37
|
+
- The first call may take a few seconds while the sidecar binary downloads; it is
|
|
38
|
+
cached afterwards (per-version) under `%LOCALAPPDATA%\lazy-cherry-pick-mcp\`.
|
|
39
|
+
|
|
40
|
+
## Tool catalog & conflict-resolution loop
|
|
41
|
+
|
|
42
|
+
See [docs/MCP.md](https://github.com/tentaikhoan24/lazy-cherry-pick/blob/master/docs/MCP.md)
|
|
43
|
+
in the main repo for the full 22-tool catalog, the AI-driven conflict-resolution
|
|
44
|
+
loop, and protocol details.
|
|
45
|
+
|
|
46
|
+
## Troubleshooting
|
|
47
|
+
|
|
48
|
+
- **404 downloading the sidecar binary right after a new version is published**: the
|
|
49
|
+
corresponding GitHub Release may still be a draft. Wait for it to be published, or
|
|
50
|
+
use the previous version pinned (`npx lazy-cherry-pick-mcp@<previous-version>`).
|
|
51
|
+
- **Unsupported platform error**: only Windows x64 has a prebuilt binary today. Build
|
|
52
|
+
the sidecar from source (see the main repo README) and point your MCP client's
|
|
53
|
+
`command` directly at the resulting `.exe` with `args: ["--mcp"]`.
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const os = require('os');
|
|
7
|
+
const https = require('https');
|
|
8
|
+
const { spawnSync } = require('child_process');
|
|
9
|
+
|
|
10
|
+
const pkg = require('../package.json');
|
|
11
|
+
|
|
12
|
+
const REPO = 'tentaikhoan24/lazy-cherry-pick';
|
|
13
|
+
|
|
14
|
+
// process.platform-process.arch -> release asset name (target-triple suffix)
|
|
15
|
+
const ASSET_BY_PLATFORM = {
|
|
16
|
+
'win32-x64': 'sidecar-x86_64-pc-windows-msvc.exe',
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
function assetName() {
|
|
20
|
+
return ASSET_BY_PLATFORM[`${process.platform}-${process.arch}`];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function cacheDir() {
|
|
24
|
+
const base = process.platform === 'win32'
|
|
25
|
+
? (process.env.LOCALAPPDATA || os.homedir())
|
|
26
|
+
: (process.env.XDG_CACHE_HOME || path.join(os.homedir(), '.cache'));
|
|
27
|
+
return path.join(base, 'lazy-cherry-pick-mcp', `v${pkg.version}`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function download(url, dest, redirectsLeft) {
|
|
31
|
+
if (redirectsLeft === undefined) redirectsLeft = 5;
|
|
32
|
+
return new Promise((resolve, reject) => {
|
|
33
|
+
const req = https.get(url, { headers: { 'User-Agent': 'lazy-cherry-pick-mcp' } }, (res) => {
|
|
34
|
+
const { statusCode, headers } = res;
|
|
35
|
+
if (statusCode >= 300 && statusCode < 400 && headers.location) {
|
|
36
|
+
res.resume();
|
|
37
|
+
if (redirectsLeft <= 0) return reject(new Error('too many redirects'));
|
|
38
|
+
return download(headers.location, dest, redirectsLeft - 1).then(resolve, reject);
|
|
39
|
+
}
|
|
40
|
+
if (statusCode !== 200) {
|
|
41
|
+
res.resume();
|
|
42
|
+
return reject(new Error(`HTTP ${statusCode} fetching ${url}`));
|
|
43
|
+
}
|
|
44
|
+
const file = fs.createWriteStream(dest);
|
|
45
|
+
res.pipe(file);
|
|
46
|
+
file.on('finish', () => file.close((err) => (err ? reject(err) : resolve())));
|
|
47
|
+
file.on('error', reject);
|
|
48
|
+
});
|
|
49
|
+
req.on('error', reject);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function ensureBinary() {
|
|
54
|
+
const asset = assetName();
|
|
55
|
+
if (!asset) {
|
|
56
|
+
throw new Error(
|
|
57
|
+
`unsupported platform ${process.platform}/${process.arch} — only Windows x64 is published today. ` +
|
|
58
|
+
`Build the sidecar from source: https://github.com/${REPO}#mcp-server--ai-integration`
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const dir = cacheDir();
|
|
63
|
+
const dest = path.join(dir, asset);
|
|
64
|
+
if (fs.existsSync(dest)) return dest;
|
|
65
|
+
|
|
66
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
67
|
+
const url = `https://github.com/${REPO}/releases/download/v${pkg.version}/${asset}`;
|
|
68
|
+
const tmp = `${dest}.${process.pid}.tmp`;
|
|
69
|
+
process.stderr.write(`lazy-cherry-pick-mcp: downloading sidecar binary (v${pkg.version})...\n`);
|
|
70
|
+
try {
|
|
71
|
+
await download(url, tmp);
|
|
72
|
+
} catch (err) {
|
|
73
|
+
try { fs.unlinkSync(tmp); } catch {}
|
|
74
|
+
throw new Error(`failed to download ${url}: ${err.message}`);
|
|
75
|
+
}
|
|
76
|
+
fs.renameSync(tmp, dest);
|
|
77
|
+
return dest;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
(async () => {
|
|
81
|
+
let bin;
|
|
82
|
+
try {
|
|
83
|
+
bin = await ensureBinary();
|
|
84
|
+
} catch (err) {
|
|
85
|
+
process.stderr.write(`lazy-cherry-pick-mcp: ${err.message}\n`);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const result = spawnSync(bin, ['--mcp'], { stdio: 'inherit' });
|
|
90
|
+
if (result.error) {
|
|
91
|
+
process.stderr.write(`lazy-cherry-pick-mcp: failed to launch sidecar: ${result.error.message}\n`);
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
process.exit(result.status === null ? 1 : result.status);
|
|
95
|
+
})();
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "lazy-cherry-pick-mcp",
|
|
3
|
+
"version": "0.15.0",
|
|
4
|
+
"description": "MCP server for Lazy Cherry Pick: AI tools for git status, branches, commits, diffs, cherry-pick, fetch/pull/push, and conflict resolution. Run via npx, no desktop install needed.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"homepage": "https://github.com/tentaikhoan24/lazy-cherry-pick",
|
|
7
|
+
"bugs": "https://github.com/tentaikhoan24/lazy-cherry-pick/issues",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/tentaikhoan24/lazy-cherry-pick.git",
|
|
11
|
+
"directory": "mcp-npm"
|
|
12
|
+
},
|
|
13
|
+
"bin": {
|
|
14
|
+
"lazy-cherry-pick-mcp": "bin/cli.js"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"bin"
|
|
18
|
+
],
|
|
19
|
+
"os": [
|
|
20
|
+
"win32"
|
|
21
|
+
],
|
|
22
|
+
"cpu": [
|
|
23
|
+
"x64"
|
|
24
|
+
],
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=18"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"mcp",
|
|
30
|
+
"model-context-protocol",
|
|
31
|
+
"git",
|
|
32
|
+
"cherry-pick",
|
|
33
|
+
"ai",
|
|
34
|
+
"claude",
|
|
35
|
+
"llm-tools"
|
|
36
|
+
]
|
|
37
|
+
}
|