@andrebuzeli/git-mcp 10.0.0 → 10.0.1

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 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 => {
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);
@@ -53,7 +55,15 @@ export function createServer(opts) {
53
55
  return res.status(400).json(createErrorResponse('VALIDATION_ERROR', 'projectPath is required for all tool calls'));
54
56
  }
55
57
  try {
56
- // TODO: validate params via JSON Schema
58
+ // Validate params via JSON Schema if available
59
+ if (t.inputSchema) {
60
+ const validate = ajv.compile(t.inputSchema);
61
+ const valid = validate(params ?? {});
62
+ if (!valid) {
63
+ const errors = validate.errors?.map(e => `${e.instancePath} ${e.message}`).join(', ') || 'Invalid parameters';
64
+ return res.status(400).json(createErrorResponse('VALIDATION_ERROR', `Invalid parameters: ${errors}`));
65
+ }
66
+ }
57
67
  const result = await t.handle(params ?? {}, { providerManager: opts.providerManager, gitAdapter: opts.gitAdapter });
58
68
  res.json({ success: true, result });
59
69
  }
@@ -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;
@@ -2,6 +2,38 @@ import { Tool, MCPContext } from '../types.js';
2
2
  export declare class GitBackupTool 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
+ backupPath: {
18
+ type: string;
19
+ description: string;
20
+ };
21
+ compress: {
22
+ type: string;
23
+ description: string;
24
+ };
25
+ confirm: {
26
+ type: string;
27
+ description: string;
28
+ };
29
+ name: {
30
+ type: string;
31
+ description: string;
32
+ };
33
+ };
34
+ required: string[];
35
+ additionalProperties: boolean;
36
+ };
5
37
  handle(params: Record<string, any>, ctx: MCPContext): Promise<{
6
38
  success: boolean;
7
39
  backupPath: string;
@@ -6,6 +6,38 @@ export class GitBackupTool {
6
6
  constructor() {
7
7
  this.name = 'git-backup';
8
8
  this.description = 'Repository backup and restore operations';
9
+ this.inputSchema = {
10
+ type: "object",
11
+ properties: {
12
+ projectPath: {
13
+ type: "string",
14
+ description: "Absolute path to the project/repository (REQUIRED)"
15
+ },
16
+ action: {
17
+ type: "string",
18
+ enum: ["backup", "list", "verify", "restore"],
19
+ description: "Action to perform: backup (create backup), list (list backups), verify (verify backup), restore (restore from backup)"
20
+ },
21
+ backupPath: {
22
+ type: "string",
23
+ description: "Path to backup file (required for restore/verify)"
24
+ },
25
+ compress: {
26
+ type: "boolean",
27
+ description: "Compress backup (optional for backup, default: true)"
28
+ },
29
+ confirm: {
30
+ type: "boolean",
31
+ description: "Confirm destructive operations (optional for restore)"
32
+ },
33
+ name: {
34
+ type: "string",
35
+ description: "Backup name (optional for backup)"
36
+ }
37
+ },
38
+ required: ["projectPath", "action"],
39
+ additionalProperties: true
40
+ };
9
41
  }
10
42
  async handle(params, ctx) {
11
43
  const action = params.action;
@@ -2,5 +2,53 @@ import { Tool, MCPContext } from '../types.js';
2
2
  export declare class GitBranchesTool 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
+ branchName: {
18
+ type: string;
19
+ description: string;
20
+ };
21
+ checkout: {
22
+ type: string;
23
+ description: string;
24
+ };
25
+ sourceBranch: {
26
+ type: string;
27
+ description: string;
28
+ };
29
+ confirm: {
30
+ type: string;
31
+ description: string;
32
+ };
33
+ force: {
34
+ type: string;
35
+ description: string;
36
+ };
37
+ targetBranch: {
38
+ type: string;
39
+ description: string;
40
+ };
41
+ baseBranch: {
42
+ type: string;
43
+ description: string;
44
+ };
45
+ compareBranch: {
46
+ type: string;
47
+ description: string;
48
+ };
49
+ };
50
+ required: string[];
51
+ additionalProperties: boolean;
52
+ };
5
53
  handle(params: Record<string, any>, ctx: MCPContext): Promise<any>;
6
54
  }
@@ -7,6 +7,54 @@ export class GitBranchesTool {
7
7
  constructor() {
8
8
  this.name = 'git-branches';
9
9
  this.description = 'Branch management operations - automatic dual-provider execution for remote queries';
10
+ this.inputSchema = {
11
+ type: "object",
12
+ properties: {
13
+ projectPath: {
14
+ type: "string",
15
+ description: "Absolute path to the project/repository (REQUIRED)"
16
+ },
17
+ action: {
18
+ type: "string",
19
+ enum: ["create", "list", "get", "delete", "merge", "compare"],
20
+ description: "Action to perform: create (create branch), list (list branches), get (get branch info), delete (delete branch), merge (merge branches), compare (compare branches)"
21
+ },
22
+ branchName: {
23
+ type: "string",
24
+ description: "Branch name (required for create/get/delete/merge)"
25
+ },
26
+ checkout: {
27
+ type: "boolean",
28
+ description: "Checkout after creating branch (optional for create, default: true)"
29
+ },
30
+ sourceBranch: {
31
+ type: "string",
32
+ description: "Source branch to create from (optional for create)"
33
+ },
34
+ confirm: {
35
+ type: "boolean",
36
+ description: "Confirm destructive operations (optional for delete)"
37
+ },
38
+ force: {
39
+ type: "boolean",
40
+ description: "Force delete branch (optional for delete)"
41
+ },
42
+ targetBranch: {
43
+ type: "string",
44
+ description: "Target branch for merge (optional for merge)"
45
+ },
46
+ baseBranch: {
47
+ type: "string",
48
+ description: "Base branch for comparison (required for compare)"
49
+ },
50
+ compareBranch: {
51
+ type: "string",
52
+ description: "Branch to compare against base (required for compare)"
53
+ }
54
+ },
55
+ required: ["projectPath", "action"],
56
+ additionalProperties: true
57
+ };
10
58
  }
11
59
  async handle(params, ctx) {
12
60
  const action = params.action;
@@ -2,6 +2,42 @@ import { Tool, MCPContext } from '../types.js';
2
2
  export declare class GitConfigTool implements Tool {
3
3
  name: string;
4
4
  description: string;
5
+ inputSchema: {
6
+ type: "object";
7
+ properties: {
8
+ action: {
9
+ type: string;
10
+ enum: string[];
11
+ description: string;
12
+ };
13
+ projectPath: {
14
+ type: string;
15
+ description: string;
16
+ };
17
+ global: {
18
+ type: string;
19
+ description: string;
20
+ };
21
+ system: {
22
+ type: string;
23
+ description: string;
24
+ };
25
+ key: {
26
+ type: string;
27
+ description: string;
28
+ };
29
+ value: {
30
+ type: string;
31
+ description: string;
32
+ };
33
+ showScope: {
34
+ type: string;
35
+ description: string;
36
+ };
37
+ };
38
+ required: string[];
39
+ additionalProperties: boolean;
40
+ };
5
41
  handle(params: Record<string, any>, ctx: MCPContext): Promise<{
6
42
  success: boolean;
7
43
  key: any;
@@ -6,6 +6,42 @@ export class GitConfigTool {
6
6
  constructor() {
7
7
  this.name = 'git-config';
8
8
  this.description = 'Git configuration management - local Git operations';
9
+ this.inputSchema = {
10
+ type: "object",
11
+ properties: {
12
+ action: {
13
+ type: "string",
14
+ enum: ["get", "set", "unset", "list", "show", "edit"],
15
+ description: "Configuration operation to perform"
16
+ },
17
+ projectPath: {
18
+ type: "string",
19
+ description: "Absolute path to the Git repository"
20
+ },
21
+ global: {
22
+ type: "boolean",
23
+ description: "Use global configuration scope (optional, default: false)"
24
+ },
25
+ system: {
26
+ type: "boolean",
27
+ description: "Use system configuration scope (optional, default: false)"
28
+ },
29
+ key: {
30
+ type: "string",
31
+ description: "Configuration key name (e.g., 'user.name', 'user.email') - required for get, set, unset, show"
32
+ },
33
+ value: {
34
+ type: "string",
35
+ description: "Configuration value to set - required for set action"
36
+ },
37
+ showScope: {
38
+ type: "boolean",
39
+ description: "Include configuration scope in show action response (optional, default: false)"
40
+ }
41
+ },
42
+ required: ["projectPath", "action"],
43
+ additionalProperties: true
44
+ };
9
45
  }
10
46
  async handle(params, ctx) {
11
47
  const action = params.action;
@@ -2,6 +2,57 @@ import { Tool } from '../types.js';
2
2
  export declare class GitFilesTool implements Tool {
3
3
  name: string;
4
4
  description: string;
5
+ inputSchema: {
6
+ type: "object";
7
+ properties: {
8
+ action: {
9
+ type: string;
10
+ enum: string[];
11
+ description: string;
12
+ };
13
+ projectPath: {
14
+ type: string;
15
+ description: string;
16
+ };
17
+ filePath: {
18
+ type: string;
19
+ description: string;
20
+ };
21
+ directoryPath: {
22
+ type: string;
23
+ description: string;
24
+ };
25
+ content: {
26
+ type: string;
27
+ description: string;
28
+ };
29
+ comment: {
30
+ type: string;
31
+ description: string;
32
+ };
33
+ patterns: {
34
+ type: string;
35
+ items: {
36
+ type: string;
37
+ };
38
+ description: string;
39
+ };
40
+ searchText: {
41
+ type: string;
42
+ description: string;
43
+ };
44
+ query: {
45
+ type: string;
46
+ description: string;
47
+ };
48
+ searchPath: {
49
+ type: string;
50
+ description: string;
51
+ };
52
+ };
53
+ required: string[];
54
+ additionalProperties: boolean;
55
+ };
5
56
  handle(params: Record<string, any>): Promise<{
6
57
  success: boolean;
7
58
  path: string;
@@ -5,6 +5,55 @@ export class GitFilesTool {
5
5
  constructor() {
6
6
  this.name = 'git-files';
7
7
  this.description = 'Read-only file operations for repositories - local operations only';
8
+ this.inputSchema = {
9
+ type: "object",
10
+ properties: {
11
+ action: {
12
+ type: "string",
13
+ enum: ["read", "list", "create", "update", "delete", "search"],
14
+ description: "File operation to perform"
15
+ },
16
+ projectPath: {
17
+ type: "string",
18
+ description: "Absolute path to the project directory"
19
+ },
20
+ filePath: {
21
+ type: "string",
22
+ description: "Relative path to the file within projectPath - required for read, create, update, delete"
23
+ },
24
+ directoryPath: {
25
+ type: "string",
26
+ description: "Relative path to directory for listing - optional, defaults to projectPath root"
27
+ },
28
+ content: {
29
+ type: "string",
30
+ description: "File content to write - required for create and update actions"
31
+ },
32
+ comment: {
33
+ type: "string",
34
+ description: "Comment to add when appending patterns to .gitignore - optional for add action"
35
+ },
36
+ patterns: {
37
+ type: "array",
38
+ items: { type: "string" },
39
+ description: "Array of file patterns - required for add and remove actions"
40
+ },
41
+ searchText: {
42
+ type: "string",
43
+ description: "Text to search for in files - required for search action"
44
+ },
45
+ query: {
46
+ type: "string",
47
+ description: "Alternative name for searchText - required for search action"
48
+ },
49
+ searchPath: {
50
+ type: "string",
51
+ description: "Relative path to search within - optional for search, defaults to projectPath root"
52
+ }
53
+ },
54
+ required: ["projectPath", "action"],
55
+ additionalProperties: true
56
+ };
8
57
  }
9
58
  async handle(params) {
10
59
  const action = params.action;
@@ -2,6 +2,29 @@ import { Tool } from '../types.js';
2
2
  export declare class GitFixTool 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
+ githubRepo: {
13
+ type: string;
14
+ description: string;
15
+ };
16
+ giteaRepo: {
17
+ type: string;
18
+ description: string;
19
+ };
20
+ autoDetect: {
21
+ type: string;
22
+ description: string;
23
+ };
24
+ };
25
+ required: string[];
26
+ additionalProperties: boolean;
27
+ };
5
28
  handle(args: any): Promise<{
6
29
  content: any[];
7
30
  }>;