@zereight/mcp-gitlab 1.0.14 → 1.0.15

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/build/index.js CHANGED
@@ -264,7 +264,7 @@ async function createMergeRequest(projectId, options) {
264
264
  * @param {string} [previousPath] - The previous path of the file in case of rename
265
265
  * @returns {Promise<GitLabCreateUpdateFileResponse>} The file update response
266
266
  */
267
- async function createOrUpdateFile(projectId, filePath, content, commitMessage, branch, previousPath) {
267
+ async function createOrUpdateFile(projectId, filePath, content, commitMessage, branch, previousPath, last_commit_id, commit_id) {
268
268
  const encodedPath = encodeURIComponent(filePath);
269
269
  const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/files/${encodedPath}`);
270
270
  const body = {
@@ -277,14 +277,38 @@ async function createOrUpdateFile(projectId, filePath, content, commitMessage, b
277
277
  // Check if file exists
278
278
  let method = "POST";
279
279
  try {
280
- await getFileContents(projectId, filePath, branch);
280
+ // Get file contents to check existence and retrieve commit IDs
281
+ const fileData = await getFileContents(projectId, filePath, branch);
281
282
  method = "PUT";
283
+ // If fileData is not an array, it's a file content object with commit IDs
284
+ if (!Array.isArray(fileData)) {
285
+ // Use commit IDs from the file data if not provided in parameters
286
+ if (!commit_id && fileData.commit_id) {
287
+ body.commit_id = fileData.commit_id;
288
+ }
289
+ else if (commit_id) {
290
+ body.commit_id = commit_id;
291
+ }
292
+ if (!last_commit_id && fileData.last_commit_id) {
293
+ body.last_commit_id = fileData.last_commit_id;
294
+ }
295
+ else if (last_commit_id) {
296
+ body.last_commit_id = last_commit_id;
297
+ }
298
+ }
282
299
  }
283
300
  catch (error) {
284
301
  if (!(error instanceof Error && error.message.includes("File not found"))) {
285
302
  throw error;
286
303
  }
287
- // File doesn't exist, use POST
304
+ // File doesn't exist, use POST - no need for commit IDs for new files
305
+ // But still use any provided as parameters if they exist
306
+ if (commit_id) {
307
+ body.commit_id = commit_id;
308
+ }
309
+ if (last_commit_id) {
310
+ body.last_commit_id = last_commit_id;
311
+ }
288
312
  }
289
313
  const response = await fetch(url.toString(), {
290
314
  method,
@@ -659,7 +683,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
659
683
  }
660
684
  case "create_or_update_file": {
661
685
  const args = CreateOrUpdateFileSchema.parse(request.params.arguments);
662
- const result = await createOrUpdateFile(args.project_id, args.file_path, args.content, args.commit_message, args.branch, args.previous_path);
686
+ const result = await createOrUpdateFile(args.project_id, args.file_path, args.content, args.commit_message, args.branch, args.previous_path, args.last_commit_id, args.commit_id);
663
687
  return {
664
688
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
665
689
  };
package/build/schemas.js CHANGED
@@ -39,7 +39,9 @@ export const GitLabFileContentSchema = z.object({
39
39
  content_sha256: z.string(), // Changed from sha to match GitLab API
40
40
  ref: z.string(), // Added as GitLab requires branch reference
41
41
  blob_id: z.string(), // Added to match GitLab API
42
+ commit_id: z.string(), // ID of the current file version
42
43
  last_commit_id: z.string(), // Added to match GitLab API
44
+ execute_filemode: z.boolean().optional(), // Added to match GitLab API
43
45
  });
44
46
  export const GitLabDirectoryContentSchema = z.object({
45
47
  name: z.string(),
@@ -122,7 +124,7 @@ export const CreateBranchOptionsSchema = z.object({
122
124
  export const GitLabCreateUpdateFileResponseSchema = z.object({
123
125
  file_path: z.string(),
124
126
  branch: z.string(),
125
- commit_id: z.string(), // Changed from sha to match GitLab API
127
+ commit_id: z.string().optional(), // Optional since it's not always returned by the API
126
128
  content: GitLabFileContentSchema.optional(),
127
129
  });
128
130
  export const GitLabSearchResponseSchema = z.object({
@@ -236,6 +238,14 @@ export const CreateOrUpdateFileSchema = ProjectParamsSchema.extend({
236
238
  .string()
237
239
  .optional()
238
240
  .describe("Path of the file to move/rename"),
241
+ last_commit_id: z
242
+ .string()
243
+ .optional()
244
+ .describe("Last known file commit ID"),
245
+ commit_id: z
246
+ .string()
247
+ .optional()
248
+ .describe("Current file commit ID (for update operations)"),
239
249
  });
240
250
  export const SearchRepositoriesSchema = z.object({
241
251
  search: z.string().describe("Search query"), // Changed from query to match GitLab API
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zereight/mcp-gitlab",
3
- "version": "1.0.14",
3
+ "version": "1.0.15",
4
4
  "description": "MCP server for using the GitLab API",
5
5
  "license": "MIT",
6
6
  "author": "zereight",