MCP Helm Server について
MCP Helm Serverは、ローカルにHelmをインストールせずに、AIアシスタントからHelmリポジトリやチャートを調べるためのサーバーです。Kubernetesリソース全般ではなくチャート情報に特化し、valuesやテンプレートの内容確認を支援します。
主な機能
- 01チャートとバージョンの一覧表示
- 02最新の安定版の確認
- 03valuesとチャートファイルの取得
- 04チャート依存関係の確認
- 05コンテナイメージの抽出
活用シーン
- 01HTTPまたはOCIリポジトリのチャート確認
- 02Helmデプロイ前のvalues確認
- 03パターンを指定したテンプレートやメタデータの調査
- 04チャートのイメージと依存関係の把握
MCP 対応
標準MCPプロトコルを通じて、Helmリポジトリとチャートを調べるツールをMCPクライアントに公開します。HTTPリポジトリとOCIレジストリに対応します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
docker run -i --rm ghcr.io/zekker6/mcp-helm:v1.3.0ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ghcr.io/zekker6/mcp-helm:v1.3.0stdioツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
MCP Helm サーバー
Helm リポジトリやチャートを操作するためのツールを提供する MCP(Model Context Protocol)サーバーです。この サーバーを使うと、ローカルに Helm をインストールしなくても、AI アシスタントが Helm リポジトリを検索したり、チャート情報を取得したり、チャートの値にアクセスしたりできます。
Helm で MCP を使う目的は、LLM を使用する際に values.yaml の形式やチャートの内容を捏造してしまうことを避けることです。
このサーバーは、代わりにその情報へアクセスする標準化された方法を提供し、AI アシスタントが Helm チャートやリポジトリを簡単に操作できるようにします。
この MCP サーバーが提供するのは、Helm リポジトリを操作するためのツールのみです。ほかの Kubernetes リソースを操作する必要がある場合は、Kubernetes リソース用のツールを提供する別の MCP サーバーをご検討ください。
機能
MCP Helm サーバーは、以下のツールを提供します。
- list_repository_charts - Helm リポジトリで利用可能なすべてのチャートを一覧表示します(OCI レジストリの場合はチャート名を表示します)
- list_chart_versions - チャートで利用可能なすべてのバージョン/タグを一覧表示します
- get_latest_version_of_chart - 指定したチャートの最新の安定版(プレリリースではないバージョン)を取得します
- get_chart_values - チャートの values ファイルを取得します(最新バージョンまたは指定したバージョン)
- get_chart_contents - チャートの内容(テンプレート、values、メタデータを含む)を取得します。必要に応じて、ファイルパスの glob パターン(例:
templates/**)で絞り込めます - get_chart_dependencies -
Chart.yamlファイルで定義されているチャートの依存関係を取得します - get_chart_images - テンプレートをレンダリングして Kubernetes マニフェストを解析し、Helm チャートで使われているコンテナイメージを抽出します
リポジトリの種類
すべてのツールは、従来の HTTP Helm リポジトリと OCI レジストリの両方に対応しています。
| リポジトリの種類 | 例の URL |
|---|---|
| HTTP リポジトリ | https://charts.example.com |
| OCI レジストリ | oci://ghcr.io/org/charts/mychart |
| OCI(Docker Hub) | oci://docker.io/library/mysql |
OCI レジストリのサポート
OCI(Open Container Initiative)レジストリは、Helm チャートを OCI アーティファクトとして保存します。複数の チャートが同じインデックスを共有する HTTP リポジトリとは異なり、OCI レジストリには通常、リポジトリごとに 1 つのチャートと、複数のバージョンタグが含まれます。
OCI の使用例:
repository_url: oci://ghcr.io/nginxinc/charts/nginx-ingress
chart_name: (empty - chart name is in the URL)
インストールせずに試す
MCP Helm サーバーには、インストールせずに機能を試せる公開インスタンスがあります:https://mcp-helm.zekker.dev/mcp
インストール
Docker で実行する
Docker を使って MCP Helm サーバーを実行できます。Go のインストールやソースからのビルドが不要なため、最も簡単に始められる方法です。
docker run -d --name mcp-helm -p 8012:8012 ghcr.io/zekker6/mcp-helm:v1.3.0 -mode=sse
--mode=sse フラグは、MCP クライアントが接続する際に使う Server-Sent Events モードを有効にするためのものです。
代わりに、-mode=http を使って Streamable HTTP モードを有効にすることもできます。
ビルド済みバイナリから
リリースページからバイナリをダウンロードしてください。
Linux x86_64 の例です(ほかのアーキテクチャやプラットフォーム向けのものも利用できます)。
latest=$(curl -s https://api.github.com/repos/zekker6/mcp-helm/releases/latest | grep 'tag_name' | cut -d\" -f4)
wget https://github.com/zekker6/mcp-helm/releases/download/$latest/mcp-helm_Linux_x86_64.tar.gz
tar axvf mcp-helm_Linux_x86_64.tar.gz
Mise を使用する
Mise(mise-en-place)は、開発環境をセットアップするツールです。
mise i ubi:zekker6/mcp-helm@latest
Go でインストールする
注:Go 1.26.0 が必要です。
go install github.com/zekker6/mcp-helm/cmd/mcp-helm@latest
ソースからビルドする
注:Go 1.26.0 が必要です。
Kubernetes モジュール v0.37.1 を使用する際は、k8s.io/kube-openapi を v0.0.0-20260721132016-d427ff9ee9ad に、Kustomize の api/kyaml を
v0.21.2 に固定してください。より新しいリビジョンでは structured-merge-diff/v7 が取り込まれ、
Kubernetes モジュールの structured-merge-diff/v6 型と互換性がなくなります。
-
リポジトリをクローンします:
git clone https://github.com/zekker6/mcp-helm.git cd mcp-helm -
バイナリをビルドします:
go build -o mcp-helm ./cmd/mcp-helm -
サーバーを実行します:
./mcp-helm
設定
MCP クライアントがこのサーバーに接続するように設定します。このサーバーは、ツールの検出と実行のための標準 MCP プロトコルを実装しています。
http モードと sse モードでは、POST ボディは 8 MiB に制限されます。これより大きなリクエストは、Content-Length のないチャンク転送を含め、HTTP 413 を受け取ります。HTTP サーバーは、リクエストヘッダーに 5 秒、ヘッダーとボディを合わせて 30 秒、アイドル接続に 60 秒を許可します。SSE レスポンスには書き込み期限がなく、これらのリクエスト読み取りの予算を超えて開いたままになる場合があります。これらの制限は、受け入れられたツール呼び出しによって実行される処理を制限するものではありません。
リポジトリインデックスのキャッシュ
HTTP Helm リポジトリのインデックスは、初回使用時にダウンロードされ、-repo-index-max-age(デフォルトは 1h)の間再利用されます。この期間を超えると、次のリクエストでインデックスが再度ダウンロードされるため、新しく公開されたチャートバージョンが再起動なしで反映されます。-repo-index-max-age=0 を設定すると、毎回のリクエストでインデックスがダウンロードされます。OCI レジストリは常にライブで照会されます。
デフォルトでは、各クライアントは最大 16 個のリポジトリインデックスを保持し、起動時のメモリ割り当てに基づいて算出されたソースバイトの予算を持ち、どちらかの上限に達すると、最も最近使われていないインデックスから破棄されます。MCP サーバーは、1 つの Helm クライアントとそのキャッシュをリクエスト間で共有します。パースされた Go オブジェクトはメモリオーバーヘッドを増やしますが、これはプロセスのヒープ制限ではありません。破棄は、アクティブなリクエストがすでに保持しているスナップショットには影響しません。インデックスファイルは、パース後に削除されるプライベートな一時ディレクトリを使用します。これはダウンロードまたはパースの失敗時も同様です。HTTP チャートアーカイブはメモリから直接読み込まれます。共有 Helm キャッシュディレクトリ内の既存ファイルは読み取られたり削除されたりしません。キャッシュされたスナップショットは、リクエストコンテキストやダウンロードクライアントを保持しません。
キャッシュとダウンロードの制限
デフォルト値は lib/helm_client/limits.go と lib/helm_client/memory.go 内の名前付き定数です。Helm クライアントの作成時に読み取られる環境変数で上書きできます。値は正の 10 進整数である必要があり、バイト制限はバイト単位で指定し、MiB などの接尾辞付き単位は使用できません。未設定の変数はデフォルト値を使用します。空、ゼロ、負、不正な形式、またはオーバーフローする値は起動に失敗します。既存のクライアントは環境の変更を再読み込みしません。-repo-index-max-age フラグは引き続き TTL を制御します。
| 環境変数 | デフォルト | 制御対象 |
|---|---|---|
MCP_HELM_REPO_CACHE_MAX_ENTRIES | 16 | 保持するリポジトリインデックスの数 |
MCP_HELM_REPO_CACHE_MAX_BYTES | 自動、以下で説明 | 保持するインデックスソースの合計バイト数 |
MCP_HELM_INDEX_MAX_BYTES | 33554432 (32 MiB) | HTTP インデックスダウンロードあたりのバイト数 |
MCP_HELM_CHART_MAX_BYTES | 104857600 (100 MiB) | 圧縮された HTTP チャートアーカイブあたりのバイト数 |
MCP_HELM_OCI_MAX_BYTES | 134217728 (128 MiB) | OCI プルあたりのレスポンスボディの合計バイト数 |
MCP_HELM_REPO_CACHE_MAX_BYTES が未設定の場合、クライアントは 検出された最小メモリ割り当ての 1/16、上限 256 MiB を使用します。Linux cgroup v1/v2 の制限(可視の親制限を含む)、GOMEMLIMIT によって初期化された現在の Go ランタイムメモリ制限、およびホストの合計 RAM を考慮します。変動する空きメモリや Kubernetes のメモリリクエストは使用しません。この計算は Go のメモリ制限を変更しません。
| メモリ割り当て | 自動キャッシュソースバイト予算 |
|---|---|
| 512 MiB | 32 MiB |
| 1 GiB | 64 MiB |
| 2 GiB | 128 MiB |
| 4 GiB 以上 | 256 MiB |
制限を検出できない場合、クライアントは 64 MiB にフォールバックします。読み取り不能なコンテナコントローラーなどによる検出エラーは、より小さい検出予算があればそれを保持しつつ、結果を 64 MiB に上限設定します。起動ログは、サイジングモード、選択された予算、検出された割り当てとそのソース(利用可能な場合)、および検出エラーを報告します。バックグラウンドでのサイズ変更は実行されません。割り当ての変更は新しいクライアントの起動時に有効になります。明示的なバイト上書きは検出と自動上限をバイパスします。小さな割り当てでは、キャッシュ予算より大きい有効なインデックスをダウンロードできますが、保持されません。これらのソースバイト予算は測定されたヒープ制限ではなく、並行処理による OOM を防ぐものではありません。
OCI 予算には、マニフェスト、設定、チャートレイヤー、認証レスポンス、リダイレクト、およびリトライが含まれます。並行プルは独立した予算を持ちます。Content-Length のないレスポンスは読み取り中にチェックされ、サイズ超過のダウンロードは切り詰めて解析されるのではなく失敗します。これらの制限は並行リクエストやチャートレンダリングのメモリを制限しません。Helm の解凍されたチャートコンテンツの制限は引き続き適用されます。OCI ダウンロードは、呼び出し元のキャンセルとレジストリリクエストのキャンセルの両方を尊重し、レスポンスボディの読み取り中も同様です。
たとえば、より大きなワーキングセットとより大きな個別インデックスを許可します。
env MCP_HELM_REPO_CACHE_MAX_ENTRIES=32 \
MCP_HELM_REPO_CACHE_MAX_BYTES=134217728 \
MCP_HELM_INDEX_MAX_BYTES=67108864 \
./mcp-helm -mode=http
共有サーバーの検証
task test:repos を実行すると、Prometheus Community、Grafana、Bitnami、Jetstack、Argo、および
ingress-nginx から現在のインデックスを取得します。設定された制限に対してワーキングセットをチェックし、それらの
正確なインデックスを 8 つの同時呼び出し元でローカルに再生し、ウォームキャッシュの再利用を検証し、各パブリック
リポジトリから代表的なチャートを 1 つダウンロードします。繰り返しの負荷フェーズではパブリックサーバーに
アクセスしません。テストはソースサイズ、レイテンシ、失敗、および静止時の Go ヒープ使用量をログに記録します。
これにはキャプチャされたテストフィクスチャが含まれ、プロセスの RSS ではありません。パブリックエンドポイント
またはチャート形式の失敗はスキップされるのではなく、テストを失敗させます。task test ではこのネットワーク
チェックは無効のままです。task test:all はバイナリをビルドし、ユニットテスト、エンドツーエンドテスト、および
パブリックリポジトリテストをまとめて実行します。
CI はリンティング後に task test:all を実行するため、パブリックリポジトリのチェックも変更をゲートします。
OCI チャートを参照するインデックスについては、直接の OCI 参照も個別にテストします。HTTP リポジトリローダーは
現在、Bitnami の nginx チャートを含む oci:// アーカイブ URL を追跡しません。これらのチャートには直接の OCI
リポジトリ URL を使用してください。この互換性の失敗はパブリックテストで引き続き可視化されます。
通常のテストでは、ローカルリポジトリに対して 8 つの独立した MCP HTTP クライアントも実行します。これには強制的な キャッシュ削除と繰り返しのチャートダウンロードが含まれます。成功した実行は互換性と並行性のリグレッションチェック であり、本番環境の容量保証ではありません。キャッシュ制限は保持を制限するものであり、アクティブユーザー数を制限する ものではありません。コールドインデックスの取得は依然としてグローバルロックを共有し、チャートアーカイブはリクエスト ごとにダウンロードされます。インデックス制限は最大のリポジトリに合わせて、キャッシュのバイト制限は頻繁に使用される ワーキングセット全体に成長の余地を加えてサイズ設定してください。
認証
サーバーは OCI レジストリと HTTP Helm リポジトリの両方の認証をサポートしています。
Go クライアントを埋め込む場合、HTTP リポジトリのダウンロードは http.DefaultTransport が *http.Transport で
あればそれをクローンします。それがラップされているか、別の http.RoundTripper に置き換えられている場合、
ダウンロードは環境プロキシサポートを備えたプライベートトランスポートを使用します。ラッパーは使用されません。
クライアントのリポジトリ TLS オプションは引き続き適用されます。
コマンドラインフラグ
| フラグ | 説明 |
|---|---|
-username | 基本認証用のユーザー名(HTTP リポジトリ、および -registry-credentials でカバーされない OCI レジストリ) |
-password-file | パスワードを含むファイルへのパス |
-registry-credentials | Docker 形式の認証情報ファイルへのパス(例: ~/.docker/config.json)。リストされた OCI レジストリに対して優先されます |
-registry-plain-http | OCI レジストリにプレーン HTTP を使用(安全でない、開発専用) |
-tls-cert | HTTP リポジトリ用の TLS クライアント証明書ファイルへのパス |
-tls-key | HTTP リポジトリ用の TLS クライアント鍵ファイルへのパス |
-tls-ca | サーバー証明書を検証するための CA 証明書ファイルへのパス |
-tls-insecure-skip-verify | TLS 証明書の検証をスキップ(安全でない) |
-pass-credentials-all | すべてのチャート URL とリダイレクト元に HTTP リポジトリの認証情報を送信(安全でない) |
HTTP リポジトリの認証情報は、デフォルトではリポジトリ自身のスキーム、ホスト、ポートに送信されます。他の
オリジンにあるチャートアーカイブは引き続きダウンロードできますが、リダイレクト後や HTTPS から HTTP への
ダウングレード後を含め、リポジトリの認証情報は受け取りません。-pass-credentials-all は、それらの認証情報を
すべてのチャート URL とリダイレクト元に送信することをオプトインします。リポジトリのチャート URL とすべての
リダイレクト先を信頼できる場合にのみ使用してください。
基本認証
ユーザー名/パスワード認証を必要とするリポジトリの場合:
# Create a password file (recommended for security)
echo "your-password" > /path/to/password.txt
chmod 600 /path/to/password.txt
# Run with basic auth
./mcp-helm -username myuser -password-file /path/to/password.txt
OCI レジストリ認証
プライベート OCI レジストリの場合、認証は以下の方法で設定できます。
- Docker 認証情報 - サーバーは
~/.docker/config.jsonの認証情報を自動的に使用します - 明示的な認証情報ファイル -
-registry-credentialsフラグを使用します
# Using Docker login (credentials stored in ~/.docker/config.json)
docker login ghcr.io
echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin
# Using explicit credentials file
./mcp-helm -registry-credentials /path/to/docker/config.json
# Using basic auth for OCI registry
./mcp-helm -username myuser -password-file /path/to/password.txt
基本認証とレジストリ認証情報ファイルの併用
1 つのインスタンスで、プライベート HTTP リポジトリとプライベート OCI レジストリを同時に扱うことができます。
-username/-password-file と -registry-credentials の両方が設定されている場合、OCI リクエストはレジストリホストごとにルーティングされます。
- 認証情報ファイルがチャートのレジストリホストに対する認証情報を解決できる場合、そのホスト単位の認証情報が使用されます(
auths、credHelpers、credsStoreのすべてが参照され、Helm CLI と同じ Docker 認証情報の解決方法を使用するため、Docker Hub の正規キーhttps://index.docker.io/v1/も正しく照合されます)。 - それ以外の場合は、静的な
-username/-password-fileによる基本認証が使用されます。
これにより、-registry-credentials が対象とする OCI レジストリに対しては引き続き -registry-credentials が優先されつつ、基本認証は HTTP リポジトリ(および認証情報ファイルで解決できない OCI レジストリ)に適用されます。
# HTTP repos use basic auth; OCI hosts in config.json use their per-host creds
./mcp-helm \
-username myuser -password-file /path/to/password.txt \
-registry-credentials /path/to/docker/config.json
外部認証情報ストア(credsStore)やレジストリ単位のヘルパー(credHelpers)の背後にある認証情報は、実行時にそのヘルパーバイナリを呼び出すことで解決されます。
実行環境でヘルパーが利用できない場合、影響を受けるレジストリは基本認証にフォールバックします。起動時に警告がログに出力されるため、この状態を把握できます。ルーティングでは -registry-credentials に渡されたファイルのみが考慮されます(暗黙的な ~/.docker/config.json へのフォールバックはありません)。そのため、必要なプライベート OCI レジストリはすべてこのファイルに記載してください。
TLS/mTLS 設定
カスタム TLS 要件を持つリポジトリの場合:
# Custom CA certificate (for self-signed or internal CAs)
./mcp-helm -tls-ca /path/to/ca.crt
# Client certificate authentication (mTLS)
./mcp-helm -tls-cert /path/to/client.crt -tls-key /path/to/client.key
# Combined: mTLS with custom CA
./mcp-helm -tls-cert client.crt -tls-key client.key -tls-ca ca.crt
# Skip TLS verification (development only, not recommended for production)
./mcp-helm -tls-insecure-skip-verify
Docker 設定
認証を渡す Docker の例:
# With basic auth
docker run -d --name mcp-helm -p 8012:8012 \
-v /path/to/password.txt:/secrets/password.txt:ro \
ghcr.io/zekker6/mcp-helm:v1.3.0 \
-mode=sse -username myuser -password-file /secrets/password.txt
# With Docker credentials
docker run -d --name mcp-helm -p 8012:8012 \
-v ~/.docker/config.json:/root/.docker/config.json:ro \
ghcr.io/zekker6/mcp-helm:v1.3.0 \
-mode=sse
可観測性
サーバーは OpenTelemetry のトレース、メトリクス、ログを OTLP 経由でエクスポートできます。これはデフォルトでは無効です。OTEL_ENABLED が未設定の場合、何もエクスポートされず、エクスポーターも構築されず、プロバイダーもグローバルに登録されず、インストルメンテーションもインストールされないため、バイナリは現在とまったく同じように動作します。
OTEL_ENABLED が唯一のスイッチです。OTEL_SDK_DISABLED は参照されません。また OTEL_EXPORTER_OTLP_PROTOCOL も同様です。ワイヤプロトコルは、以下で説明するエンドポイントのスキームから決定されます。
環境変数
| 変数 | デフォルト | 説明 |
|---|---|---|
OTEL_ENABLED | false | マスタースイッチ。この値が真とみなせる値(true、1、t)の場合にのみテレメトリーが設定されます |
OTEL_EXPORTER_OTLP_ENDPOINT | - | 3 つのシグナルすべてのベースエンドポイント。有効化時には必須です。ただし、シグナルごとのエンドポイントがすべて設定されている場合は除きます |
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT | ベースエンドポイント | トレース専用のオーバーライド。そのまま使用されます(HTTP の場合は完全なパスを含めてください) |
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT | ベースエンドポイント | メトリクス専用のオーバーライド。そのまま使用されます |
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT | ベースエンドポイント | ログ専用のオーバーライド。そのまま使用されます |
OTEL_SERVICE_NAME | mcp-helm | コレクターに報告されるサービス名 |
OTEL_RESOURCE_ATTRIBUTES | - | 追加のリソース属性。例: deployment.environment.name=production |
OTEL_EXPORTER_OTLP_HEADERS | - | すべてのエクスポートに付与されるヘッダー。例: 認証用。SDK のエクスポーターによって読み取られます |
OTEL_EXPORTER_OTLP_TIMEOUT | 10000 | エクスポートのタイムアウト(ミリ秒)。SDK のエクスポーターによって読み取られます |
OTEL_EXPORTER_OTLP_COMPRESSION | - | gzip を設定するとエクスポートが圧縮されます。SDK のエクスポーターによって読み取られます |
OTEL_METRIC_EXPORT_INTERVAL | 60000 | メトリクスのエクスポート間隔(ミリ秒) |
OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION | base2_exponential_bucket_histogram | 両方の OTLP トランスポートにおけるヒストグラム集約。クラシックなバケットにするには explicit_bucket_histogram を設定します |
OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE | cumulative | カウンターとヒストグラムは開始またはリセット以降に蓄積されます。SDK は delta と lowmemory も受け付けます |
OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT | 4096 | スパン属性値の最大長。それより長い値は切り詰められます。SDK のデフォルトは無制限ですが、いくつかの値はクライアントから送られてきます。OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT が優先され、-1 で上限が解除されます |
OTEL_EXPORTER_OTLP_CERTIFICATE | システムルート | https:// または grpcs:// のコレクターを検証するために使用される PEM CA バンドル。SDK のエクスポーターによって読み取られます |
OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE | - | コレクターへの mTLS 用の PEM クライアント証明書。SDK のエクスポーターによって読み取られます |
OTEL_EXPORTER_OTLP_CLIENT_KEY | - | コレクターへの mTLS 用の PEM クライアントキー。SDK のエクスポーターによって読み取られます |
テレメトリーが有効で、エンドポイントが欠落しているか不正な形式の場合、サーバーは該当する変数名を示すエラーとともに非ゼロで終了します。タイプミスが「テレメトリーなし」へ暗黙的に縮退することはありません。OTEL_ENABLED がオフの場合、エンドポイント変数はまったく解析されないため、環境内の古い値が起動を壊すことはありません。
リソース属性
サーバーは service.name(OTEL_SERVICE_NAME から、なければ mcp-helm)と service.version を自身で設定し、それ以外は
OTEL_RESOURCE_ATTRIBUTES から読み取ります。セマンティック規約はそれ以上のものを求めており、残りはデプロイメントから
取得する必要があります:
| 属性 | 取得元 |
|---|---|
deployment.environment.name | OTEL_RESOURCE_ATTRIBUTES。.name サフィックスに注意 - 素の deployment.environment は非推奨です |
service.instance.id | downward API からの OTEL_RESOURCE_ATTRIBUTES。レプリカが複数稼働する場合は必須です。そうでなければすべてのインスタンスの系列が衝突します |
service.namespace | 他のサービスがバックエンドを共有する場合の OTEL_RESOURCE_ATTRIBUTES |
k8s.pod.uid およびその他の k8s.* | Collector の k8sattributes プロセッサ。これらを追加するためのサポートされた方法です |
Kubernetes では、最初の 2 つは downward API から取得します:
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: OTEL_RESOURCE_ATTRIBUTES
value: deployment.environment.name=production,service.instance.id=$(POD_NAME)
エンドポイントスキーム
ワイヤプロトコルと TLS はどちらもエンドポイントの URL スキームから決定されます:
| エンドポイント | プロトコル | TLS | エクスポート先 |
|---|---|---|---|
grpc://collector:4317 | OTLP/gRPC | なし | collector:4317 |
grpcs://otel.example.com:4317 | OTLP/gRPC | あり | otel.example.com:4317 |
http://collector:4318 | OTLP/HTTP | なし | http://collector:4318/v1/traces、/v1/metrics、/v1/logs |
https://otel.example.com | OTLP/HTTP | あり | https://otel.example.com/v1/traces、/v1/metrics、/v1/logs |
その他のスキームは、受け入れられる 4 つのスキームを示す起動エラーとなります。
- base エンドポイントはベース URL です: HTTP の場合、末尾のスラッシュを取り除いたうえでシグナルのパス(
/v1/traces、/v1/metrics、/v1/logs)が追加されます。 末尾にスラッシュが付いた状態で注入された Collector エンドポイントも処理されます。 - シグナルごとのエンドポイントは、OTLP 仕様が要求するとおりそのまま使用されるため、HTTP の場合は
/v1/tracesなどを含む完全な パスを指定する必要があります。 - gRPC エンドポイントは
host:portのみを保持します。gRPC にはシグナルのパスがないため、パスは破棄されます。 - プロトコルはシグナルごとに解決されるため、混在した構成も機能します: トレースは gRPC 経由、メトリクスとログは
HTTP 経由という構成がサポートされています。ログの場合、
grpcs://はカスタム CA がなくても TLS を要求します。プライベート CA にはOTEL_EXPORTER_OTLP_CERTIFICATEまたはOTEL_EXPORTER_OTLP_LOGS_CERTIFICATEを使用してください。
構成例
3 つのシグナルすべてに 1 つのエンドポイントを使用する場合:
OTEL_ENABLED=true \
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318 \
./mcp-helm -mode=http
トレース、メトリクス、ログは http://otel-collector:4318/v1/traces、/v1/metrics、/v1/logs に送信されます。この
エンドポイントを grpc://otel-collector:4317 に切り替えると、他の変更なしに 3 つのシグナルすべてが OTLP/gRPC に移行します。
シグナルごとのエンドポイントで、プロトコルと TLS を混在させる場合:
OTEL_ENABLED=true \
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=grpc://otel-collector:4317 \
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=https://metrics.example.com/v1/metrics \
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=https://logs.example.com/v1/logs \
OTEL_SERVICE_NAME=mcp-helm \
OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=production \
./mcp-helm -mode=http
Docker の場合:
docker run -d --name mcp-helm -p 8012:8012 \
-e OTEL_ENABLED=true \
-e OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318 \
ghcr.io/zekker6/mcp-helm:latest -mode=http
OTEL_* 変数は、OpenTelemetry サポートが導入される前にビルドされたイメージでは無視されるため、サポートを含むタグを固定するか、
latest を使用してください。
出力される内容
トレース
HTTP 経由のツール呼び出しは、受信リクエストからそれが引き起こす Helm の処理に至るまで、1 つのトレースを生成します:
POST /mcp (HTTP server span)
tools/call get_chart_images (MCP server span)
tool.get_chart_images (MCP tool span)
helm.get_chart_images (Helm operation span)
helm.load_chart
helm.oci.pull
helm.parse.images
カスタムテレメトリ名は、アプリケーション固有の mcp_helm.* 名前空間を使用し、個人ドメインは含みません。以下に示す
Helm 固有の属性は、可読性のために mcp_helm.helm. プレフィックスを省略しています。実際に出力される名前にはこのプレフィックスが含まれます。
OpenTelemetry の命名ガイドライン
は、標準名前空間との衝突を避けることを推奨しており、必須の逆 DNS プレフィックスを定めているわけではありません。レジストリ属性
(url.full、server.address、server.port、error.type、gen_ai.*、mcp.*、jsonrpc.*、rpc.*) は完全な形で示しています。
以前のカスタム名前空間を使用している既存のクエリは更新する必要があります。標準の OTel 名は変更されません。
| Span | Kind | 属性 |
|---|---|---|
<METHOD> <route> | server | otelhttp HTTP サーバーセマンティック規約、および POST が伝送した JSON-RPC メッセージ (以下)。sse モードと http モードのみ |
<mcp method> [<tool>] | server | mcp.method.name、jsonrpc.request.id、gen_ai.tool.name、gen_ai.operation.name、mcp.session.id、mcp.protocol.version、network.transport、network.protocol.name、rpc.response.status_code、error.type |
tool.<name> | internal | - |
helm.list_charts | internal | repository.url、repository.type、chart.count |
helm.list_chart_versions | internal | + chart.name、version.count |
helm.get_latest_version | internal | + chart.name、chart.version (解決済み) |
helm.get_latest_values | internal | + chart.name、chart.version (解決済み)。ライブラリ専用。これに到達する MCP ツールはありません |
helm.get_chart_values | internal | + chart.name、chart.version |
helm.get_chart_contents | internal | + chart.name、chart.version、recursive |
helm.get_chart_dependencies | internal | + chart.name、chart.version、dependency.count |
helm.get_chart_images | internal | + chart.name、chart.version、recursive、image.count |
helm.load_chart | internal | repository.type、chart.name、chart.version |
helm.oci.pull | client | oci.ref、server.address、server.port |
helm.oci.tags | client | oci.ref、server.address、server.port |
helm.repo.index | client | repository.url、server.address、server.port |
helm.chart.download | client | url.full、server.address、server.port |
helm.parse.images | internal | recursive |
helm.parse.contents | internal | recursive |
失敗した span は ERROR ステータスでマークされ、例外を記録し、error.type を持ちます。URL 属性は
サニタイズされます。リポジトリ、OCI、またはチャートの URL が span 属性になる前に、user:password@ のユーザー情報は除去されます。
helm.chart.download スパンは url.full を報告します。これは、チャート URL が実際に取得されたリソースそのものであるためです。
helm.repo.index はそうではありません。Helm ゲッターがインデックスパスを自身で解決するため、このサーバーが保持する URL はリクエストされたものとは異なります。
MCP サーバースパンは MCP セマンティック規約 に従います。名前は {mcp.method.name} {target} となり、例えば tools/call get_chart_values、tools/list、ping のようになります。クライアントが名前を選ぶため、登録されたツールのみがターゲットになります。登録されていないツールでも gen_ai.tool.name には到達します。mcp-go が実装していないメソッドは、HTTP インストルメンテーションが未知のメソッドを扱うのと同じように、MCP という名前のスパンに mcp.method.name=_OTHER として記録されるため、クライアントがリクエストごとにスパン名を生成することはできません。サーバーは、github.com/mark3labs/mcp-go/otel ではなく、mcp-go のトレーシングインターフェース用の独自アダプターを通じてトレースし、mcp-go が設定する mcp.method と mcp.tool.name のキーは省略します。レジストリがどちらも定義していないためです。未知のメソッドのスパンは現在、jsonrpc.request.id を省略します。mcp-go がそのパスでトレーサーやエラーフックに ID を公開していないためです。延期された修正 には上流の API サポートが必要です。
mcp.protocol.version は、mcp-go がそれを認識した場合にのみ、リクエストの有効なバージョンを記録します。サポートされていないメタデータ値や生のプロトコルヘッダーは、スパンやメトリクスにコピーされません。network.transport は、sse モードと http モードでは tcp であり、network.protocol.name=http を伴います。stdio モードでは pipe です。
JSON-RPC エラーで応答されたリクエストは、コードを rpc.response.status_code に保持します。規約では -32700、-32600、-32601、-32602(未知のツールを含む)、および -32002 を呼び出し元に帰属させるため、これらは error.type を未設定のままにし、スパンステータスを UNSET にします。その他のコードは error.type をそのコードに設定し、ステータスを ERROR に設定し、JSON-RPC エラーメッセージで説明されます。ツールハンドラーがエラーを返すのではなく、呼び出し元に失敗を報告した場合は、error.type を tool_error に設定し、同様に ERROR ステータスになります。
各記録 POST スパンは、そのボディがどの JSON-RPC メッセージを運んだかも mcp_helm.jsonrpc.message.kind(request、notification、response)として記録します。通知は mcp.method.name を追加し、レジストリがリストしていないメソッドの場合は _OTHER となります。応答は jsonrpc.request.id を追加します。mcp-go は自身がディスパッチするリクエストに対してのみ MCP スパンを開くため、通知や、アイドルセッションが送信する POST のほとんどを占めるサーバーピングへのクライアントの応答については、HTTP スパンが唯一の記録となります。リクエストのメソッドと ID はその MCP スパンに留まるため、それらに対するクエリは各リクエストを一度だけカウントします。アノテーションのキャプチャは 64 KiB に制限されています。それより大きいボディは解析もアノテーションもされません。記録しないスパンはキャプチャを完全にスキップします。これらの制限はテレメトリにのみ影響します。トランスポートは依然として元のボディと読み取りエラーを受け取ります。
受信する W3C traceparent / tracestate ヘッダーは sse モードと http モードで尊重されるため、ツール呼び出しは新しいトレースを開始するのではなく、呼び出し元のトレースに参加します。クライアントがリクエストの params._meta(SEP-414)に入れるトレースコンテキストは、すべてのモードで MCP サーバースパンの親となります。stdio も含まれます。規約が MCP クライアントスパンをその親とするためです。これが既存のトランスポートコンテキストを置き換える場合、MCP スパンはそのコンテキストにリンクし、異なるトレース間でも HTTP スパンへの接続を保持します。メタデータが存在しないか無効な場合は、追加のリンクなしで既存の親を保持します。どちらもない場合、stdio モードの各 MCP リクエストはルートスパンとなります。
メトリクス
| メトリクス | 種類 | 単位 | 属性 |
|---|---|---|---|
mcp.server.operation.duration | ヒストグラム | s | mcp.method.name、gen_ai.tool.name、gen_ai.operation.name、mcp.protocol.version、network.transport、network.protocol.name、rpc.response.status_code、error.type |
mcp_helm.helm.operation.duration | ヒストグラム | s | …helm.operation、…helm.repository.type、error.type |
http.server.* | otelhttp 由来 | - | http.server.request.duration、http.server.request.body.size、http.server.response.body.size。sse/http モードのみ |
go.* | OTel ランタイム計装由来 | - | Go ランタイムのメモリ、GC、ゴルーチンのメトリクス |
mcp.server.operation.duration は、MCP セマンティック規約が受信側に対して定義するヒストグラムです。これは mcp-go がスパンを開始するすべてのリクエストを対象とし、受信からレスポンスの準備が整うまでをカバーします。エラーで応答するものも含まれます。通知は測定されず、その時点より前に mcp-go が拒否するメッセージ(不正な JSON、誤った jsonrpc バージョン)も同様に測定されません。どちらもスパンを取得しないためです。
MCP、Helm、HTTP、ランタイムのヒストグラムを含むすべてのヒストグラムは、OTLP/HTTP と OTLP/gRPC の両方でデフォルトで base-2 指数集約を使用します。バケットは記録された値に適応し、正または負の範囲ごとに最大 160 バケット、最大スケールは 20 です。メトリクスはデフォルトで累積的な時間性を使用します。つまり、繰り返しエクスポートしても最新の間隔のみを報告するのではなく、以前の観測値が保持されます。プロセスの再起動により累積値はリセットされます。
上記の標準環境変数は、どちらのデフォルトも個別に上書きできます。明示的な集約を選択した場合、MCP と Helm の duration ヒストグラムは 10 ms から 300 s までの推奨境界を使用します。Collector とバックエンドが指数ヒストグラムを受け入れることを確認してください。従来の _bucket シリーズを必要とするクエリは更新が必要になる場合があります。
error.type は成功時には存在しません。これは規約が規定するとおりです。ok 値でフィルタリングするのではなく、属性が未設定であることでフィルタリングしてください。mcp.server.operation.duration では、これはスパンと一致します。すなわち、規約がそのコードを呼び出し元に帰属させる場合を除き JSON-RPC エラーコード、または呼び出し元に失敗を報告したツールハンドラーの場合は tool_error です(mcp-go はこれをエラー結果を伴う成功レスポンスとして配信します)。パニックを起こしたツールハンドラーには -32603 が応答されます。mcp_helm.helm.operation.duration では、Go のエラー型が保持されます。ヒストグラムの count 値のレートは呼び出しレートを提供するため、別途カウンターはありません。
Helm の操作はネストし、各レベルが独自のポイントを記録します。get_latest_values は get_latest_version と get_chart_values をラップし、chart_version を省略するツール呼び出しは、要求された操作の前に get_latest_version を記録します。操作間でヒストグラムの count を合計するのではなく、mcp_helm.helm.operation でフィルタリングしてください。そうしないと、1 回の論理呼び出しが複数回カウントされます。
メトリクスの属性は意図的に低カーディナリティです。リポジトリ URL、チャート名、チャートバージョンはスパンにのみ現れ、メトリクスには決して現れません。gen_ai.tool.name は登録済みのツールに対してのみ記録され、mcp.method.name は _OTHER にフォールバックするため、どちらもクライアントからの任意の文字列を保持しません。プロトコルバージョンは mcp-go がサポートするバージョンに制限されています。http.server.* メトリクスでは、server.address と server.port はリクエストの Host ヘッダーではなく -httpListenAddr を報告するため、そのヘッダーを変化させる非認証のプローブが値ごとにシリーズを開くことはできません。
ログ
テレメトリーを有効にすると、ログレコードは stderr に加えて OTLP ログエクスポーターにも tee されます。両方のシンクは
-logLevel に従うため、レベルを上げればフィルタリングされたレコードは stderr にも出力されず、ネットワークにも流れません。また、各ツール呼び出しは
ツール名、所要時間、そして失敗時には error.type を含む INFO レコードを 1 件出力します。このレコードが表すのは JSON-RPC レスポンスではなく
ハンドラーです。返されたエラーはその Go の型名で示され、呼び出し元に報告された失敗は tool_error、パニックは _OTHER となります。
トレースされた呼び出し箇所から出力されるすべてのレコードは、そのスパンと関連付けられるため、ログ、トレース、メトリクスは
バックエンドで一致します。2 つのシンクはこの関連付けを異なる方法で伝えます。stderr の行には trace_id と span_id フィールドが付き、
エクスポートされるレコードにはログデータモデル独自のトレース ID フィールドが付き、これは SDK が出力元のコンテキストから埋めます。
ID はエクスポートされるレコードの属性からは取り除かれるため、ネットワーク上に二重に載ることはありません。
制限事項
次の 2 点は意図的に計装していません。
- リクエストごとの送信 HTTP スパンはありません。 送信処理は手動の
helm.repo.index、helm.chart.download、helm.oci.pull、helm.oci.tagsクライアントスパンでカバーされています。OCI リクエストは依然として Helm の SDK が 内部で作成するコンテキストを使用しており、これらのリクエストを計装するとツールのトレースから切り離されたスパンが生成されてしまいます。 - 長時間存続するストリームリクエストは HTTP トレースとメトリクスから除外されます。
sseモードのGET /sseリクエストと、httpモードのGET /mcpリクエストは、クライアントセッションの存続期間中オープンなままです。これらをトレースすると数時間に及ぶ スパンが生成され、セッションの持続時間がリクエストレイテンシのヒストグラムに含まれてしまうため、どちらもフィルタリングされます。これらのセッションで やり取りされる JSON-RPC リクエストは通常どおりトレースされます。
シャットダウン
SIGTERM または SIGINT を受け取ると、サーバーは新規の処理の受け付けを停止し、処理中のリクエストを 10 秒以内にドレインし、その後
バッファリングされたテレメトリーを 5 秒以内にフラッシュします。そのため、決して切断しないクライアントや、決して応答しないコレクターが
プロセスを存続させ続けることはできません。これらの予算が別々になっているのは意図的です。ドレインに時間がかかっても、フラッシュに必要な時間を
消費することはできません。2 回目のシグナルで即座に終了します。
プロセスに完了する余地を与えてください。terminationGracePeriodSeconds(または docker stop -t)を少なくとも 20 秒に設定しないと、
シグナルを受けた時点でバッファリングされていたスパンとログレコードは失われます。
起動に失敗したトランスポート(ポートがすでに使用されている、使用できないリッスンアドレスなど)は fatal としてログに記録され、
ステータス 1 で終了します。
ロードマップ
- OpenTelemetry 計装(OTLP 経由のトレース、メトリクス、ログ)
- ツールの追加
- リポジトリ内のすべてのチャートを一覧表示する
- チャートのすべてのバージョンを一覧表示する
- チャートの最新バージョンを取得する
- チャートの values を取得する
- チャートの最新バージョンの values を取得する
- チャートの完全な内容を抽出する
- Charts.yaml から依存チャートを抽出する
- チャートで使用されているイメージを抽出する
- OCI レジストリをサポートする
- OCI レジストリからチャートをプルする
- OCI レジストリからタグ/バージョンを一覧表示する
- Docker 認証情報による認証をサポートする
- プライベート HTTP リポジトリの使用をサポートする
- HTTP ベーシック認証の認証情報を提供する方法を追加する
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。