@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 = process.env.GITEA_URL;
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 resp = await axios.get(`${this.giteaBaseUrl}/api/v1/user`, {
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
  }
@@ -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.name || 'origin';
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.name;
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.name || 'origin';
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.name || 'origin';
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
- return process.env.GITEA_URL;
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
- if (!token) {
49
- throw new Error('GITEA_TOKEN not configured');
50
- }
51
- // Remove protocol from baseUrl
52
- const urlWithoutProtocol = baseUrl.replace(/^https?:\/\//, '');
53
- return `http://${owner}:${token}@${urlWithoutProtocol}/${owner}/${repo}.git`;
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.6",
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",