terraform-cloud-mcp
by severity1
Verified
# Terraform Cloud MCP Server
A Model Context Protocol (MCP) server that integrates Claude with the Terraform Cloud API, allowing Claude to manage your Terraform infrastructure through natural conversation.
## Features
- **Authentication** - Validate tokens and get user information
- **Workspace Management** - Create, read, update, delete, lock/unlock workspaces
- **Run Management** - Create runs, list runs, get run details, apply/discard/cancel runs
- **Future Features** - State management, variables management, and more
## Quick Start
### Setup
```bash
# Clone the repository
git clone https://github.com/yourusername/terraform-cloud-mcp.git
cd terraform-cloud-mcp
# Create and activate virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
```
### Starting the Server
The server supports multiple ways to provide your Terraform Cloud API token:
```bash
# Using MCP development tools (recommended for development)
mcp dev server.py
# Using standard Python
python server.py
# With token via environment variable
export TFC_TOKEN=YOUR_TF_TOKEN
python server.py
# Using a .env file
echo "TFC_TOKEN=YOUR_TF_TOKEN" > .env
python server.py
# Run in background
python server.py > server.log 2>&1 & echo $! > server.pid
```
When a token is provided, Claude can use it without you having to specify it in every command.
### Connecting with Claude
#### Using Claude Code CLI
```bash
# Add the MCP server
claude mcp add terraform-cloud-mcp "$(pwd)/server.py"
# With token
claude mcp add terraform-cloud-mcp -e TFC_TOKEN=YOUR_TF_TOKEN -- "$(pwd)/server.py"
# Verify it was added
claude mcp list
# For testing, you can use the MCP Inspector
# This automatically opens when running `mcp dev server.py`
# MCP Inspector runs at http://localhost:5173
```
## Available Tools
### Authentication Tools
The following tools help validate and work with Terraform Cloud API tokens:
- `validate_token()`
Validates a Terraform Cloud API token
- `get_terraform_user_info()`
Gets user information for the provided token
### Workspace Management Tools
#### List & Search
Tools for finding and inspecting workspaces:
- `list_workspaces(organization, ...)`
List and filter workspaces with comprehensive options
*Required:* `organization` - Organization name
*Optional:* Filtering by name, tags, pagination, sorting and more
- `get_workspace_details(organization, workspace_name)`
Get detailed information about a specific workspace
*Required:* `organization`, `workspace_name`
#### Create & Update
Tools for creating and modifying workspaces:
- `create_workspace(organization, name, ...)`
Create a new workspace with various configuration options
*Required:* `organization`, `name`
*Optional:* Configure Terraform version, VCS settings, execution mode, etc.
- `update_workspace(organization, workspace_name, ...)`
Update an existing workspace's configuration
*Required:* `organization`, `workspace_name`
*Optional:* Update name, description, settings, VCS connections, etc.
#### Delete
Tools for removing workspaces:
- `delete_workspace(organization, workspace_name)`
Delete a workspace and all its content
*Required:* `organization`, `workspace_name`
- `safe_delete_workspace(organization, workspace_name)`
Delete only if the workspace isn't managing any resources
*Required:* `organization`, `workspace_name`
#### Lock & Unlock
Tools for controlling workspace access:
- `lock_workspace(organization, workspace_name, reason)`
Lock a workspace to prevent runs
*Required:* `organization`, `workspace_name`
*Optional:* `reason` - Explanation for the lock
- `unlock_workspace(organization, workspace_name)`
Unlock a workspace to allow runs
*Required:* `organization`, `workspace_name`
- `force_unlock_workspace(organization, workspace_name)`
Force unlock a workspace locked by another user
*Required:* `organization`, `workspace_name`
### Run Management Tools
Tools for managing Terraform runs (plan, apply, and other operations):
- `create_run(organization, workspace_name, ...)`
Create and queue a Terraform run in a workspace
*Required:* `organization`, `workspace_name`
*Optional:* `message`, `auto_apply`, `is_destroy`, `refresh`, `refresh_only`, `plan_only`, `target_addrs`, `replace_addrs`, `variables`, and more configuration options
- `list_runs_in_workspace(organization, workspace_name, ...)`
List and filter runs in a specific workspace with comprehensive options
*Required:* `organization`, `workspace_name`
*Optional:* Pagination, filtering by status/operation/source, searching by user/commit
- `list_runs_in_organization(organization, ...)`
List and filter runs across an entire organization
*Required:* `organization`
*Optional:* Pagination, filtering by workspace/status/operation/source, searching by user/commit
- `get_run_details(run_id)`
Get detailed information about a specific run
*Required:* `run_id`
- `apply_run(run_id, comment)`
Apply a run that is paused waiting for confirmation after a plan
*Required:* `run_id`
*Optional:* `comment`
- `discard_run(run_id, comment)`
Discard a run that is waiting for confirmation or priority
*Required:* `run_id`
*Optional:* `comment`
- `cancel_run(run_id, comment)`
Cancel a run that is currently planning or applying
*Required:* `run_id`
*Optional:* `comment`
- `force_cancel_run(run_id, comment)`
Forcefully cancel a run immediately (after a normal cancel)
*Required:* `run_id`
*Optional:* `comment`
- `force_execute_run(run_id)`
Forcefully execute a pending run by canceling prior runs
*Required:* `run_id`
## Example Conversations
### Authentication & Listing
```
# Using explicit token
User: Can you validate this Terraform Cloud API token: my-tf-token-value
Claude: [Validates token and confirms it's working]
# Using default token (if server started with TFC_TOKEN)
User: Can you validate my Terraform Cloud API token?
Claude: [Validates token and confirms it's working]
User: List all my workspaces in "example-org"
Claude: [Lists all workspaces in the organization]
User: Find all workspaces in "example-org" with names containing "prod"
Claude: [Lists matching workspaces with "prod" in their names]
User: List workspaces in "example-org" with the "environment:production" tag
Claude: [Lists workspaces with that specific tag]
```
### Workspace Management
```
User: Get details for the "production" workspace in "example-org"
Claude: [Shows detailed information about the workspace]
User: Create a new workspace in "example-org" called "staging" with auto-apply enabled
Claude: [Creates the requested workspace]
User: Update my "staging" workspace to use Terraform version 1.5.0
Claude: [Updates the workspace with the specified version]
User: Delete my "dev-test" workspace in "example-org"
Claude: [Deletes the workspace]
User: Delete my "staging" workspace but only if it's not managing any resources
Claude: [Uses safe_delete_workspace to safely delete the workspace]
```
### Locking Workspaces
```
User: Lock my "production" workspace while we do maintenance
Claude: [Locks the workspace with the provided reason]
User: The maintenance is complete, unlock "production" now
Claude: [Unlocks the workspace]
User: Someone left "staging" locked and they're out today. Can you force unlock it?
Claude: [Force unlocks the workspace]
```
### Run Management
```
User: Create a plan for my "production" workspace
Claude: [Creates a plan-only run in the workspace]
User: Create a destroy plan for "dev-test" workspace
Claude: [Creates a destroy plan run in the workspace]
User: Run a targeted plan in "staging" that only affects the database resources
Claude: [Creates a plan with target_addrs for database resources]
User: Create a plan with custom variables in the "development" workspace
Claude: [Creates a run with custom variable values for that specific run]
User: Create a run in "sandbox" workspace with auto-apply enabled
Claude: [Creates a run with auto_apply=True to automatically apply after planning]
User: List all runs in my "production" workspace
Claude: [Lists all runs in the workspace with details]
User: Show me runs in "example-org" that have errored in the last month
Claude: [Lists runs with error status in the organization]
User: Find all destroy plan runs in my organization
Claude: [Lists runs with is_destroy=true across all workspaces]
User: Get details for run ID "run-CZcmD7eagjhyX0vN"
Claude: [Shows detailed information about the specific run]
### Run Actions
```
User: Apply the pending run for "staging" workspace
Claude: [Uses apply_run to apply the waiting run]
User: Cancel the run "run-CZcmD7eagjhyX0vN", it's taking too long
Claude: [Uses cancel_run to safely interrupt the running process]
User: Discard the plan for the "dev" workspace, those changes aren't needed
Claude: [Uses discard_run to discard the pending run]
User: Force cancel the stuck run in "production"
Claude: [Uses force_cancel_run to immediately terminate the stuck run]
User: I need to execute this run immediately, force execute it
Claude: [Uses force_execute_run to bypass the queue and start the run]
```
### Coming Soon
```
User: List all variables defined in "production"
Claude: [Will use list_workspace_variables tool]
User: Show me the plan output and explain the changes
Claude: [Will use get_plan_output and explain_plan tools]
```
## Development
### Requirements
- Python 3.9+
- MCP (includes FastMCP and development tools)
- Terraform Cloud API token
### Project Structure
The code is organized into a modular structure:
```
terraform-cloud-mcp/
├── api/ # API client and communication
│ ├── __init__.py
│ └── client.py # HTTP client for Terraform Cloud API
├── models/ # Data models
│ ├── __init__.py
│ └── auth.py # Authentication models
├── tools/ # MCP tools implementation
│ ├── __init__.py
│ ├── auth.py # Authentication tools
│ ├── runs.py # Run management tools (create, list, apply, discard, cancel runs)
│ └── workspaces.py # Workspace management tools
├── utils/ # Utility functions
│ ├── __init__.py
│ └── validators.py # Input validation
├── server.py # Main server entry point
└── requirements.txt # Project dependencies
```
### Extending the Server
To add new features:
1. Add new tools to the appropriate module in the `tools` directory
2. Register new tools in `server.py`
3. Follow the existing patterns for parameter validation and error handling
4. Update documentation in README.md
5. Add tests for new functionality
## Troubleshooting
If you encounter issues:
1. Check server logs (debug logging is enabled by default)
2. Note that `Processing request of type CallToolRequest` is informational, not an error
3. Debug logging is already enabled in server.py:
```python
# Already in server.py
import logging
logging.basicConfig(level=logging.DEBUG)
```
4. If using `mcp dev server.py`, use the MCP Inspector at http://localhost:5173 to debug tool calls
## Contributing
Contributions are welcome! Please open an issue or pull request if you'd like to contribute to this project.