Terraform MCP Server

Terraform Registry lookups and workspace, run and variable tools for HCP Terraform and Terraform Enterprise

Official · HashiCorp Go Remote (hosted) · Streamable HTTPLocal · stdio DevOps and monitoringCloud platformsDeveloper tools

86 popularity score ★ 1.6k ⇣ 1.7M pulls

Connect your client

Remote (hosted)

Add in one click

Opens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.

Or add it by command or config

VS Code.vscode/mcp.json, or the user configuration from MCP: Open User Configuration
{
  "servers": {
    "terraform": {
      "type": "http",
      "url": "https://mcp.terraform.io/mcp",
      "headers": {
        "Authorization": "Bearer ${input:hcp-terraform-token}"
      }
    }
  },
  "inputs": [
    {
      "type": "promptString",
      "id": "hcp-terraform-token",
      "description": "HCP Terraform API token",
      "password": true
    }
  ]
}
Cursor.cursor/mcp.json in a project, or ~/.cursor/mcp.json for all projects
{
  "mcpServers": {
    "terraform": {
      "url": "https://mcp.terraform.io/mcp",
      "headers": {
        "Authorization": "Bearer <YOUR_HCP_TERRAFORM_TOKEN>"
      }
    }
  }
}
Claude Codeshell
claude mcp add terraform -s user -t http \
  --header "Authorization: Bearer <TFE_TOKEN>" \
  https://mcp.terraform.io/mcp
Codex~/.codex/config.toml
[mcp_servers.terraform]
url = "https://mcp.terraform.io/mcp"
http_headers = { "Authorization" = "Bearer <TFE_TOKEN>" }
kiro cli~/.kiro/settings/mcp.json, or .kiro/settings/mcp.json in a workspace
{
  "mcpServers": {
    "terraform": {
      "url": "https://mcp.terraform.io/mcp",
      "headers": {
        "Authorization": "Bearer <YOUR_HCP_TERRAFORM_TOKEN>"
      }
    }
  }
}
opencodeopencode.json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "terraform": {
      "type": "remote",
      "url": "https://mcp.terraform.io/mcp",
      "enabled": true,
      "headers": {
        "Authorization": "Bearer <YOUR_HCP_TERRAFORM_TOKEN>"
      }
    }
  }
}
ibm bob.bob/mcp.json
{
  "mcpServers": {
    "terraform": {
      "url": "https://mcp.terraform.io/mcp",
      "headers": {
        "Authorization": "Bearer <YOUR_HCP_TERRAFORM_TOKEN>"
      }
    }
  }
}
Local (Docker)

Add in one click

Opens the app, which asks before it adds the server.

Or add it by command or config

Claude CodeTerminal
claude mcp add terraform -- docker run -i --rm hashicorp/terraform-mcp-server:1.4.1
Claude Desktopclaude_desktop_config.json
{
  "mcpServers": {
    "terraform": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "hashicorp/terraform-mcp-server:1.4.1"
      ]
    }
  }
}
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "terraform": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "hashicorp/terraform-mcp-server:1.4.1"
      ]
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "terraform": {
      "type": "stdio",
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "hashicorp/terraform-mcp-server:1.4.1"
      ]
    }
  }
}
Codex~/.codex/config.toml
[mcp_servers.terraform]
command = "docker"
args = ["run", "-i", "--rm", "hashicorp/terraform-mcp-server:1.4.1"]
Gemini CLITerminal
gemini mcp add --scope user terraform docker -- run -i --rm hashicorp/terraform-mcp-server:1.4.1
Local (from source)

Add in one click

Opens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.

Or add it by command or config

FirstTerminal
go install github.com/hashicorp/terraform-mcp-server/cmd/terraform-mcp-server@v1.4.1
Claude CodeTerminal
claude mcp add terraform -- '<ABSOLUTE_PATH_TO_GOPATH>/bin/terraform-mcp-server' stdio
Claude Desktopclaude_desktop_config.json
{
  "mcpServers": {
    "terraform": {
      "command": "<ABSOLUTE_PATH_TO_GOPATH>/bin/terraform-mcp-server",
      "args": [
        "stdio"
      ]
    }
  }
}
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "terraform": {
      "command": "<ABSOLUTE_PATH_TO_GOPATH>/bin/terraform-mcp-server",
      "args": [
        "stdio"
      ]
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "terraform": {
      "type": "stdio",
      "command": "<ABSOLUTE_PATH_TO_GOPATH>/bin/terraform-mcp-server",
      "args": [
        "stdio"
      ]
    }
  }
}
Codex~/.codex/config.toml
[mcp_servers.terraform]
command = "<ABSOLUTE_PATH_TO_GOPATH>/bin/terraform-mcp-server"
args = ["stdio"]
Gemini CLITerminal
gemini mcp add --scope user terraform '<ABSOLUTE_PATH_TO_GOPATH>/bin/terraform-mcp-server' -- stdio

Settings 12

Set together: hcp-terraform
TFE_TOKEN secret Optional: HCP Terraform or Terraform Enterprise API token; without it only the public registry tools are available. For registry-private and terraform toolsets.
TFE_ADDRESS Optional: Address of the HCP Terraform or Terraform Enterprise instance, with protocol. Default https://app.terraform.io.
TFE_SKIP_TLS_VERIFY Optional: Skip TLS verification against HCP Terraform or Terraform Enterprise. Default false.
ENABLE_TF_OPERATIONS Optional: Set to true to register the delete, force-unlock and run-action tools and allow auto-approve or destroy runs. Default false. For delete, force-unlock and run-action tools.
LOG_LEVEL Optional: Logging level, from trace to panic. Default info.
OTEL_METRICS_ENABLED Optional: Set to true to emit OpenTelemetry tool and HTTP metrics to your own collector in HTTP mode. Default false.
Set together: http
TRANSPORT_MODE Optional: Set to streamable-http to serve over HTTP instead of stdio. Default stdio.
TRANSPORT_PORT Optional: HTTP port; setting it also switches the server to HTTP mode. Default 8080.
TRANSPORT_HOST Optional: Address the HTTP server binds to; a non-localhost address needs MCP_TLS_CERT_FILE and MCP_TLS_KEY_FILE. Default 127.0.0.1.
MCP_ORGANIZATION_ALLOWLIST Optional: Comma-separated HCP Terraform organizations whose tokens may use an HTTP deployment.
MCP_REQUIRE_TOKEN Optional: Set to true to reject HTTP requests without a valid Authorization bearer token.
MCP_ALLOWED_ORIGINS Optional: Comma-separated origins allowed by CORS in HTTP mode.

In a container, a setting goes in with -e NAME=value after docker run.

What it does

HashiCorp's own MCP server for Terraform does two separate jobs. The first is looking things up in the public Terraform Registry: searching provider documentation, modules and Sentinel/OPA policies, fetching the docs for a given resource or data source, and finding the newest version of a provider or module. Run locally, this part needs no account.

The second job is working on an HCP Terraform or Terraform Enterprise organization. With an API token it can list organizations and projects, create and update workspaces, set workspace variables and variable sets, tag workspaces, attach policy sets, manage teams, start runs, and read plan and apply logs, structured plan JSON, state versions and Stacks. It can also search an organization's private registry. The tools that delete projects, teams or workspaces, force-unlock a workspace or act on runs are not registered at all unless ENABLE_TF_OPERATIONS is true (pkg/tools/dynamic_tool.go), and create_run only offers auto-approve and destroy runs then.

Version 1.4.1 registers 61 tools (pkg/toolsets/registry.go). Tools are grouped into the toolsets registry, registry-private and terraform. The README says only registry is on by default, but in the 1.4.1 code the --toolsets flag defaults to all (pkg/cli/commands.go). The token-based tools are simply not registered until a session has a working HCP Terraform client. --tools narrows it to single tools. It also serves read-only resources such as the Terraform style guide. It runs over stdio for one user or as a Streamable HTTP service that several users share, each sending their own token.

HashiCorp also runs it for you at mcp.terraform.io, currently in beta. That copy talks to HCP Terraform only, so Terraform Enterprise users still need to run their own. It asks for a token even for plain registry lookups. You can't change its settings, and the five destructive tools are left out, which also means create_run can't do auto-approve or destroy runs there.

What it needs

To run it yourselfDocker
Runs onmacOS, Windows, Linux
HCP Terraform or Terraform EnterpriseFree tierOnly for the private registry and terraform toolsets; registry lookups need no account

Docker for the published image, or a Go toolchain to build it with go install. Registry lookups need nothing else. The HCP Terraform and private registry tools need an API token in TFE_TOKEN, plus TFE_ADDRESS when the instance is not app.terraform.io.

Limits

  • Not covered Talks to the Terraform Registry and, with a valid TFE_TOKEN, the HCP Terraform/TFE APIs. It does not run the terraform CLI against local files or state
  • Read only Deletes, force-unlock, run actions and auto-approve or destroy runs are unavailable unless ENABLE_TF_OPERATIONS=true, and never on the hosted endpoint
  • Early release The hosted endpoint at mcp.terraform.io is in beta, and HashiCorp advises against relying on it in production
  • Not covered The hosted endpoint reaches HCP Terraform only, needs a token even for registry tools, and its toolsets and settings cannot be changed
  • Limit Its README says only the registry toolset is on by default, but the 1.4.1 code enables all toolsets when --toolsets is not given
  • Limit The Search toolset (execute_query, prepare_import and related tools) and its TF_MCP_QUERY_WORKSPACE, TF_CLOUD_ORGANIZATION settings are only on main, not released
  • Limit Setting TRANSPORT_PORT, TRANSPORT_HOST or MCP_ENDPOINT alone switches it to HTTP mode instead of stdio (pkg/cli/flags.go)
  • Rate limit HTTP mode rate-limits to 10 requests/s (burst 20) globally and 5/s (burst 10) per session by default. The hosted endpoint returns a tool error, not HTTP 429, when over
  • Limit In HTTP mode it refuses to bind to a non-localhost address without MCP_TLS_CERT_FILE and MCP_TLS_KEY_FILE
  • Limit Its makers warn that its output must be reviewed before acting on it

The README says only the registry toolset is on by default, yet in the released code every toolset is enabled when --toolsets is not passed. The private registry and HCP Terraform tools still appear only once a valid token is set. Deleting projects, teams and workspaces, force-unlocking workspaces, acting on runs, and auto-approve or destroy runs are refused unless ENABLE_TF_OPERATIONS=true. In HTTP mode TFE_ADDRESS can only be set on the server, and tokens in query strings are rejected.

Who it suits

Suits anyone writing Terraform who wants provider and module details looked up from the registry, and teams on HCP Terraform or Terraform Enterprise who want an assistant to inspect workspaces and runs or set up workspaces and variables. HCP Terraform users who would rather not run Docker can point a client at the hosted beta endpoint with a token. Terraform Enterprise users, and anyone who needs the delete or run-action tools, have to run it themselves. Platform teams can self-host one shared HTTP instance with per-user tokens and an organization allowlist. To keep an assistant from changing your organization, pass --toolsets=registry or leave ENABLE_TF_OPERATIONS false.

Tools 60 of 61

38 only read, 17 change things, 5 can delete or overwrite.

search_provider_docs
Find a provider's documentation pages in the public registry by service or resource
get_provider_details
Fetch full markdown docs for one provider resource, data source or guide
get_latest_provider_version
Return the newest published version of a provider
get_provider_capabilities
List the resource types, data sources and functions a provider offers
search_modules
Search public registry modules by keyword
get_module_details
Show a module's inputs, outputs, examples and submodules
get_latest_module_version
Return the newest published version of a module
search_policies
Search Sentinel and OPA policy libraries in the registry
get_policy_details
Fetch the content and details of one policy library
search_private_modules
Search modules in an organization's private registry
get_private_module_details
Show details of one private registry module
search_private_providers
Search providers in an organization's private registry
get_private_provider_details
Show details of one private registry provider
whoami
Show the account the configured token belongs to
get_token_permissions
List the actions the configured token is allowed to take
list_terraform_orgs
List the organizations the token can see
list_terraform_projects
List projects in an organization
create_project changes
Create a project in an organization
get_project
Show one project's details
delete_project deletes
Delete an empty project (needs ENABLE_TF_OPERATIONS)
list_teams
List teams in an organization
get_team
Show one team's details
create_team changes
Create a team
add_team_member changes
Add a user to a team
grant_team_access changes
Give a team access to a workspace or project
delete_team deletes
Delete a team (needs ENABLE_TF_OPERATIONS)
list_workspaces
List or search workspaces in an organization
get_workspace_details
Show a workspace's settings, variables and state
create_workspace changes
Create a workspace
create_no_code_workspace changes
Create a workspace from a no-code module
update_workspace changes
Change a workspace's settings
delete_workspace_safely deletes
Delete a workspace only if it manages no resources (needs ENABLE_TF_OPERATIONS)
force_unlock_workspace changes
Force-release a workspace lock (needs ENABLE_TF_OPERATIONS)
list_runs
List runs in a workspace or organization
get_run_details
Show one run's status and details
get_run_comments
Read the comments left on a run
create_run changes
Queue a plan, plan-and-apply or refresh run; auto-approve and destroy need ENABLE_TF_OPERATIONS
action_run deletes
Apply, discard or cancel a run (needs ENABLE_TF_OPERATIONS)
get_plan_details
Show a plan's status and change summary
get_plan_logs
Read a plan's log output
get_plan_json_output
Fetch the structured JSON output of a plan
get_apply_details
Show an apply's status and results
get_apply_logs
Read an apply's log output
list_workspace_variables
List a workspace's variables
create_workspace_variable changes
Add a variable to a workspace
update_workspace_variable changes
Change a workspace variable
list_variable_sets
List variable sets in an organization
create_variable_set changes
Create a variable set
create_variable_in_variable_set changes
Add a variable to a variable set
delete_variable_in_variable_set deletes
Remove a variable from a variable set
attach_variable_set_to_workspaces changes
Apply a variable set to workspaces
detach_variable_set_from_workspaces changes
Remove a variable set from workspaces
create_workspace_tags changes
Add tags to a workspace
read_workspace_tags
Read a workspace's tags
attach_policy_set_to_workspaces changes
Apply a policy set to workspaces
list_workspace_policy_sets
List policy sets on a workspace
list_stacks
List Terraform Stacks in a project
get_stack_details
Show one Stack's details
list_state_versions
List a workspace's state versions
get_state_version
Show one state version of a workspace

Resources 3

/terraform/style-guide
The Terraform style guide as markdown
/terraform/module-development
Guide to module structure, composition, publishing and refactoring
/terraform/providers/{namespace}/name/{name}/version/{version}
Overview documentation for one provider version

Similar servers