Problem
The terraform-code-generation and terraform-module-generation plugins both define an identical MCP server in their plugin.json:
"mcpServers": {
"terraform": {
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "TFE_TOKEN", "-e", "TFE_ADDRESS", "hashicorp/terraform-mcp-server"]
}
}
This causes two issues:
1. Duplicate containers per session
Both plugins launch the exact same hashicorp/terraform-mcp-server image with identical arguments. With both plugins enabled, every Claude Code session starts 2 identical containers. They provide the same MCP tools, so there's no benefit to running two.
2. Containers are never cleaned up
The containers are started with -i --rm, but when a Claude Code session ends, the stdin pipe is not cleanly closed. The container doesn't detect the broken pipe and keeps running indefinitely. The --rm flag never triggers because the container never exits.
Over time this leads to an ever-growing list of orphaned containers:
CONTAINER ID IMAGE CREATED STATUS
2a55cef7afb5 hashicorp/terraform-mcp-server 2 hours ago Up 2 hours
11453ae06a6d hashicorp/terraform-mcp-server 2 hours ago Up 2 hours
207c224f8d3a hashicorp/terraform-mcp-server 6 hours ago Up 6 hours
872fd3600b83 hashicorp/terraform-mcp-server 6 hours ago Up 6 hours
2fb5383d29f9 hashicorp/terraform-mcp-server 11 hours ago Up 11 hours
80532aa71341 hashicorp/terraform-mcp-server 11 hours ago Up 11 hours
... (12 containers from ~6 sessions over 5 days)
Suggested fixes
For the duplicate container issue
Use a fixed --name for the Docker container so that when both plugins are enabled, the second docker run detects the already-running container instead of spawning a duplicate. A wrapper script could first check if a container with that name is already running and reuse it, or both plugins could coordinate on a shared container name.
For the leaked container issue
The container needs a way to detect that stdin has been closed and exit cleanly, so that --rm actually triggers. Options:
- Add stdin EOF detection inside the MCP server process
- Use a wrapper entrypoint that monitors the stdin pipe and kills the process on broken pipe
- Use
--name combined with a cleanup-before-start pattern (docker rm -f <name> before docker run)
Workaround
I'm currently using a wrapper script that forces a fixed container name and kills any stale container before starting:
#!/bin/bash
CONTAINER_NAME="terraform-mcp-server"
docker rm -f "$CONTAINER_NAME" 2>/dev/null
exec docker run -i --rm --name "$CONTAINER_NAME" -e TFE_TOKEN -e TFE_ADDRESS hashicorp/terraform-mcp-server
Plus a Claude Code Stop hook to clean up on session exit:
{"type": "command", "command": "docker rm -f terraform-mcp-server 2>/dev/null || true"}
Environment
- Claude Code (latest)
- Both
terraform-code-generation@hashicorp and terraform-module-generation@hashicorp plugins enabled
- Docker on Linux (Ubuntu 24.04)
Problem
The
terraform-code-generationandterraform-module-generationplugins both define an identical MCP server in theirplugin.json:This causes two issues:
1. Duplicate containers per session
Both plugins launch the exact same
hashicorp/terraform-mcp-serverimage with identical arguments. With both plugins enabled, every Claude Code session starts 2 identical containers. They provide the same MCP tools, so there's no benefit to running two.2. Containers are never cleaned up
The containers are started with
-i --rm, but when a Claude Code session ends, the stdin pipe is not cleanly closed. The container doesn't detect the broken pipe and keeps running indefinitely. The--rmflag never triggers because the container never exits.Over time this leads to an ever-growing list of orphaned containers:
Suggested fixes
For the duplicate container issue
Use a fixed
--namefor the Docker container so that when both plugins are enabled, the seconddocker rundetects the already-running container instead of spawning a duplicate. A wrapper script could first check if a container with that name is already running and reuse it, or both plugins could coordinate on a shared container name.For the leaked container issue
The container needs a way to detect that stdin has been closed and exit cleanly, so that
--rmactually triggers. Options:--namecombined with a cleanup-before-start pattern (docker rm -f <name>beforedocker run)Workaround
I'm currently using a wrapper script that forces a fixed container name and kills any stale container before starting:
Plus a Claude Code Stop hook to clean up on session exit:
{"type": "command", "command": "docker rm -f terraform-mcp-server 2>/dev/null || true"}Environment
terraform-code-generation@hashicorpandterraform-module-generation@hashicorpplugins enabled