关于 Terraform CWD MCP Server
Terraform CWD MCP Server 为编码 Agent 提供当前 Terraform 工作目录的事实,包括锁文件固定版本的 Provider Schema。它还可检查计划、状态、模块和 Provider 升级影响。
主要功能
- 01固定版本的 Provider Schema 与参数检查
- 02不显示值的已保存计划摘要
- 03脱敏状态检查
- 04根模块及已安装模块接口
- 05Provider 升级影响验证
适用场景
- 01编辑 Terraform 资源前核对参数
- 02查看已保存计划的变更和替换原因
- 03检查状态地址及脱敏属性
- 04升级 Provider 前评估配置影响
MCP 相关
它向 MCP 客户端提供检查当前 Terraform 工作目录的工具。其 Schema 对应锁定版本,可补充 HashiCorp 的 terraform-mcp-server。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
9收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| dir | string | 否 | Terraform 根模块目录(必须已初始化)。默认值:TERRAFORM_CWD_MCP_DIR;否则使用服务器的工作目录。 |
详细介绍
@yawlabs/terraform-cwd-mcp
点击一次即可将其添加到本地 Yaw MCP 配置,这样它就能在每个 Yaw Terminal 会话中使用。也可以按照下文手动安装。
**了解当前 Terraform 工作目录中的真实情况:.terraform.lock.hcl 中锁定的确切提供程序架构(避免编码 Agent 编写不存在、已移除或只读的参数),以及已保存的计划、状态(已脱敏)、本地和已安装的模块,还有提供程序升级会造成的影响。**它与 HashiCorp 的 terraform-mcp-server 相辅相成,而非取而代之:该服务根据 Terraform Registry 文档提供答案,文档描述的是提供程序的最新版本;本服务则根据根模块中的 terraform providers schema -json 提供答案,描述的是你实际锁定的版本。两者都运行。
由 Yaw Labs 构建并维护。
为什么选这个?
你的锁文件写着 hashicorp/aws 5.31.0;而 Registry 文档(以及模型的训练数据)说的可能是更早或更晚的版本。于是 Agent 会编写在你锁定版本之后才添加、之前已移除的参数,或完全无法设置的 computed 参数。terraform validate 能发现这些问题——但那时代码已经写好了。这个服务让 Agent 能在编写代码之前进行检查。
- 锁定版本,而非最新版本 —— 真实依据是根模块中运行
terraform providers schema -json的结果,版本则从.terraform.lock.hcl读取。 - 只读,从不初始化 —— 它绝不会运行
terraform init(不会下载内容、联系后端或重写锁文件)。如果目录尚未初始化,会返回明确的操作提示,告诉你该运行什么命令。 - 按锁文件缓存 —— 架构转储会缓存在内存和磁盘中,缓存键由根路径和锁文件内容组成,因此提供程序升级后缓存会自动失效。AWS 提供程序的架构有数十 MB;每次锁文件变更只需转储一次,而不是每次提问都转储。
- 答案简洁 ——
tf_get_schema会将一种类型渲染为紧凑的缩进大纲,并标注required/optional/optional+computed/computed (read-only)、[deprecated]、[sensitive]和[write_only],而不是直接向模型提供原始 JSON。 - 跨平台 —— 支持 macOS、Linux 和 Windows。Terraform 会直接启动(不经过 shell),并以流式方式输出,因此没有缓冲区上限。
工具
| 工具 | 功能 |
|---|---|
tf_list_providers | 根模块中的提供程序及其固定版本,以及资源/数据/临时资源数量。请先调用此工具。 |
tf_search_types | 按类型查找名称中包含某个子字符串(s3_bucket)的类型。 |
tf_get_schema | 指定类型在固定版本中的所有参数和嵌套块,以及模式和标志。编写或编辑块之前请使用此工具。 |
tf_check_arguments | 验证点分路径(["bucket", "versioning.enabled"]),并为每个路径返回 ok、ok (block)(两者都可能带有 [deprecated])、READ-ONLY (computed)、'<x>' is an attribute, not a block 或 UNKNOWN。 |
tf_summarize_plan | 汇总已保存的计划(plan_file:由 terraform plan -out 生成的二进制文件或计划 JSON),或计划 JSON 文本(plan_json,例如通过官方服务获取的 HCP 运行计划)。先列出删除和替换,以及导致每项替换的属性;然后列出更新(变更路径)、创建、导入、移动、遗忘、漂移、延迟变更和输出;列出 Terraform 自身的 Plan: 计数;并发出销毁警告,指出需要 moved 块的重命名。不显示任何值。 |
tf_module_interface | 根模块、本地模块路径或按地址指定的已安装模块(module.network,包括已下载的注册表/git 模块)的变量(精确类型表达式、必需/可选、默认值、[sensitive]/[not nullable]/[ephemeral]、验证数量)、输出和模块调用。标记尚未安装或已过期的模块调用。不调用子进程。 |
tf_state_addresses | 当前状态中的资源实例地址(terraform state list),支持子字符串筛选和 id 查询。 |
tf_show_resource | 从状态中获取一个实例的属性值(terraform show -json),对敏感值进行隐藏,并在页脚说明隐藏了什么以及原因。 |
tf_upgrade_impact | 将固定的提供程序升级到指定确切版本时会有哪些影响:检查配置(根模块和已安装模块)使用的参数、嵌套块、属性读取和 provider 块参数,在目标版本中是否被移除、变为只读、重新定型、新设为必需或弃用;检查阻止升级的版本约束;并在临时副本上通过 terraform validate 确认。 |
每个工具都接受可选的 dir(根模块);kind 可设为 resource(默认值)、data 或 ephemeral。
与 HashiCorp 官方服务的职权划分。 对于固定版本的参数有效性,以及此目录中的计划、状态和模块内容,以本服务为准。官方服务则以用法文档、最新版本、公开注册表模块和 HCP/TFE 运行数据为准。对于 HCP 运行的计划,请在官方服务中获取其计划 ID(get_run_details),再用 get_plan_json_output(plan_id) 获取计划,并将 JSON 作为 plan_json 传给 tf_summarize_plan(这些工具需要官方服务的 terraform 工具集和 TFE_TOKEN)。
哪些操作是只读的,哪些会触及网络
- **绝不会写入:**你的根模块、它的
.terraform/、锁文件和状态。不会在其中运行terraform init。 - 状态工具(
tf_state_addresses、tf_show_resource)会运行terraform state list/terraform show -json,这两个命令绝不会锁定或刷新状态。使用远程后端时,它们会使用服务从 MCP 客户端继承的凭据读取 S3/GCS/HCP。如果选择了一个不存在的非默认工作区,Terraform 会创建它(s3 后端会写入空状态),因此服务会先检查terraform workspace list,并拒绝操作。 tf_upgrade_impact会在临时目录中运行terraform init,下载目标 provider 版本并存入插件缓存(TERRAFORM_CWD_MCP_PLUGIN_CACHE,否则使用你的TF_PLUGIN_CACHE_DIR,再否则使用<cache>/plugins);随后会在配置的临时副本上运行terraform validate,其中.terraform/providers条目会链接到你已有的包。绝不会复制状态和*.tfvars。调用会串行执行(插件缓存不支持并发安装)。- 脱敏(
tf_show_resource):Terraform 的敏感标记;状态中任何位置与标记值相等或包含标记值的字符串;类似密钥的键下的值(password、api_token、client_secret等,但不包括password_length或secret_arn);以及符合密钥特征的字符串(私钥、JWT、GitHub/GitLab/Slack/npm 令牌;URL 密码会在原位置脱敏)。刻意不提供“显示敏感信息”开关。Terraform 自身显示的未标记派生值(例如敏感文件的content_md5)会照常输出。 - 每个 Terraform 子进程都会获得
CHECKPOINT_DISABLE=1,因此不会通过版本检查与外界通信。
tf_summarize_plan 输出示例(真实计划的删节版):
plan (terraform 1.15.7, format 1.2): applyable, complete
totals: 1 delete, 5 replace, 1 update, 1 create, 0 read, 1 import, 1 move, 1 forget, 0 unchanged (terraform: 1 to import, 6 to add, 1 to change, 6 to destroy)
DELETE (1)
- null_resource.gone (not in configuration)
REPLACE (5)
-/+ local_sensitive_file.sf delete-then-create; forced by: content [sensitive]
+/- random_string.cbd create-before-destroy; forced by: keepers
...
UPDATE (1)
~ terraform_data.cfg: input.version, output (known after apply)
WARNING: 6 object(s) will be destroyed (1 delete, 5 replace). 1 moved block(s) applied; none covers these.
tf_upgrade_impact 输出示例(真实 validate 运行结果):
upgrade hashicorp/random 2.3.1 -> 3.6.3 (major) for /work/infra
constraints: root pins 2.3.1 as local name rnd (change it to allow 3.6.3)
used types: resource random_password, random_id
affected arguments (2):
random_password.p.number (main.tf:18): DEPRECATED in 3.6.3
reads random_id.i.b64 (main.tf:36): REMOVED in 3.6.3
validate on a temp copy, 3.6.3 vs 2.3.1: 1 new error, 1 new warning, 1 warning resolved
error main.tf:36: Unsupported attribute - This object has no argument, nested block, or exported attribute named "b64".
warning main.tf:18 random_password.p: Attribute Deprecated - **NOTE**: This is deprecated, use `numeric` instead.
verdict: BREAKING (1 error after upgrade)
tf_get_schema 输出示例:
resource random_password (registry.terraform.io/hashicorp/random 3.9.1)
bcrypt_hash: string computed (read-only) [sensitive] - A bcrypt hash of the generated random password. ...
keepers: ["map","string"] optional - Arbitrary map of values that, when changed, will trigger recreation of resource. ...
length: number required - The length of the password desired. ...
number: bool optional+computed [deprecated] - Include numeric characters in the result. ...
result: string computed (read-only) [sensitive] - The generated random password.
快速开始
1. 初始化根模块一次(由你而非服务执行):
terraform init -backend=false
-backend=false 就足够了:架构只需要 providers,不需要状态。
**2. 添加服务。**在根模块中使用 Claude Code:
# macOS / Linux / WSL
claude mcp add terraform-cwd -- npx -y @yawlabs/terraform-cwd-mcp@latest
# Windows
claude mcp add terraform-cwd -- cmd /c npx -y @yawlabs/terraform-cwd-mcp@latest
或者将其添加到根模块中的 .mcp.json(也可以放在任何位置,并设置 TERRAFORM_CWD_MCP_DIR):
macOS / Linux / WSL:
{
"mcpServers": {
"terraform-cwd": {
"command": "npx",
"args": ["-y", "@yawlabs/terraform-cwd-mcp@latest"]
}
}
}
Windows:
{
"mcpServers": {
"terraform-cwd": {
"command": "cmd",
"args": ["/c", "npx", "-y", "@yawlabs/terraform-cwd-mcp@latest"]
}
}
}
**为什么 Windows 上要多一步?**从 Node 20 开始,
child_process.spawn无法直接执行.cmd文件(Windows 上的npx就是这种文件)。使用cmd /c包装是标准解决方法。
3. 重启 MCP 客户端,并提出例如这样的请求:“添加一个带版本控制的 S3 存储桶——先对照我们固定的 AWS provider 检查参数。”
告诉你的 Agent 使用它
只要项目明确告知,Agent 就能可靠地使用该服务。将以下内容粘贴到根模块的 CLAUDE.md(或 AGENTS.md)中:
## Terraform provider schemas
This repo pins provider versions in `.terraform.lock.hcl`; registry docs and your
training data describe other versions. Use the terraform-cwd MCP server:
- Call `tf_list_providers` once per session to see the pinned versions.
- Before writing or editing any `resource`, `data` or `ephemeral` block, call
`tf_get_schema` for that type.
- Call `tf_check_arguments` with every argument path you set (dotted for nested
blocks, e.g. `versioning.enabled`). Never use an argument it reports as
`UNKNOWN` or `READ-ONLY (computed)`; replace a `[deprecated]` one if the
schema offers an alternative.
- Before calling a module, read its inputs with `tf_module_interface`.
- After `terraform plan -out=tfplan`, review it with `tf_summarize_plan`
(plan_file: tfplan) and call out every DELETE and REPLACE.
- Before bumping a provider version, run `tf_upgrade_impact`.
搭配使用
HashiCorp 的 terraform-mcp-server
hashicorp/terraform-mcp-server 解答有关注册表和 HCP 的问题;此服务则解答当前工作目录中的实际情况。两者可以同时运行——它们的功能没有重叠;如果两者的结果不一致,下表说明以谁为准:
| 问题 | 权威来源 |
|---|---|
| 参数 X 对我锁定的 Provider 版本有效吗? | terraform-cwd-mcp |
| 升级到 vN 后,我使用的哪些参数会出问题? | terraform-cwd-mcp(tf_upgrade_impact) |
| 这个已保存的计划、这个状态或这个本地 / 已安装模块包含什么? | terraform-cwd-mcp |
| 资源 X 应如何使用?文档和示例怎么说? | terraform-mcp-server |
| 最新的 Provider 或模块版本是什么? | terraform-mcp-server |
| 我该使用哪个公共注册表模块? | terraform-mcp-server |
| HCP Terraform / TFE 工作区和运行 | terraform-mcp-server |
| HCP 运行的计划 | terraform-mcp-server 获取计划(get_run_details -> 计划 ID -> get_plan_json_output(plan_id));tf_summarize_plan 使用 plan_json 汇总计划 |
官方服务启动时仅启用 registry 工具集。HCP / TFE 相关条目要求启动时使用 --toolsets=registry,terraform(或 all),并设置 TFE_TOKEN。其文档搜索工具从 v1.3.1 开始叫作 search_provider_docs(此前为 search_providers;这是一次 BREAKING 重命名),如果你按名称将工具列入允许列表,这一点很重要。
Yaw Mode 技能
Yaw Terminal 的 Yaw Mode 提供四项技能,可驱动这两个服务;任一服务缺失时也能优雅降级,并且操作止步于 terraform plan(绝不会执行 apply 或 destroy):
/yaw-tf—— 日常编写 / 编辑 / 修复:根据锁定的架构检查每个参数,然后运行 fmt、validate、plan 并汇总;需要时交由以下三项技能处理。/yaw-tf-refactor—— 重命名、模块迁移和导入:使用moved/import/removed块;只有当计划显示没有 destroy 和 replace 时才算完成。/yaw-tf-plan-review—— 针对本地已保存计划或 HCP 运行的 go / no-go 检查清单:先检查 destroy,再检查 checkov / trivy,以及 IAM、网络和加密方面的风险点。/yaw-tf-upgrade—— Provider 升级:获取最新版本,使用tf_upgrade_impact检查你实际使用的参数,查看升级指南,然后进行编辑、重新锁定版本、validate 和 plan。
配置
全部可选。
| 环境变量 | 默认值 | 用途 |
|---|---|---|
TERRAFORM_CWD_MCP_DIR | 服务的工作目录 | 工具调用未传入 dir 时使用的根模块。 |
TERRAFORM_CWD_MCP_CACHE | ~/.cache/terraform-cwd-mcp | 架构转储的缓存位置(<key>.json)。可随时安全删除。 |
TERRAFORM_CWD_MCP_BINARY | terraform | 要运行的二进制文件,例如完整路径,或用于 OpenTofu 的 tofu(输出相同的 providers schema -json)。 |
TERRAFORM_CWD_MCP_TIMEOUT_MS | 300000 | 超时后终止任何 terraform 命令(架构转储、状态读取、目标初始化、验证)。 |
TERRAFORM_CWD_MCP_PLUGIN_CACHE | TF_PLUGIN_CACHE_DIR,否则为 <cache>/plugins | tf_upgrade_impact 保存已下载提供程序包的位置。 |
运行时(oam 或 Node):
terraform-cwd-mcp 命令在找到可用的 oam 时优先使用它,否则使用 Node。它不会在低于 0.19.0 的 oam 上提供服务。
| 环境变量 | 默认值 | 用途 |
|---|---|---|
TERRAFORM_CWD_MCP_RUNTIME | auto | auto:使用版本为 0.19.0 或更高的最新 oam,否则使用 Node。oam:使用 oam,否则报错退出。node:始终使用 Node——当问题只在 oam 下出现时,可用作备用方案。 |
OAM_BIN | (未设置) | 要使用的 oam 二进制文件路径。否则,启动器会检查 OAM_INSTALL_DIR、已安装位置(~/.oam/bin,以及 Windows 上的 %LOCALAPPDATA%\oam\bin)和 PATH,并选择最新版本。 |
旧版 oam 可通过 oam self-update 更新。在默认使用 oam 运行服务的 Yaw MCP 中,运行 yaw-mcp set <namespace> runtime=node 可将此服务切换到 Node。没有 --permission 沙盒选项:该服务会启动 terraform,并读取调用指定的任何目录,因此没有可授予的有限权限。
要求
- Node.js 20+
PATH中需有 Terraform(或 OpenTofu),且版本足够新,支持terraform providers schema -json(0.12+;临时资源需要 1.10+)- 除在根目录或本地路径上运行的
tf_module_interface,以及使用计划 JSON 的tf_summarize_plan外,其他工具都需要已初始化的根模块(存在.terraform/和.terraform.lock.hcl) - 状态工具:后端已初始化(运行
terraform init,而不是-backend=false),且服务器环境中有其凭据 tf_upgrade_impact:首次请求目标版本时需要访问注册表(之后针对该版本的运行均可离线)<dir>/.terraform中需有.terraform/:不支持TF_DATA_DIR
贡献
git clone https://github.com/YawLabs/terraform-cwd-mcp.git
cd terraform-cwd-mcp
npm install
npm run lint # Biome check
npm run lint:fix # Auto-fix
npm run build # tsup bundle + declarations
npm test # Vitest (the integration test runs only when terraform is on PATH)
npm run typecheck # oam check . when oam is installed, else tsc --noEmit
npm run check:oam-floor # the oam floor agrees across the repo and matches the latest oam release
完整工作流(包括发布流程)请参阅 CONTRIBUTING.md。
许可证
MIT
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。