Use-cases
When a Terraform workspace lock gets stuck (e.g. a run crashes or is interrupted and the lock isn't released, or the locking session times out without releasing), there is no way today to recover from inside an AI assistant context.
Operators have to leave their MCP-driven flow and either:
- Click "Force unlock" in the HCP Terraform/TFE UI, or
- Hand-roll
POST /api/v2/workspaces/:id/actions/force-unlock via curl with their TFE token.
Both options break the assistant loop and the second is the kind of action operators tend to get wrong under pressure (correct URL, correct headers, correct method on the right workspace ID).
Attempted Solutions
delete_workspace_safely doesn't apply — the workspace is healthy, just locked.
action_run (cancel/discard) only helps if the lock is held by a specific run that is still active. A stuck or orphaned lock can't be cleared this way.
- The go-tfe client already exposes the operation as
client.Workspaces.ForceUnlock(ctx, workspaceID), so it's a small wrap of an existing primitive.
We're already running a bespoke Lambda + Bedrock AgentCore gateway target internally at Aircall to expose this single operation. It would be much simpler to retire that and rely on a first-class tool here.
Proposal
Add a force_unlock_workspace MCP tool patterned on delete_workspace_safely:
- Input:
workspace_id (required, e.g. ws-abc123…).
- Behaviour: call
tfeClient.Workspaces.ForceUnlock(ctx, workspaceID).
- Annotations:
ReadOnlyHint=false, DestructiveHint=true, OpenWorldHint=true.
- Toolset:
Terraform.
- Gated behind
ENABLE_TF_OPERATIONS=true, same opt-in flag as delete_workspace_safely and action_run. Default off.
- TFE-side authorisation is enforced by the existing
can-force-unlock permission on the workspace, so the tool inherits that.
- Description should explicitly warn that force-unlocking while a run is still active can leave state inconsistent, and that the safe fallback is to cancel/discard the run via
action_run first.
Implementation is in PR #371.
Open questions for maintainers (happy to adjust in review):
- Input shape. I went with
workspace_id to match delete_workspace_safely and the underlying go-tfe API. get_workspace_details instead takes terraform_org_name + workspace_name. If maintainers would rather accept org+name here (the recovery use case often starts from a name, not an ID), I'll change it.
- Gating. Reusing
ENABLE_TF_OPERATIONS keeps the matrix simple. If a finer-grained flag is preferred (e.g. ENABLE_TF_FORCE_UNLOCK), happy to add it.
Use-cases
When a Terraform workspace lock gets stuck (e.g. a run crashes or is interrupted and the lock isn't released, or the locking session times out without releasing), there is no way today to recover from inside an AI assistant context.
Operators have to leave their MCP-driven flow and either:
POST /api/v2/workspaces/:id/actions/force-unlockvia curl with their TFE token.Both options break the assistant loop and the second is the kind of action operators tend to get wrong under pressure (correct URL, correct headers, correct method on the right workspace ID).
Attempted Solutions
delete_workspace_safelydoesn't apply — the workspace is healthy, just locked.action_run(cancel/discard) only helps if the lock is held by a specific run that is still active. A stuck or orphaned lock can't be cleared this way.client.Workspaces.ForceUnlock(ctx, workspaceID), so it's a small wrap of an existing primitive.We're already running a bespoke Lambda + Bedrock AgentCore gateway target internally at Aircall to expose this single operation. It would be much simpler to retire that and rely on a first-class tool here.
Proposal
Add a
force_unlock_workspaceMCP tool patterned ondelete_workspace_safely:workspace_id(required, e.g.ws-abc123…).tfeClient.Workspaces.ForceUnlock(ctx, workspaceID).ReadOnlyHint=false,DestructiveHint=true,OpenWorldHint=true.Terraform.ENABLE_TF_OPERATIONS=true, same opt-in flag asdelete_workspace_safelyandaction_run. Default off.can-force-unlockpermission on the workspace, so the tool inherits that.action_runfirst.Implementation is in PR #371.
Open questions for maintainers (happy to adjust in review):
workspace_idto matchdelete_workspace_safelyand the underlying go-tfe API.get_workspace_detailsinstead takesterraform_org_name+workspace_name. If maintainers would rather accept org+name here (the recovery use case often starts from a name, not an ID), I'll change it.ENABLE_TF_OPERATIONSkeeps the matrix simple. If a finer-grained flag is preferred (e.g.ENABLE_TF_FORCE_UNLOCK), happy to add it.