Skip to main content
This guide shows how to run Terraform operations through an MCP (Message Control Plane) server using the Terraform MCP bridge (tfmcp). You will learn to initialize a Terraform workspace, plan and apply a simple configuration that creates a local file — all triggered by MCP-style JSON-RPC calls (stdio). This workflow is useful when you want programmatic, message-driven control of Terraform from agents, automation pipelines, or AI assistants that already speak MCP/JSON-RPC.

Prerequisites (Ubuntu)

Install the required system packages, Rust toolchain, and the Terraform MCP bridge. The following table summarizes the key prerequisites and where to find them.
RequirementPurposeInstall / Reference
build toolsCompile native dependenciesSee the command below
Rust (rustup)Build the tfmcp crateSee the command below
Terraform MCP bridgeRuns the MCP server and handles Terraform callscargo install tf-mcp or cargo install terraform-mcp
Install the build tools:
sudo apt-get update
sudo apt-get install -y build-essential
Install Rust via rustup:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# follow the prompts and add Rust to your PATH (typically by sourcing ~/.cargo/env)
source "$HOME/.cargo/env"
Install the Terraform MCP bridge (the binary is commonly named tfmcp):
# Either of these may be available depending on the crate name/version
cargo install tf-mcp
# or
cargo install terraform-mcp
Cargo will download and compile crates during installation; when complete the tfmcp binary should be on your PATH.

Start the MCP bridge / server

Start the MCP server so it can accept MCP-style requests over stdio in this demo:
tfmcp mcp
The server will run in the foreground and listen for JSON-RPC messages on stdin/stdout.

Create a sample Terraform project

Create a working directory and a minimal Terraform configuration that writes a local file. Create the directory and enter it:
mkdir terraform-demo
cd terraform-demo
Create main.tf with the following content:
terraform {
  required_providers {
    local = {
      source  = "hashicorp/local"
      version = "~> 2.0"
    }
  }
}

provider "local" {}

resource "local_file" "example" {
  filename = "${path.module}/example.txt"
  content  = "Hello from tfmcp!"
}
Initialize and validate the workspace, then create a plan:
terraform init
terraform validate
terraform plan
Sample (cleaned) plan output:
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # local_file.example will be created
  + resource "local_file" "example" {
      + content               = "Hello from tfmcp!"
      + filename              = "./example.txt"
      + directory_permission  = "0777"
      + file_permission       = "0777"
      + id                    = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Interact with the Terraform MCP server via JSON-RPC (stdio)

While tfmcp mcp is running in one terminal, send JSON-RPC messages from another terminal using a heredoc. The example sequence below performs:
  1. An initialize request to the MCP server.
  2. A tools/call request for get_terraform_plan.
  3. A tools/call request for apply_terraform with auto_approve=true.
Send these requests via stdio:
tfmcp mcp <<EOF
{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {}}
{"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "get_terraform_plan", "arguments": {}}}
{"jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": {"name": "apply_terraform", "arguments": {"auto_approve": true}}}
EOF
For quick reference, common MCP tool calls used in this demo:
MethodPurposeExample
initializePrepare the MCP tool session{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}
tools/call with get_terraform_planRequest a Terraform plan{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"get_terraform_plan","arguments":{}}}
tools/call with apply_terraformApply the Terraform plan{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"apply_terraform","arguments":{"auto_approve":true}}}
Wrap any JSON examples containing curly braces in code blocks to avoid parsing issues (as done above).

Security policy and auto-approve

By default the MCP bridge may block automated apply operations for safety. If auto-approve is blocked, you will see an error such as:
{
  "jsonrpc":"2.0",
  "id":3,
  "error":{
    "code":-32603,
    "message":"Failed to apply Terraform configuration: Auto-approve for apply operation blocked by security policy. Set TFMCP_ALLOW_AUTO_APPROVE=true to enable."
  }
}
Setting TFMCP_ALLOW_AUTO_APPROVE=true allows automated apply operations. Only enable this when you trust the Terraform configuration and understand the security implications.
If you decide to allow auto-approve, export the environment variable and re-run the JSON-RPC sequence:
export TFMCP_ALLOW_AUTO_APPROVE=true

# Re-send the JSON-RPC sequence (initialize, plan, apply)
tfmcp mcp <<EOF
{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {}}
{"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "get_terraform_plan", "arguments": {}}}
{"jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": {"name": "apply_terraform", "arguments": {"auto_approve": true}}}
EOF

Successful apply and verification

When the apply completes, the MCP server will return the standard Terraform apply summary, for example:
local_file.example: Creation complete after 0s [id=<resource-id>]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Verify the created file:
cat example.txt
# Output:
# Hello from tfmcp!

Why use Terraform with MCP?

  • Consistent control channel: If your orchestration or automation stack already uses MCP/JSON-RPC, adding Terraform as an MCP tool keeps infrastructure control within the same messaging paradigm.
  • Programmatic integration: Enables other agents, CI/CD pipelines, or AI assistants to request Terraform operations programmatically without shelling out or managing separate APIs.
  • Auditability & policy: An MCP gateway can centralize security checks, logging, and policy enforcement around Terraform operations.

Troubleshooting tips

  • Ensure tfmcp is on your PATH after cargo install (check ~/.cargo/bin).
  • If terraform init fails, review provider version constraints and network access to provider registries.
  • If JSON-RPC messages are not being processed, confirm tfmcp mcp is running in the terminal where you expect it and that your heredoc is directed at the same tfmcp instance.

Summary

  • Installed the Terraform MCP bridge (tfmcp) and required toolchain.
  • Created a simple Terraform configuration that writes a local file.
  • Executed Terraform init/plan/apply through MCP JSON-RPC calls (stdio).
  • Addressed auto-approve security via the TFMCP_ALLOW_AUTO_APPROVE environment variable.
  • Verified the resulting resource and discussed reasons to use Terraform via MCP in automated systems.
If you need an example for integrating this into a CI pipeline or automating the JSON-RPC calls programmatically (Python, Node, etc.), I can provide sample clients that interact with tfmcp via stdio.

Watch Video