Skip to main content
Glama

gitlab-ci-mcp

PyPI Python License: MIT Downloads

GitLab CI/CD用MCPサーバー。LLMエージェント(Claude Code、Cursor、OpenCode、DevX Agentなど)がパイプライン、ジョブ、スケジュール、ブランチ、タグ、マージリクエスト、リポジトリファイルを操作できるようにします。

Python、FastMCP、stdioトランスポートを使用。

あらゆるGitLab(SaaSの gitlab.com またはセルフホスト/オンプレミス)で動作します。企業ネットワークを考慮して設計されており、設定可能な NO_PROXY 処理、オプションのSSL検証切り替え、環境変数によるプロジェクトごとのスコープ設定が可能です。

設計のハイライト

  • ツールアノテーション — すべてのツールに readOnlyHint / destructiveHint / idempotentHint / openWorldHint が付与されており、MCPクライアントが操作を分類できます(例:gitlab_merge_mr や gitlab_delete_schedule のような破壊的な操作のみ確認を求めるなど)。

  • すべてのツールで構造化された出力 — 各ツールはTypedDictの戻り値の型を宣言するため、FastMCPが自動的に outputSchema を生成し、すべての結果には事前レンダリングされたMarkdownテキストブロックに加えて structuredContent が含まれます。構造化データをレンダリングできるクライアントはそれを使用し、コンパクトなテキストを好むエージェントはMarkdownを使用します。response_format パラメータは不要です。

  • 構造化されたエラー — 認証、404、403、429(レート制限)、5xx、環境変数不足などのエラーは、アクション可能な ToolError メッセージ(例:「GitLab認証に失敗しました… GITLAB_TOKEN に api スコープがあるか確認してください」)に変換され、isError=True の結果として表示されます。

  • Pydanticによる入力検証 — すべての引数には型付き制約(範囲、長さ、リテラル)があり、JSON Schemaとして自動的に公開されます。

  • 呼び出しごとのプロジェクトスコープ — すべてのツールは、プロジェクトをまたいだクエリのために GITLAB_PROJECT_PATH を上書きするオプションの 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 として記述され、python-gitlab の呼び出しを明示的に asyncio.to_thread でラップします。

Related MCP server: gitlab-mcp

機能

日常的な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日間にわたる読みやすい要約を返します:

Last 7d:  96.4%  up   | 27/28 success
Last 30d: 92.1%       | 105/114 success
Last 10:  success success success failed success ...

オンコールやトリアージに便利です:покажи health master за последние 7 дней(過去7日間のmasterの健全性を表示して)。

インストール

Python 3.10+が必要です。

# via uvx (recommended)
uvx --from gitlab-ci-mcp gitlab-ci-mcp

# or via 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)

すべてのツールは、呼び出しごとに GITLAB_PROJECT_PATH を上書きするオプションの project_path 引数を受け入れます。これはプロジェクトをまたいだクエリに便利です。

Claude Code

完全なチュートリアル: docs/claude-code.md — 前提条件、2つのインストールパス、マルチプロジェクト設定、企業プロキシの背後にあるセルフホストGitLab、トラブルシューティング、アンインストール。

短いバージョン:

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 に記述:

{
  "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"
      }
    }
  }
}

確認:

claude mcp list
# gitlab: uvx --from gitlab-ci-mcp gitlab-ci-mcp - ✓ Connected

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で1時間あたり2000リクエスト。管理者が設定可能 — インスタンスの /admin/application_settings/network を参照)。

  • サーバーは project_path ごとに 1つの python-gitlab HTTPセッションをキャッシュするため、同じプロジェクトに対する繰り返しのツール呼び出しは接続を再利用し、毎回再認証することはありません。

  • リストツールはデフォルトで per_page=20 となっており、1回の呼び出しを少数のAPIリクエスト内に収めます。

  • 429 Too Many Requests に達した場合、エラーハンドラーがアクション可能なメッセージを返します。待機してから、より大きな per_page または少ない呼び出し回数で再試行してください。

企業プロキシの背後にあるセルフホストGitLab

ラップトップにローカルHTTPプロキシ(例:企業Webアクセス用の http://127.0.0.1:3128)があり、GitLabがイントラネット内にある場合、プロキシが内部リクエストを傍受して切断することがあります。2つのオプションがあります:

  1. GITLAB_NO_PROXY_DOMAINS を設定する — サーバーは起動時にそれらを NO_PROXY に追加し、自身のプロセスから HTTP_PROXY/HTTPS_PROXY をクリアするため、GitLabのトラフィックに影響を与えません。

  2. MCPの env セクションで HTTP_PROXY="" などを明示的に空にして渡す。

開発

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トランスポート、MCPメッセージをstdinで待機):

GITLAB_URL=... GITLAB_TOKEN=... GITLAB_PROJECT_PATH=... gitlab-ci-mcp

ライセンス

MIT — LICENSE を参照。

謝辞

python-gitlab および MCP Python SDK を基に構築されています。

Available Tools

24 tools
gitlab_cancel_pipelineA
DestructiveIdempotent

Cancel a running pipeline. In-flight jobs will be interrupted.

Destructive for in-progress work. Cancelling an already-finished pipeline is a no-op.

Examples: - "Pipeline 123 is stuck, cancel it" → pipeline_id=123 - Don't use on finished pipelines — no effect; use gitlab_retry_pipeline if you want to rerun it.

Inputs: pipeline_id (required), project_path (required). Returns: ref, status, web_url, created_at, +2 more

gitlab_ci_mcp_check_updatesB
Read-onlyIdempotent

Check updates when enabled; defaults off and never installs or runs at startup.

Inputs: no named parameters. Returns: cached, detail, status, release_url, +4 more

gitlab_compare_branchesA
Read-onlyIdempotent

Compare two branches — returns up to 30 commits and the list of changed files.

Use for "what's in release/x.y vs master?" or for release-note drafting.

Examples: - "What's new in release/1.5 vs master" → source='release/1.5', target='master' - Don't use to fetch full diffs of an MR — use gitlab_get_merge_request_changes.

Inputs: source (required), project_path (required), target. Returns: source, target, commits, diffs_count, +2 more

gitlab_create_merge_requestA

Create a merge request from source_branch into target_branch.

Not idempotent: creates a new MR each call. Check existing MRs first via gitlab_list_merge_requests if you want to avoid duplicates.

Examples: - "Open an MR from feature/login to master" → source_branch='feature/login' - "Open a WIP MR with a label" → title='Draft: ...', labels=['wip'] - Don't use to merge an already-open MR — use gitlab_merge_mr.

Inputs: project_path (required), source_branch (required), title, labels, +3 more. Returns: iid, hint, state, title, +6 more

gitlab_create_scheduleA

Create a new CI/CD schedule with the given cron and variables.

Not idempotent: duplicate calls create duplicate schedules with auto-incrementing IDs.

Examples: - "Schedule a nightly build on master at 02:00 Europe/Berlin" → description='Nightly build', cron='0 2 * * *', ref='master', timezone='Europe/Berlin', variables={'NIGHTLY': '1'} - Don't use to update existing schedules — use gitlab_update_schedule.

Inputs: cron (required), variables (required), description (required), project_path (required), +3 more. Returns: ref, cron, active, status, +2 more

gitlab_delete_scheduleA
DestructiveIdempotent

Delete a schedule by ID. Cannot be undone.

Examples: - "Delete schedule 42" → schedule_id=42 - If you only want to pause it temporarily, call gitlab_update_schedule with active=False instead.

Inputs: schedule_id (required), project_path (required). Returns: ref, cron, active, status, +2 more

gitlab_get_fileA
Read-onlyIdempotent

Read a text file from the repository, truncated to 500 lines.

For binaries, gets decoded as UTF-8 with errors replaced — you will likely get garbage; use for text content only.

Examples: - "Show me .gitlab-ci.yml on master" → file_path='.gitlab-ci.yml' - "Read src/app.py from the release-1.2 tag" → file_path='src/app.py', ref='release-1.2' - Don't use for listings — use gitlab_list_repository_tree.

Inputs: file_path (required), project_path (required), ref. Returns: ref, size, content, file_path, +2 more

gitlab_get_job_logA
Read-onlyIdempotent

Fetch the trace/log of a job, with optional regex filter.

Two modes:

  • Default: return the last tail lines (token-efficient, good for "why did this just fail?").

  • With grep_pattern: return only matching lines with grep_context surrounding lines on each side — ideal for finding "ERROR" / "Traceback" in megabyte-scale CI logs without pulling the whole trace into context.

Examples: - "Why did job 789 fail" → default tail=100, look at the end of the log - "Show me the first stage output of job 789" → tail=5000 and scan for stage separator - "Find every Traceback in job 789" → grep_pattern='Traceback', grep_context=5 - "All ERROR lines from job 789" → grep_pattern='ERROR|FAIL'

Inputs: job_id (required), project_path (required), tail, grep_context, +1 more. Returns: log, job_id, truncated, bytes_read, +6 more

gitlab_get_merge_requestA
Read-onlyIdempotent

Get full information about a merge request by internal ID (iid).

Includes state, branches, author, assignees, reviewers, labels, conflict status, description and timestamps.

Examples: - "Show me the description and state of !42" → mr_iid=42 - Don't use to see changed files — use gitlab_get_merge_request_changes.

Inputs: mr_iid (required), project_path (required). Returns: iid, state, title, author, +13 more

gitlab_get_merge_request_changesA
Read-onlyIdempotent

List changed files in a merge request with truncated diffs (2KB per file).

Useful for code-review-style queries ("what changed in !42?"). Diffs beyond 2KB are truncated — fetch the raw file via gitlab_get_file for full content.

Examples: - "What did MR !42 change" → mr_iid=42 - If you need full content of a changed file, use gitlab_get_file with the MR's source branch.

Inputs: mr_iid (required), project_path (required). Returns: files, title, mr_iid, files_count, +4 more

gitlab_get_pipelineA
Read-onlyIdempotent

Get a single pipeline with full timing details.

Useful right after gitlab_list_pipelines — lists only return summaries. Returns status, ref, source, durations (queued/total), and started/finished timestamps.

Examples: - "Why was pipeline 123 slow" → check queued_duration and duration fields - "Is pipeline 456 still running" → look at status - Don't use to see individual jobs — use gitlab_get_pipeline_jobs.

Inputs: pipeline_id (required), project_path (required). Returns: id, ref, source, status, +7 more

gitlab_get_pipeline_jobsA
Read-onlyIdempotent

List jobs of a pipeline with stage, status, duration and web URL.

Use after noticing a failed pipeline to drill down into which specific job broke and fetch its log via gitlab_get_job_log.

Examples: - "What jobs are in pipeline 123" → pipeline_id=123 - "Which job failed in pipeline 456" → filter result by status='failed' client-side - Don't use for overall pipeline status — use gitlab_get_pipeline instead.

Inputs: pipeline_id (required), project_path (required). Returns: jobs, jobs_count, pipeline_id

gitlab_list_branchesA
Read-onlyIdempotent

List branches of a project, optionally filtered by substring.

Includes default, protected and merged flags, and the short id of the tip commit with its title and date.

Examples: - "List all branches with 'release' in name" → search='release' - "Next page of branches" → page=2 - Don't use when you want to check if a specific branch exists by exact name — use gitlab_get_file on that ref and look at the error instead.

Inputs: project_path (required), page, search, per_page. Returns: count, project, branches, pagination

gitlab_list_merge_requestsA
Read-onlyIdempotent

List merge requests of a project, optionally filtered by state.

Examples: - "What MRs are open right now" → default (state='opened') - "What merged last week" → state='merged' then filter by updated_at client-side - "Everything regardless of state" → state='all' - Don't use when you have an MR IID — use gitlab_get_merge_request for detail.

Inputs: project_path (required), page, state, per_page. Returns: count, state, project, pagination, +1 more

gitlab_list_pipelinesA
Read-onlyIdempotent

List recent pipelines of a project, newest first.

Use for triage ("show failed pipelines on master"), release readiness checks, or feeding pipeline IDs into follow-up calls. Read-only and idempotent.

Returns PipelinesListOutput: project, count, pagination and pipelines[] (each PipelineSummary). The tool result additionally carries a markdown table in its text content.

Examples: - "Show failed pipelines on master" → status='failed', ref='master' - "Last nightly schedule runs" → source='schedule' - "Second page of pipelines" → page=2 - Don't use when you have a specific pipeline ID — use gitlab_get_pipeline instead.

Inputs: project_path (required), ref, page, source, +2 more. Returns: count, project, pipelines, pagination

gitlab_list_repository_treeA
Read-onlyIdempotent

List files and directories at a given path in the repository.

Examples: - "Show top-level files" → default call - "All .py files recursively" → recursive=True then filter on .py in path - Don't use for full-text content — use gitlab_get_file for that.

Inputs: project_path (required), ref, page, path, +2 more. Returns: ref, path, count, items, +2 more

gitlab_list_schedulesA
Read-onlyIdempotent

List all CI/CD schedules of a project.

Variable keys whose name hints at a secret (TOKEN, PASSWORD, SECRET, CREDENTIAL, PRIVATE_KEY, API_KEY) keep the key but have the value replaced by *** so the agent still sees which variables exist.

Examples: - "What schedules do we have and are they all active" → default call - Don't use to run a schedule now — use gitlab_trigger_pipeline with the schedule's variables instead.

Inputs: project_path (required). Returns: project, schedules, active_count, schedules_count

gitlab_list_tagsA
Read-onlyIdempotent

List tags of a project, newest first.

Useful for release-note generation or checking the last shipped version.

Examples: - "What was the last release tag" → default call, take the first item - "All v2.x releases" → search='v2.'

Inputs: project_path (required), page, search, per_page. Returns: tags, count, project, pagination

gitlab_merge_mrA
DestructiveIdempotent

Perform the actual merge if GitLab reports the MR can be merged.

Destructive: writes to the target branch. Checks merge_status first and returns status='cannot_merge' if conflicts exist or pipelines are required.

Examples: - "Merge !42" → mr_iid=42 - Don't call without checking gitlab_get_merge_request first when you suspect conflicts.

Inputs: mr_iid (required), project_path (required). Returns: iid, hint, state, title, +6 more

gitlab_pipeline_healthA
Read-onlyIdempotent

Aggregate success rate over 7 and 30 days with a trend indicator.

Great for stand-ups and on-call hand-offs. Returns success rate %, totals, last-10 statuses and a trend (up/down/flat).

Emits progress via the MCP Context (info log + report_progress) — useful in IDEs that show per-tool progress bars.

Examples: - "How stable is master" → default (ref='master', source='schedule') - "Push-driven pipeline health" → source='push' - Don't use for a single pipeline — use gitlab_get_pipeline.

Inputs: project_path (required), ref, source. Returns: ref, trend, source, status, +16 more

gitlab_project_infoA
Read-onlyIdempotent

Return basic metadata about a project: ID, default branch, visibility, counts.

Examples: - "What's the project ID and default branch" → default call - "Is this repo public or private" → look at visibility

Inputs: project_path (required). Returns: id, name, web_url, created_at, +7 more

gitlab_retry_pipelineA

Retry all failed jobs of an existing pipeline.

Creates new job runs (new history entries). Safe to call when the pipeline has at least one failed/canceled job; has no effect if everything already passed.

Examples: - "Retry the failed jobs in pipeline 123" → pipeline_id=123 - Don't use to rerun a successful pipeline — use gitlab_trigger_pipeline instead.

Inputs: pipeline_id (required), project_path (required). Returns: ref, status, web_url, created_at, +2 more

gitlab_trigger_pipelineA

Create a new pipeline on the given ref, optionally with CI variables.

Not idempotent: each call creates a new pipeline. Consumes minutes on your runners — avoid calling in loops.

Examples: - "Run the pipeline on master" → default (ref='master') - "Run the pipeline on feature/x with DEBUG=1" → ref='feature/x', variables={'DEBUG': '1'} - Don't call to retry — use gitlab_retry_pipeline which keeps the same pipeline ID.

Inputs: project_path (required), ref, variables. Returns: ref, status, web_url, created_at, +2 more

gitlab_update_scheduleA
DestructiveIdempotent

Update an existing schedule. Only provided fields change.

Destructive when variables is set: the entire variable set is replaced, so ensure the caller sends a full list.

Examples: - "Deactivate schedule 42" → schedule_id=42, active=False - "Change cron of schedule 42 to hourly" → schedule_id=42, cron='0 * * * *' - Don't pass variables unless you want to replace them entirely.

Inputs: schedule_id (required), project_path (required), ref, cron, +3 more. Returns: ref, cron, active, status, +2 more

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4/5.0

    Scored across 24 tools

    Disambiguation5/5

    Tools are clearly separated by resource and action: pipeline tools split into list/get/jobs/log/trigger/retry/cancel/health, MR tools into list/get/changes/create/merge, and schedule CRUD is explicit. The only mild overlap is among pipeline-read tools, but the descriptions make boundaries clear.

    Naming Consistency4/5

    Most tools follow a predictable gitlab_verb_noun pattern such as gitlab_get_pipeline, gitlab_list_branches, and gitlab_create_schedule. Exceptions include noun-phrase names like gitlab_pipeline_health and gitlab_project_info, the abbreviated gitlab_merge_mr, and the meta gitlab_ci_mcp_check_updates.

    Tool Count4/5

    At 24 tools the set is on the heavy side, but it covers several distinct areas—pipeline operations, job logs, merge requests, repository browsing, and schedules—and most tools have a clear role. The lone meta update-check tool is slightly out of place but does not dominate the surface.

    Completeness3/5

    Core CI lifecycle coverage is strong: pipelines can be listed, inspected, triggered, retried, cancelled, and health-checked, and schedules have full CRUD. However, notable gaps remain: merge requests cannot be updated, closed, commented on, or approved; branches and tags are list-only; and repository file operations are read-only.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers