@andrebuzeli/git-mcp 10.0.0 → 10.0.2

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.
Files changed (125) hide show
  1. package/dist/index.js +28 -3
  2. package/dist/prompts/gitPrompts.d.ts +1 -22
  3. package/dist/prompts/gitPrompts.js +58 -179
  4. package/dist/server.js +11 -6
  5. package/dist/tools/gitAnalytics.d.ts +28 -0
  6. package/dist/tools/gitAnalytics.js +28 -0
  7. package/dist/tools/gitArchive.d.ts +37 -0
  8. package/dist/tools/gitArchive.js +37 -0
  9. package/dist/tools/gitBackup.d.ts +32 -0
  10. package/dist/tools/gitBackup.js +32 -0
  11. package/dist/tools/gitBranches.d.ts +48 -0
  12. package/dist/tools/gitBranches.js +48 -0
  13. package/dist/tools/gitConfig.d.ts +36 -0
  14. package/dist/tools/gitConfig.js +36 -0
  15. package/dist/tools/gitFiles.d.ts +51 -0
  16. package/dist/tools/gitFiles.js +49 -0
  17. package/dist/tools/gitFix.tool.d.ts +23 -0
  18. package/dist/tools/gitFix.tool.js +23 -0
  19. package/dist/tools/gitHistory.d.ts +47 -0
  20. package/dist/tools/gitHistory.js +45 -0
  21. package/dist/tools/gitIgnore.d.ts +35 -0
  22. package/dist/tools/gitIgnore.js +33 -0
  23. package/dist/tools/gitIssues.d.ts +78 -0
  24. package/dist/tools/gitIssues.js +74 -0
  25. package/dist/tools/gitMonitor.d.ts +24 -0
  26. package/dist/tools/gitMonitor.js +24 -0
  27. package/dist/tools/gitPush.d.ts +5 -0
  28. package/dist/tools/gitPush.js +7 -1
  29. package/dist/tools/gitSync.d.ts +24 -0
  30. package/dist/tools/gitSync.js +130 -42
  31. package/dist/tools/gitUpdate.d.ts +46 -0
  32. package/dist/tools/gitUpdate.js +44 -0
  33. package/dist/tools/gitUpload.d.ts +31 -0
  34. package/dist/tools/gitUpload.js +46 -5
  35. package/dist/tools/gitWorkflow.d.ts +103 -0
  36. package/dist/tools/gitWorkflow.js +130 -3
  37. package/dist/types.d.ts +1 -0
  38. package/dist/utils/agentHelpers.d.ts +11 -0
  39. package/dist/utils/agentHelpers.js +41 -0
  40. package/dist/utils/contextDetector.d.ts +0 -0
  41. package/dist/utils/contextDetector.js +1 -0
  42. package/dist/utils/gitAdapter.d.ts +2 -2
  43. package/dist/utils/gitAdapter.js +4 -4
  44. package/package.json +1 -1
  45. package/dist/.tsbuildinfo +0 -1
  46. package/dist/config.d.ts.map +0 -1
  47. package/dist/config.js.map +0 -1
  48. package/dist/index.d.ts.map +0 -1
  49. package/dist/index.js.map +0 -1
  50. package/dist/prompts/gitPrompts.d.ts.map +0 -1
  51. package/dist/prompts/gitPrompts.js.map +0 -1
  52. package/dist/providers/giteaProvider.d.ts.map +0 -1
  53. package/dist/providers/giteaProvider.js.map +0 -1
  54. package/dist/providers/githubProvider.d.ts.map +0 -1
  55. package/dist/providers/githubProvider.js.map +0 -1
  56. package/dist/providers/providerManager.d.ts.map +0 -1
  57. package/dist/providers/providerManager.js.map +0 -1
  58. package/dist/resources/toolsGuide.d.ts.map +0 -1
  59. package/dist/resources/toolsGuide.js.map +0 -1
  60. package/dist/server.d.ts.map +0 -1
  61. package/dist/server.js.map +0 -1
  62. package/dist/tools/gitAnalytics.d.ts.map +0 -1
  63. package/dist/tools/gitAnalytics.js.map +0 -1
  64. package/dist/tools/gitArchive.d.ts.map +0 -1
  65. package/dist/tools/gitArchive.js.map +0 -1
  66. package/dist/tools/gitBackup.d.ts.map +0 -1
  67. package/dist/tools/gitBackup.js.map +0 -1
  68. package/dist/tools/gitBranches.d.ts.map +0 -1
  69. package/dist/tools/gitBranches.js.map +0 -1
  70. package/dist/tools/gitChangelog.d.ts.map +0 -1
  71. package/dist/tools/gitChangelog.js.map +0 -1
  72. package/dist/tools/gitConfig.d.ts.map +0 -1
  73. package/dist/tools/gitConfig.js.map +0 -1
  74. package/dist/tools/gitFiles.d.ts.map +0 -1
  75. package/dist/tools/gitFiles.js.map +0 -1
  76. package/dist/tools/gitFix.d.ts.map +0 -1
  77. package/dist/tools/gitFix.js.map +0 -1
  78. package/dist/tools/gitFix.tool.d.ts.map +0 -1
  79. package/dist/tools/gitFix.tool.js.map +0 -1
  80. package/dist/tools/gitHistory.d.ts.map +0 -1
  81. package/dist/tools/gitHistory.js.map +0 -1
  82. package/dist/tools/gitIgnore.d.ts.map +0 -1
  83. package/dist/tools/gitIgnore.js.map +0 -1
  84. package/dist/tools/gitIssues.d.ts.map +0 -1
  85. package/dist/tools/gitIssues.js.map +0 -1
  86. package/dist/tools/gitLog.d.ts.map +0 -1
  87. package/dist/tools/gitLog.js.map +0 -1
  88. package/dist/tools/gitMonitor.d.ts.map +0 -1
  89. package/dist/tools/gitMonitor.js.map +0 -1
  90. package/dist/tools/gitPackages.d.ts.map +0 -1
  91. package/dist/tools/gitPackages.js.map +0 -1
  92. package/dist/tools/gitPulls.d.ts.map +0 -1
  93. package/dist/tools/gitPulls.js.map +0 -1
  94. package/dist/tools/gitPush.d.ts.map +0 -1
  95. package/dist/tools/gitPush.js.map +0 -1
  96. package/dist/tools/gitRelease.d.ts.map +0 -1
  97. package/dist/tools/gitRelease.js.map +0 -1
  98. package/dist/tools/gitRemote.d.ts.map +0 -1
  99. package/dist/tools/gitRemote.js.map +0 -1
  100. package/dist/tools/gitReset.d.ts.map +0 -1
  101. package/dist/tools/gitReset.js.map +0 -1
  102. package/dist/tools/gitStash.d.ts.map +0 -1
  103. package/dist/tools/gitStash.js.map +0 -1
  104. package/dist/tools/gitSync.d.ts.map +0 -1
  105. package/dist/tools/gitSync.js.map +0 -1
  106. package/dist/tools/gitTags.d.ts.map +0 -1
  107. package/dist/tools/gitTags.js.map +0 -1
  108. package/dist/tools/gitUpdate.d.ts.map +0 -1
  109. package/dist/tools/gitUpdate.js.map +0 -1
  110. package/dist/tools/gitUpload.d.ts.map +0 -1
  111. package/dist/tools/gitUpload.js.map +0 -1
  112. package/dist/tools/gitWorkflow.d.ts.map +0 -1
  113. package/dist/tools/gitWorkflow.js.map +0 -1
  114. package/dist/types.d.ts.map +0 -1
  115. package/dist/types.js.map +0 -1
  116. package/dist/utils/apiHelpers.d.ts.map +0 -1
  117. package/dist/utils/apiHelpers.js.map +0 -1
  118. package/dist/utils/errors.d.ts.map +0 -1
  119. package/dist/utils/errors.js.map +0 -1
  120. package/dist/utils/gitAdapter.d.ts.map +0 -1
  121. package/dist/utils/gitAdapter.js.map +0 -1
  122. package/dist/utils/repoHelpers.d.ts.map +0 -1
  123. package/dist/utils/repoHelpers.js.map +0 -1
  124. package/dist/utils/safetyController.d.ts.map +0 -1
  125. package/dist/utils/safetyController.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
3
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
- import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
4
+ import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
5
5
  import { ProviderManager } from './providers/providerManager.js';
6
6
  import { loadMCPConfig } from './config.js';
7
7
  import { IsomorphicGitAdapter } from './utils/gitAdapter.js';
@@ -27,6 +27,7 @@ import { GitUpdateTool } from './tools/gitUpdate.js';
27
27
  import { GitHistoryTool } from './tools/gitHistory.js';
28
28
  import { GitFixTool } from './tools/gitFix.tool.js';
29
29
  import { GitIgnoreTool } from './tools/gitIgnore.js';
30
+ import { GIT_PROMPTS } from './prompts/gitPrompts.js';
30
31
  import TOOLS_GUIDE from './resources/toolsGuide.js';
31
32
  async function main() {
32
33
  // Load optional mcp.json configuration (will populate process.env if values present)
@@ -68,11 +69,12 @@ async function main() {
68
69
  if (process.env.DEBUG) {
69
70
  console.error(`Registered ${tools.length} Git tools`);
70
71
  console.error(`Registered ${resources.length} resource(s)`);
72
+ console.error(`Registered ${GIT_PROMPTS.length} prompt(s)`);
71
73
  }
72
74
  // Create MCP Server with STDIO transport
73
75
  const server = new Server({
74
76
  name: '@andrebuzeli/git-mcp',
75
- version: '7.3.2',
77
+ version: '10.0.1',
76
78
  });
77
79
  // Register tool list handler
78
80
  server.setRequestHandler(ListToolsRequestSchema, async () => {
@@ -146,7 +148,29 @@ async function main() {
146
148
  ],
147
149
  };
148
150
  });
149
- // Start server with STDIO transport
151
+ // Register prompt list handler
152
+ server.setRequestHandler(ListPromptsRequestSchema, async () => {
153
+ return {
154
+ prompts: GIT_PROMPTS.map(prompt => ({
155
+ name: prompt.name,
156
+ description: prompt.description,
157
+ arguments: prompt.arguments,
158
+ })),
159
+ };
160
+ });
161
+ // Register prompt get handler
162
+ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
163
+ const promptName = request.params.name;
164
+ const prompt = GIT_PROMPTS.find(p => p.name === promptName);
165
+ if (!prompt) {
166
+ throw new Error(`Prompt not found: ${promptName}`);
167
+ }
168
+ const result = await prompt.generate(request.params.arguments ?? {}, { providerManager, gitAdapter });
169
+ return {
170
+ description: result.description,
171
+ messages: result.messages,
172
+ };
173
+ });
150
174
  const transport = new StdioServerTransport();
151
175
  await server.connect(transport);
152
176
  // Only log in debug mode
@@ -154,6 +178,7 @@ async function main() {
154
178
  console.error(`✅ git-mcp MCP server running via STDIO`);
155
179
  console.error(`Tools: ${tools.length} registered`);
156
180
  console.error(`Resources: ${resources.length} registered`);
181
+ console.error(`Prompts: ${GIT_PROMPTS.length} registered`);
157
182
  }
158
183
  }
159
184
  main().catch(err => {
@@ -26,11 +26,6 @@ export declare class GitUpdatePrompt implements Prompt {
26
26
  name: string;
27
27
  title: string;
28
28
  description: string;
29
- arguments: {
30
- name: string;
31
- description: string;
32
- required: boolean;
33
- }[];
34
29
  generate(args: Record<string, any>, ctx: MCPContext): Promise<{
35
30
  description: string;
36
31
  messages: {
@@ -41,19 +36,13 @@ export declare class GitUpdatePrompt implements Prompt {
41
36
  };
42
37
  }[];
43
38
  }>;
44
- }
45
- /**
39
+ } /**
46
40
  * /gitfix - Fix repository configuration
47
41
  */
48
42
  export declare class GitFixPrompt implements Prompt {
49
43
  name: string;
50
44
  title: string;
51
45
  description: string;
52
- arguments: {
53
- name: string;
54
- description: string;
55
- required: boolean;
56
- }[];
57
46
  generate(args: Record<string, any>, ctx: MCPContext): Promise<{
58
47
  description: string;
59
48
  messages: {
@@ -72,11 +61,6 @@ export declare class GitLogPrompt implements Prompt {
72
61
  name: string;
73
62
  title: string;
74
63
  description: string;
75
- arguments: {
76
- name: string;
77
- description: string;
78
- required: boolean;
79
- }[];
80
64
  generate(args: Record<string, any>, ctx: MCPContext): Promise<{
81
65
  description: string;
82
66
  messages: {
@@ -95,11 +79,6 @@ export declare class GitReleasePrompt implements Prompt {
95
79
  name: string;
96
80
  title: string;
97
81
  description: string;
98
- arguments: {
99
- name: string;
100
- description: string;
101
- required: boolean;
102
- }[];
103
82
  generate(args: Record<string, any>, ctx: MCPContext): Promise<{
104
83
  description: string;
105
84
  messages: {
@@ -1,4 +1,3 @@
1
- import { getRepoInfo } from '../utils/repoHelpers.js';
2
1
  /**
3
2
  * /gitupdate - Complete update workflow with remote traceability
4
3
  */
@@ -7,31 +6,10 @@ export class GitUpdatePrompt {
7
6
  this.name = "gitupdate";
8
7
  this.title = "Git Update - Complete Workflow";
9
8
  this.description = "Execute complete Git update (add, commit, push) with full remote traceability via issues";
10
- this.arguments = [
11
- {
12
- name: "projectPath",
13
- description: "Absolute path to the repository (REQUIRED)",
14
- required: true
15
- }
16
- ];
17
9
  }
18
10
  async generate(args, ctx) {
19
- const projectPath = args.projectPath;
20
- if (!projectPath) {
21
- throw new Error('projectPath is required');
22
- }
23
- // Get current status to generate context
24
- const status = await ctx.gitAdapter.status(projectPath);
25
- const repoInfo = getRepoInfo(projectPath);
26
- const filesChanged = [
27
- ...status.modified,
28
- ...status.created,
29
- ...status.deleted,
30
- ...status.renamed.map((r) => `${r.from} → ${r.to}`)
31
- ];
32
- const changesSummary = filesChanged.length > 0
33
- ? `\n\nFiles to be committed:\n${filesChanged.map(f => `- ${f}`).join('\n')}`
34
- : '\n\nNo changes detected.';
11
+ // PROMPT instrui o AI AGENT - não detecta nada
12
+ // AI AGENT é responsável por detectar workspace e passar projectPath obrigatório
35
13
  return {
36
14
  description: "Git update workflow with remote traceability",
37
15
  messages: [
@@ -39,33 +17,27 @@ export class GitUpdatePrompt {
39
17
  role: "user",
40
18
  content: {
41
19
  type: "text",
42
- text: `Execute git-update tool for repository: ${repoInfo.repoName}
43
- Project path: ${projectPath}
44
- Current branch: ${status.current || 'unknown'}
45
- ${changesSummary}
20
+ text: `Execute the git-update tool to update the current project.
46
21
 
47
- Use the git-update tool with these exact parameters:
48
- {
49
- "projectPath": "${projectPath}",
50
- "message": "Generate appropriate conventional commit message based on the changes above",
51
- "files": ["."]
52
- }
22
+ You must call the git-update tool with:
23
+ - projectPath: (REQUIRED) Detect the user's current workspace folder path
24
+ - message: (optional) Generate appropriate conventional commit message
25
+ - files: (optional) Default is ["."]
53
26
 
54
27
  The tool will automatically:
55
28
  1. Stage all changes
56
- 2. Create commit with the message
57
- 3. Push to GitHub and Gitea with force
58
- 4. Create traceability issues on both providers with change details
59
- 5. Return complete tracking report
29
+ 2. Create commit
30
+ 3. Push to GitHub and Gitea
31
+ 4. Create traceability issues
32
+ 5. Return tracking report
60
33
 
61
- Execute the tool now without asking for confirmation.`
34
+ Call the tool now with the workspace path you detect from context.`
62
35
  }
63
36
  }
64
37
  ]
65
38
  };
66
39
  }
67
- }
68
- /**
40
+ } /**
69
41
  * /gitfix - Fix repository configuration
70
42
  */
71
43
  export class GitFixPrompt {
@@ -73,24 +45,9 @@ export class GitFixPrompt {
73
45
  this.name = "gitfix";
74
46
  this.title = "Git Fix - Repository Configuration";
75
47
  this.description = "Automatically fix and configure Git repository for dual-provider system";
76
- this.arguments = [
77
- {
78
- name: "projectPath",
79
- description: "Absolute path to the repository (REQUIRED)",
80
- required: true
81
- }
82
- ];
83
48
  }
84
49
  async generate(args, ctx) {
85
- const projectPath = args.projectPath;
86
- if (!projectPath) {
87
- throw new Error('projectPath is required');
88
- }
89
- const remotes = await ctx.gitAdapter.listRemotes(projectPath);
90
- const repoInfo = getRepoInfo(projectPath);
91
- const remotesInfo = remotes.length > 0
92
- ? `\n\nCurrent remotes:\n${remotes.map(r => `- ${r.name}: ${r.url}`).join('\n')}`
93
- : '\n\nNo remotes configured.';
50
+ // PROMPT instrui o AI AGENT - não detecta nada
94
51
  return {
95
52
  description: "Fix Git repository configuration",
96
53
  messages: [
@@ -98,27 +55,20 @@ export class GitFixPrompt {
98
55
  role: "user",
99
56
  content: {
100
57
  type: "text",
101
- text: `Execute git-fix tool for repository: ${repoInfo.repoName}
102
- Project path: ${projectPath}
103
- ${remotesInfo}
58
+ text: `Execute the git-fix tool to fix Git repository configuration.
104
59
 
105
- Use the git-fix tool with these exact parameters:
106
- {
107
- "projectPath": "${projectPath}",
108
- "autoDetect": true
109
- }
60
+ You must call the git-fix tool with:
61
+ - projectPath: (REQUIRED) Detect the user's current workspace folder path
62
+ - autoDetect: true (optional)
110
63
 
111
64
  The tool will automatically:
112
65
  1. Detect existing GitHub/Gitea remotes from URLs
113
- 2. Remove broken/duplicate remotes (origin, github, gitea)
114
- 3. Configure clean dual-provider setup:
115
- - github → GitHub repository
116
- - gitea → Gitea repository
117
- - origin → Dual-push (pushes to both simultaneously)
66
+ 2. Remove broken/duplicate remotes
67
+ 3. Configure dual-provider setup (github, gitea, origin)
118
68
  4. Create .gitignore if missing
119
- 5. Return before/after remote configuration
69
+ 5. Return configuration report
120
70
 
121
- Execute the tool now without asking for confirmation.`
71
+ Call the tool now with the workspace path you detect from context.`
122
72
  }
123
73
  }
124
74
  ]
@@ -133,23 +83,9 @@ export class GitLogPrompt {
133
83
  this.name = "gitlog";
134
84
  this.title = "Git Log - Generate Changelog";
135
85
  this.description = "Generate Keep a Changelog format changelog and commit it to the repository";
136
- this.arguments = [
137
- {
138
- name: "projectPath",
139
- description: "Absolute path to the repository (REQUIRED)",
140
- required: true
141
- }
142
- ];
143
86
  }
144
87
  async generate(args, ctx) {
145
- const projectPath = args.projectPath;
146
- if (!projectPath) {
147
- throw new Error('projectPath is required');
148
- }
149
- const repoInfo = getRepoInfo(projectPath);
150
- // Get recent commits for context
151
- const log = await ctx.gitAdapter.log(projectPath, { maxCount: 20 });
152
- const logSummary = log.slice(0, 5).map((commit) => `- ${commit.oid.substring(0, 7)} ${commit.commit.message.split('\n')[0]}`).join('\n');
88
+ // PROMPT instrui o AI AGENT - não detecta nada
153
89
  return {
154
90
  description: "Generate changelog in repository",
155
91
  messages: [
@@ -157,30 +93,22 @@ export class GitLogPrompt {
157
93
  role: "user",
158
94
  content: {
159
95
  type: "text",
160
- text: `Generate changelog for repository: ${repoInfo.repoName}
161
- Project path: ${projectPath}
162
-
163
- Recent commits:
164
- ${logSummary}
96
+ text: `Execute the git-history tool to generate a changelog.
165
97
 
166
- Use the git-history tool with these exact parameters:
167
- {
168
- "projectPath": "${projectPath}",
169
- "action": "generate_changelog",
170
- "outputFile": "CHANGELOG.md",
171
- "since": "last-tag",
172
- "format": "keepachangelog"
173
- }
98
+ You must call the git-history tool with:
99
+ - projectPath: (REQUIRED) Detect the user's current workspace folder path
100
+ - action: "generate_changelog" (REQUIRED)
101
+ - outputFile: "CHANGELOG.md" (optional)
102
+ - since: "last-tag" (optional)
103
+ - format: "keepachangelog" (optional)
174
104
 
175
105
  The tool will automatically:
176
- 1. Analyze all commits since last tag/release
177
- 2. Group changes by type (Added, Fixed, Changed, Removed, etc.)
178
- 3. Generate Keep a Changelog formatted CHANGELOG.md
179
- 4. Save in repository root
180
- 5. Commit with message: "docs: Update CHANGELOG.md"
181
- 6. Push to GitHub and Gitea
106
+ 1. Analyze commits since last tag
107
+ 2. Generate Keep a Changelog format
108
+ 3. Save to repository
109
+ 4. Commit and push
182
110
 
183
- Execute the tool now without asking for confirmation.`
111
+ Call the tool now with the workspace path you detect from context.`
184
112
  }
185
113
  }
186
114
  ]
@@ -195,35 +123,9 @@ export class GitReleasePrompt {
195
123
  this.name = "gitrelease";
196
124
  this.title = "Git Release - Create Release";
197
125
  this.description = "Create new release with automatic or manual version and changelog (always uses force)";
198
- this.arguments = [
199
- {
200
- name: "projectPath",
201
- description: "Absolute path to the repository (REQUIRED)",
202
- required: true
203
- },
204
- {
205
- name: "version",
206
- description: "Optional version (e.g., '1.5.0'). If not provided, auto-detects from commits.",
207
- required: false
208
- }
209
- ];
210
126
  }
211
127
  async generate(args, ctx) {
212
- const projectPath = args.projectPath;
213
- if (!projectPath) {
214
- throw new Error('projectPath is required');
215
- }
216
- const userVersion = args.version; // Manual version from user chat
217
- const repoInfo = getRepoInfo(projectPath);
218
- // Get current tags to provide context
219
- const tags = await ctx.gitAdapter.listTags(projectPath);
220
- const latestTag = tags.length > 0 ? tags[0] : 'No tags yet';
221
- const versionStrategy = userVersion
222
- ? `Use the specified version: v${userVersion}`
223
- : `Analyze commits since last tag for automatic semver bump:
224
- - breaking changes (BREAKING CHANGE:) → major bump
225
- - feat: → minor bump
226
- - fix: → patch bump`;
128
+ // PROMPT instrui o AI AGENT - não detecta nada
227
129
  return {
228
130
  description: "Create new release with changelog",
229
131
  messages: [
@@ -231,58 +133,35 @@ export class GitReleasePrompt {
231
133
  role: "user",
232
134
  content: {
233
135
  type: "text",
234
- text: `Create release for repository: ${repoInfo.repoName}
235
- Project path: ${projectPath}
236
- Latest tag: ${latestTag}
237
- ${userVersion ? `Requested version: v${userVersion}` : 'Version: Auto-detect from commits'}
136
+ text: `Execute the release workflow to create a new version.
238
137
 
239
- Execute the following workflow automatically:
138
+ Workflow steps:
240
139
 
241
- STEP 1: Generate changelog
242
- Use git-history tool:
243
- {
244
- "projectPath": "${projectPath}",
245
- "action": "generate_changelog",
246
- "since": "last-tag",
247
- "format": "keepachangelog"
248
- }
140
+ 1. Generate changelog using git-history tool:
141
+ - projectPath: (REQUIRED) Detect workspace
142
+ - action: "generate_changelog"
249
143
 
250
- STEP 2: Determine version
251
- ${versionStrategy}
144
+ 2. Determine next version from commits (semver)
252
145
 
253
- STEP 3: Create tag with FORCE
254
- Use git-tags tool:
255
- {
256
- "projectPath": "${projectPath}",
257
- "action": "create",
258
- "tagName": "v{next-version}",
259
- "message": "Release v{next-version}",
260
- "force": true
261
- }
146
+ 3. Create tag using git-tags tool:
147
+ - projectPath: (REQUIRED) Detect workspace
148
+ - action: "create"
149
+ - tagName: Next version
150
+ - force: true
262
151
 
263
- STEP 4: Push tag with FORCE
264
- Use git-tags tool:
265
- {
266
- "projectPath": "${projectPath}",
267
- "action": "push",
268
- "tagName": "v{next-version}",
269
- "force": true
270
- }
271
-
272
- STEP 5: Create releases on GitHub and Gitea
273
- Use git-release tool:
274
- {
275
- "projectPath": "${projectPath}",
276
- "action": "create",
277
- "tagName": "v{next-version}",
278
- "name": "Release v{next-version}",
279
- "body": "{changelog-content-from-step1}",
280
- "force": true
281
- }
152
+ 4. Push tag using git-tags tool:
153
+ - projectPath: (REQUIRED) Detect workspace
154
+ - action: "push"
155
+ - tagName: Same version
156
+ - force: true
282
157
 
283
- This will create releases on both GitHub and Gitea simultaneously with force flag.
158
+ 5. Create releases using git-release tool:
159
+ - projectPath: (REQUIRED) Detect workspace
160
+ - action: "create"
161
+ - tagName: Same version
162
+ - body: Changelog content
284
163
 
285
- Execute the entire workflow now without asking for confirmation.`
164
+ Execute all steps with the workspace path you detect from context.`
286
165
  }
287
166
  }
288
167
  ]
package/dist/server.js CHANGED
@@ -1,9 +1,11 @@
1
1
  import express from 'express';
2
2
  import bodyParser from 'body-parser';
3
+ import Ajv from 'ajv';
3
4
  import { createErrorResponse } from './utils/errors.js';
4
5
  export function createServer(opts) {
5
6
  const app = express();
6
7
  app.use(bodyParser.json({ limit: '1mb' }));
8
+ const ajv = new Ajv({ allErrors: true, removeAdditional: false });
7
9
  const toolRegistry = new Map();
8
10
  for (const t of opts.tools)
9
11
  toolRegistry.set(t.name, t);
@@ -47,13 +49,16 @@ export function createServer(opts) {
47
49
  const t = toolRegistry.get(tool);
48
50
  if (!t)
49
51
  return res.status(404).json(createErrorResponse('TOOL_NOT_FOUND', `Tool not found: ${tool}`));
50
- // Enforce projectPath presence for all tool calls to avoid agents calling tools without context
51
- // Many tools require projectPath; centralize the check so callers receive a clear validation error.
52
- if (!params || !params.projectPath) {
53
- return res.status(400).json(createErrorResponse('VALIDATION_ERROR', 'projectPath is required for all tool calls'));
54
- }
55
52
  try {
56
- // TODO: validate params via JSON Schema
53
+ // Validate params via JSON Schema if available
54
+ if (t.inputSchema) {
55
+ const validate = ajv.compile(t.inputSchema);
56
+ const valid = validate(params ?? {});
57
+ if (!valid) {
58
+ const errors = validate.errors?.map(e => `${e.instancePath} ${e.message}`).join(', ') || 'Invalid parameters';
59
+ return res.status(400).json(createErrorResponse('VALIDATION_ERROR', `Invalid parameters: ${errors}`));
60
+ }
61
+ }
57
62
  const result = await t.handle(params ?? {}, { providerManager: opts.providerManager, gitAdapter: opts.gitAdapter });
58
63
  res.json({ success: true, result });
59
64
  }
@@ -2,5 +2,33 @@ import { Tool, MCPContext } from '../types.js';
2
2
  export declare class GitAnalyticsTool implements Tool {
3
3
  name: string;
4
4
  description: string;
5
+ inputSchema: {
6
+ type: "object";
7
+ properties: {
8
+ projectPath: {
9
+ type: string;
10
+ description: string;
11
+ };
12
+ action: {
13
+ type: string;
14
+ enum: string[];
15
+ description: string;
16
+ };
17
+ limit: {
18
+ type: string;
19
+ description: string;
20
+ };
21
+ since: {
22
+ type: string;
23
+ description: string;
24
+ };
25
+ until: {
26
+ type: string;
27
+ description: string;
28
+ };
29
+ };
30
+ required: string[];
31
+ additionalProperties: boolean;
32
+ };
5
33
  handle(params: Record<string, any>, ctx: MCPContext): Promise<any>;
6
34
  }
@@ -5,6 +5,34 @@ export class GitAnalyticsTool {
5
5
  constructor() {
6
6
  this.name = 'git-analytics';
7
7
  this.description = 'Repository analytics and statistics - automatic dual-provider execution using GitHub and Gitea APIs';
8
+ this.inputSchema = {
9
+ type: "object",
10
+ properties: {
11
+ projectPath: {
12
+ type: "string",
13
+ description: "Absolute path to the project/repository (REQUIRED)"
14
+ },
15
+ action: {
16
+ type: "string",
17
+ enum: ["stats", "commits", "contributors"],
18
+ description: "Action to perform: stats (get repo statistics), commits (get commit history), contributors (get contributor stats)"
19
+ },
20
+ limit: {
21
+ type: "number",
22
+ description: "Maximum number of commits to return (optional for commits action, default: 100)"
23
+ },
24
+ since: {
25
+ type: "string",
26
+ description: "Start date for commits/contributors query (ISO 8601 format, optional)"
27
+ },
28
+ until: {
29
+ type: "string",
30
+ description: "End date for commits/contributors query (ISO 8601 format, optional)"
31
+ }
32
+ },
33
+ required: ["projectPath", "action"],
34
+ additionalProperties: true
35
+ };
8
36
  }
9
37
  async handle(params, ctx) {
10
38
  params = normalizeToolParams(params);
@@ -2,6 +2,43 @@ import { Tool, MCPContext } from '../types.js';
2
2
  export declare class GitArchiveTool implements Tool {
3
3
  name: string;
4
4
  description: string;
5
+ inputSchema: {
6
+ type: "object";
7
+ properties: {
8
+ projectPath: {
9
+ type: string;
10
+ description: string;
11
+ };
12
+ action: {
13
+ type: string;
14
+ enum: string[];
15
+ description: string;
16
+ };
17
+ archiveName: {
18
+ type: string;
19
+ description: string;
20
+ };
21
+ outputPath: {
22
+ type: string;
23
+ description: string;
24
+ };
25
+ format: {
26
+ type: string;
27
+ enum: string[];
28
+ description: string;
29
+ };
30
+ ref: {
31
+ type: string;
32
+ description: string;
33
+ };
34
+ archivePath: {
35
+ type: string;
36
+ description: string;
37
+ };
38
+ };
39
+ required: string[];
40
+ additionalProperties: boolean;
41
+ };
5
42
  handle(params: Record<string, any>, ctx: MCPContext): Promise<{
6
43
  success: boolean;
7
44
  archivePath: string;
@@ -5,6 +5,43 @@ export class GitArchiveTool {
5
5
  constructor() {
6
6
  this.name = 'git-archive';
7
7
  this.description = 'Repository archive operations';
8
+ this.inputSchema = {
9
+ type: "object",
10
+ properties: {
11
+ projectPath: {
12
+ type: "string",
13
+ description: "Absolute path to the project/repository (REQUIRED)"
14
+ },
15
+ action: {
16
+ type: "string",
17
+ enum: ["create", "list", "verify", "extract"],
18
+ description: "Action to perform: create (create archive), list (list archives), verify (verify archive), extract (extract archive)"
19
+ },
20
+ archiveName: {
21
+ type: "string",
22
+ description: "Name for the archive file (optional for create, default: timestamp-based)"
23
+ },
24
+ outputPath: {
25
+ type: "string",
26
+ description: "Output directory for archives (optional for create, default: .git-archives)"
27
+ },
28
+ format: {
29
+ type: "string",
30
+ enum: ["tar", "tar.gz", "zip"],
31
+ description: "Archive format (optional for create, default: tar.gz)"
32
+ },
33
+ ref: {
34
+ type: "string",
35
+ description: "Git reference to archive (optional for create, default: HEAD)"
36
+ },
37
+ archivePath: {
38
+ type: "string",
39
+ description: "Path to archive file (required for verify/extract)"
40
+ }
41
+ },
42
+ required: ["projectPath", "action"],
43
+ additionalProperties: true
44
+ };
8
45
  }
9
46
  async handle(params, ctx) {
10
47
  const action = params.action;