内容
# gitlab-ci-mcp
<!-- mcp-name: io.github.mshegolev/gitlab-ci-mcp -->
[](https://pypi.org/project/gitlab-ci-mcp/)
[](https://pypi.org/project/gitlab-ci-mcp/)
[](LICENSE)
[](https://pepy.tech/project/gitlab-ci-mcp)
GitLab CI/CD 的 MCP 服务器。允许 LLM 代理(Claude Code、Cursor、OpenCode、DevX Agent 等)与管道、作业、计划、分支、标签、合并请求和仓库文件一起工作。
Python,[FastMCP](https://github.com/modelcontextprotocol/python-sdk),stdio 传输。
与任何 GitLab 配合使用 — SaaS `gitlab.com` 或自托管 /本地部署。为企业网络设计:可配置的 `NO_PROXY` 处理,可选的 SSL 验证切换,通过环境变量实现每个项目的范围限定。
## 设计亮点
- **工具注释** — 每个工具都带有 `readOnlyHint` / `destructiveHint` / `idempotentHint` / `openWorldHint`,以便 MCP 客户端可以分类操作(例如,仅在破坏性操作(如 `gitlab_merge_mr`、`gitlab_delete_schedule`)上请求确认)。
- **每个工具的结构化输出** — 每个工具都声明了一个 TypedDict 返回类型,因此 FastMCP 自动生成一个 `outputSchema`,每个结果都带有 `structuredContent` 和预渲染的 Markdown 文本块。可以使用结构化数据的客户端使用它;喜欢简洁文本的代理使用 Markdown。不需要 `response_format` 参数。
- **结构化错误** — 身份验证、404、403、429(速率限制)、5xx、缺少环境错误被转换为可操作的 `ToolError` 消息(例如 _“GitLab 身份验证失败… 请验证 GITLAB_TOKEN 具有 `api` 作用域”_),并作为 `isError=True` 结果显示。
- **Pydantic 输入验证** — 每个参数都有类型化的约束(范围、长度、字面值),自动暴露为 JSON Schema。
- **每个调用的项目范围限定** — 每个工具都接受一个可选的 `project_path` 参数,该参数覆盖 `GITLAB_PROJECT_PATH` 以进行跨项目查询。
- **分页** — 列表工具返回一个包含 `page`、`total`、`has_more`、`next_page` 的 `pagination` 块,并在 Markdown 页脚中提供下一页的提示。
- **MCP 上下文集成** — `gitlab_pipeline_health` 和 `gitlab_get_job_log` 是 `async` 的,并通过 MCP 上下文发出 `info` 日志和 `report_progress` 事件,以便客户端可以显示进度条。
- **MCP 资源** — `gitlab://project/info` 和 `gitlab://project/ci-config` 镜像了客户端偏好的通用查找,而这些客户端更喜欢资源模型而不是工具。
- **生命周期管理** — `python-gitlab` HTTP 会话在服务器关闭时通过 `asynccontextmanager` 生命周期钩子干净地关闭。
- **日志 grep** — `gitlab_get_job_log` 接受 `grep_pattern` + `grep_context`(周围的行),用于对兆字节级 CI 日志进行正则表达式过滤,而无需将整个跟踪信息拉入代理上下文。
### 线程模型
FastMCP 自动在工作线程中运行同步工具(`anyio.to_thread.run_sync`),因此它们不会阻塞 asyncio 事件循环 — `python-gitlab` 是一个同步库,自己包装每个调用的 `asyncio.to_thread` 将是一种仪式。受益于 MCP 上下文的工具(进度、信息日志)被编写为 `async def`,并显式地用 `asyncio.to_thread` 包装 `python-gitlab` 调用。
## 功能
涵盖日常 CI/CD 表面的 23 种工具:
**管道**
`gitlab_list_pipelines` · `gitlab_get_pipeline` · `gitlab_get_pipeline_jobs` · `gitlab_get_job_log` · `gitlab_trigger_pipeline` · `gitlab_retry_pipeline` · `gitlab_cancel_pipeline` · `gitlab_pipeline_health`
**计划**
`gitlab_list_schedules` · `gitlab_create_schedule` · `gitlab_update_schedule` · `gitlab_delete_schedule`
**分支和标签**
`gitlab_list_branches` · `gitlab_list_tags` · `gitlab_compare_branches`
**合并请求**
`gitlab_list_merge_requests` · `gitlab_get_merge_request` · `gitlab_get_merge_request_changes` · `gitlab_create_merge_request` · `gitlab_merge_mr`
**仓库和项目**
`gitlab_get_file` · `gitlab_list_repository_tree` · `gitlab_project_info`
### 管道健康报告
`gitlab_pipeline_health` 返回一个现成的 7/30 天总结:
```
最近 7 天: 96.4% 正常 | 27/28 成功
最近 30 天: 92.1% | 105/114 成功
最近 10 天: 成功 成功 成功 失败 成功 ...
```
方便用于值班 / 故障排除:`покажи health master за последние 7 дней`.
## 安装
需要 Python 3.10+.
```bash
# 通过 uvx(推荐)
uvx --from gitlab-ci-mcp gitlab-ci-mcp
# 或通过 pip/pipx
pipx install gitlab-ci-mcp
```
## 配置
所有配置都通过环境变量进行:
| 变量 | 必需 | 描述 |
| --- | --- | --- |
| `GITLAB_URL` | **是** | 基本 URL,例如 `https://gitlab.example.com` |
| `GITLAB_TOKEN` | **是** | 个人访问令牌,带有 `api` 作用域 |
| `GITLAB_PROJECT_PATH` | **是** | 默认项目,例如 `my-org/my-repo` |
| `GITLAB_SSL_VERIFY` | 否 | `true`(默认)/ `false` |
| `GITLAB_NO_PROXY_DOMAINS` | 否 | 以逗号分隔的域名列表,添加到 `NO_PROXY`(在企业网络中通过本地 HTTP 代理使用 - 例如 `.corp.example.com,gitlab.internal`) |
每个工具都接受一个可选的 `project_path` 参数,该参数覆盖 `GITLAB_PROJECT_PATH` 进行跨项目查询。
## Claude Code
**完整教程:** [docs/claude-code.md](docs/claude-code.md) — 先决条件、两条安装路径、多项目设置、自托管 GitLab 在企业代理后面、故障排除、卸载。
简要版本:
```bash
claude mcp add gitlab uvx --from gitlab-ci-mcp gitlab-ci-mcp \
--env GITLAB_URL=https://gitlab.example.com \
--env GITLAB_TOKEN=glpat-xxxxxx \
--env GITLAB_PROJECT_PATH=my-org/my-repo
```
或在 `~/.claude.json` / 项目 `.mcp.json` 中:
```json
{
"mcpServers": {
"gitlab": {
"type": "stdio",
"command": "uvx",
"args": ["--from", "gitlab-ci-mcp", "gitlab-ci-mcp"],
"env": {
"GITLAB_URL": "https://gitlab.example.com",
"GITLAB_TOKEN": "${GITLAB_TOKEN}",
"GITLAB_PROJECT_PATH": "my-org/my-repo",
"GITLAB_SSL_VERIFY": "true"
}
}
}
}
```
检查:
```bash
claude mcp list
# gitlab: uvx --from gitlab-ci-mcp gitlab-ci-mcp - ✓ 已连接
```
## Cursor / OpenCode / DevX Agent
同样的想法 — 将 MCP 配置指向 `uvx --from gitlab-ci-mcp gitlab-ci-mcp`,并使用上述环境变量。参见每个工具的 MCP 配置语法。
## 示例提示
```
что сломалось в последнем pipeline master
```
```
покажи health master за 7 дней для проекта my-org/other-repo
```
```
создай MR из feature/foo в master с title "feat: foo"
```
```
покажи содержимое .gitlab-ci.yml из master
```
## 速率限制和连接重用
GitLab 强制执行每个用户的速率限制(通常为 REST API 2000 req/h,由管理员配置 - 参见您实例的 `/admin/application_settings/network`)。
- 服务器缓存每个 `project_path` 的一个 `python-gitlab` HTTP 会话,因此针对同一项目的重复工具调用重用连接并且不会每次重新进行身份验证。
- 列表工具默认为 `per_page=20`,以保持单个调用在少量 API 请求内。
- 如果您遇到 `429 Too Many Requests`,错误处理程序会返回一个可操作的错误信息 - 等待并使用更大的 `per_page` 或更少的调用重试。
## 自托管 GitLab 在企业代理后面
当您的笔记本电脑有本地 HTTP 代理(例如 `http://127.0.0.1:3128` 用于企业 Web 访问)但 GitLab 在内网时,代理会拦截并杀死内部请求。有两个选项:
1. 设置 `GITLAB_NO_PROXY_DOMAINS` — 服务器将在启动时将它们添加到 `NO_PROXY`,**并清除 `HTTP_PROXY`/`HTTPS_PROXY` 以防止它们影响 GitLab 流量**。
2. 在 MCP `env` 部分传递显式为空的 `HTTP_PROXY=""` 等。
## 开发
```bash
git clone https://github.com/mshegolev/gitlab-ci-mcp
cd gitlab-ci-mcp
python -m venv .venv && . .venv/bin/activate
pip install -e '.[dev]'
pytest
```
直接运行服务器(stdio 传输,等待 stdin 获取 MCP 消息):
```bash
GITLAB_URL=... GITLAB_TOKEN=... GITLAB_PROJECT_PATH=... gitlab-ci-mcp
```
## 许可证
MIT — 参见 [LICENSE](LICENSE).
## 致谢
基于 [python-gitlab](https://github.com/python-gitlab/python-gitlab) 和 [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk)。