@andrebuzeli/git-mcp 6.3.1 → 7.0.0
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/dist/index.js +1 -1
- package/dist/resources/toolsGuide.js +206 -12
- package/dist/tools/gitAnalytics.d.ts +1 -24
- package/dist/tools/gitAnalytics.js +168 -43
- package/dist/tools/gitBranches.d.ts +1 -67
- package/dist/tools/gitBranches.js +151 -19
- package/dist/tools/gitMonitor.d.ts +1 -46
- package/dist/tools/gitMonitor.js +184 -14
- package/dist/tools/gitTags.d.ts +1 -25
- package/dist/tools/gitTags.js +161 -13
- package/dist/utils/dualExecution.d.ts +49 -0
- package/dist/utils/dualExecution.js +96 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -77,7 +77,7 @@ async function main() {
|
|
|
77
77
|
// Create MCP Server with STDIO transport
|
|
78
78
|
const server = new index_js_1.Server({
|
|
79
79
|
name: '@andrebuzeli/git-mcp',
|
|
80
|
-
version: '6.3.
|
|
80
|
+
version: '6.3.2',
|
|
81
81
|
});
|
|
82
82
|
// Register tool list handler
|
|
83
83
|
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
|
|
@@ -10,10 +10,68 @@ exports.TOOLS_GUIDE = {
|
|
|
10
10
|
name: "Git-MCP Tools Complete Guide",
|
|
11
11
|
description: "Detailed documentation and usage instructions for all 20 Git tools with 102 actions",
|
|
12
12
|
mimeType: "text/markdown",
|
|
13
|
-
content: `# 🛠️ Git-MCP
|
|
13
|
+
content: `# 🛠️ Git-MCP v7.0.0 - Complete Tools Guide
|
|
14
14
|
|
|
15
|
-
> **Comprehensive documentation for all
|
|
16
|
-
> **Supports:**
|
|
15
|
+
> **Comprehensive documentation for all 21 Git tools with 110+ actions**
|
|
16
|
+
> **Supports:** Automatic DUAL execution on GitHub + Gitea APIs
|
|
17
|
+
> **BREAKING CHANGES in v7.0.0:** ALL tools now execute DUAL automatically with env var usernames
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 🚀 v7.0.0 MAJOR UPDATE: AUTOMATIC DUAL EXECUTION
|
|
22
|
+
|
|
23
|
+
**ALL TOOLS NOW:**
|
|
24
|
+
- ✅ Execute on BOTH GitHub and Gitea APIs automatically
|
|
25
|
+
- ✅ Use GITHUB_USERNAME and GITEA_USERNAME from environment variables
|
|
26
|
+
- ✅ Return separated responses: \`{ github: {...}, gitea: {...} }\`
|
|
27
|
+
- ✅ NO manual owner/user/author parameters needed
|
|
28
|
+
- ✅ Each provider uses its own credentials automatically
|
|
29
|
+
|
|
30
|
+
### Environment Variables Required:
|
|
31
|
+
\\\`\\\`\\\`bash
|
|
32
|
+
GITHUB_TOKEN=your_github_token
|
|
33
|
+
GITHUB_USERNAME=YourGitHubUsername
|
|
34
|
+
GITEA_TOKEN=your_gitea_token
|
|
35
|
+
GITEA_USERNAME=yourGiteaUsername
|
|
36
|
+
GITEA_URL=http://your-gitea-server:port
|
|
37
|
+
\\\`\\\`\\\`
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## ⚠️ CRITICAL: projectPath Requirements
|
|
42
|
+
|
|
43
|
+
**ALL TOOLS REQUIRE projectPath PARAMETER**
|
|
44
|
+
|
|
45
|
+
### ✅ Correct Usage:
|
|
46
|
+
\\\`\\\`\\\`javascript
|
|
47
|
+
{
|
|
48
|
+
"projectPath": "Z:/absolute/path/to/project-root"
|
|
49
|
+
// Must be the ROOT folder of the opened project
|
|
50
|
+
// NOT a subfolder, NOT a file, NOT a parent folder
|
|
51
|
+
}
|
|
52
|
+
\\\`\\\`\\\`
|
|
53
|
+
|
|
54
|
+
### ❌ WRONG Usage:
|
|
55
|
+
\\\`\\\`\\\`javascript
|
|
56
|
+
// ❌ Relative path
|
|
57
|
+
"projectPath": "./my-project"
|
|
58
|
+
|
|
59
|
+
// ❌ Subfolder instead of root
|
|
60
|
+
"projectPath": "/project-root/src"
|
|
61
|
+
|
|
62
|
+
// ❌ Parent folder
|
|
63
|
+
"projectPath": "/path/to/workspace"
|
|
64
|
+
|
|
65
|
+
// ❌ File path
|
|
66
|
+
"projectPath": "/project/package.json"
|
|
67
|
+
\\\`\\\`\\\`
|
|
68
|
+
|
|
69
|
+
### 📋 Rule:
|
|
70
|
+
**projectPath MUST be:**
|
|
71
|
+
- ✅ Absolute path (starts with / or drive letter)
|
|
72
|
+
- ✅ Points to the ROOT folder of the opened project
|
|
73
|
+
- ✅ The same folder you opened in your IDE
|
|
74
|
+
- ✅ Contains .git folder (for Git operations)
|
|
17
75
|
|
|
18
76
|
---
|
|
19
77
|
|
|
@@ -22,13 +80,14 @@ exports.TOOLS_GUIDE = {
|
|
|
22
80
|
1. [Quick Start](#quick-start)
|
|
23
81
|
2. [Provider Types](#provider-types)
|
|
24
82
|
3. [Core Workflow Tools](#core-workflow-tools)
|
|
25
|
-
4. [
|
|
26
|
-
5. [
|
|
27
|
-
6. [
|
|
28
|
-
7. [
|
|
29
|
-
8. [
|
|
30
|
-
9. [
|
|
31
|
-
10. [
|
|
83
|
+
4. [Migration Tools (NEW)](#migration-tools)
|
|
84
|
+
5. [Remote Management Tools](#remote-management-tools)
|
|
85
|
+
6. [Issue & Pull Request Tools](#issue--pull-request-tools)
|
|
86
|
+
7. [Release & Package Tools](#release--package-tools)
|
|
87
|
+
8. [Branch & Tag Tools](#branch--tag-tools)
|
|
88
|
+
9. [Configuration & Monitoring Tools](#configuration--monitoring-tools)
|
|
89
|
+
10. [Advanced Tools](#advanced-tools)
|
|
90
|
+
11. [Best Practices](#best-practices)
|
|
32
91
|
|
|
33
92
|
---
|
|
34
93
|
|
|
@@ -91,6 +150,8 @@ npm install @andrebuzeli/git-mcp
|
|
|
91
150
|
|
|
92
151
|
**Type:** HYBRID - Local operations + Remote operations (GitHub/Gitea)
|
|
93
152
|
|
|
153
|
+
**projectPath:** ⚠️ REQUIRED - Absolute path to project ROOT folder (where you opened the project in IDE)
|
|
154
|
+
|
|
94
155
|
**Actions:**
|
|
95
156
|
- \`init\` - Initialize new repository
|
|
96
157
|
- \`status\` - Check repository status
|
|
@@ -289,6 +350,138 @@ npm install @andrebuzeli/git-mcp
|
|
|
289
350
|
|
|
290
351
|
---
|
|
291
352
|
|
|
353
|
+
## 🔧 Migration Tools (NEW in v6.3.1)
|
|
354
|
+
|
|
355
|
+
### 21. **git-fix** (LOCAL)
|
|
356
|
+
**Description:** Fix local Git repositories to work with dual-provider system (GitHub + Gitea)
|
|
357
|
+
|
|
358
|
+
**Type:** LOCAL - Converts existing repos to dual-provider configuration
|
|
359
|
+
|
|
360
|
+
**projectPath:** ⚠️ REQUIRED - Absolute path to project ROOT folder that needs fixing
|
|
361
|
+
|
|
362
|
+
**Features:**
|
|
363
|
+
- 🔍 **Auto-detection:** Automatically detects repository name from existing remotes
|
|
364
|
+
- ✅ **Username correction:** Uses correct usernames from GITHUB_USERNAME and GITEA_USERNAME env vars
|
|
365
|
+
- 🗑️ **Clean setup:** Removes old remotes and creates standardized configuration
|
|
366
|
+
- 🔄 **Dual-push:** Configures origin to push to both GitHub and Gitea simultaneously
|
|
367
|
+
- 📝 **Preserves history:** Keeps all commits and Git history intact
|
|
368
|
+
- ⚙️ **.gitignore creation:** Creates standard .gitignore if missing
|
|
369
|
+
|
|
370
|
+
**Parameters:**
|
|
371
|
+
- \\\`projectPath\\\` (required) - Absolute path to Git repository ROOT folder
|
|
372
|
+
- \\\`autoDetect\\\` (optional) - Auto-detect repo name from remotes (default: true)
|
|
373
|
+
- \\\`githubRepo\\\` (optional) - GitHub repo in format "owner/repo" (auto-detected if not provided)
|
|
374
|
+
- \\\`giteaRepo\\\` (optional) - Gitea repo in format "owner/repo" (auto-detected if not provided)
|
|
375
|
+
|
|
376
|
+
**Requirements:**
|
|
377
|
+
- \\\`GITHUB_USERNAME\\\` env var (REQUIRED)
|
|
378
|
+
- \\\`GITEA_USERNAME\\\` env var (REQUIRED)
|
|
379
|
+
- \\\`GITEA_URL\\\` env var (default: http://localhost:3000)
|
|
380
|
+
|
|
381
|
+
**When to use:**
|
|
382
|
+
- ✅ Existing Git repo NOT configured for dual-provider
|
|
383
|
+
- ✅ Migrating from single remote (GitHub OR Gitea) to dual-push
|
|
384
|
+
- ✅ Fixing incorrect username configuration
|
|
385
|
+
- ✅ Standardizing repository configuration across projects
|
|
386
|
+
|
|
387
|
+
**What it does:**
|
|
388
|
+
1. ✅ Verifies/initializes Git repository
|
|
389
|
+
2. 🔍 Captures current remotes (before state)
|
|
390
|
+
3. 🔍 Auto-detects repository name from existing URLs
|
|
391
|
+
4. 🗑️ Removes old remotes (origin, github, gitea)
|
|
392
|
+
5. ➕ Adds new 'github' remote with correct username
|
|
393
|
+
6. ➕ Adds new 'gitea' remote with correct username
|
|
394
|
+
7. ⚙️ Configures 'origin' for dual-push (GitHub + Gitea)
|
|
395
|
+
8. 📝 Creates .gitignore if missing
|
|
396
|
+
9. 📊 Shows before/after comparison
|
|
397
|
+
|
|
398
|
+
**Examples:**
|
|
399
|
+
|
|
400
|
+
\\\`\\\`\\\`javascript
|
|
401
|
+
// 1. Auto-detect and fix repository
|
|
402
|
+
{
|
|
403
|
+
"tool": "git-fix",
|
|
404
|
+
"params": {
|
|
405
|
+
"projectPath": "Z:/my-old-project",
|
|
406
|
+
"autoDetect": true
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// Before:
|
|
411
|
+
// origin → https://github.com/olduser/old-project.git
|
|
412
|
+
|
|
413
|
+
// After:
|
|
414
|
+
// github → https://github.com/Your-GitHub-Username/old-project.git
|
|
415
|
+
// gitea → http://nas-ubuntu:9999/your-gitea-username/old-project.git
|
|
416
|
+
// origin → dual-push to both
|
|
417
|
+
|
|
418
|
+
// 2. Manual repo specification
|
|
419
|
+
{
|
|
420
|
+
"tool": "git-fix",
|
|
421
|
+
"params": {
|
|
422
|
+
"projectPath": "Z:/my-project",
|
|
423
|
+
"githubRepo": "Andre-Buzeli/my-project",
|
|
424
|
+
"giteaRepo": "andrebuzeli/my-project",
|
|
425
|
+
"autoDetect": false
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// 3. Fix multiple projects (use sequentially)
|
|
430
|
+
// Project 1
|
|
431
|
+
{
|
|
432
|
+
"tool": "git-fix",
|
|
433
|
+
"params": {
|
|
434
|
+
"projectPath": "Z:/project-1",
|
|
435
|
+
"autoDetect": true
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// Project 2
|
|
440
|
+
{
|
|
441
|
+
"tool": "git-fix",
|
|
442
|
+
"params": {
|
|
443
|
+
"projectPath": "Z:/project-2",
|
|
444
|
+
"autoDetect": true
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
\\\`\\\`\\\`
|
|
448
|
+
|
|
449
|
+
**Result Structure:**
|
|
450
|
+
\\\`\\\`\\\`json
|
|
451
|
+
{
|
|
452
|
+
"success": true,
|
|
453
|
+
"projectPath": "Z:/my-project",
|
|
454
|
+
"fixed": [
|
|
455
|
+
"✅ Repositório Git válido encontrado",
|
|
456
|
+
"🔍 Nome do repo auto-detectado: my-project",
|
|
457
|
+
"✅ GitHub repo: Andre-Buzeli/my-project",
|
|
458
|
+
"✅ Gitea repo: andrebuzeli/my-project",
|
|
459
|
+
"🗑️ Removido remote antigo: origin",
|
|
460
|
+
"✅ Adicionado remote GitHub: https://github.com/Andre-Buzeli/my-project.git",
|
|
461
|
+
"✅ Adicionado remote Gitea: http://nas-ubuntu:9999/andrebuzeli/my-project.git",
|
|
462
|
+
"✅ Configurado origin para push dual (GitHub + Gitea)",
|
|
463
|
+
"✅ Histórico de commits preservado",
|
|
464
|
+
"✅ Criado .gitignore padrão"
|
|
465
|
+
],
|
|
466
|
+
"warnings": [],
|
|
467
|
+
"errors": [],
|
|
468
|
+
"remotes": {
|
|
469
|
+
"before": [...],
|
|
470
|
+
"after": [...]
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
\\\`\\\`\\\`
|
|
474
|
+
|
|
475
|
+
**⚠️ Important Notes:**
|
|
476
|
+
- Always backup your repository before running git-fix
|
|
477
|
+
- Requires valid GITHUB_USERNAME and GITEA_USERNAME env vars
|
|
478
|
+
- Repository name detection works with github.com and Gitea URLs
|
|
479
|
+
- Falls back to folder name if no remote detected
|
|
480
|
+
- Does NOT push to remotes (only configures them)
|
|
481
|
+
- Safe to run multiple times (idempotent)
|
|
482
|
+
|
|
483
|
+
---
|
|
484
|
+
|
|
292
485
|
## 🌐 Remote Management Tools
|
|
293
486
|
|
|
294
487
|
### 5. **git-remote** (LOCAL)
|
|
@@ -1411,8 +1604,9 @@ for (const repo of repos) {
|
|
|
1411
1604
|
| git-backup | LOCAL | 4 | Backup operations |
|
|
1412
1605
|
| git-archive | LOCAL | 4 | Archive creation |
|
|
1413
1606
|
| git-files | LOCAL | 4 | File operations |
|
|
1607
|
+
| **git-fix** | **LOCAL** | **1** | **Migrate repos to dual-provider (NEW v6.3.1)** |
|
|
1414
1608
|
|
|
1415
|
-
**Total:
|
|
1609
|
+
**Total: 21 tools, 110+ actions**
|
|
1416
1610
|
|
|
1417
1611
|
---
|
|
1418
1612
|
|
|
@@ -1485,7 +1679,7 @@ for (const repo of repos) {
|
|
|
1485
1679
|
|
|
1486
1680
|
---
|
|
1487
1681
|
|
|
1488
|
-
**Git-MCP
|
|
1682
|
+
**Git-MCP v6.3.1** | Built with ❤️ for developers | 110+ Actions | 21 Tools | 3 Provider Types | NEW: git-fix migration tool
|
|
1489
1683
|
`
|
|
1490
1684
|
};
|
|
1491
1685
|
exports.default = exports.TOOLS_GUIDE;
|
|
@@ -2,28 +2,5 @@ import { Tool, MCPContext } from '../types';
|
|
|
2
2
|
export declare class GitAnalyticsTool implements Tool {
|
|
3
3
|
name: string;
|
|
4
4
|
description: string;
|
|
5
|
-
handle(params: Record<string, any>, ctx: MCPContext): Promise<
|
|
6
|
-
success: boolean;
|
|
7
|
-
stats: {
|
|
8
|
-
totalCommits: number;
|
|
9
|
-
branches: number;
|
|
10
|
-
tags: number;
|
|
11
|
-
latestCommit: (import("simple-git").DefaultLogFields & import("simple-git").ListLogLine) | null;
|
|
12
|
-
};
|
|
13
|
-
commits?: undefined;
|
|
14
|
-
details?: undefined;
|
|
15
|
-
contributors?: undefined;
|
|
16
|
-
} | {
|
|
17
|
-
success: boolean;
|
|
18
|
-
commits: number;
|
|
19
|
-
details: readonly (import("simple-git").DefaultLogFields & import("simple-git").ListLogLine)[];
|
|
20
|
-
stats?: undefined;
|
|
21
|
-
contributors?: undefined;
|
|
22
|
-
} | {
|
|
23
|
-
success: boolean;
|
|
24
|
-
contributors: any[];
|
|
25
|
-
stats?: undefined;
|
|
26
|
-
commits?: undefined;
|
|
27
|
-
details?: undefined;
|
|
28
|
-
}>;
|
|
5
|
+
handle(params: Record<string, any>, ctx: MCPContext): Promise<any>;
|
|
29
6
|
}
|
|
@@ -4,65 +4,190 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.GitAnalyticsTool = void 0;
|
|
7
|
-
const simple_git_1 = __importDefault(require("simple-git"));
|
|
8
7
|
const errors_1 = require("../utils/errors");
|
|
8
|
+
const axios_1 = __importDefault(require("axios"));
|
|
9
|
+
const repoHelpers_1 = require("../utils/repoHelpers");
|
|
9
10
|
class GitAnalyticsTool {
|
|
10
11
|
constructor() {
|
|
11
12
|
this.name = 'git-analytics';
|
|
12
|
-
this.description = 'Repository analytics and statistics';
|
|
13
|
+
this.description = 'Repository analytics and statistics - automatic dual-provider execution using GitHub and Gitea APIs';
|
|
13
14
|
}
|
|
14
15
|
async handle(params, ctx) {
|
|
15
16
|
const action = params.action;
|
|
16
17
|
const projectPath = params.projectPath;
|
|
17
|
-
if (!action
|
|
18
|
-
throw new errors_1.MCPError('VALIDATION_ERROR', 'action
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
if (!action)
|
|
19
|
+
throw new errors_1.MCPError('VALIDATION_ERROR', 'action is required');
|
|
20
|
+
if (!projectPath)
|
|
21
|
+
throw new errors_1.MCPError('VALIDATION_ERROR', 'projectPath is required');
|
|
22
|
+
// Auto-extract repo info from projectPath
|
|
23
|
+
const repoInfo = (0, repoHelpers_1.getRepoInfo)(projectPath);
|
|
24
|
+
const repo = repoInfo.repoName;
|
|
25
|
+
// Each provider uses its own username from env
|
|
26
|
+
const githubOwner = process.env.GITHUB_USERNAME;
|
|
27
|
+
const giteaOwner = process.env.GITEA_USERNAME;
|
|
21
28
|
switch (action) {
|
|
22
29
|
case 'stats': {
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
const results = { success: true, providers: {} };
|
|
31
|
+
// GitHub API
|
|
32
|
+
if (ctx.providerManager.github && githubOwner) {
|
|
33
|
+
try {
|
|
34
|
+
const repoData = await ctx.providerManager.github.rest.repos.get({
|
|
35
|
+
owner: githubOwner,
|
|
36
|
+
repo: repo,
|
|
37
|
+
});
|
|
38
|
+
const branches = await ctx.providerManager.github.rest.repos.listBranches({
|
|
39
|
+
owner: githubOwner,
|
|
40
|
+
repo: repo,
|
|
41
|
+
});
|
|
42
|
+
const tags = await ctx.providerManager.github.rest.repos.listTags({
|
|
43
|
+
owner: githubOwner,
|
|
44
|
+
repo: repo,
|
|
45
|
+
});
|
|
46
|
+
const commits = await ctx.providerManager.github.rest.repos.listCommits({
|
|
47
|
+
owner: githubOwner,
|
|
48
|
+
repo: repo,
|
|
49
|
+
per_page: 1,
|
|
50
|
+
});
|
|
51
|
+
results.providers.github = {
|
|
52
|
+
success: true,
|
|
53
|
+
stats: {
|
|
54
|
+
totalCommits: repoData.data.size,
|
|
55
|
+
branches: branches.data.length,
|
|
56
|
+
tags: tags.data.length,
|
|
57
|
+
defaultBranch: repoData.data.default_branch,
|
|
58
|
+
latestCommit: commits.data[0] || null,
|
|
59
|
+
size: repoData.data.size,
|
|
60
|
+
language: repoData.data.language,
|
|
61
|
+
stars: repoData.data.stargazers_count,
|
|
62
|
+
forks: repoData.data.forks_count,
|
|
63
|
+
openIssues: repoData.data.open_issues_count,
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
results.providers.github = { success: false, error: err.message };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Gitea API
|
|
72
|
+
if (ctx.providerManager.giteaBaseUrl && giteaOwner) {
|
|
73
|
+
try {
|
|
74
|
+
const repoData = await axios_1.default.get(`${ctx.providerManager.giteaBaseUrl}/api/v1/repos/${giteaOwner}/${repo}`, { headers: { Authorization: `token ${ctx.providerManager.giteaToken}` } });
|
|
75
|
+
const branches = await axios_1.default.get(`${ctx.providerManager.giteaBaseUrl}/api/v1/repos/${giteaOwner}/${repo}/branches`, { headers: { Authorization: `token ${ctx.providerManager.giteaToken}` } });
|
|
76
|
+
const tags = await axios_1.default.get(`${ctx.providerManager.giteaBaseUrl}/api/v1/repos/${giteaOwner}/${repo}/tags`, { headers: { Authorization: `token ${ctx.providerManager.giteaToken}` } });
|
|
77
|
+
const commits = await axios_1.default.get(`${ctx.providerManager.giteaBaseUrl}/api/v1/repos/${giteaOwner}/${repo}/commits`, {
|
|
78
|
+
params: { limit: 1 },
|
|
79
|
+
headers: { Authorization: `token ${ctx.providerManager.giteaToken}` }
|
|
80
|
+
});
|
|
81
|
+
results.providers.gitea = {
|
|
82
|
+
success: true,
|
|
83
|
+
stats: {
|
|
84
|
+
totalCommits: repoData.data.size,
|
|
85
|
+
branches: branches.data.length,
|
|
86
|
+
tags: tags.data.length,
|
|
87
|
+
defaultBranch: repoData.data.default_branch,
|
|
88
|
+
latestCommit: commits.data[0] || null,
|
|
89
|
+
size: repoData.data.size,
|
|
90
|
+
language: repoData.data.language,
|
|
91
|
+
stars: repoData.data.stars_count,
|
|
92
|
+
forks: repoData.data.forks_count,
|
|
93
|
+
openIssues: repoData.data.open_issues_count,
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
results.providers.gitea = { success: false, error: err.message };
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return results;
|
|
35
102
|
}
|
|
36
103
|
case 'commits': {
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
104
|
+
const results = { success: true, providers: {} };
|
|
105
|
+
// GitHub API
|
|
106
|
+
if (ctx.providerManager.github && githubOwner) {
|
|
107
|
+
try {
|
|
108
|
+
const commits = await ctx.providerManager.github.rest.repos.listCommits({
|
|
109
|
+
owner: githubOwner,
|
|
110
|
+
repo: repo,
|
|
111
|
+
since: params.since,
|
|
112
|
+
until: params.until,
|
|
113
|
+
per_page: params.limit || 100,
|
|
114
|
+
});
|
|
115
|
+
results.providers.github = {
|
|
116
|
+
success: true,
|
|
117
|
+
commits: commits.data.length,
|
|
118
|
+
details: commits.data,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
results.providers.github = { success: false, error: err.message };
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// Gitea API
|
|
126
|
+
if (ctx.providerManager.giteaBaseUrl && giteaOwner) {
|
|
127
|
+
try {
|
|
128
|
+
const commits = await axios_1.default.get(`${ctx.providerManager.giteaBaseUrl}/api/v1/repos/${giteaOwner}/${repo}/commits`, {
|
|
129
|
+
params: {
|
|
130
|
+
since: params.since,
|
|
131
|
+
until: params.until,
|
|
132
|
+
limit: params.limit || 100,
|
|
133
|
+
},
|
|
134
|
+
headers: { Authorization: `token ${ctx.providerManager.giteaToken}` }
|
|
135
|
+
});
|
|
136
|
+
results.providers.gitea = {
|
|
137
|
+
success: true,
|
|
138
|
+
commits: commits.data.length,
|
|
139
|
+
details: commits.data,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
results.providers.gitea = { success: false, error: err.message };
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return results;
|
|
49
147
|
}
|
|
50
148
|
case 'contributors': {
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
149
|
+
const results = { success: true, providers: {} };
|
|
150
|
+
// GitHub API
|
|
151
|
+
if (ctx.providerManager.github && githubOwner) {
|
|
152
|
+
try {
|
|
153
|
+
const contributors = await ctx.providerManager.github.rest.repos.listContributors({
|
|
154
|
+
owner: githubOwner,
|
|
155
|
+
repo: repo,
|
|
156
|
+
per_page: 100,
|
|
157
|
+
});
|
|
158
|
+
results.providers.github = {
|
|
159
|
+
success: true,
|
|
160
|
+
contributors: contributors.data.map((c) => ({
|
|
161
|
+
login: c.login,
|
|
162
|
+
name: c.login,
|
|
163
|
+
contributions: c.contributions,
|
|
164
|
+
avatar_url: c.avatar_url,
|
|
165
|
+
})),
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
catch (err) {
|
|
169
|
+
results.providers.github = { success: false, error: err.message };
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// Gitea API
|
|
173
|
+
if (ctx.providerManager.giteaBaseUrl && giteaOwner) {
|
|
174
|
+
try {
|
|
175
|
+
const contributors = await axios_1.default.get(`${ctx.providerManager.giteaBaseUrl}/api/v1/repos/${giteaOwner}/${repo}/contributors`, { headers: { Authorization: `token ${ctx.providerManager.giteaToken}` } });
|
|
176
|
+
results.providers.gitea = {
|
|
177
|
+
success: true,
|
|
178
|
+
contributors: contributors.data.map((c) => ({
|
|
179
|
+
login: c.login,
|
|
180
|
+
name: c.name || c.login,
|
|
181
|
+
contributions: c.contributions,
|
|
182
|
+
avatar_url: c.avatar_url,
|
|
183
|
+
})),
|
|
184
|
+
};
|
|
57
185
|
}
|
|
58
|
-
|
|
59
|
-
|
|
186
|
+
catch (err) {
|
|
187
|
+
results.providers.gitea = { success: false, error: err.message };
|
|
60
188
|
}
|
|
61
|
-
}
|
|
62
|
-
return
|
|
63
|
-
success: true,
|
|
64
|
-
contributors: Array.from(contributors.values()).sort((a, b) => b.count - a.count),
|
|
65
|
-
};
|
|
189
|
+
}
|
|
190
|
+
return results;
|
|
66
191
|
}
|
|
67
192
|
default:
|
|
68
193
|
throw new errors_1.MCPError('VALIDATION_ERROR', `Unsupported action: ${action}`);
|
|
@@ -2,71 +2,5 @@ import { Tool, MCPContext } from '../types';
|
|
|
2
2
|
export declare class GitBranchesTool implements Tool {
|
|
3
3
|
name: string;
|
|
4
4
|
description: string;
|
|
5
|
-
handle(params: Record<string, any>, ctx: MCPContext): Promise<
|
|
6
|
-
success: boolean;
|
|
7
|
-
branch: any;
|
|
8
|
-
branches?: undefined;
|
|
9
|
-
current?: undefined;
|
|
10
|
-
deleted?: undefined;
|
|
11
|
-
result?: undefined;
|
|
12
|
-
baseBranch?: undefined;
|
|
13
|
-
compareBranch?: undefined;
|
|
14
|
-
commits?: undefined;
|
|
15
|
-
diff?: undefined;
|
|
16
|
-
} | {
|
|
17
|
-
branches: string[];
|
|
18
|
-
current: string;
|
|
19
|
-
success?: undefined;
|
|
20
|
-
branch?: undefined;
|
|
21
|
-
deleted?: undefined;
|
|
22
|
-
result?: undefined;
|
|
23
|
-
baseBranch?: undefined;
|
|
24
|
-
compareBranch?: undefined;
|
|
25
|
-
commits?: undefined;
|
|
26
|
-
diff?: undefined;
|
|
27
|
-
} | {
|
|
28
|
-
success: boolean;
|
|
29
|
-
branch: string;
|
|
30
|
-
current: boolean;
|
|
31
|
-
branches?: undefined;
|
|
32
|
-
deleted?: undefined;
|
|
33
|
-
result?: undefined;
|
|
34
|
-
baseBranch?: undefined;
|
|
35
|
-
compareBranch?: undefined;
|
|
36
|
-
commits?: undefined;
|
|
37
|
-
diff?: undefined;
|
|
38
|
-
} | {
|
|
39
|
-
success: boolean;
|
|
40
|
-
deleted: any;
|
|
41
|
-
branch?: undefined;
|
|
42
|
-
branches?: undefined;
|
|
43
|
-
current?: undefined;
|
|
44
|
-
result?: undefined;
|
|
45
|
-
baseBranch?: undefined;
|
|
46
|
-
compareBranch?: undefined;
|
|
47
|
-
commits?: undefined;
|
|
48
|
-
diff?: undefined;
|
|
49
|
-
} | {
|
|
50
|
-
success: boolean;
|
|
51
|
-
result: import("simple-git").MergeResult;
|
|
52
|
-
branch?: undefined;
|
|
53
|
-
branches?: undefined;
|
|
54
|
-
current?: undefined;
|
|
55
|
-
deleted?: undefined;
|
|
56
|
-
baseBranch?: undefined;
|
|
57
|
-
compareBranch?: undefined;
|
|
58
|
-
commits?: undefined;
|
|
59
|
-
diff?: undefined;
|
|
60
|
-
} | {
|
|
61
|
-
success: boolean;
|
|
62
|
-
baseBranch: any;
|
|
63
|
-
compareBranch: any;
|
|
64
|
-
commits: readonly (import("simple-git").DefaultLogFields & import("simple-git").ListLogLine)[];
|
|
65
|
-
diff: string;
|
|
66
|
-
branch?: undefined;
|
|
67
|
-
branches?: undefined;
|
|
68
|
-
current?: undefined;
|
|
69
|
-
deleted?: undefined;
|
|
70
|
-
result?: undefined;
|
|
71
|
-
}>;
|
|
5
|
+
handle(params: Record<string, any>, ctx: MCPContext): Promise<any>;
|
|
72
6
|
}
|