FlowFuse / FlowFuse/flowfuse

5.1-c Delete and destructive tools (phase 2)

Open
#7,686 0 comments 0 reactions 0 assignees View on GitHub
story
Dominant language
JavaScript
Stars
400
Forks
89
Avg merge
1d 20h
Merged PRs (30d)
149

Description

**Parent:** #7670 (5.1 Instance lifecycle and actions)
**Tool file:** `forge/ee/lib/mcp/tools/instances.js` (extend), `forge/ee/lib/mcp/tools/devices.js` (extend)

`destructiveHint: true`. Kept separate from ordinary writes so MCP clients gate them behind confirmation by default. Rollback lives here because it overwrites the running flows even though it is not a delete.

| Tool | Endpoint | Scope | Annotation |
|---|---|---|---|
| `platform_delete_instance` (`instanceType`: `hosted`\|`remote`) | hosted: `DELETE /projects/:id`; remote: `DELETE /devices/:id` | `project:delete` (hosted), `device:delete` (remote) | destructive |
| `platform_rollback_hosted_instance` | `POST /projects/:id/actions/rollback` | `project:snapshot:rollback` | destructive |

**Consolidation notes:**
- `platform_delete_instance` covers both hosted and remote instances through an `instanceType` discriminator, mirroring the read tools. It routes to `DELETE /projects/:id` (`project:delete`) or `DELETE /devices/:id` (`device:delete`) based on `instanceType`.

**Design notes:** rollback validates that the snapshot belongs to the instance; surface the validation error descriptively.

**Tool definitions (description + zod inputSchema):**
```js
platform_delete_instance: {
description: 'Permanently deletes an instance. instanceType selects whether instanceId is a hosted instance UUID or a remote instance (device) hashid.',
inputSchema: z.object({
instanceId: z.string().describe('Instance id: hosted instance UUID, or remote instance (device) hashid'),
instanceType: z.enum(['hosted', 'remote']).describe('Whether instanceId refers to a hosted instance or a remote instance (device)')
})
}

platform_rollback_hosted_instance: {
description: 'Rolls a hosted instance back to a snapshot, overwriting the running flows. The snapshot is validated to belong to the instance.',
inputSchema: z.object({
instanceId: z.string().uuid().describe('UUID of the hosted instance to roll back'),
snapshot: z.string().describe('Opaque hashid of the snapshot to roll back to')
})
}
```

**Tests:** every tool carries `destructiveHint: true`; read-only PAT rejected; `platform_delete_instance` routes by `instanceType`; rollback with a foreign snapshot returns the descriptive error.

---

Contributor guide

Open the contributing guide

Research direction

Start by reading forge/ee/lib/mcp/tools/instances.js and forge/ee/lib/mcp/tools/devices.js, especially the existing read tools and their authentication checks. Add the two destructive tools with the specified schemas, routes, scopes, annotations, and rollback validation, then run the MCP tool tests covering destructive hints, PAT rejection, instanceType routing, and foreign snapshots.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
api, backend, security
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.