gitlab-mcp 0.1.5 → 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/.dockerignore +7 -0
  2. package/.editorconfig +9 -0
  3. package/.env.example +75 -0
  4. package/.github/workflows/nodejs.yml +31 -0
  5. package/.github/workflows/npm-publish.yml +31 -0
  6. package/.husky/pre-commit +1 -0
  7. package/.nvmrc +1 -0
  8. package/.prettierrc.json +6 -0
  9. package/Dockerfile +20 -0
  10. package/README.md +416 -251
  11. package/docker-compose.yml +10 -0
  12. package/docs/architecture.md +310 -0
  13. package/docs/authentication.md +299 -0
  14. package/docs/configuration.md +149 -0
  15. package/docs/deployment.md +336 -0
  16. package/docs/tools.md +294 -0
  17. package/eslint.config.js +23 -0
  18. package/package.json +70 -32
  19. package/scripts/get-oauth-token.example.sh +15 -0
  20. package/src/config/env.ts +171 -0
  21. package/src/http.ts +605 -0
  22. package/src/index.ts +77 -0
  23. package/src/lib/auth-context.ts +19 -0
  24. package/src/lib/gitlab-client.ts +1810 -0
  25. package/src/lib/logger.ts +17 -0
  26. package/src/lib/network.ts +45 -0
  27. package/src/lib/oauth.ts +287 -0
  28. package/src/lib/output.ts +51 -0
  29. package/src/lib/policy.ts +78 -0
  30. package/src/lib/request-runtime.ts +376 -0
  31. package/src/lib/sanitize.ts +25 -0
  32. package/src/server/build-server.ts +17 -0
  33. package/src/tools/gitlab.ts +3128 -0
  34. package/src/tools/health.ts +27 -0
  35. package/src/tools/mr-code-context.ts +473 -0
  36. package/src/types/context.ts +13 -0
  37. package/tests/auth-context.test.ts +102 -0
  38. package/tests/gitlab-client.test.ts +674 -0
  39. package/tests/graphql-guard.test.ts +121 -0
  40. package/tests/integration/agent-loop.integration.test.ts +552 -0
  41. package/tests/integration/server.integration.test.ts +543 -0
  42. package/tests/mr-code-context.test.ts +600 -0
  43. package/tests/oauth.test.ts +43 -0
  44. package/tests/output.test.ts +186 -0
  45. package/tests/policy.test.ts +324 -0
  46. package/tests/request-runtime.test.ts +252 -0
  47. package/tests/sanitize.test.ts +123 -0
  48. package/tests/upload-reference.test.ts +84 -0
  49. package/tsconfig.build.json +11 -0
  50. package/tsconfig.json +21 -0
  51. package/vitest.config.ts +12 -0
  52. package/LICENSE +0 -21
  53. package/build/index.js +0 -1642
  54. package/build/schemas.js +0 -684
  55. package/build/test-note.js +0 -54
package/build/schemas.js DELETED
@@ -1,684 +0,0 @@
1
- import { z } from "zod";
2
- // Base schemas for common types
3
- export const GitLabAuthorSchema = z.object({
4
- name: z.string(),
5
- email: z.string(),
6
- date: z.string(),
7
- });
8
- // Namespace related schemas
9
- // Base schema for project-related operations
10
- const ProjectParamsSchema = z.object({
11
- project_id: z.string().describe("Project ID or URL-encoded path"), // Changed from owner/repo to match GitLab API
12
- });
13
- export const GitLabNamespaceSchema = z.object({
14
- id: z.number(),
15
- name: z.string(),
16
- path: z.string(),
17
- kind: z.enum(["user", "group"]),
18
- full_path: z.string(),
19
- parent_id: z.number().nullable(),
20
- avatar_url: z.string().nullable(),
21
- web_url: z.string(),
22
- members_count_with_descendants: z.number().optional(),
23
- billable_members_count: z.number().optional(),
24
- max_seats_used: z.number().optional(),
25
- seats_in_use: z.number().optional(),
26
- plan: z.string().optional(),
27
- end_date: z.string().nullable().optional(),
28
- trial_ends_on: z.string().nullable().optional(),
29
- trial: z.boolean().optional(),
30
- root_repository_size: z.number().optional(),
31
- projects_count: z.number().optional(),
32
- });
33
- export const GitLabNamespaceExistsResponseSchema = z.object({
34
- exists: z.boolean(),
35
- suggests: z.array(z.string()).optional(),
36
- });
37
- // Repository related schemas
38
- export const GitLabOwnerSchema = z.object({
39
- username: z.string(),
40
- id: z.number(),
41
- avatar_url: z.string(),
42
- web_url: z.string(),
43
- name: z.string(),
44
- state: z.string(), // Added as GitLab includes user state
45
- });
46
- export const GitLabRepositorySchema = z.object({
47
- id: z.number(),
48
- name: z.string(),
49
- path_with_namespace: z.string(),
50
- visibility: z.string().optional(),
51
- owner: GitLabOwnerSchema.optional(),
52
- web_url: z.string().optional(),
53
- description: z.string().nullable(),
54
- fork: z.boolean().optional(),
55
- ssh_url_to_repo: z.string().optional(),
56
- http_url_to_repo: z.string().optional(),
57
- created_at: z.string().optional(),
58
- last_activity_at: z.string().optional(),
59
- default_branch: z.string().optional(),
60
- namespace: z.object({
61
- id: z.number(),
62
- name: z.string(),
63
- path: z.string(),
64
- kind: z.string(),
65
- full_path: z.string(),
66
- avatar_url: z.string().nullable().optional(),
67
- web_url: z.string().optional(),
68
- }).optional(),
69
- readme_url: z.string().optional().nullable(),
70
- topics: z.array(z.string()).optional(),
71
- tag_list: z.array(z.string()).optional(),
72
- open_issues_count: z.number().optional(),
73
- archived: z.boolean().optional(),
74
- forks_count: z.number().optional(),
75
- star_count: z.number().optional(),
76
- permissions: z.object({
77
- project_access: z.object({
78
- access_level: z.number(),
79
- notification_level: z.number().optional(),
80
- }).optional().nullable(),
81
- group_access: z.object({
82
- access_level: z.number(),
83
- notification_level: z.number().optional(),
84
- }).optional().nullable(),
85
- }).optional(),
86
- container_registry_enabled: z.boolean().optional(),
87
- container_registry_access_level: z.string().optional(),
88
- issues_enabled: z.boolean().optional(),
89
- merge_requests_enabled: z.boolean().optional(),
90
- wiki_enabled: z.boolean().optional(),
91
- jobs_enabled: z.boolean().optional(),
92
- snippets_enabled: z.boolean().optional(),
93
- can_create_merge_request_in: z.boolean().optional(),
94
- resolve_outdated_diff_discussions: z.boolean().optional(),
95
- shared_runners_enabled: z.boolean().optional(),
96
- shared_with_groups: z.array(z.object({
97
- group_id: z.number(),
98
- group_name: z.string(),
99
- group_full_path: z.string(),
100
- group_access_level: z.number(),
101
- })).optional(),
102
- });
103
- // Project schema (extended from repository schema)
104
- export const GitLabProjectSchema = GitLabRepositorySchema;
105
- // File content schemas
106
- export const GitLabFileContentSchema = z.object({
107
- file_name: z.string(),
108
- file_path: z.string(),
109
- size: z.number(),
110
- encoding: z.string(),
111
- content: z.string(),
112
- content_sha256: z.string(),
113
- ref: z.string(),
114
- blob_id: z.string(),
115
- commit_id: z.string(),
116
- last_commit_id: z.string(),
117
- execute_filemode: z.boolean().optional(), // Added to match GitLab API
118
- });
119
- export const GitLabDirectoryContentSchema = z.object({
120
- name: z.string(),
121
- path: z.string(),
122
- type: z.string(),
123
- mode: z.string(),
124
- id: z.string(),
125
- web_url: z.string(), // Changed from html_url to match GitLab API
126
- });
127
- export const GitLabContentSchema = z.union([
128
- GitLabFileContentSchema,
129
- z.array(GitLabDirectoryContentSchema),
130
- ]);
131
- // Operation schemas
132
- export const FileOperationSchema = z.object({
133
- path: z.string(),
134
- content: z.string(),
135
- });
136
- // Tree and commit schemas
137
- export const GitLabTreeEntrySchema = z.object({
138
- id: z.string(),
139
- name: z.string(),
140
- type: z.enum(["blob", "tree"]),
141
- path: z.string(),
142
- mode: z.string(),
143
- });
144
- export const GitLabTreeSchema = z.object({
145
- id: z.string(),
146
- tree: z.array(GitLabTreeEntrySchema),
147
- });
148
- export const GitLabCommitSchema = z.object({
149
- id: z.string(),
150
- short_id: z.string(),
151
- title: z.string(),
152
- author_name: z.string(),
153
- author_email: z.string(),
154
- authored_date: z.string(),
155
- committer_name: z.string(),
156
- committer_email: z.string(),
157
- committed_date: z.string(),
158
- web_url: z.string(),
159
- parent_ids: z.array(z.string()), // Changed from parents to match GitLab API
160
- });
161
- // Reference schema
162
- export const GitLabReferenceSchema = z.object({
163
- name: z.string(),
164
- commit: z.object({
165
- id: z.string(),
166
- web_url: z.string(), // Changed from url to match GitLab API
167
- }),
168
- });
169
- // Input schemas for operations
170
- export const CreateRepositoryOptionsSchema = z.object({
171
- name: z.string(),
172
- description: z.string().optional(),
173
- visibility: z.enum(["private", "internal", "public"]).optional(),
174
- initialize_with_readme: z.boolean().optional(), // Changed from auto_init to match GitLab API
175
- });
176
- export const CreateIssueOptionsSchema = z.object({
177
- title: z.string(),
178
- description: z.string().optional(),
179
- assignee_ids: z.array(z.number()).optional(),
180
- milestone_id: z.number().optional(),
181
- labels: z.array(z.string()).optional(),
182
- });
183
- export const CreateMergeRequestOptionsSchema = z.object({
184
- // Changed from CreatePullRequestOptionsSchema
185
- title: z.string(),
186
- description: z.string().optional(),
187
- source_branch: z.string(),
188
- target_branch: z.string(),
189
- allow_collaboration: z.boolean().optional(),
190
- draft: z.boolean().optional(),
191
- });
192
- export const CreateBranchOptionsSchema = z.object({
193
- name: z.string(),
194
- ref: z.string(), // The source branch/commit for the new branch
195
- });
196
- // Response schemas for operations
197
- export const GitLabCreateUpdateFileResponseSchema = z.object({
198
- file_path: z.string(),
199
- branch: z.string(),
200
- commit_id: z.string().optional(),
201
- content: GitLabFileContentSchema.optional(),
202
- });
203
- export const GitLabSearchResponseSchema = z.object({
204
- count: z.number().optional(),
205
- total_pages: z.number().optional(),
206
- current_page: z.number().optional(),
207
- items: z.array(GitLabRepositorySchema),
208
- });
209
- // Issue related schemas
210
- export const GitLabLabelSchema = z.object({
211
- id: z.number(),
212
- name: z.string(),
213
- color: z.string(),
214
- text_color: z.string(),
215
- description: z.string().nullable(),
216
- description_html: z.string().nullable(),
217
- open_issues_count: z.number().optional(),
218
- closed_issues_count: z.number().optional(),
219
- open_merge_requests_count: z.number().optional(),
220
- subscribed: z.boolean().optional(),
221
- priority: z.number().nullable().optional(),
222
- is_project_label: z.boolean().optional(),
223
- });
224
- export const GitLabUserSchema = z.object({
225
- username: z.string(),
226
- id: z.number(),
227
- name: z.string(),
228
- avatar_url: z.string(),
229
- web_url: z.string(), // Changed from html_url to match GitLab API
230
- });
231
- export const GitLabMilestoneSchema = z.object({
232
- id: z.number(),
233
- iid: z.number(),
234
- title: z.string(),
235
- description: z.string(),
236
- state: z.string(),
237
- web_url: z.string(), // Changed from html_url to match GitLab API
238
- });
239
- export const GitLabIssueSchema = z.object({
240
- id: z.number(),
241
- iid: z.number(),
242
- project_id: z.number(),
243
- title: z.string(),
244
- description: z.string(),
245
- state: z.string(),
246
- author: GitLabUserSchema,
247
- assignees: z.array(GitLabUserSchema),
248
- labels: z.array(GitLabLabelSchema).or(z.array(z.string())),
249
- milestone: GitLabMilestoneSchema.nullable(),
250
- created_at: z.string(),
251
- updated_at: z.string(),
252
- closed_at: z.string().nullable(),
253
- web_url: z.string(),
254
- references: z.object({
255
- short: z.string(),
256
- relative: z.string(),
257
- full: z.string(),
258
- }).optional(),
259
- time_stats: z.object({
260
- time_estimate: z.number(),
261
- total_time_spent: z.number(),
262
- human_time_estimate: z.string().nullable(),
263
- human_total_time_spent: z.string().nullable(),
264
- }).optional(),
265
- confidential: z.boolean().optional(),
266
- due_date: z.string().nullable().optional(),
267
- discussion_locked: z.boolean().nullable().optional(),
268
- weight: z.number().nullable().optional(),
269
- });
270
- // NEW SCHEMA: For issue with link details (used in listing issue links)
271
- export const GitLabIssueWithLinkDetailsSchema = GitLabIssueSchema.extend({
272
- issue_link_id: z.number(),
273
- link_type: z.enum(['relates_to', 'blocks', 'is_blocked_by']),
274
- link_created_at: z.string(),
275
- link_updated_at: z.string(),
276
- });
277
- // Fork related schemas
278
- export const GitLabForkParentSchema = z.object({
279
- name: z.string(),
280
- path_with_namespace: z.string(),
281
- owner: z.object({
282
- username: z.string(),
283
- id: z.number(),
284
- avatar_url: z.string(),
285
- }).optional(),
286
- web_url: z.string(), // Changed from html_url to match GitLab API
287
- });
288
- export const GitLabForkSchema = GitLabRepositorySchema.extend({
289
- forked_from_project: GitLabForkParentSchema.optional(), // Made optional to handle cases where GitLab API doesn't include it
290
- });
291
- // Merge Request related schemas (equivalent to Pull Request)
292
- export const GitLabMergeRequestDiffRefSchema = z.object({
293
- base_sha: z.string(),
294
- head_sha: z.string(),
295
- start_sha: z.string(),
296
- });
297
- export const GitLabMergeRequestSchema = z.object({
298
- id: z.number(),
299
- iid: z.number(),
300
- project_id: z.number(),
301
- title: z.string(),
302
- description: z.string().nullable(),
303
- state: z.string(),
304
- merged: z.boolean().optional(),
305
- draft: z.boolean().optional(),
306
- author: GitLabUserSchema,
307
- assignees: z.array(GitLabUserSchema).optional(),
308
- source_branch: z.string(),
309
- target_branch: z.string(),
310
- diff_refs: GitLabMergeRequestDiffRefSchema.nullable().optional(),
311
- web_url: z.string(),
312
- created_at: z.string(),
313
- updated_at: z.string(),
314
- merged_at: z.string().nullable(),
315
- closed_at: z.string().nullable(),
316
- merge_commit_sha: z.string().nullable(),
317
- detailed_merge_status: z.string().optional(),
318
- merge_status: z.string().optional(),
319
- merge_error: z.string().nullable().optional(),
320
- work_in_progress: z.boolean().optional(),
321
- blocking_discussions_resolved: z.boolean().optional(),
322
- should_remove_source_branch: z.boolean().nullable().optional(),
323
- force_remove_source_branch: z.boolean().nullable().optional(),
324
- allow_collaboration: z.boolean().optional(),
325
- allow_maintainer_to_push: z.boolean().optional(),
326
- changes_count: z.string().nullable().optional(),
327
- merge_when_pipeline_succeeds: z.boolean().optional(),
328
- squash: z.boolean().optional(),
329
- labels: z.array(z.string()).optional(),
330
- });
331
- // Discussion related schemas
332
- export const GitLabDiscussionNoteSchema = z.object({
333
- id: z.number(),
334
- type: z.enum(["DiscussionNote", "DiffNote", "Note"]).nullable(),
335
- body: z.string(),
336
- attachment: z.any().nullable(),
337
- author: GitLabUserSchema,
338
- created_at: z.string(),
339
- updated_at: z.string(),
340
- system: z.boolean(),
341
- noteable_id: z.number(),
342
- noteable_type: z.enum(["Issue", "MergeRequest", "Snippet", "Commit", "Epic"]),
343
- project_id: z.number().optional(),
344
- noteable_iid: z.number().nullable(),
345
- resolvable: z.boolean().optional(),
346
- resolved: z.boolean().optional(),
347
- resolved_by: GitLabUserSchema.nullable().optional(),
348
- resolved_at: z.string().nullable().optional(),
349
- position: z.object({
350
- base_sha: z.string(),
351
- start_sha: z.string(),
352
- head_sha: z.string(),
353
- old_path: z.string(),
354
- new_path: z.string(),
355
- position_type: z.enum(["text", "image", "file"]),
356
- old_line: z.number().nullable(),
357
- new_line: z.number().nullable(),
358
- line_range: z.object({
359
- start: z.object({
360
- line_code: z.string(),
361
- type: z.enum(["new", "old"]),
362
- old_line: z.number().nullable(),
363
- new_line: z.number().nullable(),
364
- }),
365
- end: z.object({
366
- line_code: z.string(),
367
- type: z.enum(["new", "old"]),
368
- old_line: z.number().nullable(),
369
- new_line: z.number().nullable(),
370
- }),
371
- }).nullable().optional(),
372
- width: z.number().optional(),
373
- height: z.number().optional(),
374
- x: z.number().optional(),
375
- y: z.number().optional(), // For image diff notes
376
- }).optional(),
377
- });
378
- export const GitLabDiscussionSchema = z.object({
379
- id: z.string(),
380
- individual_note: z.boolean(),
381
- notes: z.array(GitLabDiscussionNoteSchema),
382
- });
383
- // Input schema for listing merge request discussions
384
- export const ListMergeRequestDiscussionsSchema = ProjectParamsSchema.extend({
385
- merge_request_iid: z.number().describe("The IID of a merge request"),
386
- });
387
- // Input schema for updating a merge request discussion note
388
- export const UpdateMergeRequestNoteSchema = ProjectParamsSchema.extend({
389
- merge_request_iid: z.number().describe("The IID of a merge request"),
390
- discussion_id: z.string().describe("The ID of a thread"),
391
- note_id: z.number().describe("The ID of a thread note"),
392
- body: z.string().describe("The content of the note or reply"),
393
- resolved: z.boolean().optional().describe("Resolve or unresolve the note"), // Optional based on API docs
394
- });
395
- // API Operation Parameter Schemas
396
- export const CreateOrUpdateFileSchema = ProjectParamsSchema.extend({
397
- file_path: z.string().describe("Path where to create/update the file"),
398
- content: z.string().describe("Content of the file"),
399
- commit_message: z.string().describe("Commit message"),
400
- branch: z.string().describe("Branch to create/update the file in"),
401
- previous_path: z
402
- .string()
403
- .optional()
404
- .describe("Path of the file to move/rename"),
405
- last_commit_id: z
406
- .string()
407
- .optional()
408
- .describe("Last known file commit ID"),
409
- commit_id: z
410
- .string()
411
- .optional()
412
- .describe("Current file commit ID (for update operations)"),
413
- });
414
- export const SearchRepositoriesSchema = z.object({
415
- search: z.string().describe("Search query"),
416
- page: z
417
- .number()
418
- .optional()
419
- .describe("Page number for pagination (default: 1)"),
420
- per_page: z
421
- .number()
422
- .optional()
423
- .describe("Number of results per page (default: 20)"),
424
- });
425
- export const CreateRepositorySchema = z.object({
426
- name: z.string().describe("Repository name"),
427
- description: z.string().optional().describe("Repository description"),
428
- visibility: z
429
- .enum(["private", "internal", "public"])
430
- .optional()
431
- .describe("Repository visibility level"),
432
- initialize_with_readme: z
433
- .boolean()
434
- .optional()
435
- .describe("Initialize with README.md"),
436
- });
437
- export const GetFileContentsSchema = ProjectParamsSchema.extend({
438
- file_path: z.string().describe("Path to the file or directory"),
439
- ref: z.string().optional().describe("Branch/tag/commit to get contents from"),
440
- });
441
- export const PushFilesSchema = ProjectParamsSchema.extend({
442
- branch: z.string().describe("Branch to push to"),
443
- files: z
444
- .array(z.object({
445
- file_path: z.string().describe("Path where to create the file"),
446
- content: z.string().describe("Content of the file"),
447
- }))
448
- .describe("Array of files to push"),
449
- commit_message: z.string().describe("Commit message"),
450
- });
451
- export const CreateIssueSchema = ProjectParamsSchema.extend({
452
- title: z.string().describe("Issue title"),
453
- description: z.string().optional().describe("Issue description"),
454
- assignee_ids: z
455
- .array(z.number())
456
- .optional()
457
- .describe("Array of user IDs to assign"),
458
- labels: z.array(z.string()).optional().describe("Array of label names"),
459
- milestone_id: z.number().optional().describe("Milestone ID to assign"),
460
- });
461
- export const CreateMergeRequestSchema = ProjectParamsSchema.extend({
462
- title: z.string().describe("Merge request title"),
463
- description: z.string().optional().describe("Merge request description"),
464
- source_branch: z.string().describe("Branch containing changes"),
465
- target_branch: z.string().describe("Branch to merge into"),
466
- draft: z.boolean().optional().describe("Create as draft merge request"),
467
- allow_collaboration: z
468
- .boolean()
469
- .optional()
470
- .describe("Allow commits from upstream members"),
471
- });
472
- export const ForkRepositorySchema = ProjectParamsSchema.extend({
473
- namespace: z.string().optional().describe("Namespace to fork to (full path)"),
474
- });
475
- export const CreateBranchSchema = ProjectParamsSchema.extend({
476
- branch: z.string().describe("Name for the new branch"),
477
- ref: z.string().optional().describe("Source branch/commit for new branch"),
478
- });
479
- export const GitLabMergeRequestDiffSchema = z.object({
480
- old_path: z.string(),
481
- new_path: z.string(),
482
- a_mode: z.string(),
483
- b_mode: z.string(),
484
- diff: z.string(),
485
- new_file: z.boolean(),
486
- renamed_file: z.boolean(),
487
- deleted_file: z.boolean(),
488
- });
489
- export const GetMergeRequestSchema = ProjectParamsSchema.extend({
490
- merge_request_iid: z
491
- .number()
492
- .describe("The internal ID of the merge request"),
493
- });
494
- export const UpdateMergeRequestSchema = GetMergeRequestSchema.extend({
495
- title: z.string().optional().describe("The title of the merge request"),
496
- description: z
497
- .string()
498
- .optional()
499
- .describe("The description of the merge request"),
500
- target_branch: z.string().optional().describe("The target branch"),
501
- assignee_ids: z
502
- .array(z.number())
503
- .optional()
504
- .describe("The ID of the users to assign the MR to"),
505
- labels: z.array(z.string()).optional().describe("Labels for the MR"),
506
- state_event: z
507
- .enum(["close", "reopen"])
508
- .optional()
509
- .describe("New state (close/reopen) for the MR"),
510
- remove_source_branch: z
511
- .boolean()
512
- .optional()
513
- .describe("Flag indicating if the source branch should be removed"),
514
- squash: z
515
- .boolean()
516
- .optional()
517
- .describe("Squash commits into a single commit when merging"),
518
- draft: z.boolean().optional().describe("Work in progress merge request"),
519
- });
520
- export const GetMergeRequestDiffsSchema = GetMergeRequestSchema.extend({
521
- view: z.enum(["inline", "parallel"]).optional().describe("Diff view type"),
522
- });
523
- export const CreateNoteSchema = z.object({
524
- project_id: z.string().describe("Project ID or namespace/project_path"),
525
- noteable_type: z
526
- .enum(["issue", "merge_request"])
527
- .describe("Type of noteable (issue or merge_request)"),
528
- noteable_iid: z.number().describe("IID of the issue or merge request"),
529
- body: z.string().describe("Note content"),
530
- });
531
- // Issues API operation schemas
532
- export const ListIssuesSchema = z.object({
533
- project_id: z.string().describe("Project ID or URL-encoded path"),
534
- assignee_id: z.number().optional().describe("Return issues assigned to the given user ID"),
535
- assignee_username: z.string().optional().describe("Return issues assigned to the given username"),
536
- author_id: z.number().optional().describe("Return issues created by the given user ID"),
537
- author_username: z.string().optional().describe("Return issues created by the given username"),
538
- confidential: z.boolean().optional().describe("Filter confidential or public issues"),
539
- created_after: z.string().optional().describe("Return issues created after the given time"),
540
- created_before: z.string().optional().describe("Return issues created before the given time"),
541
- due_date: z.string().optional().describe("Return issues that have the due date"),
542
- label_name: z.array(z.string()).optional().describe("Array of label names"),
543
- milestone: z.string().optional().describe("Milestone title"),
544
- scope: z.enum(['created-by-me', 'assigned-to-me', 'all']).optional().describe("Return issues from a specific scope"),
545
- search: z.string().optional().describe("Search for specific terms"),
546
- state: z.enum(['opened', 'closed', 'all']).optional().describe("Return issues with a specific state"),
547
- updated_after: z.string().optional().describe("Return issues updated after the given time"),
548
- updated_before: z.string().optional().describe("Return issues updated before the given time"),
549
- with_labels_details: z.boolean().optional().describe("Return more details for each label"),
550
- page: z.number().optional().describe("Page number for pagination"),
551
- per_page: z.number().optional().describe("Number of items per page"),
552
- });
553
- export const GetIssueSchema = z.object({
554
- project_id: z.string().describe("Project ID or URL-encoded path"),
555
- issue_iid: z.number().describe("The internal ID of the project issue"),
556
- });
557
- export const UpdateIssueSchema = z.object({
558
- project_id: z.string().describe("Project ID or URL-encoded path"),
559
- issue_iid: z.number().describe("The internal ID of the project issue"),
560
- title: z.string().optional().describe("The title of the issue"),
561
- description: z.string().optional().describe("The description of the issue"),
562
- assignee_ids: z.array(z.number()).optional().describe("Array of user IDs to assign issue to"),
563
- confidential: z.boolean().optional().describe("Set the issue to be confidential"),
564
- discussion_locked: z.boolean().optional().describe("Flag to lock discussions"),
565
- due_date: z.string().optional().describe("Date the issue is due (YYYY-MM-DD)"),
566
- labels: z.array(z.string()).optional().describe("Array of label names"),
567
- milestone_id: z.number().optional().describe("Milestone ID to assign"),
568
- state_event: z.enum(['close', 'reopen']).optional().describe("Update issue state (close/reopen)"),
569
- weight: z.number().optional().describe("Weight of the issue (0-9)"),
570
- });
571
- export const DeleteIssueSchema = z.object({
572
- project_id: z.string().describe("Project ID or URL-encoded path"),
573
- issue_iid: z.number().describe("The internal ID of the project issue"),
574
- });
575
- // Issue links related schemas
576
- export const GitLabIssueLinkSchema = z.object({
577
- source_issue: GitLabIssueSchema,
578
- target_issue: GitLabIssueSchema,
579
- link_type: z.enum(['relates_to', 'blocks', 'is_blocked_by']),
580
- });
581
- export const ListIssueLinksSchema = z.object({
582
- project_id: z.string().describe("Project ID or URL-encoded path"),
583
- issue_iid: z.number().describe("The internal ID of a project's issue"),
584
- });
585
- export const GetIssueLinkSchema = z.object({
586
- project_id: z.string().describe("Project ID or URL-encoded path"),
587
- issue_iid: z.number().describe("The internal ID of a project's issue"),
588
- issue_link_id: z.number().describe("ID of an issue relationship"),
589
- });
590
- export const CreateIssueLinkSchema = z.object({
591
- project_id: z.string().describe("Project ID or URL-encoded path"),
592
- issue_iid: z.number().describe("The internal ID of a project's issue"),
593
- target_project_id: z.string().describe("The ID or URL-encoded path of a target project"),
594
- target_issue_iid: z.number().describe("The internal ID of a target project's issue"),
595
- link_type: z.enum(['relates_to', 'blocks', 'is_blocked_by']).optional().describe("The type of the relation, defaults to relates_to"),
596
- });
597
- export const DeleteIssueLinkSchema = z.object({
598
- project_id: z.string().describe("Project ID or URL-encoded path"),
599
- issue_iid: z.number().describe("The internal ID of a project's issue"),
600
- issue_link_id: z.number().describe("The ID of an issue relationship"),
601
- });
602
- // Namespace API operation schemas
603
- export const ListNamespacesSchema = z.object({
604
- search: z.string().optional().describe("Search term for namespaces"),
605
- page: z.number().optional().describe("Page number for pagination"),
606
- per_page: z.number().optional().describe("Number of items per page"),
607
- owned: z.boolean().optional().describe("Filter for namespaces owned by current user"),
608
- });
609
- export const GetNamespaceSchema = z.object({
610
- namespace_id: z.string().describe("Namespace ID or full path"),
611
- });
612
- export const VerifyNamespaceSchema = z.object({
613
- path: z.string().describe("Namespace path to verify"),
614
- });
615
- // Project API operation schemas
616
- export const GetProjectSchema = z.object({
617
- project_id: z.string().describe("Project ID or URL-encoded path"),
618
- });
619
- export const ListProjectsSchema = z.object({
620
- search: z.string().optional().describe("Search term for projects"),
621
- page: z.number().optional().describe("Page number for pagination"),
622
- per_page: z.number().optional().describe("Number of items per page"),
623
- owned: z.boolean().optional().describe("Filter for projects owned by current user"),
624
- membership: z.boolean().optional().describe("Filter for projects where current user is a member"),
625
- simple: z.boolean().optional().describe("Return only limited fields"),
626
- archived: z.boolean().optional().describe("Filter for archived projects"),
627
- visibility: z.enum(["public", "internal", "private"]).optional().describe("Filter by project visibility"),
628
- order_by: z.enum(["id", "name", "path", "created_at", "updated_at", "last_activity_at"]).optional().describe("Return projects ordered by field"),
629
- sort: z.enum(["asc", "desc"]).optional().describe("Return projects sorted in ascending or descending order"),
630
- with_issues_enabled: z.boolean().optional().describe("Filter projects with issues feature enabled"),
631
- with_merge_requests_enabled: z.boolean().optional().describe("Filter projects with merge requests feature enabled"),
632
- min_access_level: z.number().optional().describe("Filter by minimum access level"),
633
- });
634
- // Label operation schemas
635
- export const ListLabelsSchema = z.object({
636
- project_id: z.string().describe("Project ID or URL-encoded path"),
637
- with_counts: z.boolean().optional().describe("Whether or not to include issue and merge request counts"),
638
- include_ancestor_groups: z.boolean().optional().describe("Include ancestor groups"),
639
- search: z.string().optional().describe("Keyword to filter labels by"),
640
- });
641
- export const GetLabelSchema = z.object({
642
- project_id: z.string().describe("Project ID or URL-encoded path"),
643
- label_id: z.union([z.number(), z.string()]).describe("The ID or title of a project's label"),
644
- include_ancestor_groups: z.boolean().optional().describe("Include ancestor groups"),
645
- });
646
- export const CreateLabelSchema = z.object({
647
- project_id: z.string().describe("Project ID or URL-encoded path"),
648
- name: z.string().describe("The name of the label"),
649
- color: z.string().describe("The color of the label given in 6-digit hex notation with leading '#' sign"),
650
- description: z.string().optional().describe("The description of the label"),
651
- priority: z.number().nullable().optional().describe("The priority of the label"),
652
- });
653
- export const UpdateLabelSchema = z.object({
654
- project_id: z.string().describe("Project ID or URL-encoded path"),
655
- label_id: z.union([z.number(), z.string()]).describe("The ID or title of a project's label"),
656
- new_name: z.string().optional().describe("The new name of the label"),
657
- color: z.string().optional().describe("The color of the label given in 6-digit hex notation with leading '#' sign"),
658
- description: z.string().optional().describe("The new description of the label"),
659
- priority: z.number().nullable().optional().describe("The new priority of the label"),
660
- });
661
- export const DeleteLabelSchema = z.object({
662
- project_id: z.string().describe("Project ID or URL-encoded path"),
663
- label_id: z.union([z.number(), z.string()]).describe("The ID or title of a project's label"),
664
- });
665
- // Group projects schema
666
- export const ListGroupProjectsSchema = z.object({
667
- group_id: z.string().describe("Group ID or path"),
668
- include_subgroups: z.boolean().optional().describe("Include projects from subgroups"),
669
- search: z.string().optional().describe("Search term to filter projects"),
670
- order_by: z.enum(['name', 'path', 'created_at', 'updated_at', 'last_activity_at']).optional().describe("Field to sort by"),
671
- sort: z.enum(['asc', 'desc']).optional().describe("Sort direction"),
672
- page: z.number().optional().describe("Page number"),
673
- per_page: z.number().optional().describe("Number of results per page"),
674
- archived: z.boolean().optional().describe("Filter for archived projects"),
675
- visibility: z.enum(["public", "internal", "private"]).optional().describe("Filter by project visibility"),
676
- with_issues_enabled: z.boolean().optional().describe("Filter projects with issues feature enabled"),
677
- with_merge_requests_enabled: z.boolean().optional().describe("Filter projects with merge requests feature enabled"),
678
- min_access_level: z.number().optional().describe("Filter by minimum access level"),
679
- with_programming_language: z.string().optional().describe("Filter by programming language"),
680
- starred: z.boolean().optional().describe("Filter by starred projects"),
681
- statistics: z.boolean().optional().describe("Include project statistics"),
682
- with_custom_attributes: z.boolean().optional().describe("Include custom attributes"),
683
- with_security_reports: z.boolean().optional().describe("Include security reports")
684
- });