@ekho/gitlab-mcp 1.1.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 (226) hide show
  1. package/LICENSE +21 -0
  2. package/PLAN.md +517 -0
  3. package/README.md +429 -0
  4. package/dist/config.d.ts +35 -0
  5. package/dist/config.js +59 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/groups/access_tokens/tools.d.ts +3 -0
  8. package/dist/groups/access_tokens/tools.js +198 -0
  9. package/dist/groups/access_tokens/tools.js.map +1 -0
  10. package/dist/groups/admin/tools.d.ts +3 -0
  11. package/dist/groups/admin/tools.js +136 -0
  12. package/dist/groups/admin/tools.js.map +1 -0
  13. package/dist/groups/ai_catalog/queries.d.ts +3 -0
  14. package/dist/groups/ai_catalog/queries.js +75 -0
  15. package/dist/groups/ai_catalog/queries.js.map +1 -0
  16. package/dist/groups/ai_catalog/tools.d.ts +3 -0
  17. package/dist/groups/ai_catalog/tools.js +40 -0
  18. package/dist/groups/ai_catalog/tools.js.map +1 -0
  19. package/dist/groups/analytics/queries.d.ts +1 -0
  20. package/dist/groups/analytics/queries.js +28 -0
  21. package/dist/groups/analytics/queries.js.map +1 -0
  22. package/dist/groups/analytics/tools.d.ts +3 -0
  23. package/dist/groups/analytics/tools.js +110 -0
  24. package/dist/groups/analytics/tools.js.map +1 -0
  25. package/dist/groups/audit_events/tools.d.ts +3 -0
  26. package/dist/groups/audit_events/tools.js +112 -0
  27. package/dist/groups/audit_events/tools.js.map +1 -0
  28. package/dist/groups/boards/tools.d.ts +3 -0
  29. package/dist/groups/boards/tools.js +46 -0
  30. package/dist/groups/boards/tools.js.map +1 -0
  31. package/dist/groups/branches/tools.d.ts +3 -0
  32. package/dist/groups/branches/tools.js +122 -0
  33. package/dist/groups/branches/tools.js.map +1 -0
  34. package/dist/groups/ci_catalog/queries.d.ts +2 -0
  35. package/dist/groups/ci_catalog/queries.js +63 -0
  36. package/dist/groups/ci_catalog/queries.js.map +1 -0
  37. package/dist/groups/ci_catalog/tools.d.ts +3 -0
  38. package/dist/groups/ci_catalog/tools.js +45 -0
  39. package/dist/groups/ci_catalog/tools.js.map +1 -0
  40. package/dist/groups/ci_lint/tools.d.ts +3 -0
  41. package/dist/groups/ci_lint/tools.js +36 -0
  42. package/dist/groups/ci_lint/tools.js.map +1 -0
  43. package/dist/groups/ci_variables/tools.d.ts +3 -0
  44. package/dist/groups/ci_variables/tools.js +201 -0
  45. package/dist/groups/ci_variables/tools.js.map +1 -0
  46. package/dist/groups/code_search/tools.d.ts +3 -0
  47. package/dist/groups/code_search/tools.js +70 -0
  48. package/dist/groups/code_search/tools.js.map +1 -0
  49. package/dist/groups/commits/tools.d.ts +3 -0
  50. package/dist/groups/commits/tools.js +192 -0
  51. package/dist/groups/commits/tools.js.map +1 -0
  52. package/dist/groups/compliance/queries.d.ts +1 -0
  53. package/dist/groups/compliance/queries.js +22 -0
  54. package/dist/groups/compliance/queries.js.map +1 -0
  55. package/dist/groups/compliance/tools.d.ts +3 -0
  56. package/dist/groups/compliance/tools.js +104 -0
  57. package/dist/groups/compliance/tools.js.map +1 -0
  58. package/dist/groups/container_registry/tools.d.ts +3 -0
  59. package/dist/groups/container_registry/tools.js +113 -0
  60. package/dist/groups/container_registry/tools.js.map +1 -0
  61. package/dist/groups/custom_roles/queries.d.ts +5 -0
  62. package/dist/groups/custom_roles/queries.js +69 -0
  63. package/dist/groups/custom_roles/queries.js.map +1 -0
  64. package/dist/groups/custom_roles/tools.d.ts +3 -0
  65. package/dist/groups/custom_roles/tools.js +84 -0
  66. package/dist/groups/custom_roles/tools.js.map +1 -0
  67. package/dist/groups/deployments/tools.d.ts +3 -0
  68. package/dist/groups/deployments/tools.js +98 -0
  69. package/dist/groups/deployments/tools.js.map +1 -0
  70. package/dist/groups/discussions/tools.d.ts +3 -0
  71. package/dist/groups/discussions/tools.js +144 -0
  72. package/dist/groups/discussions/tools.js.map +1 -0
  73. package/dist/groups/duo_chat/queries.d.ts +4 -0
  74. package/dist/groups/duo_chat/queries.js +76 -0
  75. package/dist/groups/duo_chat/queries.js.map +1 -0
  76. package/dist/groups/duo_chat/tools.d.ts +3 -0
  77. package/dist/groups/duo_chat/tools.js +95 -0
  78. package/dist/groups/duo_chat/tools.js.map +1 -0
  79. package/dist/groups/environments/tools.d.ts +3 -0
  80. package/dist/groups/environments/tools.js +105 -0
  81. package/dist/groups/environments/tools.js.map +1 -0
  82. package/dist/groups/events/tools.d.ts +3 -0
  83. package/dist/groups/events/tools.js +64 -0
  84. package/dist/groups/events/tools.js.map +1 -0
  85. package/dist/groups/feature_flags/tools.d.ts +3 -0
  86. package/dist/groups/feature_flags/tools.js +137 -0
  87. package/dist/groups/feature_flags/tools.js.map +1 -0
  88. package/dist/groups/groups/tools.d.ts +3 -0
  89. package/dist/groups/groups/tools.js +145 -0
  90. package/dist/groups/groups/tools.js.map +1 -0
  91. package/dist/groups/integrations/tools.d.ts +3 -0
  92. package/dist/groups/integrations/tools.js +143 -0
  93. package/dist/groups/integrations/tools.js.map +1 -0
  94. package/dist/groups/jobs/tools.d.ts +3 -0
  95. package/dist/groups/jobs/tools.js +209 -0
  96. package/dist/groups/jobs/tools.js.map +1 -0
  97. package/dist/groups/keys/tools.d.ts +3 -0
  98. package/dist/groups/keys/tools.js +140 -0
  99. package/dist/groups/keys/tools.js.map +1 -0
  100. package/dist/groups/labels/tools.d.ts +3 -0
  101. package/dist/groups/labels/tools.js +110 -0
  102. package/dist/groups/labels/tools.js.map +1 -0
  103. package/dist/groups/members/tools.d.ts +3 -0
  104. package/dist/groups/members/tools.js +136 -0
  105. package/dist/groups/members/tools.js.map +1 -0
  106. package/dist/groups/merge_requests/tools.d.ts +3 -0
  107. package/dist/groups/merge_requests/tools.js +288 -0
  108. package/dist/groups/merge_requests/tools.js.map +1 -0
  109. package/dist/groups/milestones/tools.d.ts +3 -0
  110. package/dist/groups/milestones/tools.js +143 -0
  111. package/dist/groups/milestones/tools.js.map +1 -0
  112. package/dist/groups/packages/tools.d.ts +3 -0
  113. package/dist/groups/packages/tools.js +157 -0
  114. package/dist/groups/packages/tools.js.map +1 -0
  115. package/dist/groups/pipeline_schedules/tools.d.ts +3 -0
  116. package/dist/groups/pipeline_schedules/tools.js +127 -0
  117. package/dist/groups/pipeline_schedules/tools.js.map +1 -0
  118. package/dist/groups/pipeline_triggers/tools.d.ts +3 -0
  119. package/dist/groups/pipeline_triggers/tools.js +74 -0
  120. package/dist/groups/pipeline_triggers/tools.js.map +1 -0
  121. package/dist/groups/pipelines/tools.d.ts +3 -0
  122. package/dist/groups/pipelines/tools.js +140 -0
  123. package/dist/groups/pipelines/tools.js.map +1 -0
  124. package/dist/groups/projects/tools.d.ts +3 -0
  125. package/dist/groups/projects/tools.js +189 -0
  126. package/dist/groups/projects/tools.js.map +1 -0
  127. package/dist/groups/protected_environments/tools.d.ts +3 -0
  128. package/dist/groups/protected_environments/tools.js +77 -0
  129. package/dist/groups/protected_environments/tools.js.map +1 -0
  130. package/dist/groups/releases/tools.d.ts +3 -0
  131. package/dist/groups/releases/tools.js +153 -0
  132. package/dist/groups/releases/tools.js.map +1 -0
  133. package/dist/groups/repository_files/tools.d.ts +3 -0
  134. package/dist/groups/repository_files/tools.js +163 -0
  135. package/dist/groups/repository_files/tools.js.map +1 -0
  136. package/dist/groups/runners/tools.d.ts +3 -0
  137. package/dist/groups/runners/tools.js +108 -0
  138. package/dist/groups/runners/tools.js.map +1 -0
  139. package/dist/groups/search/tools.d.ts +3 -0
  140. package/dist/groups/search/tools.js +58 -0
  141. package/dist/groups/search/tools.js.map +1 -0
  142. package/dist/groups/secrets/queries.d.ts +10 -0
  143. package/dist/groups/secrets/queries.js +121 -0
  144. package/dist/groups/secrets/queries.js.map +1 -0
  145. package/dist/groups/secrets/tools.d.ts +8 -0
  146. package/dist/groups/secrets/tools.js +167 -0
  147. package/dist/groups/secrets/tools.js.map +1 -0
  148. package/dist/groups/security_policies/queries.d.ts +3 -0
  149. package/dist/groups/security_policies/queries.js +75 -0
  150. package/dist/groups/security_policies/queries.js.map +1 -0
  151. package/dist/groups/security_policies/tools.d.ts +3 -0
  152. package/dist/groups/security_policies/tools.js +40 -0
  153. package/dist/groups/security_policies/tools.js.map +1 -0
  154. package/dist/groups/security_reports/queries.d.ts +1 -0
  155. package/dist/groups/security_reports/queries.js +75 -0
  156. package/dist/groups/security_reports/queries.js.map +1 -0
  157. package/dist/groups/security_reports/tools.d.ts +3 -0
  158. package/dist/groups/security_reports/tools.js +51 -0
  159. package/dist/groups/security_reports/tools.js.map +1 -0
  160. package/dist/groups/snippets/tools.d.ts +3 -0
  161. package/dist/groups/snippets/tools.js +148 -0
  162. package/dist/groups/snippets/tools.js.map +1 -0
  163. package/dist/groups/statistics/queries.d.ts +2 -0
  164. package/dist/groups/statistics/queries.js +32 -0
  165. package/dist/groups/statistics/queries.js.map +1 -0
  166. package/dist/groups/statistics/tools.d.ts +3 -0
  167. package/dist/groups/statistics/tools.js +35 -0
  168. package/dist/groups/statistics/tools.js.map +1 -0
  169. package/dist/groups/tags/tools.d.ts +3 -0
  170. package/dist/groups/tags/tools.js +97 -0
  171. package/dist/groups/tags/tools.js.map +1 -0
  172. package/dist/groups/todos/tools.d.ts +3 -0
  173. package/dist/groups/todos/tools.js +93 -0
  174. package/dist/groups/todos/tools.js.map +1 -0
  175. package/dist/groups/users/tools.d.ts +3 -0
  176. package/dist/groups/users/tools.js +121 -0
  177. package/dist/groups/users/tools.js.map +1 -0
  178. package/dist/groups/vulnerabilities/queries.d.ts +3 -0
  179. package/dist/groups/vulnerabilities/queries.js +104 -0
  180. package/dist/groups/vulnerabilities/queries.js.map +1 -0
  181. package/dist/groups/vulnerabilities/tools.d.ts +3 -0
  182. package/dist/groups/vulnerabilities/tools.js +131 -0
  183. package/dist/groups/vulnerabilities/tools.js.map +1 -0
  184. package/dist/groups/webhooks/tools.d.ts +3 -0
  185. package/dist/groups/webhooks/tools.js +213 -0
  186. package/dist/groups/webhooks/tools.js.map +1 -0
  187. package/dist/groups/wiki/tools.d.ts +3 -0
  188. package/dist/groups/wiki/tools.js +142 -0
  189. package/dist/groups/wiki/tools.js.map +1 -0
  190. package/dist/groups/work_items/queries.d.ts +16 -0
  191. package/dist/groups/work_items/queries.js +181 -0
  192. package/dist/groups/work_items/queries.js.map +1 -0
  193. package/dist/groups/work_items/tools.d.ts +3 -0
  194. package/dist/groups/work_items/tools.js +250 -0
  195. package/dist/groups/work_items/tools.js.map +1 -0
  196. package/dist/http/errors.d.ts +21 -0
  197. package/dist/http/errors.js +62 -0
  198. package/dist/http/errors.js.map +1 -0
  199. package/dist/http/graphql.d.ts +29 -0
  200. package/dist/http/graphql.js +93 -0
  201. package/dist/http/graphql.js.map +1 -0
  202. package/dist/http/rest.d.ts +96 -0
  203. package/dist/http/rest.js +369 -0
  204. package/dist/http/rest.js.map +1 -0
  205. package/dist/index.d.ts +2 -0
  206. package/dist/index.js +25 -0
  207. package/dist/index.js.map +1 -0
  208. package/dist/shared/args.d.ts +51 -0
  209. package/dist/shared/args.js +46 -0
  210. package/dist/shared/args.js.map +1 -0
  211. package/dist/shared/handlers.d.ts +6 -0
  212. package/dist/shared/handlers.js +14 -0
  213. package/dist/shared/handlers.js.map +1 -0
  214. package/dist/shared/ids.d.ts +18 -0
  215. package/dist/shared/ids.js +43 -0
  216. package/dist/shared/ids.js.map +1 -0
  217. package/dist/tools/meta.d.ts +3 -0
  218. package/dist/tools/meta.js +22 -0
  219. package/dist/tools/meta.js.map +1 -0
  220. package/dist/tools/registry.d.ts +3 -0
  221. package/dist/tools/registry.js +117 -0
  222. package/dist/tools/registry.js.map +1 -0
  223. package/dist/tools/types.d.ts +18 -0
  224. package/dist/tools/types.js +20 -0
  225. package/dist/tools/types.js.map +1 -0
  226. package/package.json +72 -0
package/README.md ADDED
@@ -0,0 +1,429 @@
1
+ # gitlab-mcp
2
+
3
+ Model Context Protocol server for GitLab. Speaks both REST and GraphQL — picks the better transport per operation. Targets **gitlab.com** primarily, with best-effort support for self-managed instances.
4
+
5
+ Status: **v1.1.0** — all 10 phases shipped plus multipart upload (wiki attachments) and binary transfers (job artifacts, generic package files). Groups B, C, A, D, F, E, G, H, J, I — full coverage of the planned roadmap. See [`PLAN.md`](PLAN.md) for details on each phase.
6
+
7
+ ## Install
8
+
9
+ From npm:
10
+
11
+ ```bash
12
+ npm install -g @ekho/gitlab-mcp
13
+ # or as a local dep
14
+ npm install @ekho/gitlab-mcp
15
+ ```
16
+
17
+ From source:
18
+
19
+ ```bash
20
+ git clone https://gitlab.com/ekho_0/gitlab-mcp.git
21
+ cd gitlab-mcp
22
+ npm install
23
+ npm run build
24
+ ```
25
+
26
+ ## Configuration
27
+
28
+ The server reads environment variables:
29
+
30
+ | Variable | Required | Default | Notes |
31
+ |---|---|---|---|
32
+ | `GITLAB_TOKEN` | yes | — | PAT, OAuth access token, project/group access token, or CI job token |
33
+ | `GITLAB_TOKEN_TYPE` | no | `pat` | `pat` \| `oauth` \| `job` — controls auth header |
34
+ | `GITLAB_BASE_URL` | no | `https://gitlab.com` | Override for self-managed |
35
+ | `GITLAB_DEFAULT_PROJECT` | no | — | Numeric id or full path (`group/sub/project`). Used when a tool's `project_id` arg is omitted. |
36
+ | `GITLAB_DEFAULT_GROUP` | no | — | Numeric id or full path |
37
+ | `GITLAB_REQUEST_TIMEOUT_MS` | no | `30000` | Per-request timeout |
38
+ | `GITLAB_MAX_RETRIES` | no | `3` | Retries on 429 and 5xx with exponential backoff |
39
+ | `GITLAB_USER_AGENT` | no | `gitlab-mcp/<ver>` | Sent as `User-Agent` |
40
+
41
+ ### Required token scopes (PAT)
42
+
43
+ - `api` — full read/write. Required for the write-heavy tools planned for Phase 1+.
44
+ - `read_api` — read-only mode if you only need listing/inspection tools.
45
+
46
+ ## Wire into an MCP client
47
+
48
+ For a stdio-based MCP client (e.g. Claude Code):
49
+
50
+ ```json
51
+ {
52
+ "mcpServers": {
53
+ "gitlab": {
54
+ "command": "node",
55
+ "args": ["/absolute/path/to/gitlab-mcp/dist/index.js"],
56
+ "env": {
57
+ "GITLAB_TOKEN": "glpat-...",
58
+ "GITLAB_DEFAULT_PROJECT": "your-group/your-project"
59
+ }
60
+ }
61
+ }
62
+ }
63
+ ```
64
+
65
+ ## Currently shipped tools
66
+
67
+ ### Smoke
68
+ - `metadata_get`, `user_current`
69
+
70
+ ### Merge Requests (B1)
71
+ - `merge_request_list`, `merge_request_get`, `merge_request_create`, `merge_request_update`
72
+ - `merge_request_merge`, `merge_request_rebase`, `merge_request_close`, `merge_request_reopen`
73
+ - `merge_request_changes`, `merge_request_commits`, `merge_request_pipelines`, `merge_request_participants`
74
+
75
+ ### Approvals (B2)
76
+ - `merge_request_approve`, `merge_request_unapprove`, `merge_request_approval_state`
77
+ - `approval_rule_list`, `approval_rule_create`, `approval_rule_update`, `approval_rule_delete`
78
+
79
+ ### Discussions & Notes (B3)
80
+ - `discussion_list`, `discussion_create`, `discussion_reply`, `discussion_resolve`
81
+ - `note_update`, `note_delete`, `suggestion_create`
82
+
83
+ ### Work Items (B4, B5) — via GraphQL
84
+ - `work_item_list`, `work_item_get`, `work_item_types_list`
85
+ - `work_item_create`, `work_item_update`, `work_item_delete`
86
+
87
+ Epics are work items with `type=Epic`. Hierarchy (`parent_id`) sets the parent relationship.
88
+
89
+ ### Labels (B6)
90
+ - `label_list_project`, `label_list_group`
91
+ - `label_create`, `label_update`, `label_delete`
92
+ - `label_subscribe`, `label_unsubscribe`
93
+
94
+ ### Milestones & Iterations (B7)
95
+ - `milestone_list_project`, `milestone_list_group`, `milestone_get`
96
+ - `milestone_create`, `milestone_update`, `milestone_close`, `milestone_delete`
97
+ - `iteration_list_group`
98
+
99
+ ### Boards (B8) — read-only
100
+ - `board_list_project`, `board_list_group`, `board_get`, `board_list_lists`
101
+
102
+ ### Todos & Notifications (B9)
103
+ - `todo_list`, `todo_mark_done`, `todo_mark_all_done`
104
+ - `notification_settings_get`, `notification_settings_update`
105
+
106
+ ### Pipelines (C1)
107
+ - `pipeline_list`, `pipeline_get`, `pipeline_latest`
108
+ - `pipeline_create`, `pipeline_retry`, `pipeline_cancel`, `pipeline_delete`
109
+ - `pipeline_variables`, `pipeline_test_report`, `pipeline_test_report_summary`
110
+
111
+ ### Jobs (C2)
112
+ - `job_list_pipeline`, `job_list_project`, `job_get`
113
+ - `job_log` (with optional `tail_kb`), `job_retry`, `job_cancel`, `job_play`, `job_erase`
114
+ - `job_artifacts_keep`, `job_artifacts_delete`
115
+ - `job_artifacts_download` (full ZIP), `job_artifact_file_download` (single file)
116
+ - `job_artifacts_download_by_ref`, `job_artifact_file_download_by_ref`
117
+ - All `*_download*` accept `save_to` (write to file) or return base64 (capped by `max_inline_bytes`)
118
+
119
+ ### Pipeline Schedules (C3)
120
+ - `schedule_list`, `schedule_get`, `schedule_create`, `schedule_update`, `schedule_delete`
121
+ - `schedule_play`, `schedule_take_ownership`
122
+ - `schedule_variable_create`, `schedule_variable_update`, `schedule_variable_delete`
123
+
124
+ ### Pipeline Triggers (C4)
125
+ - `trigger_list`, `trigger_get`, `trigger_create`, `trigger_update`, `trigger_delete`
126
+ - `trigger_run_pipeline` (passes variables as `variables[KEY]=value`)
127
+
128
+ ### CI/CD Variables (C5)
129
+ - `variable_list_project|group|instance`, `variable_get_*`
130
+ - `variable_create_*`, `variable_update_*`, `variable_delete_*`
131
+ - Project/group variants accept `filter_environment_scope` to disambiguate by env
132
+
133
+ ### Runners (C6)
134
+ - `runner_list` (own), `runner_list_all` (admin), `runner_list_project`, `runner_list_group`
135
+ - `runner_get`, `runner_update`, `runner_pause`, `runner_delete`, `runner_jobs`
136
+
137
+ ### CI Lint (C7)
138
+ - `ci_lint` (instance), `ci_lint_project` (with include context, ref, dry_run, merged_yaml)
139
+
140
+ ### CI Catalog (C8) — GraphQL
141
+ - `catalog_resource_list`, `catalog_resource_get`
142
+
143
+ ### Projects (A1)
144
+ - `project_list`, `project_get`, `project_create`, `project_fork`
145
+ - `project_update`, `project_archive`, `project_unarchive`, `project_delete`
146
+ - `project_languages`, `project_star`, `project_unstar`, `project_transfer`
147
+
148
+ ### Groups (A2)
149
+ - `group_list`, `group_get`, `group_create`, `group_update`, `group_delete`
150
+ - `group_subgroups`, `group_descendants`, `group_projects`, `group_shared_projects`
151
+ - `group_transfer_project`
152
+
153
+ ### Repository files (A3)
154
+ - `file_get`, `file_get_raw`, `file_create`, `file_update`, `file_delete`
155
+ - `file_blame`, `tree_list`
156
+ - `commit_actions` (batch create/update/delete/move/chmod in a single commit)
157
+
158
+ ### Branches (A4)
159
+ - `branch_list`, `branch_get`, `branch_create`, `branch_delete`, `branch_delete_merged`
160
+ - `protected_branch_list`, `protected_branch_get`, `protected_branch_protect`
161
+ - `protected_branch_update`, `protected_branch_unprotect`
162
+
163
+ ### Tags (A5)
164
+ - `tag_list`, `tag_get`, `tag_create`, `tag_delete`
165
+ - `protected_tag_list`, `protected_tag_get`, `protected_tag_protect`, `protected_tag_unprotect`
166
+
167
+ ### Commits & Compare (A6, A7)
168
+ - `commit_list`, `commit_get`, `commit_diff`, `commit_refs`
169
+ - `commit_cherry_pick`, `commit_revert`
170
+ - `commit_comment_list`, `commit_comment_create`
171
+ - `commit_status_list`, `commit_status_set`
172
+ - `repository_compare`, `repository_merge_base`
173
+
174
+ ### Code search (A8)
175
+ - `code_search`, `commit_search`, `wiki_search` (each accepts scope: global | group | project)
176
+
177
+ ### Releases (D1)
178
+ - `release_list`, `release_get`, `release_create`, `release_update`, `release_delete`
179
+ - `release_link_list`, `release_link_get`, `release_link_create`, `release_link_update`, `release_link_delete`
180
+
181
+ ### Environments (D2)
182
+ - `environment_list`, `environment_get`
183
+ - `environment_create`, `environment_update`, `environment_delete`
184
+ - `environment_stop`, `environment_stop_stale`
185
+
186
+ ### Deployments (D3)
187
+ - `deployment_list`, `deployment_get`, `deployment_create`, `deployment_update`
188
+ - `deployment_approval` (approve/reject for protected envs)
189
+ - `deployment_merge_requests`
190
+
191
+ ### Feature Flags (D4)
192
+ - `feature_flag_list`, `feature_flag_get`, `feature_flag_create`, `feature_flag_update`, `feature_flag_delete`
193
+ - `feature_flag_user_list_list`, `feature_flag_user_list_get`,
194
+ `feature_flag_user_list_create`, `feature_flag_user_list_update`, `feature_flag_user_list_delete`
195
+
196
+ ### Packages (D5)
197
+ - `package_list_project`, `package_list_group`, `package_get`
198
+ - `package_files`, `package_file_delete`, `package_delete`
199
+ - Generic registry: `package_file_download_generic`, `package_file_upload_generic`
200
+ (accepts `content_base64` or `local_path`)
201
+
202
+ ### Container Registry (D6)
203
+ - `registry_repository_list_project`, `registry_repository_list_group`
204
+ - `registry_repository_get`, `registry_repository_delete`
205
+ - `registry_tag_list`, `registry_tag_get`
206
+ - `registry_tag_delete`, `registry_tag_bulk_delete` (by regex with keep_n/older_than)
207
+
208
+ ### Users (F1)
209
+ - `user_list`, `user_get`, `user_search`, `user_create`, `user_update`, `user_delete`
210
+ - `user_block`/`user_unblock`/`user_activate`/`user_deactivate`/`user_ban`/`user_unban`
211
+ - `user_set_state` (convenience by enum)
212
+
213
+ ### Members (F2)
214
+ - `member_list_project`, `member_list_group` (with `inherited` flag for "all")
215
+ - `member_get`, `member_add`, `member_update`, `member_remove`
216
+ - `billable_member_list_group`, `billable_member_remove_group`
217
+
218
+ ### Access Tokens (F3)
219
+ - `pat_list`, `pat_get`, `pat_create_self` (16.5+), `pat_create_for_user` (admin)
220
+ - `pat_revoke`, `pat_rotate`
221
+ - `project_access_token_list`/`create`/`revoke`/`rotate`
222
+ - `group_access_token_list`/`create`/`revoke`/`rotate`
223
+
224
+ ### Keys (F4)
225
+ - SSH: `ssh_key_list`, `ssh_key_get`, `ssh_key_create`, `ssh_key_delete`
226
+ - GPG: `gpg_key_list`, `gpg_key_create`, `gpg_key_delete`
227
+ - Deploy: `deploy_key_list_project`/`list_all`/`get`/`add`/`update`/`enable`/`delete`
228
+
229
+ ### Custom Roles (F5) — Premium+, GraphQL
230
+ - `member_role_list_group`, `member_role_create`, `member_role_update`, `member_role_delete`
231
+
232
+ ### Vulnerabilities (E1) — Ultimate
233
+ - `vulnerability_list_project`, `vulnerability_list_group` (GraphQL)
234
+ - `vulnerability_get` (REST)
235
+ - `vulnerability_dismiss`/`confirm`/`resolve`/`revert` (REST)
236
+ - `vulnerability_create_issue_link`
237
+
238
+ ### Security Reports (E2) — Ultimate
239
+ - `security_report_findings_pipeline` (GraphQL, per pipeline)
240
+
241
+ ### Security Policies (E3) — Ultimate, read-only
242
+ - `security_policy_list_project`, `security_policy_list_group`
243
+ - `security_policy_sync_status`
244
+
245
+ ### Compliance Frameworks (E4) — Premium+
246
+ - `compliance_framework_list`, `compliance_framework_get`
247
+ - `compliance_framework_create`, `compliance_framework_update`, `compliance_framework_delete`
248
+ - `compliance_framework_assign_project` (via GraphQL, accepts framework_id=null to unassign)
249
+
250
+ ### Audit Events (E5) — Premium+
251
+ - `audit_event_list_instance`/`list_group`/`list_project` + `get_*`
252
+ - Streaming (Ultimate): `audit_streaming_destination_list`/`get`/`create`/`update`/`delete`
253
+
254
+ ### Secrets Management (E6) — GraphQL, project 17.8+ / group 18.9+
255
+ - `project_secret_list`, `project_secret_get`, `project_secret_create`,
256
+ `project_secret_update`, `project_secret_delete`
257
+ - `group_secret_list`, `group_secret_get`, `group_secret_create`,
258
+ `group_secret_update`, `group_secret_delete`
259
+
260
+ ### Protected Environments (E7) — Premium+
261
+ - `protected_environment_list`, `protected_environment_get`
262
+ - `protected_environment_protect`, `protected_environment_update`, `protected_environment_unprotect`
263
+
264
+ ### Webhooks (G1)
265
+ - Project: `hook_list_project`/`get_project`/`create_project`/`update_project`/`delete_project`/`test_project`
266
+ - Group: `hook_list_group`/`get_group`/`create_group`/`update_group`/`delete_group`/`test_group`
267
+ - System (admin): `hook_list_system`/`create_system`/`delete_system`/`test_system`
268
+
269
+ ### Integrations (G2)
270
+ - Generic: `integration_list_project`, `integration_get`, `integration_set` (any slug), `integration_delete`
271
+ - Shortcuts: `integration_set_slack`, `integration_set_mattermost`, `integration_set_jira`, `integration_set_microsoft_teams`
272
+
273
+ ### Events (G3)
274
+ - `event_list_current_user`, `event_list_user`, `event_list_project`
275
+
276
+ ### Wiki (H1)
277
+ - `wiki_list_project`, `wiki_list_group`
278
+ - `wiki_get`, `wiki_create`, `wiki_update`, `wiki_delete` (scope: project | group)
279
+ - `wiki_attachment_upload` (multipart) — accepts `content_base64` or `local_path`
280
+
281
+ ### Snippets (H2)
282
+ - Personal: `snippet_list_personal`/`list_public`/`get`/`create`/`update`/`delete`/`raw`
283
+ - Project: `snippet_list_project`/`get_project`/`create_project`/`update_project`/`delete_project`/`raw_project`
284
+ - Multi-file snippets via `files: [{action, file_path, content, ...}]`
285
+
286
+ ### Search (H3)
287
+ - `search` (single tool) — `where: global | group | project`, `scope: projects | issues | merge_requests | milestones | snippet_titles | snippet_blobs | users | blobs | commits | wiki_blobs | notes`
288
+
289
+ ### Analytics (J1)
290
+ - `dora_metrics_project`, `dora_metrics_group` (Ultimate)
291
+ - `contribution_analytics_group`
292
+ - `group_activity_issues_count`, `group_activity_merge_requests_count`, `group_activity_new_members_count`
293
+ - `usage_trends_get` (GraphQL, instance admin)
294
+
295
+ ### Statistics (J2)
296
+ - `project_storage_breakdown`, `group_storage_breakdown`
297
+ - `ci_minutes_usage_namespace`
298
+
299
+ ### Admin / Instance (J3) — admin only
300
+ - `application_settings_get`, `application_settings_update`
301
+ - `application_list`, `application_create`, `application_delete` (OAuth apps)
302
+ - `broadcast_message_list`/`get`/`create`/`update`/`delete`
303
+ - `license_get_current`, `license_list`, `license_add`, `license_delete` (self-managed)
304
+ - `version_get`
305
+
306
+ ### Duo Chat (I1) — GraphQL, gitlab.com Duo / Duo Enterprise
307
+ - `ai_thread_list`, `ai_message_list`, `ai_chat_context_presets`
308
+ - `ai_chat_send` — returns request_id; poll `ai_message_list` for the response
309
+
310
+ ### AI Catalog (I2) — GraphQL
311
+ - `ai_catalog_item_list`, `ai_catalog_item_get`
312
+ - `ai_self_hosted_model_list` (Duo Enterprise on-prem)
313
+
314
+ ## Development
315
+
316
+ ```bash
317
+ npm run dev # tsx watch on src/index.ts
318
+ npm run typecheck # tsc --noEmit
319
+ npm test # unit tests (mocked HTTP, no network)
320
+ npm run lint
321
+ npm run format
322
+ ```
323
+
324
+ Live smoke test against the configured GitLab (hits real endpoints):
325
+
326
+ ```bash
327
+ GITLAB_TOKEN=glpat-... npm run test:smoke
328
+ ```
329
+
330
+ ## Releasing
331
+
332
+ The repo ships with a `.gitlab-ci.yml` that runs typecheck/tests/build on every push and publishes to npm on `v*` tags.
333
+
334
+ **One-time setup:**
335
+ 1. Create an automation token at https://www.npmjs.com/settings/<user>/tokens (use "Automation" type so npm 2FA does not block CI).
336
+ 2. In GitLab: Settings → CI/CD → Variables → Add variable
337
+ - Key: `NPM_TOKEN`
338
+ - Value: <the token>
339
+ - Flags: **Masked** and **Protected**
340
+ 3. Make sure the `v*` tag pattern is protected: Settings → Repository → Protected tags → Add `v*`.
341
+
342
+ **Cutting a release:**
343
+ ```bash
344
+ # 1. Bump the version in package.json (manually or via npm version <patch|minor|major>)
345
+ npm version minor # also creates the commit and the v<N> tag
346
+ git push --follow-tags
347
+ ```
348
+
349
+ The `publish_npm` job will fire on the tag pipeline. It verifies that the tag (`v1.2.0` → `1.2.0`) matches `package.json` before running `npm publish`.
350
+
351
+ **Local publish (no CI):**
352
+ ```bash
353
+ npm login # interactive, browser-based
354
+ npm pack --dry-run # preview tarball contents
355
+ npm publish --access public # publishes the current version
356
+ ```
357
+ `prepublishOnly` will clean, typecheck, test, and build first.
358
+
359
+ ## Architecture
360
+
361
+ ```
362
+ src/
363
+ index.ts # MCP stdio entry
364
+ config.ts # env → Config via zod
365
+ http/
366
+ rest.ts # undici-based REST with retry, pagination
367
+ graphql.ts # POST /api/graphql with errors[] surfacing
368
+ errors.ts # GitLabApiError
369
+ shared/
370
+ ids.ts # encodeId, resolveProject/GroupId, toGlobalId
371
+ tools/
372
+ registry.ts # registers each group
373
+ meta.ts # smoke tools
374
+ types.ts # ToolContext + result helpers
375
+ groups/ # one folder per functional group
376
+ merge_requests/ # B1 + B2
377
+ discussions/ # B3
378
+ work_items/ # B4 + B5 (GraphQL)
379
+ labels/ # B6
380
+ milestones/ # B7
381
+ boards/ # B8
382
+ todos/ # B9
383
+ pipelines/ # C1
384
+ jobs/ # C2
385
+ pipeline_schedules/ # C3
386
+ pipeline_triggers/ # C4
387
+ ci_variables/ # C5
388
+ runners/ # C6
389
+ ci_lint/ # C7
390
+ ci_catalog/ # C8 (GraphQL)
391
+ projects/ # A1
392
+ groups/ # A2
393
+ repository_files/ # A3
394
+ branches/ # A4
395
+ tags/ # A5
396
+ commits/ # A6 + A7
397
+ code_search/ # A8
398
+ releases/ # D1
399
+ environments/ # D2
400
+ deployments/ # D3
401
+ feature_flags/ # D4
402
+ packages/ # D5
403
+ container_registry/ # D6
404
+ users/ # F1
405
+ members/ # F2
406
+ access_tokens/ # F3
407
+ keys/ # F4
408
+ custom_roles/ # F5 (GraphQL)
409
+ vulnerabilities/ # E1 (REST + GraphQL)
410
+ security_reports/ # E2 (GraphQL)
411
+ security_policies/ # E3 (GraphQL)
412
+ compliance/ # E4
413
+ audit_events/ # E5
414
+ secrets/ # E6 (GraphQL)
415
+ protected_environments/ # E7
416
+ webhooks/ # G1
417
+ integrations/ # G2
418
+ events/ # G3
419
+ wiki/ # H1
420
+ snippets/ # H2
421
+ search/ # H3
422
+ analytics/ # J1
423
+ statistics/ # J2
424
+ admin/ # J3
425
+ duo_chat/ # I1 (GraphQL)
426
+ ai_catalog/ # I2 (GraphQL)
427
+ ```
428
+
429
+ Each future group lands as a new folder under `src/groups/`. See [`PLAN.md`](PLAN.md) for the per-group tool inventory.
@@ -0,0 +1,35 @@
1
+ import { z } from 'zod';
2
+ declare const TokenType: z.ZodEnum<["pat", "oauth", "job"]>;
3
+ export type TokenType = z.infer<typeof TokenType>;
4
+ declare const ConfigSchema: z.ZodObject<{
5
+ baseUrl: z.ZodDefault<z.ZodString>;
6
+ token: z.ZodString;
7
+ tokenType: z.ZodDefault<z.ZodEnum<["pat", "oauth", "job"]>>;
8
+ defaultProject: z.ZodOptional<z.ZodString>;
9
+ defaultGroup: z.ZodOptional<z.ZodString>;
10
+ userAgent: z.ZodDefault<z.ZodString>;
11
+ requestTimeoutMs: z.ZodDefault<z.ZodNumber>;
12
+ maxRetries: z.ZodDefault<z.ZodNumber>;
13
+ }, "strip", z.ZodTypeAny, {
14
+ baseUrl: string;
15
+ token: string;
16
+ tokenType: "pat" | "oauth" | "job";
17
+ userAgent: string;
18
+ requestTimeoutMs: number;
19
+ maxRetries: number;
20
+ defaultProject?: string | undefined;
21
+ defaultGroup?: string | undefined;
22
+ }, {
23
+ token: string;
24
+ baseUrl?: string | undefined;
25
+ tokenType?: "pat" | "oauth" | "job" | undefined;
26
+ defaultProject?: string | undefined;
27
+ defaultGroup?: string | undefined;
28
+ userAgent?: string | undefined;
29
+ requestTimeoutMs?: number | undefined;
30
+ maxRetries?: number | undefined;
31
+ }>;
32
+ export type Config = z.infer<typeof ConfigSchema>;
33
+ export declare function loadConfig(env?: NodeJS.ProcessEnv): Config;
34
+ export declare function authHeader(cfg: Pick<Config, 'token' | 'tokenType'>): Record<string, string>;
35
+ export {};
package/dist/config.js ADDED
@@ -0,0 +1,59 @@
1
+ import { z } from 'zod';
2
+ const TokenType = z.enum(['pat', 'oauth', 'job']);
3
+ const ConfigSchema = z.object({
4
+ baseUrl: z.string().url().default('https://gitlab.com'),
5
+ token: z.string().min(1, 'GITLAB_TOKEN is required'),
6
+ tokenType: TokenType.default('pat'),
7
+ defaultProject: z.string().optional(),
8
+ defaultGroup: z.string().optional(),
9
+ userAgent: z.string().default('gitlab-mcp/0.0.1'),
10
+ requestTimeoutMs: z.number().int().positive().default(30_000),
11
+ maxRetries: z.number().int().min(0).default(3),
12
+ });
13
+ export function loadConfig(env = process.env) {
14
+ const parsed = ConfigSchema.safeParse({
15
+ baseUrl: env.GITLAB_BASE_URL,
16
+ token: env.GITLAB_TOKEN,
17
+ tokenType: env.GITLAB_TOKEN_TYPE,
18
+ defaultProject: env.GITLAB_DEFAULT_PROJECT,
19
+ defaultGroup: env.GITLAB_DEFAULT_GROUP,
20
+ userAgent: env.GITLAB_USER_AGENT,
21
+ requestTimeoutMs: env.GITLAB_REQUEST_TIMEOUT_MS
22
+ ? Number(env.GITLAB_REQUEST_TIMEOUT_MS)
23
+ : undefined,
24
+ maxRetries: env.GITLAB_MAX_RETRIES ? Number(env.GITLAB_MAX_RETRIES) : undefined,
25
+ });
26
+ if (!parsed.success) {
27
+ const issues = parsed.error.issues
28
+ .map((i) => ` - ${envNameFor(i.path[0])}: ${i.message}`)
29
+ .join('\n');
30
+ throw new Error(`Invalid GitLab MCP configuration:\n${issues}`);
31
+ }
32
+ return parsed.data;
33
+ }
34
+ const ENV_FOR_FIELD = {
35
+ baseUrl: 'GITLAB_BASE_URL',
36
+ token: 'GITLAB_TOKEN',
37
+ tokenType: 'GITLAB_TOKEN_TYPE',
38
+ defaultProject: 'GITLAB_DEFAULT_PROJECT',
39
+ defaultGroup: 'GITLAB_DEFAULT_GROUP',
40
+ userAgent: 'GITLAB_USER_AGENT',
41
+ requestTimeoutMs: 'GITLAB_REQUEST_TIMEOUT_MS',
42
+ maxRetries: 'GITLAB_MAX_RETRIES',
43
+ };
44
+ function envNameFor(field) {
45
+ if (typeof field !== 'string')
46
+ return '<config>';
47
+ return ENV_FOR_FIELD[field] ?? field;
48
+ }
49
+ export function authHeader(cfg) {
50
+ switch (cfg.tokenType) {
51
+ case 'pat':
52
+ return { 'PRIVATE-TOKEN': cfg.token };
53
+ case 'oauth':
54
+ return { Authorization: `Bearer ${cfg.token}` };
55
+ case 'job':
56
+ return { 'JOB-TOKEN': cfg.token };
57
+ }
58
+ }
59
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { ToolContext } from '../../tools/types.js';
3
+ export declare function registerAccessTokenTools(server: McpServer, ctx: ToolContext): void;