Skip to main content
Glama
iqnupe

terraform-tools-mcp-server

by iqnupe
README.md
# terraform-tools-mcp-server

An HTTP MCP server that exposes Terraform/Terragrunt tooling as Claude Code tools, eliminating the need for Python scripts in the repository.

## Tools

### `terraform_generate_variables`
Generates a valid `variables.tf` HCL file for a Terraform module by inferring types from `*.auto.tfvars.json` input files.

Claude Code workflow:
1. Find all `<unit>.auto.tfvars.json` files across terragrunt environment directories
2. Read their contents and call `terraform_generate_variables`
3. Write the returned `variables_tf` string to `src/<project>/modules/<unit>/variables.tf`

### `terragrunt_generate_mock_outputs`
Generates a Terragrunt `mock_outputs` JSON document from a unit's `outputs.tf`.

Claude Code workflow:
1. Read `src/<project>/modules/<unit>/outputs.tf`
2. Call `terragrunt_generate_mock_outputs`
3. Write the returned `mock_outputs_json` to `src/<project>/terragrunt/common/mock_outputs/<unit>.json`
4. Update HCL dependency blocks to reference the file via `jsondecode(file("mock_outputs/<unit>.json"))`

---

## Deployment: Synology DS1019+ via Container Manager

This is the primary deployment target. The server runs as a persistent container and is reachable from any machine on the network at `http://<diskstation-ip>:8182/mcp`.

### Prerequisites

- Docker image built and pushed to a registry accessible from the NAS, **or** the source copied directly onto the NAS and built there (see below).
- Container Manager installed on the DS1019+ (DSM 7.2+).

### Option A — Build on the NAS

1. Copy the project to the NAS (e.g. via File Station or `scp`):
   ```bash
   scp -r terraform-tools-mcp-server/ admin@<diskstation-ip>:/volume1/docker/terraform-tools-mcp-server/
   ```

2. SSH into the NAS and build:
   ```bash
   ssh admin@<diskstation-ip>
   cd /volume1/docker/terraform-tools-mcp-server
   docker compose build
   ```

3. Start the container:
   ```bash
   docker compose up -d
   ```

### Option B — Build locally, push to registry, pull on NAS

1. Build and tag:
   ```bash
   docker build -t terraform-tools-mcp-server:latest .
   docker tag terraform-tools-mcp-server:latest <your-registry>/terraform-tools-mcp-server:latest
   docker push <your-registry>/terraform-tools-mcp-server:latest
   ```

2. On the NAS, update `docker-compose.yml` to reference the registry image (replace `build: .` with `image: <your-registry>/terraform-tools-mcp-server:latest`), then:
   ```bash
   docker compose pull
   docker compose up -d
   ```

### Option C — Container Manager GUI (DSM)

1. Open **Container Manager → Project → Create**.
2. Set the project path to the folder containing `docker-compose.yml`.
3. Container Manager will build and start the container automatically.
4. Port `8182` will be exposed on the NAS's LAN IP.

### Verify the container is running

```bash
curl http://<diskstation-ip>:8182/health
# Expected: {"status":"ok","server":"terraform-tools-mcp-server","version":"1.0.0"}
```

---

## Claude Code MCP configuration (VS Code)

Add the remote MCP server to your Claude Code settings so it's available in every project.

### Location of settings file

| OS      | Path |
|---------|------|
| macOS   | `~/.claude/settings.json` |
| Windows | `%APPDATA%\Claude\settings.json` |
| Linux   | `~/.claude/settings.json` |

You can also open it from VS Code via the command palette: **Claude: Open Settings**.

### settings.json entry

```json
{
  "mcpServers": {
    "terraform-tools": {
      "type": "http",
      "url": "http://<diskstation-ip>:8182/mcp"
    }
  }
}
```

Replace `<diskstation-ip>` with your NAS's LAN IP address (e.g. `192.168.1.50`) or hostname (e.g. `diskstation.local`).

### Per-project override (optional)

To scope the server to a specific project only, add the same block to `.claude/settings.json` in the project root instead of the global file.

### Verify Claude Code sees the tools

In VS Code with Claude Code, run:
```
/mcp
```
You should see `terraform-tools` listed with tools `terraform_generate_variables` and `terragrunt_generate_mock_outputs`.

---

## Local development (stdio — no Docker)

```bash
npm install
npm run build
TRANSPORT=stdio node dist/index.js
```

> **Tip — reproducible Docker builds:** Once you've run `npm install` locally, a `package-lock.json` will be generated. Commit that file alongside the project and the Dockerfile can be changed back to `npm ci` / `npm ci --omit=dev` for fully reproducible, faster image builds.

Local Claude Code config for stdio:
```json
{
  "mcpServers": {
    "terraform-tools": {
      "command": "node",
      "args": ["/absolute/path/to/terraform-tools-mcp-server/dist/index.js"],
      "env": { "TRANSPORT": "stdio" }
    }
  }
}
```

---

## Environment variables

| Variable    | Default  | Description                               |
|-------------|----------|-------------------------------------------|
| `TRANSPORT` | `http`   | `stdio` for local dev, `http` for Docker  |
| `PORT`      | `8182`   | HTTP port (only used when TRANSPORT=http) |

## Health check

```
GET http://<host>:8182/health
→ {"status":"ok","server":"terraform-tools-mcp-server","version":"1.0.0"}
```