Content
# <img src="public/images/Terraform-LogoMark_onDark.svg" width="30" align="left" style="margin-right: 12px;"/> Terraform MCP Server + Partner-Managed Resources
The Terraform MCP Server is a [Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction)
server that provides seamless integration with Terraform Registry APIs, enabling advanced
automation and interaction capabilities for Infrastructure as Code (IaC) development.
**This fork extends the base server with Partner-Managed Resources** - enabling AI-assisted security remediation through AWS Security Hub integration and HCP Terraform.
## What's New: Partner-Managed Resources
```
┌─────────────────────────────────────────────────────────────────────────────────┐
│ PARTNER-MANAGED RESOURCES WORKFLOW │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ AWS Security │ Discover ┌──────────────┐ │ HCP Terraform│ │
│ │ Hub │──────────────▶│ MCP Server │──────▶│ (CLI-Driven │ │
│ │ (Findings) │ │ │ │ Workspace) │ │
│ └──────────────┘ │ • Sync │ └──────┬───────┘ │
│ │ • Analyze │ │ │
│ ┌──────────────┐ │ • Link │ ▼ │
│ │ Claude │◀─────────────▶│ • Remediate │ ┌──────────────┐ │
│ │ Desktop │ Converse │ │ │ AWS │ │
│ │ or CLI │ └──────────────┘ │ Resources │ │
│ └──────────────┘ │ (Fixed!) │ │
│ └──────────────┘ │
└─────────────────────────────────────────────────────────────────────────────────┘
```
### Key Capabilities
- **Security Finding Discovery**: Pull findings from AWS Security Hub automatically
- **Automatic ARN → Terraform Mapping**: Discovers workspaces, parses state, and auto-links ARNs to Terraform addresses
- **Automated Remediation**: Generate and apply Terraform fixes through HCP Terraform
- **CLI-Driven Workflow**: Works with CLI-driven workspaces (configuration uploaded via API)
### How Automatic Resource Mapping Works
When you provide your HCP Terraform org, the system **automatically discovers and links** resources:
```
sync_recommendations(terraform_org: "my-org")
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ 1. DISCOVER WORKSPACES │
│ Lists all workspaces in your org (via HCP Terraform API) │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ 2. INDEX TERRAFORM STATE │
│ For each workspace, parses state and extracts cloud resource IDs: │
│ - ARNs from aws_security_group, aws_instance, aws_s3_bucket, etc. │
│ - Builds index: ARN → Terraform address │
│ Example: "arn:aws:ec2:...:sg-xxx" → "aws_security_group.web" │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ 3. SYNC & AUTO-LINK │
│ Fetches findings from Security Hub, matches ARNs to Terraform │
│ Result: Each finding knows its Terraform resource automatically! │
└─────────────────────────────────────────────────────────────────────────┘
```
**No manual linking required!** Just provide `terraform_org` and the system handles the mapping.
### Supported Resource Mappings
The auto-discovery system supports the following AWS-to-Terraform resource mappings:
| AWS Security Hub Type | Terraform Resource Type |
|-----------------------|------------------------|
| AwsEc2Instance | aws_instance |
| AwsEc2SecurityGroup | aws_security_group |
| AwsEc2Volume | aws_ebs_volume |
| AwsEc2Vpc | aws_vpc |
| AwsEc2Subnet | aws_subnet |
| AwsEc2NetworkInterface | aws_network_interface |
| AwsS3Bucket | aws_s3_bucket |
| AwsIamUser | aws_iam_user |
| AwsIamRole | aws_iam_role |
| AwsIamPolicy | aws_iam_policy |
| AwsIamAccessKey | aws_iam_access_key |
| AwsLambdaFunction | aws_lambda_function |
| AwsRdsDbInstance | aws_db_instance |
| AwsRdsDbCluster | aws_rds_cluster |
| AwsKmsKey | aws_kms_key |
| AwsSecretsManagerSecret | aws_secretsmanager_secret |
| AwsSqsQueue | aws_sqs_queue |
| AwsSnsTopic | aws_sns_topic |
| AwsSnsSubscription | aws_sns_topic_subscription |
| AwsCloudFrontDistribution | aws_cloudfront_distribution |
| AwsElbLoadBalancer | aws_elb |
| AwsElbv2LoadBalancer | aws_lb |
| AwsApiGatewayRestApi | aws_api_gateway_rest_api |
| AwsDynamoDbTable | aws_dynamodb_table |
| AwsElasticsearchDomain | aws_elasticsearch_domain |
| AwsEksCluster | aws_eks_cluster |
| AwsEcsCluster | aws_ecs_cluster |
| AwsEcsService | aws_ecs_service |
**How Resources Are Matched**: The system extracts cloud resource IDs from Terraform state and matches them to Security Hub findings using ARNs. For each resource type, these attributes are checked (in order):
| Terraform Resource | ID Attributes (priority order) |
|-------------------|-------------------------------|
| aws_instance | arn, id |
| aws_s3_bucket | arn, bucket, id |
| aws_security_group | arn, id |
| aws_lambda_function | arn, function_name |
| aws_db_instance | arn, id, identifier |
| aws_iam_role | arn, id, name |
| aws_iam_user | arn, id, name |
| aws_kms_key | arn, key_id, id |
| aws_lb / aws_alb | arn, id |
| aws_autoscaling_group | arn, id, name |
| *(others)* | arn, id |
### CLI-Driven vs VCS-Driven Workspaces
This extension is designed for **CLI-driven workspaces** where:
- Terraform configuration is uploaded directly via the HCP Terraform API
- Runs are triggered programmatically (not through Git commits)
- The AI assistant manages the configuration lifecycle
```
CLI-Driven Workflow (Supported):
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Download │───▶│ Generate │───▶│ Upload New │───▶│ Create & │
│ Current │ │ Fix Code │ │ Config │ │ Apply Run │
│ Config │ │ │ │ Version │ │ │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
VCS-Driven Workflow (Experimental - via GitHub PR):
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Clone │───▶│ Generate │───▶│ Create PR │───▶│ Merge & │
│ Repository │ │ Fix Code │ │ on GitHub │ │ Auto-Apply │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
```
## Features
- **Dual Transport Support**: Both Stdio and StreamableHTTP transports with configurable endpoints
- **Terraform Registry Integration**: Direct integration with public Terraform Registry APIs for providers, modules, and policies
- **HCP Terraform & Terraform Enterprise Support**: Full workspace management, organization/project listing, and private registry access
- **Workspace Operations**: Create, update, delete workspaces with support for variables, tags, and run management
- **Partner-Managed Resources**: Security recommendation sync, analysis, and automated remediation
> **Security Note:** At this stage, the MCP server is intended for local use only. If using the StreamableHTTP transport, always configure the MCP_ALLOWED_ORIGINS environment variable to restrict access to trusted origins only.
> **Security Note:** Depending on the query, the MCP server may expose certain Terraform data to the MCP client and LLM. Do not use the MCP server with untrusted MCP clients or LLMs.
> **Caution:** The outputs and recommendations provided by the MCP server are generated dynamically and may vary based on the query, model, and the connected MCP client. Users should thoroughly review all outputs/recommendations before implementation.
## Quick Start (Partner-Managed Resources)
### 1. Build the Server
```bash
git clone <repository>
cd cc-partner-managed-resources
go build -o terraform-mcp-server ./cmd/terraform-mcp-server
```
### 2. Configure Claude Desktop
**macOS**: `~/.config/claude/claude_desktop_config.json`
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
```json
{
"mcpServers": {
"terraform": {
"command": "/absolute/path/to/terraform-mcp-server",
"args": ["--toolsets=partner,terraform"],
"env": {
"TFE_TOKEN": "your-hcp-terraform-token",
"TFE_ADDRESS": "https://app.terraform.io",
"AWS_ACCESS_KEY_ID": "your-aws-access-key",
"AWS_SECRET_ACCESS_KEY": "your-aws-secret-key",
"AWS_REGION": "us-west-2",
"ENABLE_TF_OPERATIONS": "true"
}
}
}
}
```
### 3. Use with Claude
```
User: "Configure AWS Security Hub for us-west-2"
User: "Sync security recommendations"
User: "Show me HIGH severity findings"
User: "Remediate the SSH security group finding"
```
## Available Toolsets
| Toolset | Description | Use Case |
|---------|-------------|----------|
| `registry` | Public Terraform Registry | Search providers, modules, documentation |
| `registry-private` | Private registry access | Private modules and providers |
| `terraform` | HCP Terraform operations | Workspace management, runs, state |
| `partner` | **Partner-managed resources** | Security recommendations, remediation |
| `all` | All toolsets combined | Full functionality |
| `default` | registry + terraform | Standard usage |
## Partner Toolset - Tools Reference
### Configuration Tools
| Tool | Description |
|------|-------------|
| `configure_aws_security_hub` | Set up AWS Security Hub as recommendation source |
| `configure_aws_recommendations` | Set up AWS Compute Optimizer (cost optimization) |
| `list_recommendation_sources` | List all configured sources |
### Discovery Tools
| Tool | Description |
|------|-------------|
| `sync_recommendations` | Pull latest findings from configured sources |
| `list_recommendations` | Query with filters (severity, category, status) |
| `get_recommendation` | Get full details of a specific finding |
### Remediation Tools
| Tool | Description |
|------|-------------|
| `link_recommendation_resource` | Map finding to Terraform resource address |
| `remediate_recommendation` | Generate fix and apply through HCP Terraform |
| `preview_remediation` | Preview changes without applying |
| `apply_remediation` | Apply previously previewed changes |
### Resource Management Tools
| Tool | Description |
|------|-------------|
| `register_resources` | Register Terraform resources with partner registry |
| `resolve_resources` | Resolve ARNs to Terraform addresses |
| `get_resource_state` | Get current Terraform state for a resource |
| `get_drift_status` | Check for infrastructure drift |
### Tool Workflow Sequence
The partner tools follow a specific workflow sequence:
```
1. Configure → 2. Sync → 3. Review → 4. Remediate
───────── ────────── ──────── ─────────────
configure_aws_ sync_ list_ remediate_
security_hub recommendations recommendations recommendation
(or configure_ (with terraform_ get_ (or preview_ +
aws_ org for auto- recommendation apply_
recommendations) discovery) remediation)
```
**Notes:**
- `sync_recommendations` with `terraform_org` auto-discovers and links resources
- Manual linking via `link_recommendation_resource` is only needed if auto-discovery fails (e.g., unrecognized ARN format)
- Use `preview_remediation` to review changes before applying
## Environment Variables
### Core Variables
| Variable | Description | Default |
|----------|-------------|---------|
| `TFE_ADDRESS` | HCP Terraform or TFE address | `https://app.terraform.io` |
| `TFE_TOKEN` | Terraform Enterprise API token | (required) |
| `TFE_SKIP_TLS_VERIFY` | Skip TLS verification | `false` |
| `ENABLE_TF_OPERATIONS` | Enable Terraform operations | `false` |
### Partner Variables
| Variable | Description | Default |
|----------|-------------|---------|
| `AWS_ACCESS_KEY_ID` | AWS access key | (required for partner) |
| `AWS_SECRET_ACCESS_KEY` | AWS secret key | (required for partner) |
| `AWS_REGION` | AWS region | `us-west-2` |
| `GITHUB_TOKEN` | GitHub token (for VCS workflow) | (optional) |
### Transport Variables
| Variable | Description | Default |
|----------|-------------|---------|
| `TRANSPORT_MODE` | `stdio` or `streamable-http` | `stdio` |
| `TRANSPORT_HOST` | HTTP server host | `127.0.0.1` |
| `TRANSPORT_PORT` | HTTP server port | `8080` |
| `MCP_ENDPOINT` | HTTP endpoint path | `/mcp` |
## Testing
### E2E Test Suite
A comprehensive E2E test environment is available in `test-e2e-remediation/`:
```bash
cd test-e2e-remediation/scripts
# Configure credentials
cp env.sh.template env.sh
# Edit env.sh with your credentials
# Run MCP CLI test (no Claude Desktop required)
source env.sh
python3 mcp-full-test.py
# Or run the full infrastructure test
./01-setup-workspace.sh
./02-deploy-infrastructure.sh
# ... (see test-e2e-remediation/README.md)
```
See **[test-e2e-remediation/README.md](test-e2e-remediation/README.md)** for complete testing documentation including:
- MCP CLI testing (no Claude Desktop)
- Claude Desktop testing with step-by-step prompts
- Verified test results
## Example: Security Remediation Workflow
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ Step 1: Configure │
│ > configure_aws_security_hub(region: "us-west-2", categories: ["security"]) │
│ ✓ Configured AWS Security Hub (us-west-2) │
├─────────────────────────────────────────────────────────────────────────────┤
│ Step 2: Sync with Auto-Discovery │
│ > sync_recommendations(terraform_org: "my-org") ← Enables auto-linking! │
│ ✓ Synced 20 findings from AWS Security Hub │
│ ✓ Indexed 5 workspaces with 47 resources │
│ ✓ Auto-linked 3 recommendations to Terraform │
├─────────────────────────────────────────────────────────────────────────────┤
│ Step 3: List (already linked!) │
│ > list_recommendations(severity: "high", managed_only: true) │
│ ✓ [HIGH] EC2.19 - Security group allows SSH from 0.0.0.0/0 │
│ Resource: sg-096b4ac3e0159bed6 │
│ Terraform: aws_security_group.vulnerable ← Auto-linked! │
├─────────────────────────────────────────────────────────────────────────────┤
│ Step 4: Remediate (no manual linking needed!) │
│ > remediate_recommendation(rec_id, confirm: true) │
│ ✓ Run created: run-wQvXTgsbk9MXQd5r │
│ ✓ Status: applied │
│ ✓ SSH CIDR changed: 0.0.0.0/0 → 10.0.0.0/8 │
└─────────────────────────────────────────────────────────────────────────────┘
```
## Project Structure
```
cc-partner-managed-resources/
├── cmd/terraform-mcp-server/ # Main server binary
├── pkg/
│ ├── partner/ # Partner package
│ │ ├── recommendation_types.go # Data structures
│ │ ├── recommendation_source.go # Source interface
│ │ ├── recommendation_registry.go # Session storage
│ │ ├── code_generator.go # Terraform fix generation
│ │ └── sources/
│ │ └── aws_security_hub.go # AWS Security Hub source
│ ├── tools/partner/ # MCP tool implementations
│ ├── toolsets/ # Toolset definitions
│ └── client/ # Session and client management
├── test-e2e-remediation/ # E2E test environment
│ ├── terraform/ # Vulnerable test infrastructure
│ ├── scripts/ # Test scripts (CLI + Claude Desktop)
│ └── docs/ # Test documentation and results
└── README.md # This file
```
## Code Generation
### HCL-Based Modification (Current Implementation)
The remediation code generator (`pkg/partner/code_generator.go`) uses **HashiCorp's `hclwrite` library** for proper HCL AST manipulation:
```go
// Parse HCL content
file, diags := hclwrite.ParseConfig([]byte(content), "main.tf", hcl.InitialPos)
// Find and modify resource blocks
resourceBlock := findResourceBlock(body, "aws_security_group", "vulnerable")
// Find nested blocks with criteria matching (e.g., ingress with from_port=22)
for _, block := range body.Blocks() {
if block.Type() == "ingress" && blockMatchesCriteria(block, {"from_port": "22"}) {
block.Body().SetAttributeValue("cidr_blocks", cty.ListVal(...))
}
}
// Output preserves formatting
return string(file.Bytes())
```
**What works well:**
- Proper HCL AST parsing and serialization
- Nested block handling (ingress/egress rules, metadata_options, versioning_configuration)
- Selective block modification (e.g., only SSH ingress, not HTTPS)
- Type-aware attribute setting (lists, booleans, strings, numbers)
- Preserved formatting and structure
- Fallback to string replacement if HCL parsing fails
**Supported Fixes:**
| Check ID | Finding | Fix Applied |
|----------|---------|-------------|
| EC2.19 | SSH open to 0.0.0.0/0 | `cidr_blocks = ["10.0.0.0/8"]` |
| EC2.18 | RDP open to 0.0.0.0/0 | `cidr_blocks = ["10.0.0.0/8"]` |
| EC2.3/EC2.7 | EBS/EC2 not encrypted | `encrypted = true` |
| EC2.8 | IMDSv2 not required | `http_tokens = "required"` |
| S3.14 | Versioning disabled | `status = "Enabled"` |
| Cost | Instance oversized | `instance_type = "m5.large"` |
### Future Improvements
1. **Pluggable Fix Strategies**
- Define fix patterns as configuration/plugins
- Allow custom remediation rules per organization
- Support for organization-specific security policies
2. **Dry-run Validation**
- Run `terraform validate` on generated code before upload
- Catch syntax errors before creating a run
3. **Additional Recommendation Sources**
- AWS Trusted Advisor (requires Business support plan)
- AWS Compute Optimizer (cost optimization - partially implemented)
- Third-party security platforms
### Underutilized Features
These features are implemented but may not be commonly used:
| Feature | Tool/Parameter | Description |
|---------|---------------|-------------|
| `managed_only` | `list_recommendations` | Filter to only Terraform-managed resources |
| `force_refresh` | `sync_recommendations` | Force re-sync even if recently synced |
| `preview_only` | `remediate_recommendation` | Preview changes without applying |
| `VCS workflow` | `apply_remediation` | Create GitHub PR instead of direct upload |
---
# Original Terraform MCP Server Documentation
## Prerequisites
1. Ensure [Docker](https://www.docker.com/) is installed and running to use the server in a containerized environment.
1. Install an AI assistant that supports the Model Context Protocol (MCP).
## Command Line Options
```bash
# Stdio mode
terraform-mcp-server stdio [--log-file /path/to/log] [--toolsets <toolsets>] [--tools <tools>]
# StreamableHTTP mode
terraform-mcp-server streamable-http [--transport-port 8080] [--transport-host 127.0.0.1] [--mcp-endpoint /mcp] [--log-file /path/to/log] [--toolsets <toolsets>] [--tools <tools>]
```
## Instructions
Default instructions for the MCP server is located in `cmd/terraform-mcp-server/instructions.md`, if those do not seem appropriate for your organization's Terraform practices or if the MCP server is producing inaccurate responses, please replace them with your own instructions and rebuild the container or binary.
## Installation
### Usage with Visual Studio Code
Add the following JSON block to your User Settings (JSON) file in VS Code. You can do this by pressing `Ctrl + Shift + P` and typing `Preferences: Open User Settings (JSON)`.
```json
{
"mcp": {
"servers": {
"terraform": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "TFE_TOKEN=${input:tfe_token}",
"-e", "TFE_ADDRESS=${input:tfe_address}",
"hashicorp/terraform-mcp-server"
]
}
}
}
}
```
### Usage with Claude Desktop
```json
{
"mcpServers": {
"terraform": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "TFE_ADDRESS=<<PASTE_TFE_ADDRESS_HERE>>",
"-e", "TFE_TOKEN=<<PASTE_TFE_TOKEN_HERE>>",
"hashicorp/terraform-mcp-server"
]
}
}
}
```
### Usage with Claude Code
```sh
claude mcp add terraform -s user -t stdio -- docker run -i --rm hashicorp/terraform-mcp-server
```
### Install from source
```console
go install github.com/hashicorp/terraform-mcp-server/cmd/terraform-mcp-server@latest
```
## Building the Docker Image locally
```bash
git clone https://github.com/hashicorp/terraform-mcp-server.git
cd terraform-mcp-server
make docker-build
# Run in stdio mode
docker run -i --rm terraform-mcp-server:dev
# Run in streamable-http mode
docker run -p 8080:8080 --rm -e TRANSPORT_MODE=streamable-http -e TRANSPORT_HOST=0.0.0.0 terraform-mcp-server:dev
# Filter tools (optional)
docker run -i --rm terraform-mcp-server:dev --toolsets=registry,terraform
```
## Available Tools
[Check out available tools here](https://developer.hashicorp.com/terraform/docs/tools/mcp-server/reference#available-tools)
### Tool Filtering
Control which tools are available using `--toolsets` (groups) or `--tools` (individual):
```bash
# Enable tool groups
terraform-mcp-server --toolsets=registry,terraform,partner
# Enable specific tools only
terraform-mcp-server --tools=search_providers,get_provider_details,list_workspaces
```
## Transport Support
### 1. Stdio Transport (Default)
Standard input/output communication using JSON-RPC messages. Ideal for local development.
### 2. StreamableHTTP Transport
Modern HTTP-based transport supporting both direct HTTP requests and Server-Sent Events (SSE) streams.
- **Endpoint**: `http://{hostname}:8080/mcp`
- **Health Check**: `http://{hostname}:8080/health`
## Development
### Prerequisites
- Go (check [go.mod](./go.mod) file for specific version)
- Docker (optional, for container builds)
### Available Make Commands
| Command | Description |
|---------|-------------|
| `make build` | Build the binary |
| `make test` | Run all tests |
| `make test-e2e` | Run end-to-end tests |
| `make docker-build` | Build Docker image |
| `make run-http` | Run HTTP server locally |
| `make clean` | Remove build artifacts |
## License
This project is licensed under the terms of the MPL-2.0 open source license. Please refer to [LICENSE](./LICENSE) file for the full terms.
## Support
For bug reports and feature requests, please open an issue on GitHub.
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
markitdown
MarkItDown-MCP is a lightweight server for converting URIs to Markdown.
firecrawl
Firecrawl MCP Server enables web scraping, crawling, and content extraction.
servers
Model Context Protocol Servers
Time
A Model Context Protocol server for time and timezone conversions.
Filesystem
Node.js MCP Server for filesystem operations with dynamic access control.
Sequential Thinking
A structured MCP server for dynamic problem-solving and reflective thinking.