Claude Media
Jenkins MCP ServerでClaude Codeにビルド失敗を診断させる

Jenkins MCP ServerでClaude Codeにビルド失敗を診断させる

Jenkins MCPはJenkins公式のMCP Server Pluginを入れるだけで使えます。Claude Codeへの接続コマンドと、ビルドログ検索・変更履歴の突合・replayの診断手順を解説します。

Jenkins MCPは、Jenkins公式プラグイン「MCP Server Plugin」を入れるだけで使えます。Jenkinsインスタンス自体がMCPサーバーになる構成です。Claude Codeへの登録はclaude mcp addの1コマンドで済み、必要なのはJenkinsのAPIトークンだけです。別プロセスのサーバーを立てる必要はありません。ジョブの一覧、ビルドログの検索、失敗したPipelineのreplayまで、Claude Codeから自然文で頼めるようになります。別プロセス型の例が、Travis CIを非公式サーバーmcp-travisで操作する方法です(ClaudeとTravis CIを連携する)。

この記事は、ビルドが赤くなったときに何を頼めば原因まで届くか、という順に進めます。準備と接続、診断、再実行、権限まわりのつまずきの順です。CircleCIやBuildkiteとの違いを知りたい場合はCircleCI・Buildkite・JenkinsのMCP比較を先に読むと選びやすくなります。

Jenkins側の準備

Jenkinsの管理画面でプラグインマネージャーを開き、「MCP Server」(プラグインID: mcp-server)をインストールします。動作にはJenkins 2.541.3以降が必要です。

READMEにはClaudeやCopilotなど複数クライアントの接続例があります。この記事ではClaude Codeを使います。

接続までの4ステップ

認証はJenkins本体と同じ仕組みを使います。Jenkinsで発行したAPIトークンをBasic認証に載せるだけで、Jenkins側に新しいアカウントや権限体系を作る必要はありません。

手順

Claude CodeからJenkinsに接続する

  1. 1

    APIトークンを発行する

    Jenkinsの右上のユーザーアイコンからSecurityを開き、Add new tokenで名前を付けてGenerateします。トークンは画面を離れると二度と表示されないので、その場で控えます。控えたらDoneを押し、最後にSaveで保存します。

  2. 2

    Base64に変換する

    ユーザー名:トークンをBase64にします。この変換は暗号化ではないので、出力も元のトークンと同じ扱いで保管します。

  3. 3

    Claude Codeに登録する

    claude mcp addでStreamable HTTPのエンドポイントを登録します。ヘッダーに先ほどの文字列を渡します。

  4. 4

    whoAmIで確認する

    接続できたら最初にwhoAmIを頼み、どのユーザーとして認識されているかを見ます。権限の切り分けはここが起点になります。

Base64への変換コマンドは次のとおりです(Linux・macOS)。WindowsのPowerShellでは[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("<username>:<token>"))で同じ結果が得られます。

echo -n "<username>:<token>" | base64

出力された文字列を使い、Claude Codeに登録します。

claude mcp add jenkins http://jenkins-host/mcp-server/mcp --transport http --header "Authorization: Basic <user:token base64>"

Claude Code v2.1.287のclaude mcp add --helpで、関係するオプションを確認しました。-t, --transport <transport>はstdio・sse・httpから選びます。-H, --header <header...>でヘッダーを渡し、-s, --scope <scope>はlocal・user・projectのいずれかで、既定はlocalです。ダミーの値で--scope projectを付けて登録すると、作業ディレクトリに次の.mcp.jsonができました。

{
  "mcpServers": {
    "jenkins": {
      "type": "http",
      "url": "http://jenkins-host/mcp-server/mcp",
      "headers": {
        "Authorization": "Basic ZHVtbXk6ZHVtbXk="
      }
    }
  }
}

ここで見落としやすい点があります。--scope projectで作る.mcp.jsonはリポジトリに入れて共有する前提のファイルですが、中身のヘッダーは平文のBase64です。コマンドの画面出力では[REDACTED]と伏せられても、ファイルには値がそのまま残ります。個人のトークンを共有ファイルに入れたくないなら、既定のlocalスコープで登録するという選択肢があります。

チームで共有したいなら、ヘッダーを環境変数の参照にする手もあります。.mcp.jsonのheadersは環境変数の展開に対応しており、"Authorization": "Basic ${JENKINS_BASIC_AUTH}"と書けば、値をファイルに残さずに済みます。対話セッションでは、.mcp.jsonにあるプロジェクトスコープのサーバーを使う前に承認を求められます。スコープの違いはClaude Code MCP設定ガイドに詳しく載っています。

どのエンドポイントに繋ぐか

インストール後の追加設定は基本的に不要で、3種類のトランスポートが既定で同時に有効になります。MCP Java SDK 0.17.2をベースに、MCP仕様2025-06-18を実装しています。

トランスポートエンドポイント向いている場面
Streamable HTTPエンドポイント/mcp-server/mcp向いている場面通常の用途全般。READMEが推奨
SSEエンドポイント/mcp-server/sse(+ /mcp-server/message)向いている場面クライアントがSSEしか対応していない場合
Statelessエンドポイント/mcp-server/stateless向いている場面セッション管理なしで独立したリクエストを送るクライアント向け

SSEは長時間張りっぱなしの接続を前提にするため、プロキシやロードバランサーのアイドルタイムアウトに弱く、後述の追加設定が要ります。使わないエンドポイントは、システムプロパティのio.jenkins.plugins.mcp.server.Endpoint.disableMcpSse=trueのように個別に無効化できます。disableMcpStreamableとdisableMcpStatelessも同じ形です。共有のJenkinsで公開面を減らしたいときの選択肢になります。

ビルドが赤いとき、頼む順番

プラグインのツールは「ジョブ管理」「ビルド情報」「SCM連携」「管理情報」の4群です。診断の基本形は、次のような依頼文から始まります。

my-jobの直近のビルドが失敗している。ログを調べて原因を教えて。関連する変更点も見せて

Claudeはツールをおおむね次の順に呼びます。どのツールを呼ぶかはモデルの判断なので、順序はこの通りとは限りません。

診断の流れ

失敗ビルドの一次診断で使うツール

  1. 1

    getBuild

    最新ビルドのステータスを確認します。

  2. 2

    searchBuildLog

    エラー文字列やスタックトレースを、文字列または正規表現で検索します。検索はログのスナップショットに対して動き、maxMatchesに達した時点で走査を止めます。

  3. 3

    getBuildChangeSets

    そのビルドに含まれるコミットの変更ログを取り、どの変更が持ち込んだ失敗かを突き合わせます。

  4. 4

    getTestResults

    テストが原因なら、失敗したテストケースを直接読みます。

実行中のビルドでも、ログ系のツールは非ブロッキングのスナップショットを読みます。終わるのを待たずに途中経過へ答えが返ります。

長いログの読み方

getBuildLogは、先頭から読む方法のほかに、末尾から遡る読み方にも対応します。負のskipやlimitを渡す「end-relative」読み取りです。失敗の痕跡はログの末尾に出ることが多いので、末尾側から読み取りや検索を組む手があります。

続きを読むときは、応答に付くnextCursorをcursorとして渡します。カーソルは発行された(job, buildNumber)に結び付いており、別のビルドに使うと拒否されます。実行中のビルドでnextCursorがあるのにhasMoreContentがfalseなら、そこまでを読み切っただけで、ビルドはまだ続いています。カーソルを保持して後から呼べば、追記分だけが取れます。

totalLinesは末尾からの読み取りでは正確で、先頭やカーソルからの読み取りでは-1になります。総行数を前提にした進捗表示を組むと、この-1に当たります。1回に返る行数にはハードリミットがあります。システムプロパティio.jenkins.plugins.mcp.server.extensions.BuildLogsExtension.limit.maxの既定は10000行です。

応答を小さく保つtreeパラメータ

getBuild・getJob・getJobsは、既定ではIDと状態の要点に絞った小さな応答を返します。LLMのコンテキストを食い潰さないための既定です。フィールドを増やしたいときは、JenkinsのリモートREST APIと同じtree構文を渡します。たとえばtree=name,url,lastBuild[number,result]の形です。tree="*"を渡すと絞り込みが外れ、オブジェクト全体が返ります。

診断で「この変更は誰のコミットか」まで聞きたいのに答えが薄いときは、ツールの不足ではなくtreeで取得項目が絞られている可能性があります。依頼文に「必要ならtreeで項目を広げて」と添えておくと拾いやすくなります。

失敗を再現して直す: rebuildBuildとreplayBuild

原因の仮説が立ったら、Jenkinsfileをpushする前に試す道が2つあります。違いは「スクリプトを変えるかどうか」です。

くらべる

同じ失敗を再現するか、直して試すか

スクリプトは変えない

rebuildBuild

同じパラメータでビルドを積み直します。Replay対応のPipelineなら元のスクリプトで、そうでないパラメータ付きジョブなら同じパラメータで新しいビルドを作ります。buildNumberを省くと直近のビルドが対象です。

スクリプトを変えて試す

replayBuild

getReplayScriptsでメインスクリプトと読み込み済みスクリプトを取り、修正したmainScript(必要ならloadedScriptsも)を渡して再実行します。コミットせずに1回だけ挙動を確かめられます。

replayBuildは、ビルドがReplay可能でない場合や、権限・サンドボックスの制約でReplayが許されない場合に失敗します。getReplayScriptsもPipeline以外のジョブでは失敗します。Freestyleジョブの失敗を直したい場面では、この2つは使えません。

パラメータ付きジョブを起動する

triggerBuildはパラメータ付きジョブに対応しており、成功するとキューアイテムを返します。そのIDをgetQueueItemに渡すと、開始待ちかどうかを追えます。

{
  "jobFullName": "my-parameterized-job",
  "parameters": {
    "BRANCH": "main",
    "DEBUG_MODE": true,
    "FEATURES": ["feature1", "feature2"]
  }
}

READMEが挙げる対応状況は次のとおりです。String・Boolean・Choice・Text・Password・Runのコアパラメータは渡せます。複数選択は配列で渡せ、プラグインが追加するパラメータ型もリフレクションで自動検出されます。一方で、ファイルパラメータはアップロードが要るためMCP経由では使えません。対応外のパラメータは既定値に戻され、その旨がログに残ります。ファイルを受け取るジョブは、MCP経由ではファイルを渡せない前提で設計します。

リポジトリからジョブを逆引きする

原因がコード側にあるとき、SCM連携のツールが効きます。getJobScmとgetBuildScmはジョブ・ビルドに紐づくリポジトリ設定を返します。findJobsWithScmUrlは、指定したGitリポジトリURLをビルドしているジョブを横断的に探します。

git@github.com:myorg/shared-lib.gitを使っているJenkinsジョブを全部教えて

共有ライブラリを直した後に、どのジョブが影響を受けるかを事前に洗い出す用途に向いています。ビルドが失敗してから犯人を探すのとは逆向きの使い方です。

管理者向け: ヘルスとメトリクス、システムログ

MCP接続自体の確認用に、エンドポイントが2つあります。

監視

接続の監視エンドポイント

  • /mcp-health

    認証不要

    死活確認・ポーリング向け

  • /mcp-server/metrics

    認証あり

    利用状況の把握向け

<jenkins-url>/mcp-healthは、mcpServerStatus・activeConnections・shuttingDown・timestampをJSONで返す軽量な窓口です。READMEは10〜30秒間隔のポーリングを例に挙げ、503が返るか到達できなくなったら再接続に備えるよう書いています。Jenkinsの停止時は猶予期間つきで503を返すので、クライアントはRetry-Afterを見て再接続の間隔を決められます。

<jenkins-url>/mcp-server/metricsは認証が必要で、返す項目は次の6つです。チームでどれだけ使われているかを把握する用途です。

  • sseConnectionsTotal
  • sseConnectionsActive
  • streamableRequestsTotal
  • connectionErrorsTotal
  • uptimeSeconds
  • startTime

getSystemLogは、ビルドログではなくJenkins本体のシステムログを新しい順に読むツールで、名前付きのLog Recorderや最低ログレベルで絞れます。Recorderの名前はgetLogRecordersで一覧できます。どちらもOverall/SystemRead権限が要ります。ビルドは失敗していないのにツール呼び出しがおかしいときは、ここを見ると原因に近づけます。

権限が足りないツールは「見えない」

@Toolにはpermissionsを指定でき、呼び出し元が列挙された権限のうち1つも持たないと、そのツールはtools/listから隠れ、tools/callでも拒否されます。Jenkinsのセキュリティが無効なときは、すべてのツールが使えます。

一覧から隠れるのは、Overall/SystemReadのような全体権限で絞られたツールだけです。ジョブやフォルダ単位の権限はこの仕組みでは表せないため、各ツールの中で確認されます。一覧に出ているのに呼び出しが失敗するときは、対象ジョブの読み取り権限を疑います。

つまり、READMEに載っているツールがClaudeの一覧に出ないことがあります。この場合はClaude側の不具合ではなく、トークンの持ち主の権限が足りていない可能性があります。whoAmIで誰として認識されているかを確かめ、Jenkins側のロールを見直します。

社内向けに独自ツールを足す

McpServerExtensionを実装したクラスのメソッドに@Toolを付けると、組織固有のツールを追加できます。引数は@ToolParamで説明します。標準ツールを置き換えたい場合は、同じ名前にoverride = trueを指定します。指定が無い名前衝突では、標準ツールが優先され、重複側は警告つきで読み込まれません。偶然の上書きは起きません。override = trueが複数あるときだけ、@Extension(ordinal)が高いものが勝ちます。

ツールの戻り値の形

一覧を返すツールは要素ごとに別のテキストコンテンツに展開します。単一のオブジェクトを返すツールは、全体を1つのテキストにまとめます。@ExportedBean付きのオブジェクトにはJenkinsのJSONエクスポートが使われ、それ以外はJacksonでシリアライズされます。独自ツールでJenkinsのオブジェクトをそのまま返せば、この変換を自前で書かずに済みます。MCPのHost・Client・Serverの関係はMCPアーキテクチャの三層構造で確認できます。

よくあるつまずき

  • SSE接続がすぐ切れる: Winstone(組み込みJetty)のhttpKeepAliveTimeoutは既定で30秒です。MCPのkeep-alive pingも既定で30秒おきなので、pingが届く前に接続が閉じられることがあります。対処は2つあります。起動オプションに--httpKeepAliveTimeout=600000を足すか、Streamable HTTPに切り替えます。READMEによれば、この競合はSSE固有の問題です
  • リバースプロキシ経由で504になる: Nginxのproxy_read_timeoutが短いと、時間のかかる呼び出しが504 Gateway Timeoutで終わります。READMEは遅いtriggerBuildを例に挙げています。こちらはトランスポートを問わず起こるため、READMEの例のように600秒に伸ばします
  • Originヘッダーを必須と思い込む: OriginヘッダーがあるときはJenkinsのルートURLと照合されます(requireOriginMatchの既定はtrue)。ただしヘッダーが無いリクエストは通ります(requireOriginHeaderの既定はfalse)。ヘッダー無しを拒否したいときだけ、システムプロパティio.jenkins.plugins.mcp.server.Endpoint.requireOriginHeader=trueを設定します
  • Copilotでストリーミングが不安定: READMEはCopilotについて、Streamable HTTPがうまく動かないためSSEを使うよう書いています。他のクライアントではまずStreamable HTTPから試す流れで足ります
  • 接続はできるがツール呼び出しが失敗する: 認証ヘッダーが通っていても、トークンの持ち主の権限が足りない場合があります。whoAmIとgetStatusで、ユーザーの認識とJenkins本体の状態を切り分けます。READMEはgetStatusを、単なる稼働確認ではなく健全性と準備状態を見るツールと説明しています

まとめ

Jenkinsを別のMCPサーバーで包む必要はなく、プラグインの権限モデルがそのまま効きます。ツールが一覧に出ない、呼び出しが失敗するといったときは、Claude側より先にトークンの持ち主の権限を疑うのが近道です。

この記事を共有:XはてブLinkedIn