Loki MCP Server について
Loki MCP Serverは、Grafana Lokiのログを読み取り専用で検索するローカルMCPサーバーです。ログを調査するエージェントや運用担当者向けに、ラベル探索、件数制限付きLogQLクエリ、集計、ローカルファイルへのエクスポートを提供します。
主な機能
- 01ラベルとストリーム構成の探索
- 02件数制限付きLogQLクエリ
- 03一致行数と時間バケットの集計
- 04ログのローカルファイルへの出力
- 05接続ごとの制限とヒントの設定
活用シーン
- 01ログ検索前に関連ラベルを特定
- 02新しい・古いエラーログのページを確認
- 03一定期間のログ量を測定
- 04分析用に一致するログ行を保存
MCP 対応
stdio経由で、設定済みLoki接続向けに接続一覧、探索、検索、集計、ローカル出力の5つのテキストツールを提供します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
docker run -i --rm ghcr.io/igorolv/loki-mcp-server:0.1.0ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ghcr.io/igorolv/loki-mcp-server:0.1.0stdioツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
Loki MCP サーバー
エージェントが Grafana Loki を読み取るための、ローカルで動作する stdio MCP サーバーです。5 つのテキストツールを公開し、Loki 2.6.1 および 3.x をサポートします。Loki 自体は読み取り専用で、唯一の書き込み処理はローカルの exportLogs ファイルへの出力です。
| ツール | 目的 |
|---|---|
| listConnections | 設定済みの環境、オペレーター向けのヒント、有効なツール制限を表示します |
| discoverLogs | ラベル名、1 つのラベルの値、一致するストリームのラベルセット、またはそれらのセット内の値を一覧表示します |
| queryLogs | LogQL ログクエリの新しい方または古い方から、上限付きのページをコンパクトなテキストで読み取ります。raw=true の場合は、返された行とストリームラベルをプレビューします |
| countLogs | Loki 上で一致する行をカウントします。ラベル、クロックに合わせた時間バケット、またはその両方を指定できます |
| exportLogs | 一致する行を、raw 形式またはテンプレートで描画した形式でローカルファイルに保存します |
すべてのデータツールでは、接続を明示的に指定する必要があります。queryLogs、countLogs、exportLogs では、{app="backend"} |= "ERROR" のような LogQL のログクエリが必要です。ラベル名、値、ストリームのラベルセットに含まれる実際の組み合わせを見つけるには、discoverLogs を使用してください。サーバーが countLogs 用に構築するのは count_over_time 式のみです。フィルターを推測したり、原因を解釈したりすることはありません。ツールの応答は、出力スキーマのない読みやすいテキストです。
ビルドと実行
JDK 21 以降が必要です。このプロジェクトでは Java 21 ツールチェーンと Gradle ラッパーを使用します。
.\gradlew.bat bootJar
java -jar build/libs/loki-mcp-server.jar
Linux/macOS では ./gradlew を使用してください。プロセスは stdin で MCP JSON-RPC を待ち受けます。stdout は JSON-RPC 専用です。診断情報は stderr と ~/.loki-mcp-server/logs/loki-mcp-server.log に出力されます。
ビルド済みの loki-mcp-server.jar が各リリースに添付されているため、ビルドは任意です。
Claude Code では、次の 1 つのコマンドで jar を登録できます。
claude mcp add --scope user loki -- java -jar /path/to/loki-mcp-server.jar
Docker
イメージは各リリースで GHCR に公開されます。connections.json を格納したディレクトリを /data にマウントしてください。サーバーはログとデフォルトのエクスポートもそこに書き込みます。
docker run -i --rm -v ~/.loki-mcp-server:/data ghcr.io/igorolv/loki-mcp-server:latest
MCP クライアントが起動する場合も、同じコマンドを使用します。-i を指定すると、stdio トランスポート用に stdin が開いたままになります。connections.json の Loki URL はコンテナ内からアクセスできる必要があります。localhost ではなく Loki のホスト名を使用するか、Linux では --network host を追加してください。/data の外にある exportLogs ディレクトリはコンテナ内のパスになるため、そのディレクトリもマウントしてください。イメージをローカルでビルドするには、docker build -t loki-mcp-server . を実行します。
接続
サーバーは ~/.loki-mcp-server/connections.json、または LOKI_MCP_CONNECTIONS_FILE で指定されたパスを読み込みます。最小限のファイルは次のとおりです。
{
"connections": {
"dev": {
"description": "Development",
"hint": "Start with {app=\"backend\"}; inspect app values with discoverLogs.",
"url": "http://localhost:3100",
"timezone": "Europe/Moscow",
"serviceLabels": ["app", "container"]
}
}
}
完全な例では、ローカル以外の URL に環境変数を使用しています。hint では、モデルのスタンドに固有のセレクターとフィールドに関するアドバイスを指定します。serviceLabels では、サービスをコンパクトな行で表示するために使用するラベル名を指定します。任意の formatFile では、JSON プロファイル、プレーン行パターン、任意の framePattern を含む JSON ファイルを 1 つ指定します。詳しくは log-formats.json を参照してください。任意の exportFormat では、ツール呼び出しで format が省略された場合に exportLogs で使用するデフォルトのテンプレートを設定します。接続ファイルでは、エクスポート先を制限する exportRoots と、接続ごとの制限も設定できます。認証ヘッダーとテナントヘッダーは接続ごとに設定します。URL と認証情報がツールの応答や診断情報に含まれることはありません。形式の詳細は docs/connections.md を参照してください。
サーバーは、Loki への接続確認を行わずに、起動時に設定を厳密に読み込みます。不明なフィールド、重複キー、環境変数の不足、または無効な形式ファイルがある場合、安全な設定エラーが発生し、起動が停止します。変更を反映するには再起動が必要です。
ツールの使用方法
- listConnections を呼び出し、スタンドを選んで、表示された時間範囲、queryLogs の行数上限、リクエストタイムアウトを使って呼び出しを計画します。
- discoverLogs(connection="dev") を呼び出してラベル名を確認し、続けて discoverLogs(connection="dev", label="app") を呼び出して値を確認します。組み合わせが重要な場合は、discoverLogs(connection="dev", match="{app="backend"}") を使ってストリームのラベルセット全体を確認するか、label="namespace" を追加して、それらのセットに含まれる namespace の値を確認します。match とその時間範囲は狭く保ってください。これらはストリームのラベルであり、ログ行数ではありません。適切な場合は、静かなスタンドで時間範囲を広げます。
- countLogs で LogQL のログクエリを実行して件数を確認し、queryLogs で行を読み取ります。たとえば、{app="backend"} |= "ERROR" はログクエリです。groupBy="time", step="1d" は UTC にそろえた24時間単位のバケットを返し、groupBy="app,time" はアプリと時間ごとの件数を返します。名前付きの
| regexpキャプチャを groupBy のラベルとして使えます。日付マーカーによって、午前0時をまたぐバケットを区別できます。 - ページに表示される内容が多い場合は、クエリを絞り込みます。queryLogs は既定で最新のページを表示します。order="oldest" を指定すると、時間範囲の最初から表示します。フッターには、古い行を取得するための終了位置、または新しい行を取得するための開始位置が示されます。境界の行は繰り返されることがあります。また、1つのタイムスタンプにページ上限を超える行が含まれる場合は、クエリをさらに絞り込む必要があります。
- ユーザーがファイルを求めている場合は exportLogs を呼び出します。ユーザーの保存先を directory に指定します(例:
C:\tmp\logs)。省略した場合は既定のエクスポートディレクトリが使われます。format を省略すると、オペレーターが設定している場合は接続の設定済みexportFormatテンプレートが使われ、それ以外は raw になります。format="raw" は、クエリ内の| line_formatによる変換を含め、Loki が返した行を書き込みます。format="{time} {level} {service} {message}" はローカルで整形します。応答にはパス、件数、有効な形式が含まれますが、ログの内容は含まれません。
queryLogs は時間範囲のいずれかの端を時系列順に表示します。既定の表示では、モデルのトークンを節約するためにメッセージとスタックトレースを短縮します。接続の formatFile に任意の framePattern を指定すると、コンパクト表示で隣接する単独のフレーム行をまとめられます。raw=true を指定すると、ストリームラベルと最大4000コードポイントを含む、取得したすべての行が表示されます。これはプレビューです。完全な行を取得するには exportLogs を使います。エクスポートではページ単位で先頭から読み取り、既存のファイルを上書きしません。1ナノ秒に同じタイムスタンプの行が複数あり、Loki が1ページで返せる数を超える場合は、一部が欠落する可能性があることをエクスポート時に通知します。
既定の時間範囲は now-1h から now です。指定できる時刻には now-15m、オフセット付き RFC3339、接続のタイムゾーンにおけるローカル時刻、エポックナノ秒があります。queryLogs と exportLogs では、既定で最大1日を指定できます。countLogs では、合計、ラベルごとのグループ化、ラベルと時間の組み合わせによるグループ化は最大1日、時間のみのバケットは最大7日を指定できます。discoverLogs では、match を指定しない場合は最大7日、match を指定する場合は最大1日を指定できます。Loki リクエストの既定のタイムアウトは30秒で、queryLogs では既定で1ページあたり最大1000行を指定できます。listConnections には各スタンドで有効な値が表示されます。エクスポートは既定で25秒後に停止します。行を書き込んでいる場合は、続きの情報とともに部分的なファイルが報告されます。count がタイムアウトした場合は、1日単位の部分範囲またはより狭いクエリで再試行してください。上限は接続ごとに設定できます。docs/queries.md と docs/discovery.md を参照してください。
MCP クライアントの設定
Claude Code:
claude mcp add --scope user loki -e LOKI_MCP_CONNECTIONS_FILE=C:/path/connections.json -- java -jar C:/path/loki-mcp-server.jar
Codex (~/.codex/config.toml):
[mcp_servers.loki]
command = "java"
args = ["-jar", "C:/path/loki-mcp-server.jar"]
env = { LOKI_MCP_CONNECTIONS_FILE = "C:/path/connections.json" }
他のクライアントでは、stdio 経由で jar を起動できます。stderr と stdout は分けてください。
エラーと診断
ツールの失敗は、isError=true を伴うテキスト「Error : 」として返されます。Spring AI は現在、このテキストを2行目にも繰り返します。引数が不足している場合や誤って入力されている場合は、MCP SDK の入力検証によって応答します。Loki の HTTP 400 LogQL パースエラーは、モデルがクエリを修正できるように返されます。その他の上流レスポンス本文、URL、認証情報、テナント、ログ行全体は、応答や診断情報に含まれません。404 は呼び出されたエンドポイントに適用され、接続全体には適用されません。トランスポートの詳細はdocs/http-client.mdに記載されています。
サーバーログには、起動時に接続名と認証タイプが記録され、その後、ツール呼び出しと Loki リクエストごとに、ステータス、バイト数、所要時間を含む長さを制限した1行のログが記録されます。ログの内容はデータとして扱われ、指示のように見えるテキストもそのまま含まれます。
検証
.\gradlew.bat build
.\gradlew.bat integrationTest --console=plain
python scripts/live_smoke/run_smoke.py --connection dev
build はユニットテストと、ループバックのモック Loki に対する別プロセスでの stdio スモークテストを実行します。integrationTest には Docker と、バージョンが固定された Loki 2.6.1/3.6.0 イメージが必要です。テストデータはそのコンテナ内にのみ書き込まれます。ライブスモークテストでは、example プロファイルと、設定済みの読み取り専用のスタンド URL を使用します。コントリビューター向けルールはAGENTS.mdに、設計の経緯と未解決の項目はdocs/decisions.mdに記載されています。mcp-loki から移行するユーザーは、移行ガイドを参照してください。
ライセンス
Apache License 2.0 です。LICENSEを参照してください。サードパーティに関する通知はTHIRD-PARTY-NOTICES.mdに記載されています。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。