@andrebuzeli/git-mcp 15.8.4 → 15.8.6
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 +39 -125
- package/package.json +28 -44
- package/src/index.js +146 -139
- package/src/providers/providerManager.js +203 -217
- package/src/tools/git-diff.js +137 -126
- package/src/tools/git-help.js +285 -285
- package/src/tools/git-remote.js +472 -472
- package/src/tools/git-workflow.js +403 -403
- package/src/utils/env.js +104 -104
- package/src/utils/errors.js +431 -431
- package/src/utils/gitAdapter.js +932 -951
- package/src/utils/hooks.js +255 -255
- package/src/utils/metrics.js +198 -198
- package/src/utils/providerExec.js +58 -58
- package/src/utils/repoHelpers.js +160 -160
- package/src/utils/retry.js +123 -123
- package/install.sh +0 -68
package/README.md
CHANGED
|
@@ -1,125 +1,39 @@
|
|
|
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
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
| `GITEA_TOKEN` | Token de autenticação Gitea | - |
|
|
41
|
-
| `GIT_TIMEOUT_MS` | Timeout para operações Git | 60000 |
|
|
42
|
-
| `DEBUG_AGENT_LOG` | Habilita logging de debug | false |
|
|
43
|
-
| `ENABLE_METRICS` | Habilita métricas | false |
|
|
44
|
-
|
|
45
|
-
## Status dos Testes
|
|
46
|
-
|
|
47
|
-
```
|
|
48
|
-
Test Suites: 2 passed, 2 total
|
|
49
|
-
Tests: 13 passed, 13 total
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### Configuração Padrão (npx)
|
|
53
|
-
|
|
54
|
-
```json
|
|
55
|
-
{
|
|
56
|
-
"mcpServers": {
|
|
57
|
-
"git-mcp": {
|
|
58
|
-
"command": "npx",
|
|
59
|
-
"args": ["-y", "@andrebuzeli/git-mcp@latest"],
|
|
60
|
-
"env": {
|
|
61
|
-
"GITEA_URL": "https://seu-gitea",
|
|
62
|
-
"GITEA_TOKEN": "...",
|
|
63
|
-
"GITHUB_TOKEN": "..."
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
## 🐧 SSH Remote / Linux Server
|
|
71
|
-
|
|
72
|
-
Se você usa **VS Code Remote SSH**, **Cursor SSH** ou similar, o `npx` pode dar timeout em redes lentas.
|
|
73
|
-
|
|
74
|
-
### Solução: Instalação Global
|
|
75
|
-
|
|
76
|
-
**1. No servidor Linux, execute:**
|
|
77
|
-
```bash
|
|
78
|
-
# Instalação rápida
|
|
79
|
-
curl -fsSL https://raw.githubusercontent.com/andrebuzeli/git-mcp/main/install.sh | bash
|
|
80
|
-
|
|
81
|
-
# Ou manualmente:
|
|
82
|
-
npm install -g @andrebuzeli/git-mcp@latest
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
**2. Configure a IDE para usar o comando local:**
|
|
86
|
-
```json
|
|
87
|
-
{
|
|
88
|
-
"mcpServers": {
|
|
89
|
-
"git-mcp": {
|
|
90
|
-
"command": "git-mcp",
|
|
91
|
-
"env": {
|
|
92
|
-
"GITHUB_TOKEN": "...",
|
|
93
|
-
"GITEA_URL": "https://seu-gitea",
|
|
94
|
-
"GITEA_TOKEN": "..."
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
### Troubleshooting
|
|
102
|
-
|
|
103
|
-
| Erro | Solução |
|
|
104
|
-
|------|---------|
|
|
105
|
-
| `ETIMEDOUT` / `Request timed out` | Use instalação global ao invés de npx |
|
|
106
|
-
| `command not found: git-mcp` | Verifique se npm global está no PATH |
|
|
107
|
-
| Permissão negada | Use `sudo npm install -g @andrebuzeli/git-mcp` |
|
|
108
|
-
|
|
109
|
-
## Tools
|
|
110
|
-
|
|
111
|
-
- git-workflow: init, status, add, remove, commit, ensure-remotes, push
|
|
112
|
-
- git-remote: list, ensure
|
|
113
|
-
- git-branches: list, create, delete, rename, checkout
|
|
114
|
-
- git-tags: list, create, delete, push
|
|
115
|
-
- git-stash: list, save, apply, pop, drop, clear
|
|
116
|
-
- git-reset: soft, mixed, hard
|
|
117
|
-
- git-config: get, set, unset, list
|
|
118
|
-
- git-ignore: list, create, add, remove
|
|
119
|
-
- git-files: list, read
|
|
120
|
-
- git-history: log
|
|
121
|
-
- git-sync: fetch, pull
|
|
122
|
-
- git-issues: create, list, comment
|
|
123
|
-
- git-pulls: create, list, files
|
|
124
|
-
|
|
125
|
-
Todas as tools exigem `projectPath` e operam com derivação automática do nome do repositório a partir do caminho.
|
|
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-remote: list, ensure
|
|
27
|
+
- git-branches: list, create, delete, rename, checkout
|
|
28
|
+
- git-tags: list, create, delete, push
|
|
29
|
+
- git-stash: list, save, apply, pop, drop, clear
|
|
30
|
+
- git-reset: soft, mixed, hard
|
|
31
|
+
- git-config: get, set, unset, list
|
|
32
|
+
- git-ignore: list, create, add, remove
|
|
33
|
+
- git-files: list, read
|
|
34
|
+
- git-history: log
|
|
35
|
+
- git-sync: fetch, pull
|
|
36
|
+
- git-issues: create, list, comment
|
|
37
|
+
- git-pulls: create, list, files
|
|
38
|
+
|
|
39
|
+
Todas as tools exigem `projectPath` e operam com derivação automática do nome do repositório a partir do caminho.
|
package/package.json
CHANGED
|
@@ -1,45 +1,29 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@andrebuzeli/git-mcp",
|
|
3
|
-
"version": "15.8.
|
|
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
|
-
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
"git-
|
|
20
|
-
|
|
21
|
-
},
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
"test:providers": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config jest.comprehensive.config.js test/comprehensive/test-provider-manager.js",
|
|
30
|
-
"test:tools": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config jest.comprehensive.config.js test/comprehensive/test-tools.js",
|
|
31
|
-
"test:resources": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config jest.comprehensive.config.js test/comprehensive/test-resources.js",
|
|
32
|
-
"test:integration": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config jest.comprehensive.config.js test/comprehensive/test-integration.js",
|
|
33
|
-
"test:security": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config jest.comprehensive.config.js test/comprehensive/test-security.js"
|
|
34
|
-
},
|
|
35
|
-
"dependencies": {
|
|
36
|
-
"@modelcontextprotocol/sdk": "^0.4.0",
|
|
37
|
-
"@octokit/rest": "^20.0.0",
|
|
38
|
-
"ajv": "^8.12.0",
|
|
39
|
-
"archiver": "^7.0.1",
|
|
40
|
-
"axios": "^1.7.7"
|
|
41
|
-
},
|
|
42
|
-
"devDependencies": {
|
|
43
|
-
"jest": "^30.2.0"
|
|
44
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@andrebuzeli/git-mcp",
|
|
3
|
+
"version": "15.8.6",
|
|
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
|
+
}
|
|
45
29
|
}
|
package/src/index.js
CHANGED
|
@@ -1,139 +1,146 @@
|
|
|
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-mcpv2", version: "15.8.0" },
|
|
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
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
);
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
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-mcpv2", version: "15.8.0" },
|
|
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
|
+
const progressToken = req.params?._meta?.progressToken;
|
|
95
|
+
const tool = tools.find(t => t.name === name);
|
|
96
|
+
if (!tool) return { content: [{ type: "text", text: `Tool não encontrada: ${name}` }], isError: true };
|
|
97
|
+
try {
|
|
98
|
+
if (progressToken) {
|
|
99
|
+
await server.notification({ method: "notifications/progress", params: { progressToken, progress: 0 } });
|
|
100
|
+
}
|
|
101
|
+
const result = await tool.handle(args);
|
|
102
|
+
if (progressToken) {
|
|
103
|
+
await server.notification({ method: "notifications/progress", params: { progressToken, progress: 100 } });
|
|
104
|
+
}
|
|
105
|
+
return result;
|
|
106
|
+
} catch (e) {
|
|
107
|
+
return asToolError(e.code || "ERROR", e.message || String(e));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
// ============ RESOURCES ============
|
|
113
|
+
server.setRequestHandler(
|
|
114
|
+
(await import("@modelcontextprotocol/sdk/types.js")).ListResourcesRequestSchema,
|
|
115
|
+
async () => ({ resources: getResources() })
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
server.setRequestHandler(
|
|
119
|
+
(await import("@modelcontextprotocol/sdk/types.js")).ReadResourceRequestSchema,
|
|
120
|
+
async (req) => {
|
|
121
|
+
const uri = req.params?.uri || "";
|
|
122
|
+
const content = readResource(uri);
|
|
123
|
+
if (!content) {
|
|
124
|
+
return { contents: [{ uri, mimeType: "text/plain", text: `Resource não encontrado: ${uri}` }] };
|
|
125
|
+
}
|
|
126
|
+
return { contents: [{ uri, mimeType: "text/markdown", text: content }] };
|
|
127
|
+
}
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
// ============ PROMPTS ============
|
|
131
|
+
server.setRequestHandler(
|
|
132
|
+
(await import("@modelcontextprotocol/sdk/types.js")).ListPromptsRequestSchema,
|
|
133
|
+
async () => ({ prompts: PROMPTS })
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
server.setRequestHandler(
|
|
137
|
+
(await import("@modelcontextprotocol/sdk/types.js")).GetPromptRequestSchema,
|
|
138
|
+
async (req) => {
|
|
139
|
+
const name = req.params?.name || "";
|
|
140
|
+
const args = req.params?.arguments || {};
|
|
141
|
+
return await promptsHandler.get(name, args);
|
|
142
|
+
}
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
// Keep process alive
|
|
146
|
+
process.stdin.resume();
|