tf-approval-gate
TF Approval Gate
AI 코딩 에이전트(Claude Code, Cursor 등)가 Terraform 변경 사항을 계획하고, 정책을 검사하고, 비용을 추정할 수 있게 해주는 MCP 서버입니다 -- 그러나 실제 사람이 Slack에서 Approve를 클릭하기 전에는 에이전트가 terraform apply를 실행하는 것을 구조적으로 불가능하게 만듭니다.
왜 필요한가
AI 에이전트는 이제 실제 클라우드 계정을 대상으로 Terraform을 직접 작성하고 실행할 수 있습니다. terraform apply를 스스로 실행할 수 있는 에이전트는 사람의 개입 없이 프로덕션 인프라를 조용히 파괴하거나 잘못 구성할 수 있습니다. TF Approval Gate는 이러한 격차를 해소합니다: 모든 apply에는 실제 사람의 Slack 클릭(또는 개발 모드에서는 터미널 앞의 실제 사람)만이 발급할 수 있는 서명된 일회용 토큰이 필요합니다. 에이전트의 "사람이 승인했다"는 주장은 절대 신뢰되지 않습니다 -- 서버가 모든 것을 직접 다시 검증합니다.
Related MCP server: CloudOps OS MCP
작동 방식
에이전트가
.tf파일을 편집한 다음tf_propose_change를 호출합니다 --terraform plan, Checkov(+ OPA가 구성된 경우), Infracost(구성된 경우)를 실행하고 safe/needs_review/blocked 권장 사항이 포함된 하나의 번들 제안을 반환합니다.에이전트가
tf_request_approval을 호출합니다 -- Approve/Reject 버튼과 함께 diff + 정책 검사 결과 + 비용을 Slack에 게시합니다(APPROVAL_MODE=cli에서는 서버 터미널에 프롬프트를 표시). 정책 검사 결과가 blocking이면 게시 자체를 거부합니다.에이전트가
tf_check_approval_status를 폴링합니다.사람이 Approve를 클릭 → 서버는 클릭이 허용 목록(allow-list)에 등록된 Slack 사용자로부터 온 것인지 확인하고 해당 플랜의 체크섬에 바인딩된 서명된 일회용 토큰을 발급합니다.
에이전트가 토큰과 함께
tf_apply를 호출합니다. 서버는 서명, 만료, 일회용 상태, 플랜의 바이너리 체크섬을 다시 검증하고 클라우드 측 드리프트가 있는지 확인합니다 -- 그런 다음에만terraform apply를 실행합니다.
전체 설계와 위협 모델은 docs/architecture.md 및 docs/security-model.md를 참조하세요.
빠른 시작 (로컬, Slack 설정 불필요)
git clone https://github.com/SORABH13/tf-approval-gate.git
cd tf-approval-gate
npm install
npm run build
npm run check-binaries # confirms terraform + checkov are on PATHPATH에 Terraform과 Checkov가 필요합니다. OPA/Conftest와 Infracost는 선택 사항입니다(없으면 해당 기능이 자동으로 건너뜁니다). 또는 아무것도 설치하지 않고 아래의 Docker 이미지를 사용해도 됩니다. 세 가지가 모두 포함되어 있습니다.
개발 모드로 실행합니다(APPROVAL_MODE=cli는 Slack에 게시하는 대신 diff를 서버 터미널에 출력하고 y/n을 기다립니다 -- 첫 로컬 테스트에 적합하지만 Slack보다 보증 수준이 낮습니다. docs/security-model.md 참조):
APPROVAL_MODE=cli TF_APPROVAL_GATE_SECRET=$(openssl rand -hex 32) npm start그런 다음 Claude Code(또는 모든 MCP 클라이언트)에서 MCP 서버로 추가합니다:
{
"mcpServers": {
"tf-approval-gate": {
"command": "node",
"args": ["/absolute/path/to/tf-approval-gate/dist/index.js"],
"env": {
"APPROVAL_MODE": "cli",
"TF_APPROVAL_GATE_SECRET": "<same secret as above>"
}
}
}
}에이전트를 examples/local-demo(클라우드 자격 증명이 필요 없는 null/random 프로바이더 사용)로 지정하고 tf_workspace_init → tf_propose_change → tf_request_approval → tf_apply를 실행하도록 요청하세요.
Docker / devcontainer
docker build는 Node, Terraform, Checkov, Conftest(OPA)가 사전 설치된 이미지를 생성합니다 -- Docker 자체 외에 호스트 설정이 필요 없습니다.
docker build -t tf-approval-gate .
docker run --rm -it \
-e APPROVAL_MODE=cli \
-e TF_APPROVAL_GATE_SECRET=$(openssl rand -hex 32) \
-v "$(pwd)/examples/local-demo":/examples/local-demo:ro \
-v tf-approval-gate-data:/data \
tf-approval-gateSlack 모드에서는 -e SLACK_BOT_TOKEN=... -e SLACK_APP_TOKEN=... -e SLACK_APPROVAL_CHANNEL=... -e SLACK_APPROVER_USER_IDS=...를 추가하고 APPROVAL_MODE=cli는 제거하세요. 승인 상태는 /data 볼륨에 유지됩니다(SQLite 기반, docs/architecture.md 참조).
VS Code / GitHub Codespaces용 .devcontainer/devcontainer.json도 포함되어 있습니다 -- 컨테이너에서 저장소를 열면 terraform/checkov/conftest가 즉시 사용 준비됩니다.
Slack 설정 (프로덕션 모드)
examples/slack-app-manifest.yml에서 Slack 앱을 생성합니다.
Socket Mode를 활성화하고 앱 레벨 토큰(
xapp-...)을 생성합니다.앱을 워크스페이스에 설치하고 봇 토큰(
xoxb-...)을 복사합니다.SLACK_BOT_TOKEN,SLACK_APP_TOKEN,SLACK_APPROVAL_CHANNEL,SLACK_APPROVER_USER_IDS(Approve/Reject를 클릭할 수 있는 쉼표로 구분된 Slack 사용자 ID)를 설정합니다 -- .env.example을 참조하세요.APPROVAL_MODE=slack(기본값)으로 실행합니다.
전체 가이드: docs/slack-setup.md.
도구
도구 | 용도 |
| Terraform 프로젝트를 샌드박스 작업 디렉터리로 체크아웃/복사합니다. |
| 네이티브 파일 시스템 접근 권한이 없는 에이전트를 위해 |
|
|
| 플랜에 대해 Checkov(+ OPA/Conftest)를 실행하고 하나의 보고서로 병합합니다. |
| Infracost 월간 비용 변동 (구성되지 않은 경우 건너뜀). |
| 복합 도구: 플랜 + 정책 + 비용을 하나의 호출로 처리. 먼저 호출하세요. |
| 사람의 승인을 위해 Slack(또는 CLI)에 게시합니다. |
| 서명된 승인 토큰을 폴링합니다. |
|
|
전체 참조: docs/tool-reference.md.
상태
v0.1부터 v0.4까지 구현 및 테스트가 완료되었습니다: 정상 경로(Checkov, Slack Socket Mode / CLI 폴백), OPA/Conftest, Infracost 비용 추정, 원자적 일회용 토큰 소비를 지원하는 SQLite 기반 승인 저장소. Docker 이미지와 devcontainer가 빌드 및 검증되었습니다. 로컬 null/random 데모와 실제 AWS 계정(examples/aws-s3-demo) 모두에서 실제 엔드투엔드 실행이 수행되었습니다. 전체 로드맵과 공개 출시 전에 남은 작업은 docs/architecture.md를 참조하세요(데모 GIF 및 외부 콜드 테스트 -- CONTRIBUTING.md 참조).
라이선스
MIT -- LICENSE 참조.
Available Tools
9 toolstf_applyA
The only tool that runs terraform apply. Requires a valid approvalId + approvalToken minted by a real human approval; verifies signature, expiry, single-use, plan checksum, and drift server-side before applying.
| Name | Required | Description | Default |
|---|---|---|---|
| approvalId | Yes | ||
| workspaceId | Yes | ||
| approvalToken | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses that this is a mutation (applies) and details server-side verification of signature, expiry, single-use, plan checksum, and drift. This gives the agent important context about safety and failure conditions, though it does not describe the response format or exact effects on infrastructure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with zero waste. The primary purpose is stated first, and the security requirements are added in a compact, informative second sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with security prerequisites and no output schema, the description covers the essential usage context: what it does, when it can be used (with valid approval), and what verifications occur. It is missing details on response/return value and any prerequisites like having a plan already generated, but given sibling tools and the absence of output schema, it is largely complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains the purpose of approvalId and approvalToken (minted by human approval, verifies signature/expiry/etc.), but does not explain workspaceId at all. It adds some meaning but leaves a key parameter undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('runs') and resource ('terraform apply'), and explicitly claims to be the only tool that does so, clearly distinguishing it from siblings. The approval requirement is also front-loaded.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description makes clear that this is the tool to use when applying a Terraform plan, and its requirement for a valid approval token implies it should only be used after planning and approval. It does not explicitly name alternatives for planning (like tf_plan), but the 'only tool' phrasing provides explicit exclusion of other siblings for apply.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tf_check_approval_statusB
Polls the status of a pending approval. Returns a signed approvalToken once a human approves.
| Name | Required | Description | Default |
|---|---|---|---|
| approvalId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It mentions polling and returning a token once approved, but does not state whether the call is read-only, what happens when approval is still pending, whether it blocks or returns immediately, or if repeated calls are safe. This leaves significant ambiguity for a tool that lacks any annotation context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no redundancy. The core action is front-loaded, and the token return is stated clearly. It is concise and structured effectively, though it could be slightly more specific about the pending state.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter tool, the description covers the basic purpose and result. However, it omits details about the response when approval is not yet granted, and without an output schema, the description should clarify the return structure. It doesn't mention whether the call blocks or is a non-blocking poll. These gaps make it only partially complete for an agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has one required parameter (approvalId) with 0% description coverage. The description never mentions this parameter or how it relates to the pending approval. The parameter name is somewhat self-explanatory, but the description does not confirm that approvalId is the identifier of the approval being polled, nor does it clarify the expected format beyond the schema's uuid type. This is a gap since the description should tie the parameter to the tool's purpose.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (polls), the target (status of a pending approval), and the outcome (returns a signed approvalToken). The verb and resource are specific and distinguish it from sibling tools like tf_request_approval, which presumably creates the approval. It doesn't explicitly name a sibling, but the function is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is for polling a pending approval, which suggests using it after an approval request has been made. However, it doesn't explicitly state when to use it versus alternatives (e.g., tf_request_approval) or provide exclusions. The usage context is implied by the phrase 'Polls the status of a pending approval' but no explicit when/when-not guidance is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tf_cost_estimateB
Runs Infracost against the current plan and returns a monthly cost delta (skipped if INFRACOST_API_KEY is unset).
| Name | Required | Description | Default |
|---|---|---|---|
| workspaceId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden. It discloses the skip condition when the API key is unset, which is useful, but does not state whether the operation has side effects, requires a prior plan, or what happens if the API key is missing (e.g., returns null vs error). The description is somewhat opaque about the operational details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that front-loads the primary action and outcome, with the conditional placed as a parenthetical. There is no wasted wording or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (one parameter, no output schema), the description covers the core function and the key conditional, but omits the meaning of workspaceId and any prerequisite like requiring a successful tf_plan. This leaves the agent to guess how to invoke it correctly, warranting a middle score.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has a single parameter (workspaceId) with 0% description coverage, and the tool description does not mention this parameter at all. The agent receives no meaning about what workspaceId is or how to fill it correctly, leaving a critical gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Runs Infracost'), the target ('against the current plan'), and the output ('returns a monthly cost delta'). This distinguishes it from sibling tools that handle planning, approval, or apply phases, making its purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implicitly indicates it's for cost estimation after a plan exists, and mentions a conditional (skipped if INFRACOST_API_KEY unset), but does not explicitly say when to use it over alternatives like tf_plan or tf_apply. No explicit 'use this instead of X' guidance is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tf_planB
Runs terraform init+plan and returns a resource-level change summary.
| Name | Required | Description | Default |
|---|---|---|---|
| workspaceId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of disclosing behavior. It states that it runs init+plan and returns a summary, but it does not explicitly say whether it modifies any state, requires authentication, or is read-only. An agent might assume it applies changes because it says 'runs'—though plan is typically safe, this is not clarified. The description lacks critical side-effect disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that front-loads the action and output. Every word earns its place with no wasted verbiage. It is appropriately concise for a single-purpose tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's low complexity (one parameter) but no annotations, no output schema, and no parameter explanation, the description is incomplete. An agent lacks information about when to use it, what the change summary looks like in detail, and any prerequisites. The description covers the core action but omits essential usage and behavioral context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter is workspaceId, and its schema gives a pattern but no semantic meaning. The description does not mention or explain workspaceId at all. With 0% schema description coverage, the description should compensate, but it fails to clarify what workspaceId refers to or how it is used. This leaves the agent to guess the parameter's purpose.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Runs terraform init+plan') and a concrete output ('returns a resource-level change summary'). This clearly differentiates it from siblings like tf_apply (which applies changes) and tf_cost_estimate (which estimates cost). The verb and resource are explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies this tool is for planning Terraform changes (init+plan) and producing a change summary, which logically precedes tf_apply. However, it does not explicitly state when to use it versus tf_cost_estimate or tf_policy_check, nor does it mention prerequisites like workspace initialization. The guidance is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tf_policy_checkB
Runs Checkov (and OPA/Conftest if configured) against the current plan and returns a merged policy report.
| Name | Required | Description | Default |
|---|---|---|---|
| workspaceId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry all behavioral disclosure. It mentions the conditional execution of OPA/Conftest, but does not state whether the tool is read-only, what happens on policy violations, or if any state is modified. This leaves the agent uninformed about side effects and failure behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured sentence that front-loads the main action and output. There is no extraneous information; every word contributes to the understanding of the tool's function.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool appears straightforward, but important context is missing: no mention of required dependencies (like a generated plan), how to interpret the report, or error conditions. Given the lack of annotations and output schema, the description should provide more operational context for the agent to use it safely and effectively.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate by clarifying the parameter's meaning. It does not mention workspaceId at all, leaving the agent to infer its purpose from the name alone. The simple name and pattern offer some hint, but the description adds no value over the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Runs Checkov and OPA/Conftest') against a specific resource ('current plan') and the outcome ('merged policy report'). This distinguishes it from sibling tools like tf_plan or tf_apply, which serve different purposes. No ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no concrete guidance on when to use this tool versus alternatives. It does not mention prerequisites (e.g., a plan must exist), nor does it indicate scenarios where this tool should be skipped. The only hint is the phrase 'if configured', which is not enough to guide selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tf_propose_changeB
Composite tool: runs plan, policy check, and cost estimate together and returns one bundled Proposal with a recommendation (safe/needs_review/blocked). Call this before tf_request_approval.
| Name | Required | Description | Default |
|---|---|---|---|
| workspaceId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full responsibility. It mentions the composite nature and output recommendation, but does not disclose whether the operation is read-only, if it modifies state, requires special permissions, or has side effects. It also ignores potential failure states or rate limits. This is a significant transparency gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no fluff. The first sentence front-loads the core functionality and output, the second gives actionable usage. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a composite tool with a single parameter and no output schema, the description covers the main purpose and usage. It names the recommendation values and the intent. However, it lacks details on what a Proposal contains, error conditions, or whether state changes occur—gaps that matter for an agent deciding to call it safely.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description makes no mention of the workspaceId parameter. Schema coverage is 0%, and the description does not compensate by explaining the parameter's purpose or format. The agent gets no guidance beyond the schema pattern, which is minimal.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool runs plan, policy check, and cost estimate together and returns a bundled Proposal with a recommendation. It names specific sub-operations and differentiates from sibling tools like tf_plan, tf_policy_check, tf_cost_estimate by framing as a composite. The verb 'runs' and resource 'Proposal' are explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit timing: 'Call this before tf_request_approval.' This gives a clear context and implies when to use it instead of individual tools. However, it does not explicitly state when not to use it or mention alternatives beyond the approval flow, leaving some inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tf_request_approvalB
Sends the current plan for human approval (Slack, or the server's terminal in APPROVAL_MODE=cli). Refuses if policy findings are blocking. Returns an approvalId to poll.
| Name | Required | Description | Default |
|---|---|---|---|
| workspaceId | Yes | ||
| overridePolicy | No | Explicitly override a blocking policy verdict. Requires TF_APPROVAL_GATE_ALLOW_POLICY_OVERRIDE=true server-side. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses the delivery channel (Slack/CLI), the refusal condition (blocking policy), and the return of an approvalId. It does not mention whether the call blocks, side effects, permission requirements, or what happens on failure beyond 'refuses'. While it gives some key behavior, it is not comprehensive for a mutation-like action with no annotation support.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, readable sentence that efficiently covers the core action, channels, refusal, and return. It front-loads the primary purpose. No redundancy or filler. It is appropriately compact for the information it conveys.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given there is no output schema and no annotations, the description should provide sufficient context for an agent to call the tool correctly. It explains the overall flow (send for approval, get approvalId), but omits details like what happens if the plan is missing, whether the call is synchronous or asynchronous, error conditions beyond 'refuses', and the exact nature of the returned approvalId (format or type). For a tool that triggers a human approval process, these are important gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50%; only overridePolicy has a description, while workspaceId lacks any. The tool description does not clarify workspaceId, nor does it explicitly explain overridePolicy's purpose beyond what the schema already states. The mention of 'Refuses if policy findings are blocking' indirectly relates to policy, but does not map to parameter semantics. The description adds little value over the schema and fails to compensate for the missing workspaceId documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear action ('Sends the current plan for human approval') with the specific resource being the current plan. It also adds useful detail about the two delivery channels (Slack or CLI) and the refusal condition. It does not explicitly distinguish itself from tf_check_approval_status, but the mention of returning an approvalId to poll implies the next step, so the purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies it should be used after a plan exists and after policy checks (since it refuses on blocking findings). However, it does not explicitly state when to use it versus tf_plan, tf_policy_check, or tf_apply. It mentions returning an approvalId to poll, hinting at tf_check_approval_status but without naming it. This is enough to orient an agent but lacks explicit exclusions or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tf_workspace_initC
Checks out/copies a Terraform project into a sandboxed workdir.
| Name | Required | Description | Default |
|---|---|---|---|
| sourceDir | No | Local directory to copy .tf files from. Omit to just create an empty workspace. | |
| workspaceId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full burden of disclosing side effects and behavior. It says the tool copies/checks out a project into a sandboxed workdir, but it does not state whether an existing workdir is overwritten, whether this operation is destructive, what happens on re-initialization, or whether it creates a new workspace. The term 'sandboxed' hints at isolation but does not clarify the mutation profile.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single efficient sentence with no filler, and the primary action is front-loaded. It is appropriately short for a simple tool, though it is terse enough to omit valuable behavioral details. Structurally it earns its place without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no annotations, no output schema, and a non-trivial setup operation, the description is incomplete for safe and correct invocation. It does not explain what a successful initialization returns, how the workspaceId relates to the sandboxed workdir, or whether an empty workspace can be created (which the schema's sourceDir description does mention). An agent would need to infer too much about prerequisites and side effects.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 50%, and the description does not compensate for the gap. workspaceId has no description beyond a regex pattern, and the tool description does not clarify its role as the target workspace identifier. sourceDir is explained only in the schema, not in the tool description, so the description adds no parameter-level meaning beyond what structured fields already provide.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear action — checks out or copies a Terraform project into a sandboxed workdir — with a specific resource and destination. It distinguishes this setup tool from the planning/apply/write siblings by implying workspace preparation, though it does not explicitly name an alternative. The compound verb 'checks out/copies' is slightly ambiguous but still conveys the purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives such as tf_write_file or tf_plan. There is no mention of prerequisites, ordering, or exclusions. The only usage hint is the schema's note about omitting sourceDir to create an empty workspace, which is parameter-level guidance rather than tool-selection guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tf_write_fileA
Writes a .tf/.tfvars file into a sandboxed workspace (for agents with no native filesystem access).
| Name | Required | Description | Default |
|---|---|---|---|
| content | Yes | ||
| workspaceId | Yes | ||
| relativePath | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the behavioral disclosure burden. It discloses that writes go into a sandboxed workspace, which is useful, but it does not mention whether the write overwrites an existing file, how paths are validated, or what side effects occur. The core write behavior is clear, but edge behaviors are not.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence conveys the operation, resource type, and usage context with zero waste. The parenthetical adds relevant context without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple three-parameter write tool, the description gives enough to understand the primary action. However, it omits return value behavior, overwrite semantics, and path restrictions. Since there is no output schema and no annotations, these omissions are noticeable but not fatal for a straightforward write operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, but it gives no parameter-level detail. The parameter names (workspaceId, relativePath, content) are self-explanatory and the tool name reinforces the write-file purpose, but the description does not define path semantics or content formatting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb (Writes) and resource (.tf/.tfvars file), and scopes the write to a sandboxed workspace. This clearly differentiates it from all sibling tf_* workflow tools, none of which perform file writes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The parenthetical '(for agents with no native filesystem access)' gives an explicit condition for when this tool is appropriate. It does not name alternatives or exclusion cases, but no sibling tool competes for the same write-file role, so the guidance is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
9 tool updates
v0.1.0- First observed
tf_apply - First observed
tf_check_approval_status - First observed
tf_cost_estimate - First observed
tf_plan - First observed
tf_policy_check - First observed
tf_propose_change - First observed
tf_request_approval - First observed
tf_workspace_init - First observed
tf_write_file
TDQS
Scored across 9 tools
Each tool has a distinct role in the Terraform approval workflow: workspace setup, file writing, planning, policy/cost checks, bundled proposal, approval request, polling, and apply. The composite tf_propose_change is clearly described as an aggregate of the three analysis tools, so there is no real ambiguity about when to use it.
All tools share the tf_ prefix and snake_case style, making them recognizable as part of the same family. However, naming order is not perfectly uniform: tf_workspace_init, tf_policy_check, and tf_cost_estimate are object-first/noun phrases while tf_write_file, tf_propose_change, and tf_request_approval are verb-first.
9 tools is well-scoped for an approval-gate server covering workspace setup, plan analysis, policy/cost evaluation, human approval, and guarded apply. Each tool adds necessary functionality without redundancy or bloat.
The tool surface covers the full Terraform approval lifecycle: prepare workspace, write config, plan, run policy and cost checks, bundle results, request approval, poll for approval status, and apply with server-side validation. There are no obvious dead ends or missing operations for the stated domain.
Maintenance
Related MCP Connectors
Fail-closed policy guardrails for AI agents running kubectl, terraform, helm, and argocd.
Human-in-the-loop for AI coding agents — ask questions, get approvals via Slack.
Security reviews for coding agents: diffs checked against your org policy and live infrastructure.
Security gateway for AI agents: policy, approval, and audited execution, no secrets shared.
Related MCP Servers
- AlicenseAqualityAmaintenanceEnforces team knowledge and workflow policies for AI coding agents by providing context, decisions, and gates before code changes are made.164Apache 2.0
- AlicenseNot gradedqualityBmaintenanceAutonomous multi-agent pipeline that analyzes Terraform files for cost, governance, and compliance issues, providing real-time remediation and XAI console for human-in-the-loop approval.MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI coding agents to evaluate actions against team-defined policies, record decisions, and obtain human approvals for potentially risky operations.38 npm1-
- AlicenseAqualityBmaintenanceEnables AI agents to safely inspect and execute version-controlled operational runbooks with policy checks, dry-run planning, and out-of-band approvals.3MIT