@renfeng/ai-code-review 1.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.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +77 -0
  3. package/dist/api/gitlab-api.d.ts +63 -0
  4. package/dist/api/gitlab-api.d.ts.map +1 -0
  5. package/dist/api/gitlab-api.js +218 -0
  6. package/dist/api/gitlab-api.js.map +1 -0
  7. package/dist/bin/index.d.ts +10 -0
  8. package/dist/bin/index.d.ts.map +1 -0
  9. package/dist/bin/index.js +57 -0
  10. package/dist/bin/index.js.map +1 -0
  11. package/dist/config/glab-config.loader.d.ts +14 -0
  12. package/dist/config/glab-config.loader.d.ts.map +1 -0
  13. package/dist/config/glab-config.loader.js +87 -0
  14. package/dist/config/glab-config.loader.js.map +1 -0
  15. package/dist/errors/error-handler.d.ts +45 -0
  16. package/dist/errors/error-handler.d.ts.map +1 -0
  17. package/dist/errors/error-handler.js +134 -0
  18. package/dist/errors/error-handler.js.map +1 -0
  19. package/dist/logging/index.d.ts +2 -0
  20. package/dist/logging/index.d.ts.map +1 -0
  21. package/dist/logging/index.js +2 -0
  22. package/dist/logging/index.js.map +1 -0
  23. package/dist/logging/logger.service.d.ts +34 -0
  24. package/dist/logging/logger.service.d.ts.map +1 -0
  25. package/dist/logging/logger.service.js +91 -0
  26. package/dist/logging/logger.service.js.map +1 -0
  27. package/dist/servers/git-server.d.ts +17 -0
  28. package/dist/servers/git-server.d.ts.map +1 -0
  29. package/dist/servers/git-server.js +73 -0
  30. package/dist/servers/git-server.js.map +1 -0
  31. package/dist/servers/gitlab-server.d.ts +18 -0
  32. package/dist/servers/gitlab-server.d.ts.map +1 -0
  33. package/dist/servers/gitlab-server.js +102 -0
  34. package/dist/servers/gitlab-server.js.map +1 -0
  35. package/dist/services/git-tools.service.d.ts +111 -0
  36. package/dist/services/git-tools.service.d.ts.map +1 -0
  37. package/dist/services/git-tools.service.js +157 -0
  38. package/dist/services/git-tools.service.js.map +1 -0
  39. package/dist/services/review-tools.service.d.ts +77 -0
  40. package/dist/services/review-tools.service.d.ts.map +1 -0
  41. package/dist/services/review-tools.service.js +289 -0
  42. package/dist/services/review-tools.service.js.map +1 -0
  43. package/dist/tools/git-tools.d.ts +8 -0
  44. package/dist/tools/git-tools.d.ts.map +1 -0
  45. package/dist/tools/git-tools.js +161 -0
  46. package/dist/tools/git-tools.js.map +1 -0
  47. package/dist/tools/gitlab-tools.d.ts +8 -0
  48. package/dist/tools/gitlab-tools.d.ts.map +1 -0
  49. package/dist/tools/gitlab-tools.js +155 -0
  50. package/dist/tools/gitlab-tools.js.map +1 -0
  51. package/dist/types.d.ts +80 -0
  52. package/dist/types.d.ts.map +1 -0
  53. package/dist/types.js +7 -0
  54. package/dist/types.js.map +1 -0
  55. package/package.json +49 -0
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Error Handler
3
+ *
4
+ * Provides consistent error handling with retry logic and clear error messages.
5
+ */
6
+ import { Logger } from '../logging/logger.service.js';
7
+ export class MCPError extends Error {
8
+ code;
9
+ details;
10
+ cause;
11
+ constructor(message, code, details, cause) {
12
+ super(message);
13
+ this.code = code;
14
+ this.details = details;
15
+ this.cause = cause;
16
+ this.name = 'MCPError';
17
+ if (Error.captureStackTrace) {
18
+ Error.captureStackTrace(this, MCPError);
19
+ }
20
+ }
21
+ toJSON() {
22
+ return {
23
+ name: this.name, message: this.message, code: this.code,
24
+ details: this.details, cause: this.cause?.message, stack: this.stack,
25
+ };
26
+ }
27
+ }
28
+ export var ErrorCategory;
29
+ (function (ErrorCategory) {
30
+ ErrorCategory["CONFIGURATION"] = "configuration";
31
+ ErrorCategory["VALIDATION"] = "validation";
32
+ ErrorCategory["GIT_OPERATION"] = "git_operation";
33
+ ErrorCategory["API_CALL"] = "api_call";
34
+ ErrorCategory["NETWORK"] = "network";
35
+ ErrorCategory["PERMISSION"] = "permission";
36
+ ErrorCategory["NOT_FOUND"] = "not_found";
37
+ ErrorCategory["INTERNAL"] = "internal";
38
+ })(ErrorCategory || (ErrorCategory = {}));
39
+ export const DEFAULT_RETRY_OPTIONS = {
40
+ maxRetries: 3,
41
+ delayMs: 1000,
42
+ backoffMultiplier: 2,
43
+ };
44
+ export class ErrorHandler {
45
+ static logger = new Logger('ErrorHandler');
46
+ static async withRetry(operation, options = {}) {
47
+ const opts = { ...DEFAULT_RETRY_OPTIONS, ...options };
48
+ let lastError;
49
+ for (let attempt = 0; attempt <= opts.maxRetries; attempt++) {
50
+ try {
51
+ return await operation();
52
+ }
53
+ catch (error) {
54
+ lastError = error instanceof Error ? error : new Error(String(error));
55
+ if (attempt < opts.maxRetries && this.isTransient(lastError)) {
56
+ const delay = opts.delayMs * Math.pow(opts.backoffMultiplier, attempt);
57
+ this.logger.warn(`Operation failed, retrying (attempt ${attempt + 1}/${opts.maxRetries})`, { error: lastError.message, delay, attempt: attempt + 1, maxRetries: opts.maxRetries });
58
+ if (opts.onRetry)
59
+ opts.onRetry(attempt + 1, lastError);
60
+ await this.delay(delay);
61
+ }
62
+ else {
63
+ if (attempt >= opts.maxRetries) {
64
+ this.logger.error(`Operation failed after ${opts.maxRetries} retries`, lastError);
65
+ }
66
+ throw lastError;
67
+ }
68
+ }
69
+ }
70
+ throw lastError || new Error('Operation failed with unknown error');
71
+ }
72
+ static isTransient(error) {
73
+ const message = error.message.toLowerCase();
74
+ const patterns = [
75
+ 'econnrefused', 'econnreset', 'etimedout', 'enotfound', 'enetunreach',
76
+ 'socket hang up', 'network error', 'fetch failed',
77
+ 'rate limit', 'too many requests', '429',
78
+ '503', 'service unavailable', 'gateway timeout', '504',
79
+ 'lock', 'unable to access', 'could not resolve host',
80
+ ];
81
+ return patterns.some(p => message.includes(p));
82
+ }
83
+ static formatError(error) {
84
+ if (error instanceof MCPError) {
85
+ const parts = [`[${error.code}] ${error.message}`];
86
+ if (error.details && Object.keys(error.details).length > 0) {
87
+ parts.push(`Details: ${JSON.stringify(error.details, null, 2)}`);
88
+ }
89
+ if (error.cause)
90
+ parts.push(`Caused by: ${error.cause.message}`);
91
+ return parts.join('\n');
92
+ }
93
+ return error.message;
94
+ }
95
+ static toMCPError(error, code, details) {
96
+ if (error instanceof MCPError)
97
+ return error;
98
+ if (error instanceof Error)
99
+ return new MCPError(error.message, code, details, error);
100
+ return new MCPError(String(error), code, details);
101
+ }
102
+ static async wrap(operation, errorCode, _errorMessage, details) {
103
+ try {
104
+ return await operation();
105
+ }
106
+ catch (error) {
107
+ throw this.toMCPError(error, errorCode, {
108
+ ...details, originalMessage: error instanceof Error ? error.message : String(error),
109
+ });
110
+ }
111
+ }
112
+ static delay(ms) {
113
+ return new Promise(resolve => setTimeout(resolve, ms));
114
+ }
115
+ static configurationError(message, details) {
116
+ return new MCPError(message, ErrorCategory.CONFIGURATION, details);
117
+ }
118
+ static validationError(message, details) {
119
+ return new MCPError(message, ErrorCategory.VALIDATION, details);
120
+ }
121
+ static gitOperationError(message, details, cause) {
122
+ return new MCPError(message, ErrorCategory.GIT_OPERATION, details, cause);
123
+ }
124
+ static apiCallError(message, details, cause) {
125
+ return new MCPError(message, ErrorCategory.API_CALL, details, cause);
126
+ }
127
+ static notFoundError(message, details) {
128
+ return new MCPError(message, ErrorCategory.NOT_FOUND, details);
129
+ }
130
+ static permissionError(message, details) {
131
+ return new MCPError(message, ErrorCategory.PERMISSION, details);
132
+ }
133
+ }
134
+ //# sourceMappingURL=error-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/errors/error-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { Logger, LogLevel, type LogContext } from './logger.service.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/logging/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { Logger, LogLevel } from './logger.service.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/logging/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAmB,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Logger Service
3
+ *
4
+ * Structured logging with appropriate log levels and context.
5
+ * Provides performance timing utilities and debug mode support.
6
+ */
7
+ export declare enum LogLevel {
8
+ DEBUG = 0,
9
+ INFO = 1,
10
+ WARN = 2,
11
+ ERROR = 3
12
+ }
13
+ export interface LogContext {
14
+ operation?: string;
15
+ project?: string;
16
+ mr?: number;
17
+ duration?: number;
18
+ [key: string]: unknown;
19
+ }
20
+ export declare class Logger {
21
+ private readonly context;
22
+ private readonly minLevel;
23
+ constructor(context: string, minLevel?: LogLevel);
24
+ debug(message: string, context?: LogContext): void;
25
+ info(message: string, context?: LogContext): void;
26
+ warn(message: string, context?: LogContext): void;
27
+ error(message: string, error?: Error, context?: LogContext): void;
28
+ startTimer(operation: string): () => void;
29
+ private log;
30
+ private formatMessage;
31
+ child(childContext: string): Logger;
32
+ static parseLogLevel(level: string): LogLevel;
33
+ }
34
+ //# sourceMappingURL=logger.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.service.d.ts","sourceRoot":"","sources":["../../src/logging/logger.service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,oBAAY,QAAQ;IAClB,KAAK,IAAI;IACT,IAAI,IAAI;IACR,IAAI,IAAI;IACR,KAAK,IAAI;CACV;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;gBAExB,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,QAAwB;IAK/D,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAIlD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAIjD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAIjD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAUjE,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,IAAI;IAQzC,OAAO,CAAC,GAAG;IAmBX,OAAO,CAAC,aAAa;IAarB,KAAK,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAInC,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ;CAS9C"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Logger Service
3
+ *
4
+ * Structured logging with appropriate log levels and context.
5
+ * Provides performance timing utilities and debug mode support.
6
+ */
7
+ export var LogLevel;
8
+ (function (LogLevel) {
9
+ LogLevel[LogLevel["DEBUG"] = 0] = "DEBUG";
10
+ LogLevel[LogLevel["INFO"] = 1] = "INFO";
11
+ LogLevel[LogLevel["WARN"] = 2] = "WARN";
12
+ LogLevel[LogLevel["ERROR"] = 3] = "ERROR";
13
+ })(LogLevel || (LogLevel = {}));
14
+ export class Logger {
15
+ context;
16
+ minLevel;
17
+ constructor(context, minLevel = LogLevel.INFO) {
18
+ this.context = context;
19
+ this.minLevel = minLevel;
20
+ }
21
+ debug(message, context) {
22
+ this.log(LogLevel.DEBUG, message, context);
23
+ }
24
+ info(message, context) {
25
+ this.log(LogLevel.INFO, message, context);
26
+ }
27
+ warn(message, context) {
28
+ this.log(LogLevel.WARN, message, context);
29
+ }
30
+ error(message, error, context) {
31
+ const fullMessage = error ? `${message}: ${error.message}` : message;
32
+ const errorContext = {
33
+ ...context,
34
+ error: error?.message,
35
+ stack: error?.stack,
36
+ };
37
+ this.log(LogLevel.ERROR, fullMessage, errorContext);
38
+ }
39
+ startTimer(operation) {
40
+ const startTime = Date.now();
41
+ return () => {
42
+ const duration = Date.now() - startTime;
43
+ this.debug(`${operation} completed`, { operation, duration });
44
+ };
45
+ }
46
+ log(level, message, context) {
47
+ if (level < this.minLevel)
48
+ return;
49
+ const timestamp = new Date().toISOString();
50
+ const levelName = LogLevel[level];
51
+ const formattedMessage = this.formatMessage(timestamp, levelName, this.context, message, context);
52
+ if (level === LogLevel.ERROR) {
53
+ console.error(formattedMessage);
54
+ if (context?.stack)
55
+ console.error(context.stack);
56
+ }
57
+ else if (level === LogLevel.WARN) {
58
+ console.error(`WARN: ${formattedMessage}`);
59
+ }
60
+ else if (level === LogLevel.DEBUG) {
61
+ console.error(`DEBUG: ${formattedMessage}`);
62
+ }
63
+ else {
64
+ console.error(formattedMessage);
65
+ }
66
+ }
67
+ formatMessage(timestamp, level, context, message, data) {
68
+ const parts = [`[${timestamp}]`, `[${level}]`, `[${context}]`, message];
69
+ if (data && Object.keys(data).length > 0) {
70
+ const { stack: _stack, error: _error, ...displayData } = data;
71
+ if (Object.keys(displayData).length > 0) {
72
+ parts.push(JSON.stringify(displayData));
73
+ }
74
+ }
75
+ return parts.join(' ');
76
+ }
77
+ child(childContext) {
78
+ return new Logger(`${this.context}:${childContext}`, this.minLevel);
79
+ }
80
+ static parseLogLevel(level) {
81
+ switch (level.toLowerCase()) {
82
+ case 'debug': return LogLevel.DEBUG;
83
+ case 'info': return LogLevel.INFO;
84
+ case 'warn':
85
+ case 'warning': return LogLevel.WARN;
86
+ case 'error': return LogLevel.ERROR;
87
+ default: return LogLevel.INFO;
88
+ }
89
+ }
90
+ }
91
+ //# sourceMappingURL=logger.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.service.js","sourceRoot":"","sources":["../../src/logging/logger.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Git MCP Server
3
+ *
4
+ * Registers only GIT_TOOLS and dispatches to GitToolsService.
5
+ * No GitLab token required.
6
+ */
7
+ export declare class GitMCPServer {
8
+ private server;
9
+ private gitToolsService;
10
+ private logger;
11
+ constructor();
12
+ private setupHandlers;
13
+ private handleToolCall;
14
+ run(): Promise<void>;
15
+ shutdown(): Promise<void>;
16
+ }
17
+ //# sourceMappingURL=git-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-server.d.ts","sourceRoot":"","sources":["../../src/servers/git-server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,MAAM,CAAS;;IAcvB,OAAO,CAAC,aAAa;YAoBP,cAAc;IAmBtB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAMpB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAKhC"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Git MCP Server
3
+ *
4
+ * Registers only GIT_TOOLS and dispatches to GitToolsService.
5
+ * No GitLab token required.
6
+ */
7
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
8
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
9
+ import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
10
+ import { GIT_TOOLS } from "../tools/git-tools.js";
11
+ import { GitToolsService } from "../services/git-tools.service.js";
12
+ import { Logger } from "../logging/logger.service.js";
13
+ import { ErrorHandler } from "../errors/error-handler.js";
14
+ export class GitMCPServer {
15
+ server;
16
+ gitToolsService;
17
+ logger;
18
+ constructor() {
19
+ const logLevel = Logger.parseLogLevel(process.env.LOG_LEVEL || 'info');
20
+ this.logger = new Logger('GitServer', logLevel);
21
+ this.server = new Server({ name: "ai-code-review-git", version: "1.0.0" }, { capabilities: { tools: {} } });
22
+ this.gitToolsService = new GitToolsService(this.logger.child('GitTools'));
23
+ this.setupHandlers();
24
+ this.logger.info('Git MCP Server initialized');
25
+ }
26
+ setupHandlers() {
27
+ this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: GIT_TOOLS }));
28
+ this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
29
+ const { name, arguments: args } = request.params;
30
+ this.logger.info(`Tool call: ${name}`, { tool: name });
31
+ const endTimer = this.logger.startTimer(`Tool: ${name}`);
32
+ try {
33
+ const result = await this.handleToolCall(name, args);
34
+ endTimer();
35
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
36
+ }
37
+ catch (error) {
38
+ endTimer();
39
+ const errorMessage = ErrorHandler.formatError(error instanceof Error ? error : new Error(String(error)));
40
+ return { content: [{ type: "text", text: `Error: ${errorMessage}` }], isError: true };
41
+ }
42
+ });
43
+ }
44
+ async handleToolCall(name, args) {
45
+ const params = args;
46
+ switch (name) {
47
+ case "git_clone": return this.gitToolsService.clone(params);
48
+ case "git_clone_local": return this.gitToolsService.cloneLocal(params);
49
+ case "git_fetch": return this.gitToolsService.fetch(params);
50
+ case "git_checkout": return this.gitToolsService.checkout(params);
51
+ case "git_reset": return this.gitToolsService.reset(params);
52
+ case "git_merge_base": return this.gitToolsService.mergeBase(params);
53
+ case "git_diff": return this.gitToolsService.diff(params);
54
+ case "git_show": return this.gitToolsService.show(params);
55
+ case "git_log": return this.gitToolsService.log(params);
56
+ case "git_cleanup": return this.gitToolsService.cleanup(params);
57
+ case "write_file": return this.gitToolsService.writeFile(params);
58
+ case "git_grep": return this.gitToolsService.grep(params);
59
+ default: throw ErrorHandler.validationError(`Unknown tool: ${name}`, { tool: name });
60
+ }
61
+ }
62
+ async run() {
63
+ const transport = new StdioServerTransport();
64
+ await this.server.connect(transport);
65
+ this.logger.info('Git MCP Server started successfully');
66
+ }
67
+ async shutdown() {
68
+ this.logger.info('Shutting down Git MCP server...');
69
+ await this.server.close();
70
+ this.logger.info('Git MCP server shut down successfully');
71
+ }
72
+ }
73
+ //# sourceMappingURL=git-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-server.js","sourceRoot":"","sources":["../../src/servers/git-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * GitLab MCP Server
3
+ *
4
+ * Registers only REVIEW_TOOLS and dispatches to ReviewToolsService.
5
+ * Requires GitLab URL and token (resolved from params or glab CLI config).
6
+ */
7
+ export declare class GitLabMCPServer {
8
+ private server;
9
+ private reviewToolsService;
10
+ private logger;
11
+ constructor();
12
+ private setupHandlers;
13
+ private resolveToken;
14
+ private handleToolCall;
15
+ run(): Promise<void>;
16
+ shutdown(): Promise<void>;
17
+ }
18
+ //# sourceMappingURL=gitlab-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitlab-server.d.ts","sourceRoot":"","sources":["../../src/servers/gitlab-server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAqBH,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,MAAM,CAAS;;IAcvB,OAAO,CAAC,aAAa;IAoBrB,OAAO,CAAC,YAAY;YAqBN,cAAc;IAmCtB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAMpB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAKhC"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * GitLab MCP Server
3
+ *
4
+ * Registers only REVIEW_TOOLS and dispatches to ReviewToolsService.
5
+ * Requires GitLab URL and token (resolved from params or glab CLI config).
6
+ */
7
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
8
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
9
+ import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
10
+ import { REVIEW_TOOLS } from "../tools/gitlab-tools.js";
11
+ import { ReviewToolsService } from "../services/review-tools.service.js";
12
+ import { loadGlabConfig } from "../config/glab-config.loader.js";
13
+ import { Logger } from "../logging/logger.service.js";
14
+ import { ErrorHandler } from "../errors/error-handler.js";
15
+ export class GitLabMCPServer {
16
+ server;
17
+ reviewToolsService;
18
+ logger;
19
+ constructor() {
20
+ const logLevel = Logger.parseLogLevel(process.env.LOG_LEVEL || 'info');
21
+ this.logger = new Logger('GitLabServer', logLevel);
22
+ this.server = new Server({ name: "ai-code-review-gitlab", version: "1.0.0" }, { capabilities: { tools: {} } });
23
+ this.reviewToolsService = new ReviewToolsService(this.logger.child('ReviewTools'));
24
+ this.setupHandlers();
25
+ this.logger.info('GitLab MCP Server initialized');
26
+ }
27
+ setupHandlers() {
28
+ this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: REVIEW_TOOLS }));
29
+ this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
30
+ const { name, arguments: args } = request.params;
31
+ this.logger.info(`Tool call: ${name}`, { tool: name });
32
+ const endTimer = this.logger.startTimer(`Tool: ${name}`);
33
+ try {
34
+ const result = await this.handleToolCall(name, args);
35
+ endTimer();
36
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
37
+ }
38
+ catch (error) {
39
+ endTimer();
40
+ const errorMessage = ErrorHandler.formatError(error instanceof Error ? error : new Error(String(error)));
41
+ return { content: [{ type: "text", text: `Error: ${errorMessage}` }], isError: true };
42
+ }
43
+ });
44
+ }
45
+ resolveToken(params, gitlabUrl) {
46
+ let token = typeof params.gitlabToken === 'string' ? params.gitlabToken : undefined;
47
+ if (!token) {
48
+ try {
49
+ const hostname = new URL(gitlabUrl).hostname;
50
+ const glabConfig = loadGlabConfig(hostname);
51
+ if (glabConfig?.gitlabToken) {
52
+ token = glabConfig.gitlabToken;
53
+ this.logger.debug('Token loaded from glab CLI config', { hostname });
54
+ }
55
+ }
56
+ catch { /* Invalid URL or glab config unavailable */ }
57
+ }
58
+ if (!token) {
59
+ throw ErrorHandler.configurationError("GitLab token not found. Ensure glab CLI is authenticated for this host: " + gitlabUrl, { gitlabUrl });
60
+ }
61
+ return token;
62
+ }
63
+ async handleToolCall(name, args) {
64
+ const params = args;
65
+ const gitlabUrl = typeof params.gitlabUrl === 'string' ? params.gitlabUrl : undefined;
66
+ if (!gitlabUrl) {
67
+ throw ErrorHandler.validationError("gitlabUrl is required. Provide the GitLab instance URL (e.g. 'https://gitlab.example.com') so the correct token can be resolved from glab CLI config.", { tool: name });
68
+ }
69
+ const token = this.resolveToken(params, gitlabUrl);
70
+ switch (name) {
71
+ case "extract_mr_metadata":
72
+ return this.reviewToolsService.extractMrMetadata(params, gitlabUrl, token);
73
+ case "extract_version_refs":
74
+ return this.reviewToolsService.extractVersionRefs(params, gitlabUrl, token);
75
+ case "extract_prior_discussions":
76
+ return this.reviewToolsService.extractPriorDiscussions(params, gitlabUrl, token);
77
+ case "post_draft_notes":
78
+ return this.reviewToolsService.postDraftNotes(params, gitlabUrl, token);
79
+ case "delete_draft_notes":
80
+ return this.reviewToolsService.deleteDraftNotes(params, gitlabUrl, token);
81
+ case "publish_review":
82
+ return this.reviewToolsService.publishReview(params, gitlabUrl, token);
83
+ case "fetch_and_categorize_todos":
84
+ return this.reviewToolsService.fetchAndCategorizeTodos(params, gitlabUrl, token);
85
+ case "mark_todos_done":
86
+ return this.reviewToolsService.markTodosDone(params, gitlabUrl, token);
87
+ default:
88
+ throw ErrorHandler.validationError(`Unknown tool: ${name}`, { tool: name });
89
+ }
90
+ }
91
+ async run() {
92
+ const transport = new StdioServerTransport();
93
+ await this.server.connect(transport);
94
+ this.logger.info('GitLab MCP Server started successfully');
95
+ }
96
+ async shutdown() {
97
+ this.logger.info('Shutting down GitLab MCP server...');
98
+ await this.server.close();
99
+ this.logger.info('GitLab MCP server shut down successfully');
100
+ }
101
+ }
102
+ //# sourceMappingURL=gitlab-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitlab-server.js","sourceRoot":"","sources":["../../src/servers/gitlab-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Git Tools Service
3
+ *
4
+ * Provides local git operations as MCP tools, eliminating the need for
5
+ * shell commands that are prone to terminal hang issues (Kiro #4132).
6
+ *
7
+ * Uses simple-git for all git operations.
8
+ */
9
+ import { Logger } from '../logging/logger.service.js';
10
+ export interface GitCloneParams {
11
+ url: string;
12
+ directory: string;
13
+ cwd?: string;
14
+ }
15
+ export interface GitCloneLocalParams {
16
+ referenceDir: string;
17
+ workDir: string;
18
+ cwd?: string;
19
+ }
20
+ export interface GitFetchParams {
21
+ repoDir: string;
22
+ branches?: string[];
23
+ all?: boolean;
24
+ }
25
+ export interface GitCheckoutParams {
26
+ repoDir: string;
27
+ branch: string;
28
+ }
29
+ export interface GitMergeBaseParams {
30
+ repoDir: string;
31
+ ref1: string;
32
+ ref2: string;
33
+ }
34
+ export interface GitDiffParams {
35
+ repoDir: string;
36
+ base: string;
37
+ head?: string;
38
+ mode?: 'stat' | 'name-only' | 'full';
39
+ }
40
+ export interface GitShowParams {
41
+ repoDir: string;
42
+ ref: string;
43
+ path: string;
44
+ }
45
+ export interface GitLogParams {
46
+ repoDir: string;
47
+ maxCount?: number;
48
+ }
49
+ export interface GitCleanupParams {
50
+ directory: string;
51
+ }
52
+ export interface WriteFileParams {
53
+ filePath: string;
54
+ content: string;
55
+ }
56
+ export interface GitGrepParams {
57
+ repoDir: string;
58
+ pattern: string;
59
+ paths?: string[];
60
+ maxResults?: number;
61
+ }
62
+ export interface GitResetParams {
63
+ repoDir: string;
64
+ ref: string;
65
+ mode?: 'soft' | 'mixed' | 'hard';
66
+ }
67
+ export declare class GitToolsService {
68
+ private logger;
69
+ constructor(logger?: Logger);
70
+ private git;
71
+ clone(params: GitCloneParams): Promise<{
72
+ directory: string;
73
+ }>;
74
+ cloneLocal(params: GitCloneLocalParams): Promise<{
75
+ directory: string;
76
+ }>;
77
+ fetch(params: GitFetchParams): Promise<{
78
+ success: boolean;
79
+ }>;
80
+ checkout(params: GitCheckoutParams): Promise<{
81
+ branch: string;
82
+ }>;
83
+ reset(params: GitResetParams): Promise<{
84
+ success: boolean;
85
+ ref: string;
86
+ mode: string;
87
+ }>;
88
+ mergeBase(params: GitMergeBaseParams): Promise<{
89
+ mergeBase: string;
90
+ }>;
91
+ diff(params: GitDiffParams): Promise<{
92
+ diff: string;
93
+ }>;
94
+ show(params: GitShowParams): Promise<{
95
+ content: string;
96
+ }>;
97
+ log(params: GitLogParams): Promise<{
98
+ log: string;
99
+ }>;
100
+ cleanup(params: GitCleanupParams): Promise<{
101
+ removed: boolean;
102
+ }>;
103
+ writeFile(params: WriteFileParams): Promise<{
104
+ written: boolean;
105
+ }>;
106
+ grep(params: GitGrepParams): Promise<{
107
+ results: string;
108
+ matchCount: number;
109
+ }>;
110
+ }
111
+ //# sourceMappingURL=git-tools.service.d.ts.map