io.github.RajeevSirohi/mcp-server-terraform
Safety-first Terraform: confirmation-gated apply/destroy, risk & cost analysis, drift detection
Open source Open in the app JSON README (API)
About
Safety-first Terraform: confirmation-gated apply/destroy, risk & cost analysis, drift detection
Details
- Kind
- MCP servers
- Topic
- Cloud & DevOps
- Publisher
- rajeevsirohi
- Origin
- official
- Category
- ferramentas
- Transport
- local
- Version
- 0.2.1
- Stars
- 1
- Last push
- 2026-07-07T08:05:40Z
- Repository state
- ativo
- Language
- TypeScript
- License
- MIT
- Added
- 2026-08-29 03:02:11
- Updated
- 2026-08-29 03:02:11
- Origin id
io.github.RajeevSirohi/mcp-server-terraform
README
# mcp-server-terraform
[](https://github.com/RajeevSirohi/mcp-server-terraform/actions/workflows/ci.yml)
[](https://www.npmjs.com/package/@rajsir/mcp-server-terraform)
[](LICENSE)
A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server that lets Claude manage Terraform infrastructure through natural language.
> Run plans, apply changes, inspect state, and diagnose failures — all from a Claude conversation.
## What it does
Instead of switching to a terminal to run `terraform plan`, you can ask Claude:
> "Plan the changes in `/infra/staging` and explain what will change"
> "Apply it — but only if no resources will be destroyed"
> "Show me all the outputs from the prod workspace"
> "Something broke after the last apply — diagnose it"
The server translates these into real `terraform` CLI commands on your machine, with a built-in safety confirmation flow before any destructive operation runs.
## Tools
| Tool | Description | Destructive |
|------|-------------|-------------|
| `tf_init` | Initialize a Terraform working directory | No |
| `tf_validate` | Validate configuration syntax | No |
| `tf_plan` | Run a plan and return the diff + risk/cost summary | No |
| `tf_apply` | Apply changes (requires `confirmed: true`) | Yes |
| `tf_destroy` | Destroy infrastructure (requires `confirmed: true`) | Yes |
| `tf_output` | Read output values from state | No |
| `tf_state` | List, show, move, or remove state entries | Partial |
| `tf_workspace` | List, show, select, or create workspaces | No |
| `tf_preflight` | Check provider CLI authentication before running | No |
| `tf_drift` | Detect resources changed outside Terraform | No |
| `tf_resource` | Import, taint, untaint, or refresh resources | Yes |
### Plan risk & cost summary
Every plan (and every apply preview) is analyzed via `terraform show -json` and
annotated with a structured summary — destroyed resources are called out, and
always-on resources that commonly cause bill shock are flagged with rough
monthly costs:
```
── Plan Summary ──
+ 3 create, ~ 1 update, - 0 destroy, ± 0 replace
💸 EXPENSIVE — always-on resources being created:
⚠ aws_nat_gateway.main (~$32/month + data processing if left running)
Remember to tf_destroy when you're done experimenting.
```
Cost-flagged resource types include NAT gateways, load balancers, EKS/AKS/GKE
control planes, RDS/Cloud SQL instances, ElastiCache, Redshift, MSK, and
Azure Firewall (~$900/month!).
### Drift detection
`tf_drift` runs a refresh-only plan and reports resources that were changed
outside Terraform (e.g. manually in the cloud console), with the changed
attribute names and remediation options.
### Audit logging
Set `AUDIT_LOG_PATH` to a file path and every tool call is appended as a JSON
line with timestamp, tool name, outcome, and duration. Variable **values** are
always redacted (`db_password=<redacted>`) — only names are logged.
### Confirmation flow
`tf_apply` and `tf_destroy` use a two-step safety flow:
1. **First call** (no `confirmed`) → runs `terraform plan`, shows the diff, does nothing else
2. **Second call** (`confirmed: true`) → actually applies or destroys
Claude is instructed to never pass `confirmed: true` without first presenting the plan to you.
### Prompt
The server exposes a `/tf-diagnose` prompt that guides Claude through a systematic 5-step diagnosis of plan or apply failures.
## Prerequisites
- [Node.js](https://nodejs.org) 18 or later
- [Terraform](https://developer.hashicorp.com/terraform/downloads) CLI on your PATH
- [Claude Desktop](https://claude.ai/download) (or any MCP-compatible client)
## Installation
No install needed — run it straight from npm:
```bash
npx @rajsir/mcp-server-terraform
```
Or, for development, from source:
```bash
git clone https://github.com/RajeevSirohi/mcp-server-terraform.git
cd mcp-server-terraform
npm install
npm run build
```
## Claude Desktop setup
Add to your Claude Desktop config file:
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
```json
{
"mcpServers": {
"terraform": {
"command": "npx",
"args": ["-y", "@rajsir/mcp-server-terraform"]
}
}
}
```
(If running from source instead, use `"command": "node"` with `"args": ["/absolute/path/to/dist/index.js"]`.)
Restart Claude Desktop. You should see a hammer icon indicating tools are available.
## Usage
Once connected, just talk to Claude about your Terraform workspaces in plain language. Some examples:
### First time in a new workspace
> "Initialize the terraform config in `C:\infra\staging` and check if I'm logged into the right cloud accounts"
Claude runs `tf_init`, then `tf_preflight` — if you're not authenticated it tells you exactly which command to run (`az login`, `aws configure`, ...).
### The everyday plan → review → apply loop
> "Plan the changes in `C:\infra\staging` and explain what will change"
You get the plan diff plus a summary: how many resources created/updated/destroyed, anything destructive called out explicitly, and cost warnings for expensive always-on resources.
> "Looks good, apply it"
Claude shows the plan preview one more time and asks for your confirmation — nothing is applied until you say yes. This two-step gate is built into the server itself, not just the prompt, so Claude *cannot* skip it.
### Checking on your infrastructure
> "Did anyone change anything outside terraform in the prod workspace?"
`tf_drift` compares state against reality and reports what was modified in the console, with options to accept or revert.
> "Show me all the outputs" · "List everything in state" · "What workspaces exist?"
### Learning / experimenting (e.g. cert prep)
> "Apply the VPC lab in `C:\labs\vpc`, and when I say 'done' destroy everything"
The cost flags are your friend here — if a lab creates a NAT gateway or EKS cluster, the plan summary warns you what it costs per month if forgotten:
```
💸 EXPENSIVE — always-on resources being created:
⚠ aws_nat_gateway.main (~$32/month + data processing if left running)
Remember to tf_destroy when you're done experimenting.
```
### Fixing things
> "terraform plan is failing in `C:\infra\staging` — diagnose it"
The `/tf-diagnose` prompt walks Claude through validate → providers → plan → state → outputs systematically. There's also `/tf-login` for step-by-step authentication setup per provider.
> "Import the S3 bucket `my-legacy-bucket` into state as `aws_s3_bucket.legacy`"
> "Taint the web server so it gets recreated on the next apply"
### Recommended setup for shared or cautious environments
Run with `ALLOW_ONLY_NON_DESTRUCTIVE_TOOLS=true` (see Safety modes below) so apply/destroy are unavailable entirely, and set `AUDIT_LOG_PATH` so every operation is logged.
## Safety modes
Control which tools are available via environment variables:
| Variable | Effect |
|----------|--------|
| `ALLOW_ONLY_READONLY_TOOLS=true` | Only `tf_validate`, `tf_plan`, `tf_output` |
| `ALLOW_ONLY_NON_DESTRUCTIVE_TOOLS=true` | Blocks `tf_apply`, `tf_destroy`, `tf_state mv/rm` |
| `ALLOWED_TOOLS=tf_plan,tf_output` | Explicit comma-separated allowlist |
Example — read-only mode:
```json
{
"mcpServers": {
"terraform": {
"command": "node",
"args": ["/path/to/dist/index.js"],
"env": {
"ALLOW_ONLY_NON_DESTRUCTIVE_TOOLS": "true"
}
}
}
}
```
## Development
```bash
npm run dev # watch mode (recompiles on save)
npm test # run tests
npm run build # production build
```
### Project structure
```
src/
index.ts # MCP server entry point, tool registration
config/ # (reserved for future config/telemetry)
models/
common-parameters.ts # Shared Zod schemas
security/
tf-flags.ts # Dangerous flag blocking
tools/
tf-init.ts
tf-validate.ts
tf-plan.ts
tf-apply.ts # Two-step confirmation flow
tf-destroy.ts # Two-step confirmation flow
tf-output.ts
tf-state.ts
tf-workspace.ts
utils/
terraform-runner.ts # Core exec wrapper, workspace switching
prompts/
index.ts # /tf-diagnose prompt
tests/
tf-flags.test.ts
tf-apply.test.ts
```
### Adding a new tool
1. Create `src/tools/tf-yourcommand.ts` — export a `*Schema` const and an async handler function
2. Import both in `src/index.ts`
3. Add the schema to `readonlyTools` or `destructiveTools` array
4. Add a `case` in the `CallToolRequestSchema` handler switch
## Roadmap
- [ ] Terraform Cloud / Enterprise API support (Phase 2)
- [ ] OpenTelemetry tracing
- [ ] SSE / streamable HTTP transport for remote deployments
- [ ] Docker image on GitHub Container Registry
- [x] Plan risk & cost analysis
- [x] Drift detection
- [x] Import / taint / untaint / refresh
- [x] Audit logging
- [x] CI (build, test matrix, e2e against real terraform)
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md).
## License
MIT — see [LICENSE](LICENSE).