@andrebuzeli/git-mcp 10.0.6 → 10.0.7
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.
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Octokit } from '@octokit/rest';
|
|
2
2
|
import axios from 'axios';
|
|
3
|
+
import { getGiteaUrl } from '../utils/repoHelpers.js';
|
|
3
4
|
export class ProviderManager {
|
|
4
5
|
constructor() {
|
|
5
6
|
const ghToken = process.env.GITHUB_TOKEN;
|
|
@@ -7,7 +8,7 @@ export class ProviderManager {
|
|
|
7
8
|
this.github = new Octokit({ auth: ghToken });
|
|
8
9
|
}
|
|
9
10
|
if (process.env.GITEA_URL && process.env.GITEA_TOKEN) {
|
|
10
|
-
this.giteaBaseUrl =
|
|
11
|
+
this.giteaBaseUrl = getGiteaUrl();
|
|
11
12
|
this.giteaToken = process.env.GITEA_TOKEN;
|
|
12
13
|
}
|
|
13
14
|
}
|
|
@@ -31,7 +32,8 @@ export class ProviderManager {
|
|
|
31
32
|
}
|
|
32
33
|
if (this.giteaBaseUrl && this.giteaToken) {
|
|
33
34
|
try {
|
|
34
|
-
const
|
|
35
|
+
const base = (this.giteaBaseUrl || '').replace(/\/$/, '');
|
|
36
|
+
const resp = await axios.get(`${base}/api/v1/user`, {
|
|
35
37
|
headers: { Authorization: `token ${this.giteaToken}` },
|
|
36
38
|
timeout: timeout,
|
|
37
39
|
});
|
|
@@ -30,8 +30,6 @@ export declare class GitRemoteTool implements Tool {
|
|
|
30
30
|
remote: any;
|
|
31
31
|
url: any;
|
|
32
32
|
removed?: undefined;
|
|
33
|
-
renamed?: undefined;
|
|
34
|
-
to?: undefined;
|
|
35
33
|
remotes?: undefined;
|
|
36
34
|
pruned?: undefined;
|
|
37
35
|
} | {
|
|
@@ -39,17 +37,6 @@ export declare class GitRemoteTool implements Tool {
|
|
|
39
37
|
removed: any;
|
|
40
38
|
remote?: undefined;
|
|
41
39
|
url?: undefined;
|
|
42
|
-
renamed?: undefined;
|
|
43
|
-
to?: undefined;
|
|
44
|
-
remotes?: undefined;
|
|
45
|
-
pruned?: undefined;
|
|
46
|
-
} | {
|
|
47
|
-
success: boolean;
|
|
48
|
-
renamed: any;
|
|
49
|
-
to: any;
|
|
50
|
-
remote?: undefined;
|
|
51
|
-
url?: undefined;
|
|
52
|
-
removed?: undefined;
|
|
53
40
|
remotes?: undefined;
|
|
54
41
|
pruned?: undefined;
|
|
55
42
|
} | {
|
|
@@ -58,8 +45,6 @@ export declare class GitRemoteTool implements Tool {
|
|
|
58
45
|
remote?: undefined;
|
|
59
46
|
url?: undefined;
|
|
60
47
|
removed?: undefined;
|
|
61
|
-
renamed?: undefined;
|
|
62
|
-
to?: undefined;
|
|
63
48
|
pruned?: undefined;
|
|
64
49
|
} | {
|
|
65
50
|
success: boolean;
|
|
@@ -67,8 +52,6 @@ export declare class GitRemoteTool implements Tool {
|
|
|
67
52
|
remote?: undefined;
|
|
68
53
|
url?: undefined;
|
|
69
54
|
removed?: undefined;
|
|
70
|
-
renamed?: undefined;
|
|
71
|
-
to?: undefined;
|
|
72
55
|
remotes?: undefined;
|
|
73
56
|
}>;
|
|
74
57
|
}
|
package/dist/tools/gitRemote.js
CHANGED
|
@@ -14,7 +14,7 @@ export class GitRemoteTool {
|
|
|
14
14
|
},
|
|
15
15
|
action: {
|
|
16
16
|
type: "string",
|
|
17
|
-
enum: ["list", "add", "remove", "set-url", "get-url"],
|
|
17
|
+
enum: ["list", "add", "remove", "set-url", "get-url", "prune"],
|
|
18
18
|
description: "Remote operation to perform: list (list remotes), add (add remote), remove (remove remote), set-url (change remote URL), get-url (get remote URL)"
|
|
19
19
|
},
|
|
20
20
|
remoteName: {
|
|
@@ -38,7 +38,7 @@ export class GitRemoteTool {
|
|
|
38
38
|
const git = simpleGit({ baseDir: projectPath });
|
|
39
39
|
switch (action) {
|
|
40
40
|
case 'add': {
|
|
41
|
-
const name = params.
|
|
41
|
+
const name = params.remoteName || 'origin';
|
|
42
42
|
let url = params.url;
|
|
43
43
|
// Auto-construct URL if not provided
|
|
44
44
|
if (!url) {
|
|
@@ -61,27 +61,18 @@ export class GitRemoteTool {
|
|
|
61
61
|
return { success: true, remote: name, url };
|
|
62
62
|
}
|
|
63
63
|
case 'remove': {
|
|
64
|
-
const name = params.
|
|
64
|
+
const name = params.remoteName;
|
|
65
65
|
if (!name)
|
|
66
66
|
throw new MCPError('VALIDATION_ERROR', 'name is required');
|
|
67
67
|
await git.removeRemote(name);
|
|
68
68
|
return { success: true, removed: name };
|
|
69
69
|
}
|
|
70
|
-
case 'rename': {
|
|
71
|
-
const name = params.name;
|
|
72
|
-
const newName = params.newName;
|
|
73
|
-
if (!name || !newName)
|
|
74
|
-
throw new MCPError('VALIDATION_ERROR', 'name and newName are required');
|
|
75
|
-
await git.remote(['rename', name, newName]);
|
|
76
|
-
return { success: true, renamed: name, to: newName };
|
|
77
|
-
}
|
|
78
|
-
case 'show':
|
|
79
70
|
case 'list': {
|
|
80
71
|
const remotes = await git.getRemotes(params.verbose);
|
|
81
72
|
return { success: true, remotes };
|
|
82
73
|
}
|
|
83
74
|
case 'set-url': {
|
|
84
|
-
const name = params.
|
|
75
|
+
const name = params.remoteName || 'origin';
|
|
85
76
|
let url = params.url;
|
|
86
77
|
// Auto-construct URL if not provided
|
|
87
78
|
if (!url) {
|
|
@@ -103,8 +94,19 @@ export class GitRemoteTool {
|
|
|
103
94
|
await git.remote(['set-url', name, url]);
|
|
104
95
|
return { success: true, remote: name, url };
|
|
105
96
|
}
|
|
97
|
+
case 'get-url': {
|
|
98
|
+
const name = params.remoteName || 'origin';
|
|
99
|
+
const remotes = await git.getRemotes(true);
|
|
100
|
+
const match = remotes.find(r => r.name === name);
|
|
101
|
+
if (!match) {
|
|
102
|
+
throw new MCPError('VALIDATION_ERROR', `Remote not found: ${name}`);
|
|
103
|
+
}
|
|
104
|
+
const fetchUrl = match.refs.fetch;
|
|
105
|
+
const pushUrl = match.refs.push;
|
|
106
|
+
return { success: true, remote: name, url: { fetch: fetchUrl, push: pushUrl } };
|
|
107
|
+
}
|
|
106
108
|
case 'prune': {
|
|
107
|
-
const name = params.
|
|
109
|
+
const name = params.remoteName || 'origin';
|
|
108
110
|
await git.remote(['prune', name]);
|
|
109
111
|
return { success: true, pruned: name };
|
|
110
112
|
}
|
|
@@ -28,7 +28,12 @@ export function getGiteaOwner() {
|
|
|
28
28
|
* Get Gitea base URL from environment
|
|
29
29
|
*/
|
|
30
30
|
export function getGiteaUrl() {
|
|
31
|
-
|
|
31
|
+
const raw = process.env.GITEA_URL;
|
|
32
|
+
if (!raw)
|
|
33
|
+
return undefined;
|
|
34
|
+
// Trim whitespace and strip accidental surrounding quotes/backticks
|
|
35
|
+
const trimmed = raw.trim().replace(/^['"`]+|['"`]+$/g, '');
|
|
36
|
+
return trimmed;
|
|
32
37
|
}
|
|
33
38
|
/**
|
|
34
39
|
* Build GitHub repository URL
|
|
@@ -45,12 +50,12 @@ export function buildGiteaUrl(owner, repo) {
|
|
|
45
50
|
if (!baseUrl) {
|
|
46
51
|
throw new Error('GITEA_URL not configured');
|
|
47
52
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
return
|
|
53
|
+
// Normalize base URL (remove trailing slashes)
|
|
54
|
+
const normalized = baseUrl.replace(/\/$/, '');
|
|
55
|
+
// Preserve protocol and embed credentials only if token is provided
|
|
56
|
+
const hasToken = Boolean(token);
|
|
57
|
+
const withCreds = hasToken ? normalized.replace(/^https?:\/\//, (proto) => `${proto}${owner}:${token}@`) : normalized;
|
|
58
|
+
return `${withCreds}/${owner}/${repo}.git`;
|
|
54
59
|
}
|
|
55
60
|
/**
|
|
56
61
|
* Get repository info from project path and environment
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@andrebuzeli/git-mcp",
|
|
3
|
-
"version": "10.0.
|
|
3
|
+
"version": "10.0.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Professional MCP server for Git operations - STDIO UNIVERSAL: works in ANY IDE (Cursor, VSCode, Claude Desktop, Trae AI, Kiro.dev). Fully autonomous DUAL execution (GitHub + Gitea APIs) with automatic username detection. Smart parameter normalization handles both 'action' and 'command' formats. All tools execute on BOTH providers simultaneously. No manual parameters needed.",
|
|
6
6
|
"main": "dist/index.js",
|