@andrebuzeli/git-mcp 7.2.5 → 7.3.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/dist/config.js +6 -12
- package/dist/index.js +60 -65
- package/dist/providers/giteaProvider.js +3 -9
- package/dist/providers/githubProvider.js +3 -6
- package/dist/providers/providerManager.js +5 -12
- package/dist/resources/toolsGuide.js +2 -5
- package/dist/server.js +11 -17
- package/dist/tools/gitAnalytics.js +14 -21
- package/dist/tools/gitArchive.js +16 -23
- package/dist/tools/gitBackup.js +21 -28
- package/dist/tools/gitBranches.js +20 -27
- package/dist/tools/gitConfig.js +12 -19
- package/dist/tools/gitFiles.js +14 -21
- package/dist/tools/gitFix.js +12 -18
- package/dist/tools/gitFix.tool.js +3 -7
- package/dist/tools/gitHistory.js +18 -58
- package/dist/tools/gitIgnore.js +9 -46
- package/dist/tools/gitIssues.js +20 -24
- package/dist/tools/gitMonitor.js +14 -21
- package/dist/tools/gitPackages.js +12 -19
- package/dist/tools/gitPulls.js +18 -25
- package/dist/tools/gitRelease.js +24 -31
- package/dist/tools/gitRemote.js +19 -26
- package/dist/tools/gitReset.js +10 -17
- package/dist/tools/gitStash.js +6 -13
- package/dist/tools/gitSync.js +6 -13
- package/dist/tools/gitTags.js +18 -25
- package/dist/tools/gitUpdate.js +19 -59
- package/dist/tools/gitUpload.js +13 -53
- package/dist/tools/gitWorkflow.js +25 -32
- package/dist/types.js +1 -2
- package/dist/utils/errors.js +2 -7
- package/dist/utils/repoHelpers.js +9 -21
- package/dist/utils/safetyController.js +3 -6
- package/package.json +2 -1
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.GitWorkflowTool = void 0;
|
|
7
|
-
const simple_git_1 = __importDefault(require("simple-git"));
|
|
8
|
-
const errors_1 = require("../utils/errors");
|
|
9
|
-
const axios_1 = __importDefault(require("axios"));
|
|
10
|
-
class GitWorkflowTool {
|
|
1
|
+
import simpleGit from 'simple-git';
|
|
2
|
+
import { MCPError } from '../utils/errors';
|
|
3
|
+
import axios from 'axios';
|
|
4
|
+
export class GitWorkflowTool {
|
|
11
5
|
constructor() {
|
|
12
6
|
this.name = 'git-workflow';
|
|
13
7
|
this.description = 'Core Git operations including init, status, commit, sync, backup, and remote operations - automatic dual-provider for remote ops';
|
|
@@ -15,28 +9,28 @@ class GitWorkflowTool {
|
|
|
15
9
|
async handle(params, ctx) {
|
|
16
10
|
const action = params.action;
|
|
17
11
|
if (!action)
|
|
18
|
-
throw new
|
|
12
|
+
throw new MCPError('VALIDATION_ERROR', 'action is required');
|
|
19
13
|
const projectPath = params.projectPath;
|
|
20
|
-
const git = projectPath ? (
|
|
14
|
+
const git = projectPath ? simpleGit({ baseDir: projectPath }) : null;
|
|
21
15
|
switch (action) {
|
|
22
16
|
case 'init': {
|
|
23
17
|
if (!projectPath || !git)
|
|
24
|
-
throw new
|
|
18
|
+
throw new MCPError('VALIDATION_ERROR', 'projectPath is required for init');
|
|
25
19
|
await git.init(params.bare || false);
|
|
26
20
|
return { success: true, path: projectPath };
|
|
27
21
|
}
|
|
28
22
|
case 'status': {
|
|
29
23
|
if (!projectPath || !git)
|
|
30
|
-
throw new
|
|
24
|
+
throw new MCPError('VALIDATION_ERROR', 'projectPath is required for status');
|
|
31
25
|
const status = await git.status();
|
|
32
26
|
return { success: true, status };
|
|
33
27
|
}
|
|
34
28
|
case 'commit': {
|
|
35
29
|
if (!projectPath || !git)
|
|
36
|
-
throw new
|
|
30
|
+
throw new MCPError('VALIDATION_ERROR', 'projectPath is required for commit');
|
|
37
31
|
const message = params.message;
|
|
38
32
|
if (!message)
|
|
39
|
-
throw new
|
|
33
|
+
throw new MCPError('VALIDATION_ERROR', 'Commit message is required');
|
|
40
34
|
const files = params.files || ['.'];
|
|
41
35
|
await git.add(files);
|
|
42
36
|
const result = await git.commit(message);
|
|
@@ -44,7 +38,7 @@ class GitWorkflowTool {
|
|
|
44
38
|
}
|
|
45
39
|
case 'sync': {
|
|
46
40
|
if (!projectPath || !git)
|
|
47
|
-
throw new
|
|
41
|
+
throw new MCPError('VALIDATION_ERROR', 'projectPath is required for sync');
|
|
48
42
|
const remote = params.remote || 'origin';
|
|
49
43
|
const branch = params.branch;
|
|
50
44
|
await git.fetch(remote);
|
|
@@ -64,7 +58,7 @@ class GitWorkflowTool {
|
|
|
64
58
|
case 'create': {
|
|
65
59
|
const name = params.name;
|
|
66
60
|
if (!name)
|
|
67
|
-
throw new
|
|
61
|
+
throw new MCPError('VALIDATION_ERROR', 'name is required');
|
|
68
62
|
const githubOwner = params.owner || process.env.GITHUB_USERNAME;
|
|
69
63
|
const giteaOwner = params.owner || process.env.GITEA_USERNAME;
|
|
70
64
|
const results = { success: true, providers: {} };
|
|
@@ -85,7 +79,7 @@ class GitWorkflowTool {
|
|
|
85
79
|
// Gitea
|
|
86
80
|
if (ctx.providerManager.giteaBaseUrl) {
|
|
87
81
|
try {
|
|
88
|
-
const result = await
|
|
82
|
+
const result = await axios.post(`${ctx.providerManager.giteaBaseUrl}/api/v1/user/repos`, {
|
|
89
83
|
name,
|
|
90
84
|
description: params.description,
|
|
91
85
|
private: params.private || false,
|
|
@@ -113,7 +107,7 @@ class GitWorkflowTool {
|
|
|
113
107
|
// Gitea
|
|
114
108
|
if (ctx.providerManager.giteaBaseUrl) {
|
|
115
109
|
try {
|
|
116
|
-
const result = await
|
|
110
|
+
const result = await axios.get(`${ctx.providerManager.giteaBaseUrl}/api/v1/user/repos`, { headers: { Authorization: `token ${ctx.providerManager.giteaToken}` } });
|
|
117
111
|
results.providers.gitea = { success: true, repos: result.data };
|
|
118
112
|
}
|
|
119
113
|
catch (err) {
|
|
@@ -127,7 +121,7 @@ class GitWorkflowTool {
|
|
|
127
121
|
const giteaOwner = params.owner || process.env.GITEA_USERNAME;
|
|
128
122
|
const repo = params.repo;
|
|
129
123
|
if (!githubOwner || !repo) {
|
|
130
|
-
throw new
|
|
124
|
+
throw new MCPError('VALIDATION_ERROR', 'owner and repo are required');
|
|
131
125
|
}
|
|
132
126
|
const results = { success: true, providers: {} };
|
|
133
127
|
// GitHub
|
|
@@ -143,7 +137,7 @@ class GitWorkflowTool {
|
|
|
143
137
|
// Gitea
|
|
144
138
|
if (ctx.providerManager.giteaBaseUrl) {
|
|
145
139
|
try {
|
|
146
|
-
const result = await
|
|
140
|
+
const result = await axios.get(`${ctx.providerManager.giteaBaseUrl}/api/v1/repos/${giteaOwner}/${repo}`, { headers: { Authorization: `token ${ctx.providerManager.giteaToken}` } });
|
|
147
141
|
results.providers.gitea = { success: true, repo: result.data };
|
|
148
142
|
}
|
|
149
143
|
catch (err) {
|
|
@@ -157,7 +151,7 @@ class GitWorkflowTool {
|
|
|
157
151
|
const giteaOwner = params.owner || process.env.GITEA_USERNAME;
|
|
158
152
|
const repo = params.repo;
|
|
159
153
|
if (!githubOwner || !repo) {
|
|
160
|
-
throw new
|
|
154
|
+
throw new MCPError('VALIDATION_ERROR', 'owner and repo are required');
|
|
161
155
|
}
|
|
162
156
|
const results = { success: true, providers: {} };
|
|
163
157
|
// GitHub
|
|
@@ -181,7 +175,7 @@ class GitWorkflowTool {
|
|
|
181
175
|
// Gitea
|
|
182
176
|
if (ctx.providerManager.giteaBaseUrl) {
|
|
183
177
|
try {
|
|
184
|
-
const result = await
|
|
178
|
+
const result = await axios.patch(`${ctx.providerManager.giteaBaseUrl}/api/v1/repos/${giteaOwner}/${repo}`, {
|
|
185
179
|
description: params.description,
|
|
186
180
|
private: params.private,
|
|
187
181
|
has_issues: params.has_issues,
|
|
@@ -201,7 +195,7 @@ class GitWorkflowTool {
|
|
|
201
195
|
const giteaOwner = params.owner || process.env.GITEA_USERNAME;
|
|
202
196
|
const repo = params.repo;
|
|
203
197
|
if (!githubOwner || !repo) {
|
|
204
|
-
throw new
|
|
198
|
+
throw new MCPError('VALIDATION_ERROR', 'owner and repo are required');
|
|
205
199
|
}
|
|
206
200
|
const results = { success: true, providers: {} };
|
|
207
201
|
// GitHub
|
|
@@ -217,7 +211,7 @@ class GitWorkflowTool {
|
|
|
217
211
|
// Gitea
|
|
218
212
|
if (ctx.providerManager.giteaBaseUrl) {
|
|
219
213
|
try {
|
|
220
|
-
await
|
|
214
|
+
await axios.delete(`${ctx.providerManager.giteaBaseUrl}/api/v1/repos/${giteaOwner}/${repo}`, { headers: { Authorization: `token ${ctx.providerManager.giteaToken}` } });
|
|
221
215
|
results.providers.gitea = { success: true, deleted: true };
|
|
222
216
|
}
|
|
223
217
|
catch (err) {
|
|
@@ -231,7 +225,7 @@ class GitWorkflowTool {
|
|
|
231
225
|
const giteaOwner = params.owner || process.env.GITEA_USERNAME;
|
|
232
226
|
const repo = params.repo;
|
|
233
227
|
if (!githubOwner || !repo) {
|
|
234
|
-
throw new
|
|
228
|
+
throw new MCPError('VALIDATION_ERROR', 'owner and repo are required');
|
|
235
229
|
}
|
|
236
230
|
const results = { success: true, providers: {} };
|
|
237
231
|
// GitHub
|
|
@@ -251,7 +245,7 @@ class GitWorkflowTool {
|
|
|
251
245
|
// Gitea
|
|
252
246
|
if (ctx.providerManager.giteaBaseUrl) {
|
|
253
247
|
try {
|
|
254
|
-
const result = await
|
|
248
|
+
const result = await axios.post(`${ctx.providerManager.giteaBaseUrl}/api/v1/repos/${giteaOwner}/${repo}/forks`, { organization: params.organization }, { headers: { Authorization: `token ${ctx.providerManager.giteaToken}` } });
|
|
255
249
|
results.providers.gitea = { success: true, fork: result.data };
|
|
256
250
|
}
|
|
257
251
|
catch (err) {
|
|
@@ -263,7 +257,7 @@ class GitWorkflowTool {
|
|
|
263
257
|
case 'search': {
|
|
264
258
|
const query = params.query;
|
|
265
259
|
if (!query)
|
|
266
|
-
throw new
|
|
260
|
+
throw new MCPError('VALIDATION_ERROR', 'query is required');
|
|
267
261
|
const results = { success: true, providers: {} };
|
|
268
262
|
// GitHub
|
|
269
263
|
if (ctx.providerManager.github) {
|
|
@@ -283,7 +277,7 @@ class GitWorkflowTool {
|
|
|
283
277
|
// Gitea
|
|
284
278
|
if (ctx.providerManager.giteaBaseUrl) {
|
|
285
279
|
try {
|
|
286
|
-
const result = await
|
|
280
|
+
const result = await axios.get(`${ctx.providerManager.giteaBaseUrl}/api/v1/repos/search`, {
|
|
287
281
|
params: { q: query, limit: params.limit || 30, sort: params.sort },
|
|
288
282
|
headers: { Authorization: `token ${ctx.providerManager.giteaToken}` }
|
|
289
283
|
});
|
|
@@ -296,8 +290,7 @@ class GitWorkflowTool {
|
|
|
296
290
|
return results;
|
|
297
291
|
}
|
|
298
292
|
default:
|
|
299
|
-
throw new
|
|
293
|
+
throw new MCPError('VALIDATION_ERROR', `Unsupported action: ${action}`);
|
|
300
294
|
}
|
|
301
295
|
}
|
|
302
296
|
}
|
|
303
|
-
exports.GitWorkflowTool = GitWorkflowTool;
|
package/dist/types.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
package/dist/utils/errors.js
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MCPError = void 0;
|
|
4
|
-
exports.createErrorResponse = createErrorResponse;
|
|
5
|
-
function createErrorResponse(code, message, suggestions) {
|
|
1
|
+
export function createErrorResponse(code, message, suggestions) {
|
|
6
2
|
return {
|
|
7
3
|
success: false,
|
|
8
4
|
error: {
|
|
@@ -12,11 +8,10 @@ function createErrorResponse(code, message, suggestions) {
|
|
|
12
8
|
},
|
|
13
9
|
};
|
|
14
10
|
}
|
|
15
|
-
class MCPError extends Error {
|
|
11
|
+
export class MCPError extends Error {
|
|
16
12
|
constructor(code, message, suggestions) {
|
|
17
13
|
super(message);
|
|
18
14
|
this.code = code;
|
|
19
15
|
this.suggestions = suggestions;
|
|
20
16
|
}
|
|
21
17
|
}
|
|
22
|
-
exports.MCPError = MCPError;
|
|
@@ -1,16 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getRepoNameFromPath = getRepoNameFromPath;
|
|
7
|
-
exports.getGitHubOwner = getGitHubOwner;
|
|
8
|
-
exports.getGiteaOwner = getGiteaOwner;
|
|
9
|
-
exports.getGiteaUrl = getGiteaUrl;
|
|
10
|
-
exports.buildGitHubUrl = buildGitHubUrl;
|
|
11
|
-
exports.buildGiteaUrl = buildGiteaUrl;
|
|
12
|
-
exports.getRepoInfo = getRepoInfo;
|
|
13
|
-
const path_1 = __importDefault(require("path"));
|
|
1
|
+
import path from 'path';
|
|
14
2
|
/**
|
|
15
3
|
* Helper functions to extract repository information automatically
|
|
16
4
|
*/
|
|
@@ -18,8 +6,8 @@ const path_1 = __importDefault(require("path"));
|
|
|
18
6
|
* Extract repository name from project path
|
|
19
7
|
* Normalizes: spaces to hyphens, lowercase, keeps alphanumeric and hyphens/underscores
|
|
20
8
|
*/
|
|
21
|
-
function getRepoNameFromPath(projectPath) {
|
|
22
|
-
return
|
|
9
|
+
export function getRepoNameFromPath(projectPath) {
|
|
10
|
+
return path.basename(projectPath)
|
|
23
11
|
.toLowerCase()
|
|
24
12
|
.replace(/\s+/g, '-')
|
|
25
13
|
.replace(/[^a-z0-9-_]/g, '');
|
|
@@ -27,31 +15,31 @@ function getRepoNameFromPath(projectPath) {
|
|
|
27
15
|
/**
|
|
28
16
|
* Get GitHub owner from environment
|
|
29
17
|
*/
|
|
30
|
-
function getGitHubOwner() {
|
|
18
|
+
export function getGitHubOwner() {
|
|
31
19
|
return process.env.GITHUB_USERNAME;
|
|
32
20
|
}
|
|
33
21
|
/**
|
|
34
22
|
* Get Gitea owner from environment
|
|
35
23
|
*/
|
|
36
|
-
function getGiteaOwner() {
|
|
24
|
+
export function getGiteaOwner() {
|
|
37
25
|
return process.env.GITEA_USERNAME;
|
|
38
26
|
}
|
|
39
27
|
/**
|
|
40
28
|
* Get Gitea base URL from environment
|
|
41
29
|
*/
|
|
42
|
-
function getGiteaUrl() {
|
|
30
|
+
export function getGiteaUrl() {
|
|
43
31
|
return process.env.GITEA_URL;
|
|
44
32
|
}
|
|
45
33
|
/**
|
|
46
34
|
* Build GitHub repository URL
|
|
47
35
|
*/
|
|
48
|
-
function buildGitHubUrl(owner, repo) {
|
|
36
|
+
export function buildGitHubUrl(owner, repo) {
|
|
49
37
|
return `https://github.com/${owner}/${repo}.git`;
|
|
50
38
|
}
|
|
51
39
|
/**
|
|
52
40
|
* Build Gitea repository URL with credentials
|
|
53
41
|
*/
|
|
54
|
-
function buildGiteaUrl(owner, repo) {
|
|
42
|
+
export function buildGiteaUrl(owner, repo) {
|
|
55
43
|
const baseUrl = getGiteaUrl();
|
|
56
44
|
const token = process.env.GITEA_TOKEN;
|
|
57
45
|
if (!baseUrl) {
|
|
@@ -67,7 +55,7 @@ function buildGiteaUrl(owner, repo) {
|
|
|
67
55
|
/**
|
|
68
56
|
* Get repository info from project path and environment
|
|
69
57
|
*/
|
|
70
|
-
function getRepoInfo(projectPath) {
|
|
58
|
+
export function getRepoInfo(projectPath) {
|
|
71
59
|
const repoName = getRepoNameFromPath(projectPath);
|
|
72
60
|
const githubOwner = getGitHubOwner();
|
|
73
61
|
const giteaOwner = getGiteaOwner();
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.requireConfirmationIfDestructive = requireConfirmationIfDestructive;
|
|
4
|
-
const errors_1 = require("./errors");
|
|
5
|
-
function requireConfirmationIfDestructive(action, params) {
|
|
1
|
+
import { MCPError } from './errors';
|
|
2
|
+
export function requireConfirmationIfDestructive(action, params) {
|
|
6
3
|
const destructiveActions = new Set(['delete', 'hard', 'reset', 'drop']);
|
|
7
4
|
if (destructiveActions.has(action)) {
|
|
8
5
|
if (!params || params.confirmDestructive !== true) {
|
|
9
|
-
throw new
|
|
6
|
+
throw new MCPError('SAFETY_WARNING', `Action '${action}' is destructive and requires explicit confirmation.`, [
|
|
10
7
|
"Set 'confirmDestructive: true' to confirm",
|
|
11
8
|
'Consider safer alternatives like stash or soft reset',
|
|
12
9
|
]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@andrebuzeli/git-mcp",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.3.0",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"description": "Professional MCP server for Git operations - STDIO UNIVERSAL: works in ANY IDE (Cursor, VSCode, Claude Desktop). Fully autonomous DUAL execution (GitHub + Gitea APIs) with automatic username detection. All tools execute on BOTH providers simultaneously. No manual parameters needed.",
|
|
5
6
|
"main": "dist/index.js",
|
|
6
7
|
"types": "dist/index.d.ts",
|