@andrebuzeli/git-mcp 15.2.2 → 15.2.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@andrebuzeli/git-mcp",
3
- "version": "15.2.2",
3
+ "version": "15.2.4",
4
4
  "private": false,
5
5
  "description": "MCP server para Git com operações locais e sincronização paralela GitHub/Gitea",
6
6
  "license": "MIT",
@@ -18,13 +18,11 @@
18
18
  "git-mcp": "src/index.js",
19
19
  "git-mcpv2": "src/index.js"
20
20
  },
21
- "scripts": {
22
- },
21
+ "scripts": {},
23
22
  "dependencies": {
24
- "ajv": "^8.12.0",
25
- "axios": "^1.7.7",
23
+ "@modelcontextprotocol/sdk": "^0.4.0",
26
24
  "@octokit/rest": "^20.0.0",
27
- "isomorphic-git": "^1.27.5",
28
- "@modelcontextprotocol/sdk": "^0.4.0"
25
+ "ajv": "^8.12.0",
26
+ "axios": "^1.7.7"
29
27
  }
30
28
  }
@@ -48,7 +48,7 @@ export class ProviderManager {
48
48
 
49
49
  async getRemoteUrls(repoName) {
50
50
  const urls = {};
51
-
51
+
52
52
  // GitHub URL
53
53
  if (this.github) {
54
54
  const owner = await this.getGitHubOwner();
@@ -86,7 +86,7 @@ export class ProviderManager {
86
86
  name: repoName,
87
87
  description,
88
88
  private: false,
89
- auto_init: true,
89
+ auto_init: false,
90
90
  });
91
91
  results.github = { ok: true, repo: cr.data.full_name, created: true };
92
92
  } else {
@@ -113,7 +113,7 @@ export class ProviderManager {
113
113
  if (createIfMissing) {
114
114
  try {
115
115
  const cr = await axios.post(`${this.giteaUrl}/api/v1/user/repos`,
116
- { name: repoName, description, private: false, auto_init: true },
116
+ { name: repoName, description, private: false, auto_init: false },
117
117
  { headers: { Authorization: `token ${this.giteaToken}` }, timeout: 8000 });
118
118
  results.gitea = { ok: true, repo: `${cr.data?.owner?.login || owner}/${repoName}`, created: true };
119
119
  } catch (err) {
@@ -127,4 +127,32 @@ export class ProviderManager {
127
127
  }
128
128
  return results;
129
129
  }
130
+
131
+ async listAllRepos() {
132
+ const results = { github: [], gitea: [] };
133
+
134
+ // GitHub
135
+ if (this.github) {
136
+ try {
137
+ const { data } = await this.github.rest.repos.listForAuthenticatedUser({ per_page: 100, visibility: "all" });
138
+ results.github = data.map(r => ({ name: r.name, full_name: r.full_name, url: r.html_url, private: r.private }));
139
+ } catch (e) {
140
+ console.error("GitHub List Error:", e.message);
141
+ }
142
+ }
143
+
144
+ // Gitea
145
+ if (this.giteaUrl && this.giteaToken) {
146
+ try {
147
+ const base = this.giteaUrl.replace(/\/$/, "");
148
+ const { data } = await axios.get(`${base}/api/v1/user/repos?limit=100`, {
149
+ headers: { Authorization: `token ${this.giteaToken}` }
150
+ });
151
+ results.gitea = data.map(r => ({ name: r.name, full_name: r.full_name, url: r.html_url, private: r.private }));
152
+ } catch (e) {
153
+ console.error("Gitea List Error:", e.message);
154
+ }
155
+ }
156
+ return results;
157
+ }
130
158
  }
@@ -10,22 +10,24 @@ export function createGitRemoteTool(pm, git) {
10
10
  const inputSchema = {
11
11
  type: "object",
12
12
  properties: {
13
- projectPath: {
13
+ projectPath: {
14
14
  type: "string",
15
15
  description: "Caminho absoluto do diretório do projeto"
16
16
  },
17
- action: {
18
- type: "string",
17
+ action: {
18
+ type: "string",
19
19
  enum: [
20
- "list", "ensure", "repo-delete",
20
+ "list", "list-all", "ensure", "repo-delete",
21
21
  "release-create", "topics-set", "milestone-create", "label-create",
22
22
  "fork-create", "fork-list", "star-set", "star-unset",
23
23
  "subscription-set", "subscription-unset", "contents-create"
24
24
  ],
25
25
  description: `Ação a executar:
26
26
 
27
+ CONFIGURAÇÃO:
27
28
  CONFIGURAÇÃO:
28
29
  - list: Lista remotes configurados (github, gitea, origin)
30
+ - list-all: Lista TODOS os repositórios da conta (GitHub + Gitea)
29
31
  - ensure: Cria repos no GitHub/Gitea e configura remotes (USE ESTE se push falhar)
30
32
 
31
33
  REPOSITÓRIO:
@@ -48,32 +50,32 @@ NOTIFICAÇÕES:
48
50
  ARQUIVOS VIA API:
49
51
  - contents-create: Cria arquivo diretamente via API (sem git local)`
50
52
  },
51
- tag: {
53
+ tag: {
52
54
  type: "string",
53
55
  description: "Tag para release-create. Ex: 'v1.0.0'"
54
56
  },
55
- name: {
57
+ name: {
56
58
  type: "string",
57
59
  description: "Nome da release, label, etc."
58
60
  },
59
- body: {
61
+ body: {
60
62
  type: "string",
61
63
  description: "Descrição/corpo da release"
62
64
  },
63
- topics: {
64
- type: "array",
65
+ topics: {
66
+ type: "array",
65
67
  items: { type: "string" },
66
68
  description: "Lista de tópicos para topics-set. Ex: ['javascript', 'nodejs', 'mcp']"
67
69
  },
68
- path: {
70
+ path: {
69
71
  type: "string",
70
72
  description: "Caminho do arquivo para contents-create"
71
73
  },
72
- content: {
74
+ content: {
73
75
  type: "string",
74
76
  description: "Conteúdo do arquivo para contents-create"
75
77
  },
76
- branch: {
78
+ branch: {
77
79
  type: "string",
78
80
  description: "Branch alvo para contents-create. Default: main"
79
81
  },
@@ -113,13 +115,13 @@ QUANDO USAR:
113
115
  validateProjectPath(projectPath);
114
116
  if (action === "list") {
115
117
  const remotes = await git.listRemotes(projectPath);
116
-
118
+
117
119
  // Debug info: calculate what URLs should be
118
120
  let repoName = getRepoNameFromPath(projectPath);
119
121
  if (repoName === "GIT_MCP") repoName = "git-mcp";
120
122
  const calculated = await pm.getRemoteUrls(repoName);
121
123
 
122
- return asToolResult({
124
+ return asToolResult({
123
125
  remotes,
124
126
  configured: remotes.length > 0,
125
127
  hasGithub: remotes.some(r => r.remote === "github"),
@@ -136,6 +138,20 @@ QUANDO USAR:
136
138
  message: remotes.length === 0 ? "Nenhum remote configurado. Use action='ensure' para configurar." : undefined
137
139
  });
138
140
  }
141
+
142
+ if (action === "list-all") {
143
+ const repos = await pm.listAllRepos();
144
+ const summary = [];
145
+ if (repos.github?.length) summary.push(`${repos.github.length} GitHub repos`);
146
+ if (repos.gitea?.length) summary.push(`${repos.gitea.length} Gitea repos`);
147
+
148
+ return asToolResult({
149
+ success: true,
150
+ summary: summary.join(", "),
151
+ github: repos.github,
152
+ gitea: repos.gitea
153
+ });
154
+ }
139
155
  if (action === "ensure") {
140
156
  const repo = getRepoNameFromPath(projectPath);
141
157
  const ensured = await pm.ensureRepos({ repoName: repo, createIfMissing: true });
@@ -146,9 +162,9 @@ QUANDO USAR:
146
162
  const giteaUrl = geOwner && base ? `${base}/${geOwner}/${repo}.git` : "";
147
163
  await git.ensureRemotes(projectPath, { githubUrl, giteaUrl });
148
164
  const remotes = await git.listRemotes(projectPath);
149
- return asToolResult({
150
- success: true,
151
- ensured,
165
+ return asToolResult({
166
+ success: true,
167
+ ensured,
152
168
  remotes,
153
169
  urls: { github: githubUrl, gitea: giteaUrl },
154
170
  message: "Remotes configurados. Agora pode usar git-workflow push."
@@ -257,8 +273,8 @@ QUANDO USAR:
257
273
  });
258
274
  return asToolResult({ success: !!(out.github?.ok || out.gitea?.ok), path: filePath, branch, providers: out });
259
275
  }
260
- return asToolError("VALIDATION_ERROR", `Ação '${action}' não suportada`, {
261
- availableActions: ["list", "ensure", "repo-delete", "release-create", "topics-set", "milestone-create", "label-create", "fork-create", "fork-list", "star-set", "star-unset", "subscription-set", "subscription-unset", "contents-create"]
276
+ return asToolError("VALIDATION_ERROR", `Ação '${action}' não suportada`, {
277
+ availableActions: ["list", "ensure", "repo-delete", "release-create", "topics-set", "milestone-create", "label-create", "fork-create", "fork-list", "star-set", "star-unset", "subscription-set", "subscription-unset", "contents-create"]
262
278
  });
263
279
  } catch (e) {
264
280
  return errorToResponse(e);