Terraform MCPサーバーの使い方 — ClaudeにIaCコードを書かせる
HashiCorp公式Terraform MCPサーバーをClaude Codeに入れる手順と、実際に書き出される.mcp.json、Registry検索系ツールの呼ばれ方、共有サーバー化の設定を扱います。
Terraform MCPサーバーはHashiCorp公式のMCPサーバーで、Terraform RegistryとHCP Terraform / Terraform EnterpriseのAPIをClaude Codeなどのクライアントにつなぎます。プロバイダーやモジュールのドキュメントをその場で検索し、Sentinelポリシーの要件を確認しながらHCLを書けるのが特徴です。
ツールは大きく2系統に分かれます。公開Registryを検索する読み取り系と、HCP Terraformのワークスペースを操作する実行系です。本記事は導入と読み取り系、共有サーバー化までを扱います。ワークスペースの作成・更新や変数・Run(実行)の制御はTerraform MCPサーバーのワークスペース管理にあります。
最初に決めること — Registry検索だけか、ワークスペースまで触るか
導入手順は、どこまで任せるかで変わります。先に分岐を決めておくと、トークンや環境変数の要否で迷いません。
Terraform MCPサーバーの2つの使い方
Registry検索だけ
既定の設定のままです。有効なのはregistryツールセットで、Provider・Module・Sentinelポリシーのドキュメントを引けます。TFE_TOKENは空のままで動きます。
ワークスペースまで操作
terraformツールセットを有効にし、TFE_TOKENを渡します。create_workspace・update_workspace・delete_workspace_safely・action_runは、さらにENABLE_TF_OPERATIONS=trueが要ります。
Terraform MCPサーバーはGo製で、リポジトリはhashicorp/terraform-mcp-serverです。READMEの法的注記はIBMの名義になっています。トランスポートはローカル用のstdioが既定で、複数人で共有するときはstreamableHTTPに切り替えます。
Claude Codeに追加する
公式READMEの前提条件は、Dockerが動いていることとMCP対応のクライアントがあることの2点です。Claude Codeへの登録は1行で済みます。
Registry検索だけで始める3ステップ
- 1
Dockerを起動しておく
イメージ
hashicorp/terraform-mcp-serverは、Claude Codeが起動時にdocker runで立ち上げます。 - 2
`claude mcp add`で登録する
stdioで、ユーザースコープ(
-s user)に登録するのがREADME記載のコマンドです。 - 3
具体名で質問する
リソースアドレスを含めて頼むと、Registryツールが呼ばれやすくなります。
claude mcp add terraform -s user -t stdio -- docker run -i --rm hashicorp/terraform-mcp-serverclaude mcp add --help(v2.1.287)では、-s, --scopeがlocal・user・projectの3択で既定はlocal、-t, --transportがstdio・sse・httpの3択で既定はstdioと表示されます。--より後ろがそのままMCPサーバーの起動コマンドになります。
書き出される.mcp.jsonの中身
HCP Terraformのトークンも渡す場合は、-eでClaude Code側の環境変数に持たせ、docker runには名前だけ引き継ぎます。空のHOMEと一時ディレクトリで、プロジェクトスコープ(-s project)に登録した結果が次のとおりです(v2.1.287で確認。<token>は仮の値。実際のファイルではargsとenvが複数行に展開され、ここでは1行に整形しています)。
claude mcp add terraform -s project -t stdio -e TFE_TOKEN='<token>' \
-- docker run -i --rm -e TFE_TOKEN hashicorp/terraform-mcp-server{
"mcpServers": {
"terraform": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "TFE_TOKEN", "hashicorp/terraform-mcp-server"],
"env": { "TFE_TOKEN": "<token>" }
}
}
}トークンの値がそのまま.mcp.jsonに平文で入ります。このファイルはプロジェクトに置かれ、チームで共有する前提のものです。コミットする場合は、値を直書きせず${TFE_TOKEN}のような環境変数展開に書き換える方法があります(展開の仕様はClaude CodeのMCP設定の「environment variable expansion」節にあります)。
HTTP接続を--transport http -H "Authorization: Bearer <token>"で登録した場合は、headersにBearerトークンが入った"type": "http"のエントリが同じファイルに追加されます。コマンド側の画面表示では、Authorizationヘッダーの値は[REDACTED]に伏せられます。ファイルには伏せられずに残る点が、画面との違いです。
Claude Code自体の使い方はClaude Code完全ガイドにまとめています。
ツールの一覧と、呼ばれ方
読み取り系ツールの呼び出しはAI側が自動で行うので、手動での実行は不要です。
| ツール | グループ | 用途 |
|---|---|---|
search_providers | グループProvider | 用途サービス名でドキュメントを検索(ID・タイトル・カテゴリの一覧) |
get_provider_details | グループProvider | 用途特定コンポーネントの完全なドキュメント(Markdown) |
get_provider_capabilities | グループProvider | 用途プロバイダーが持つリソース・データソース・関数の一覧 |
get_latest_provider_version | グループProvider | 用途プロバイダーの最新バージョン |
search_modules | グループModule | 用途名前や機能で検索(説明・ダウンロード数・検証状況) |
get_module_details | グループModule | 用途入出力・サンプル・サブモジュールを含む完全なドキュメント |
get_latest_module_version | グループModule | 用途モジュールの最新バージョン |
search_policies / get_policy_details | グループPolicy | 用途Sentinelポリシー(ガバナンス要件を定義するHashiCorp独自の言語)の検索と詳細 |
get_provider_capabilitiesは、個別リソースを引く前に「このプロバイダーに何があるか」を確認する用途のツールです。
Azureストレージアカウントの実例
HashiCorpのプロンプト例ページには、VS CodeのGitHub Copilot(ChatGPT 4.1)経由の応答が載っています。「azureプロバイダーでストレージバケットを設定したい」と聞くと、サーバーは次の順に動きます。
azurermプロバイダーのstorage_accountを指定して、ドキュメントID一覧を取得する(バージョンはlatest)- 返ったドキュメントIDを2件、
providerDocIDで個別に取得する - 応答の見出しは
hashicorp/azurerm version: 4.29.0で、azurerm_storage_accountのサンプルが返る
resource "azurerm_storage_account" "example" {
name = "storageaccountname"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
account_tier = "Standard"
account_replication_type = "GRS"
tags = {
environment = "staging"
}
}同ページには「応答はモデルやクライアントによって変わる」との注記があります。コードの出どころがRegistryのドキュメントである点が、内部知識だけで生成した場合との違いです。
ツールが呼ばれないとき
同ページは、MCPサーバーを使うかどうかをモデルが決めると説明しています。一般的なTerraformの質問には、インターネット上の情報など別の情報源で答えることがあります。呼ばれやすくする指針は3つです。
google_compute_diskのように、具体的なプロバイダー名・リソース名を書く(「compute disk」では弱い)- Terraform CLIドキュメントのリソースアドレス形式を使う
- プロバイダーやモジュールの最新情報を求めると明示する
クライアント側に呼び出し用の記法がある場合は、それも使えます。同ページはVS Codeのチャットで#terraformと書く例を挙げています。プロンプト例ページのリクエスト例では、providerVersionがlatestで送られています。
HCP Terraformのワークスペース系ツールが動かないときは、terraformツールセットが有効か、TFE_TOKENが渡っているかを先に見ます。この2つはRegistry検索とは別の経路です。
ツールセットで使えるツールを絞る
既定で有効なのはregistryだけです。READMEが挙げるツールセットはregistry・registry-private・terraform・all・defaultの5つで、--toolsets(グループ単位)と--tools(ツール名単位)は同時に指定できません。
# グループ単位
terraform-mcp-server --toolsets=registry,terraform
# ツール名単位
terraform-mcp-server --tools=search_providers,get_provider_details,list_workspacesregistry-privateは組織のプライベートレジストリ、terraformはHCP Terraform / Terraform Enterpriseの操作を担当します。ツールの数が減るほど、モデルが選ぶ候補も減ります。Registry検索だけで足りる用途なら、既定のままで構成は最小です。
Docker経由で渡す場合のフラグ位置は、READMEのローカルビルド例がdocker run -i --rm terraform-mcp-server:dev --toolsets=registry,terraformの形です。イメージ名の後ろに置きます。
チームで共有する — streamableHTTPと権限の持たせ方
複数人で1つのサーバーを使うときは、streamableHTTPトランスポートを使います。
docker run -p 8080:8080 --rm \
-e TRANSPORT_MODE=streamable-http -e TRANSPORT_HOST=0.0.0.0 \
hashicorp/terraform-mcp-server
claude mcp add --transport http terraform http://localhost:8080/mcpTRANSPORT_HOSTの既定は127.0.0.1です。コンテナの外から届かせるために0.0.0.0にしているので、この例の-p 8080:8080はホストの全ネットワークインターフェースに公開されます。手元だけで試すなら、-p 127.0.0.1:8080:8080のように公開先を絞る選択肢があります。
中央に置く場合の設定は、READMEの環境変数表から次の項目が要点になります。
| 設定 | 既定値 | 役割 |
|---|---|---|
TFE_ADDRESS | 既定値未設定(reference側はhttps://app.terraform.io) | 役割接続先。HTTPモードではサーバー側の環境変数でしか決められない |
MCP_TLS_CERT_FILE / MCP_TLS_KEY_FILE | 既定値空 | 役割localhost以外で公開するときに必要 |
MCP_ALLOWED_ORIGINS / MCP_CORS_MODE | 既定値空 / strict | 役割許可するオリジン。既定ではクロスオリジンを拒否 |
MCP_ORGANIZATION_ALLOWLIST | 既定値空 | 役割許可するHCP Terraform組織名(CSV) |
MCP_RATE_LIMIT_GLOBAL / MCP_RATE_LIMIT_SESSION | 既定値10:20 / 5:10 | 役割rps:burst形式のレート制限 |
MCP_SESSION_MODE | 既定値stateful | 役割statelessにすると、リクエストごとに独立して処理 |
権限の持たせ方が、共有サーバーの設計の要です。サーバー側にトークンを置かず、利用者が自分のトークンをAuthorization: Bearer <token>かTFE_TOKENヘッダーで渡す構成が、READMEの「Centralized Deployment Example」です。HCP Terraform側の権限(RBAC)が利用者ごとに効きます。
MCP_ORGANIZATION_ALLOWLISTを設定すると、Bearerトークンが必須になります。許可リストのどの組織にも入れないトークンのリクエストは拒否されます。TFE_ADDRESSをヘッダーやクエリで渡そうとすると403、トークンをクエリパラメーターで渡すと400で拒否されます。ヘルスチェック用のエンドポイントは/healthです。
公式ページ同士で食い違っている点
導入前に目にしやすい記述のうち、ページ間で違うものがあります。
- バージョン: HashiCorp Developerの各ページは
v1.0.x (latest)と表示し、READMEのDocker例はhashicorp/terraform-mcp-server:1.3.0を指定しています - キープアライブ: referenceの環境変数表は
MCP_HEARTBEAT_INTERVAL、READMEはMCP_KEEP_ALIVEで、どちらも既定は0(無効)です - トランスポートの指定: READMEの環境変数表は
TRANSPORT_MODE=streamable-http(旧httpも有効)ですが、同じREADMEのトランスポート節はTRANSPORT_MODE=httpと書いています TFE_ADDRESSの既定値: referenceはhttps://app.terraform.io、READMEは「Optional」です
運用面では、デプロイ編のページが、サーバーや依存先の過負荷を防ぐため、全体とセッションごとのレート制限を設けることを推奨しています。計測にはOpenTelemetryのメトリクスがあり、OTEL_METRICS_ENABLEDは既定でfalseです。有効にすると、mcp_tool_calls_total・mcp_tool_errors_total・mcp_tool_duration_secondsが出ます。
READMEにはreferenceに無い設定(TF_MCP_SHARED_SECRET・MCP_ORGANIZATION_ALLOWLIST・クライアントIPの転送設定など)もあります。バージョンを固定したい場合は、イメージにタグを付けて指定します。
静的リソースとして公式スタイルガイドを参照できる
ツールとは別に、サーバーは参照用のリソースを公開しています。/terraform/style-guideは公式のスタイルガイド、/terraform/module-developmentはモジュールの構成・プロバイダー・公開・リファクタリングのガイドです。
もう1つは/terraform/providers/{namespace}/name/{name}/version/{version}形式のリソーステンプレートです。namespace(発行元)・name・versionを指定すると、そのバージョンのプロバイダーのドキュメントを引けます。get_provider_detailsは個別コンポーネントの本文を都度取得するツールで、こちらはプロバイダー単位の参照です。
セキュリティ上の注意点
セキュリティモデルのページは、ハルシネーション・プロンプトインジェクション・ツールポイズニング・Rug pull attack・Tool shadowingの5つを脅威に挙げています。Rug pull attackは、リモートに置いたMCPサーバーのツールや説明が、デプロイ後に差し替わる攻撃です。Tool shadowingは、複数のMCPサーバーをつないだとき、侵害された1つが信頼できるサーバーのツールを上書きする攻撃です。サーバーは静的なツール説明と入力検証で備えますが、変更を適用する前の出力の検証はユーザー側の作業です。基盤モデルの脆弱性と、生成コードをデプロイした後のインフラ構成は、対象外とされています。
READMEのInstructions節によると、サーバーの既定の指示はcmd/terraform-mcp-server/instructions.mdにあります。組織のTerraform運用に合わない場合や応答が不正確な場合は、自前の指示に置き換えてコンテナかバイナリを再ビルドするよう書かれています。
READMEには、クエリ次第でTerraformのデータがクライアントとLLMに渡るため、信頼できないMCPクライアントやLLMとは組み合わせないよう注記があります。
デプロイ編のページは、ローカルの127.0.0.1でstdioかstreamableHTTPを動かす構成を推奨しています。リモートに置くなら、APIゲートウェイでの認証・TLS・IP制限をクライアントとサーバーの間に足す例を挙げ、TFE_TOKENの権限を絞ることも勧めています。TFE_SKIP_TLS_VERIFYは既定でfalseです。
社内プロキシがTLS検査(Zscalerなど)をしている環境では、x509: certificate signed by unknown authorityが出ることがあります。READMEの対処は、社内CA証明書をコンテナにマウントしてSSL_CERT_FILEで指す方法です。
docker run -i --rm \
-v /path/to/corporate-ca.pem:/etc/ssl/certs/corporate-ca.pem \
-e SSL_CERT_FILE=/etc/ssl/certs/corporate-ca.pem \
hashicorp/terraform-mcp-server:1.3.0Dockerが使えない環境では、go install github.com/hashicorp/terraform-mcp-server/cmd/terraform-mcp-server@latestでバイナリを入れてterraform-mcp-server stdioを起動する代替が、同じ節にあります。システムの証明書ストアが使われます。
まとめ
.mcp.jsonをチームでコミットするかどうかで、トークンの置き方が決まります。コミットするなら、環境変数展開か利用者ごとのヘッダーに寄せ、平文の値を残さない形にします。
MCPの仕組みはMCPとは、権限設計の一般論はMCPセキュリティガイドにあります。