@andre.buzeli/git-mcp 15.12.5

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 ADDED
@@ -0,0 +1,40 @@
1
+ # @andrebuzeli/git-mcp
2
+
3
+ Servidor MCP (Model Context Protocol) para operações Git locais sem git instalado, com sincronização paralela para GitHub e Gitea.
4
+
5
+ ## Configuração MCP
6
+
7
+ ```json
8
+ {
9
+ "mcpServers": {
10
+ "git-mcp": {
11
+ "command": "npx",
12
+ "args": ["@andrebuzeli/git-mcp@latest"],
13
+ "env": {
14
+ "GITEA_URL": "https://seu-gitea",
15
+ "GITEA_TOKEN": "...",
16
+ "GITHUB_TOKEN": "..."
17
+ }
18
+ }
19
+ }
20
+ }
21
+ ```
22
+
23
+ ## Tools
24
+
25
+ - git-workflow: init, status, add, remove, commit, ensure-remotes, push
26
+ - git-update: status -> add -> commit -> push (all-in-one)
27
+ - git-remote: list, ensure
28
+ - git-branches: list, create, delete, rename, checkout
29
+ - git-tags: list, create, delete, push
30
+ - git-stash: list, save, apply, pop, drop, clear
31
+ - git-reset: soft, mixed, hard
32
+ - git-config: get, set, unset, list
33
+ - git-ignore: list, create, add, remove
34
+ - git-files: list, read
35
+ - git-history: log
36
+ - git-sync: fetch, pull
37
+ - git-issues: create, list, comment
38
+ - git-pulls: create, list, files
39
+
40
+ Todas as tools exigem `projectPath` e operam com derivação automática do nome do repositório a partir do caminho.
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@andre.buzeli/git-mcp",
3
+ "version": "15.12.5",
4
+ "private": false,
5
+ "description": "MCP server para Git com operações locais e sincronização paralela GitHub/Gitea",
6
+ "license": "MIT",
7
+ "author": "andrebuzeli",
8
+ "type": "module",
9
+ "publishConfig": {
10
+ "access": "public"
11
+ },
12
+ "files": [
13
+ "src",
14
+ "README.md"
15
+ ],
16
+ "main": "src/index.js",
17
+ "bin": {
18
+ "git-mcp": "src/index.js",
19
+ "git-mcpv2": "src/index.js"
20
+ },
21
+ "scripts": {},
22
+ "dependencies": {
23
+ "@modelcontextprotocol/sdk": "^0.4.0",
24
+ "@octokit/rest": "^20.0.0",
25
+ "ajv": "^8.12.0",
26
+ "archiver": "^7.0.0",
27
+ "axios": "^1.7.7"
28
+ }
29
+ }
package/src/index.js ADDED
@@ -0,0 +1,147 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import Ajv from "ajv";
5
+ import { loadEnv } from "./utils/env.js";
6
+ import { asToolError } from "./utils/errors.js";
7
+ import { ProviderManager } from "./providers/providerManager.js";
8
+ import { GitAdapter } from "./utils/gitAdapter.js";
9
+ import { createGitWorkflowTool } from "./tools/git-workflow.js";
10
+ import { createGitRemoteTool } from "./tools/git-remote.js";
11
+ import { createGitBranchesTool } from "./tools/git-branches.js";
12
+ import { createGitTagsTool } from "./tools/git-tags.js";
13
+ import { createGitStashTool } from "./tools/git-stash.js";
14
+ import { createGitResetTool } from "./tools/git-reset.js";
15
+ import { createGitConfigTool } from "./tools/git-config.js";
16
+ import { createGitIgnoreTool } from "./tools/git-ignore.js";
17
+ import { createGitFilesTool } from "./tools/git-files.js";
18
+ import { createGitHistoryTool } from "./tools/git-history.js";
19
+ import { createGitSyncTool } from "./tools/git-sync.js";
20
+ import { createGitIssuesTool } from "./tools/git-issues.js";
21
+ import { createGitPullsTool } from "./tools/git-pulls.js";
22
+ import { createGitMergeTool } from "./tools/git-merge.js";
23
+ import { createGitDiffTool } from "./tools/git-diff.js";
24
+ import { createGitCloneTool } from "./tools/git-clone.js";
25
+ import { createGitHelpTool } from "./tools/git-help.js";
26
+ import { getResources, readResource } from "./resources/index.js";
27
+ import { createPromptsHandler, PROMPTS } from "./prompts/index.js";
28
+
29
+ // Carrega variáveis de ambiente do arquivo .env (se existir)
30
+ loadEnv();
31
+
32
+ const pm = new ProviderManager();
33
+ const git = new GitAdapter(pm);
34
+
35
+ // Log de inicialização para stderr (não interfere com stdio do MCP)
36
+ const hasGitHub = !!process.env.GITHUB_TOKEN;
37
+ const hasGitea = !!process.env.GITEA_URL && !!process.env.GITEA_TOKEN;
38
+ if (!hasGitHub && !hasGitea) {
39
+ console.error("[git-mcp] ⚠️ Nenhum provider configurado. Operações remotas não funcionarão.");
40
+ console.error("[git-mcp] Configure GITHUB_TOKEN e/ou GITEA_URL + GITEA_TOKEN");
41
+ } else {
42
+ const providers = [];
43
+ if (hasGitHub) providers.push("GitHub");
44
+ if (hasGitea) providers.push("Gitea");
45
+ console.error(`[git-mcp] ✓ Providers ativos: ${providers.join(", ")}`);
46
+ }
47
+
48
+ const transport = new StdioServerTransport();
49
+ const server = new Server(
50
+ { name: "git-mcp", version: "15.12.4" },
51
+ { capabilities: { tools: {}, resources: {}, prompts: {} } }
52
+ );
53
+ server.connect(transport);
54
+
55
+ // Prompts handler
56
+ const promptsHandler = createPromptsHandler(git, pm);
57
+
58
+ // Ajv singleton para validação
59
+ const ajv = new Ajv({ allErrors: true });
60
+
61
+ const tools = [
62
+ createGitHelpTool(), // Primeiro: AI pode pedir ajuda
63
+ createGitWorkflowTool(pm, git),
64
+ createGitRemoteTool(pm, git),
65
+ createGitBranchesTool(git),
66
+ createGitTagsTool(git),
67
+ createGitStashTool(git),
68
+ createGitResetTool(git),
69
+ createGitConfigTool(git),
70
+ createGitIgnoreTool(git),
71
+ createGitFilesTool(git),
72
+ createGitHistoryTool(git),
73
+ createGitSyncTool(git),
74
+ createGitIssuesTool(pm),
75
+ createGitPullsTool(pm),
76
+ createGitMergeTool(git),
77
+ createGitDiffTool(git),
78
+ createGitCloneTool(git),
79
+ ];
80
+
81
+ // ============ TOOLS ============
82
+ server.setRequestHandler(
83
+ (await import("@modelcontextprotocol/sdk/types.js")).ListToolsRequestSchema,
84
+ async () => ({
85
+ tools: tools.map(t => ({ name: t.name, description: t.description, inputSchema: t.inputSchema })),
86
+ })
87
+ );
88
+
89
+ server.setRequestHandler(
90
+ (await import("@modelcontextprotocol/sdk/types.js")).CallToolRequestSchema,
91
+ async (req) => {
92
+ const name = req.params?.name || "";
93
+ const args = req.params?.arguments || {};
94
+ // Progress reporting removed to prevent timeouts/unknown token errors on slow networks
95
+ // const progressToken = req.params?._meta?.progressToken;
96
+
97
+ const tool = tools.find(t => t.name === name);
98
+ if (!tool) return { content: [{ type: "text", text: `Tool não encontrada: ${name}` }], isError: true };
99
+ try {
100
+ // if (progressToken) { await server.notification({ method: "notifications/progress", params: { progressToken, progress: 0 } }); }
101
+
102
+ const result = await tool.handle(args);
103
+
104
+ // if (progressToken) { await server.notification({ method: "notifications/progress", params: { progressToken, progress: 100 } }); }
105
+
106
+ return result;
107
+ } catch (e) {
108
+ return asToolError(e.code || "ERROR", e.message || String(e));
109
+ }
110
+ }
111
+ );
112
+
113
+ // ============ RESOURCES ============
114
+ server.setRequestHandler(
115
+ (await import("@modelcontextprotocol/sdk/types.js")).ListResourcesRequestSchema,
116
+ async () => ({ resources: getResources() })
117
+ );
118
+
119
+ server.setRequestHandler(
120
+ (await import("@modelcontextprotocol/sdk/types.js")).ReadResourceRequestSchema,
121
+ async (req) => {
122
+ const uri = req.params?.uri || "";
123
+ const content = readResource(uri);
124
+ if (!content) {
125
+ return { contents: [{ uri, mimeType: "text/plain", text: `Resource não encontrado: ${uri}` }] };
126
+ }
127
+ return { contents: [{ uri, mimeType: "text/markdown", text: content }] };
128
+ }
129
+ );
130
+
131
+ // ============ PROMPTS ============
132
+ server.setRequestHandler(
133
+ (await import("@modelcontextprotocol/sdk/types.js")).ListPromptsRequestSchema,
134
+ async () => ({ prompts: PROMPTS })
135
+ );
136
+
137
+ server.setRequestHandler(
138
+ (await import("@modelcontextprotocol/sdk/types.js")).GetPromptRequestSchema,
139
+ async (req) => {
140
+ const name = req.params?.name || "";
141
+ const args = req.params?.arguments || {};
142
+ return await promptsHandler.get(name, args);
143
+ }
144
+ );
145
+
146
+ // Keep process alive
147
+ process.stdin.resume();