# Set owners and modes of files of a web hosting package

> Sets who owns the files and folders in a folder, and what others may do with them.

- Effect: Write - Changes the account. Agents ask first.
- Idempotent: yes
- Stability: beta
- MCP tool: `manitu_webhosting_web_permission_set` on https://mcp.manitu.de/mcp
- REST: `POST https://api.manitu.de/v1/webhosting/web/permission/set`
- Needs: `service_webhosting`
- Page: /reference/webhosting/web/permission/set/

**Changes the account. Agents say what will happen and wait for an explicit yes before calling it.**

## MCP tool

`manitu_webhosting_web_permission_set`

### Description for the model

Sets owners and modes of the files and folders in a folder of a web hosting package of the manitu customer account this connection works in, by its site_id from manitu_webhosting_list - the usual cure when PHP cannot write somewhere, or files were uploaded with the wrong owner: owner.user webserver (what PHP runs as) or user (an FTP or SSH user of the package, owner.username), owner.group webserver, mode.files and mode.folders optimal (owner and group may read and write, others nothing); keep leaves that part as it is. recursive (default true) includes every folder below. It runs in the background: follow it with manitu_workflow_get and its workflow_token. Refused with E2002 per field (directory_not_found, directory_has_symlink - it never follows a symbolic link, name the real folder -, not_found, nothing_to_do ...) or a conflict when one is running (workflow_running) or the package cannot be changed now (not_configurable). Tell the customer which folder and what changes, and ask for an explicit yes first.

### Arguments

- `site_id` (integer | string, required) - The site_id from manitu_webhosting_list - never guess one. (pattern `"^[1-9][0-9]*$"`; minimum `1`)
- `directory` (string, required) - The folder, relative to the package, e.g. /web or /web/wp-content. (minLength `1`; maxLength `255`)
- `recursive` (boolean) - Every folder below as well (default true).
- `owner` (object)
  - `owner.user` (string) - keep (default), webserver or user. (one of `"keep"`, `"webserver"`, `"user"`)
  - `owner.username` (string) - For user user: an FTP or SSH user of the package (ftp..., ssh...). (minLength `1`; maxLength `64`)
  - `owner.group` (string) - keep (default) or webserver. (one of `"keep"`, `"webserver"`)
- `mode` (object)
  - `mode.files` (string) - keep (default) or optimal. (one of `"keep"`, `"optimal"`)
  - `mode.folders` (string) - keep (default) or optimal. (one of `"keep"`, `"optimal"`)

### Example

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "manitu_webhosting_web_permission_set",
    "arguments": {
      "site_id": 12345,
      "directory": "string"
    }
  }
}
```

## REST

`POST https://api.manitu.de/v1/webhosting/web/permission/set`

### Authentication

One of `X-API-Key`, `Authorization: Bearer …` - never more than one in a request.

### Request body

JSON; unknown fields are refused.

- `site_id` (integer | string, required) - The site_id from manitu_webhosting_list - never guess one. (pattern `"^[1-9][0-9]*$"`; minimum `1`)
- `directory` (string, required) - The folder, relative to the package, e.g. /web or /web/wp-content. (minLength `1`; maxLength `255`)
- `recursive` (boolean) - Every folder below as well (default true).
- `owner` (object)
  - `owner.user` (string) - keep (default), webserver or user. (one of `"keep"`, `"webserver"`, `"user"`)
  - `owner.username` (string) - For user user: an FTP or SSH user of the package (ftp..., ssh...). (minLength `1`; maxLength `64`)
  - `owner.group` (string) - keep (default) or webserver. (one of `"keep"`, `"webserver"`)
- `mode` (object)
  - `mode.files` (string) - keep (default) or optimal. (one of `"keep"`, `"optimal"`)
  - `mode.folders` (string) - keep (default) or optimal. (one of `"keep"`, `"optimal"`)

### Response

In `data`; the rest of the body as on every call.

- `workflow` (string | null, required) - What is being done, e.g. power_reboot or ngcobalt_site_web_database_copy. (one of `"create"`, `"destroy"`, `"power_start"`, `"power_stop"`, `"power_reboot"`, `"reinstall"`, `"ptr_set"`, `"vnc_enable"`, `"vnc_disable"`, `"rescuesystem_enable"`, `"rescuesystem_disable"`, `"snapshot_create"`, `"snapshot_delete"`, `"snapshot_delete_all"`, `"snapshot_revert"`, `"telemetry_await"`, `"iso_eject"`, `"none"`, `"account_contract_termination_finish"`, `"ngcobalt_site_web_application_installation_set"`, `"ngcobalt_site_web_application_installation_update"`, `"ngcobalt_site_web_permission_set"`, `"ngcobalt_site_web_database_copy"`, `"network_librenms_discover"`, `null`)
- `workflow_id` (string | null, required) - The id of this run, as vserver/workflow/list names it; null for a workflow not kept as tasks.
- `status` (string, required) - pending: waiting to start; running: started, not finished (can take a while); done: finished, everything went through; error: finished, but it or part of it failed. (one of `"pending"`, `"running"`, `"done"`, `"error"`)
- `created_at` (string | null, required) - When it was asked for. (format `date-time`)
- `started_at` (string | null, required) - When it started; null while pending, and for a workflow that does not record it. (format `date-time`)
- `ended_at` (string | null, required) - When it finished; null until then. (format `date-time`)
- `updated_at` (string | null, required) - When it last changed. (format `date-time`)
- `workflow_token` (string | null, required) - Pass it to manitu_workflow_get to see how far the workflow is - as it is, never built or changed. A secret of this workflow: do not show it to anyone. null if there is none.
- `directory` (string, required) - The folder, as the backend took it.

### Statuses

- `200` Success.
- `400` The request does not match the declared input schema.
- `401` No credential was presented, or it was not recognised.
- `403` The credential is not permitted to use this operation.
- `500` The server failed. Nothing about the request was wrong. Whether a change took effect is not known - check before trying it again.
- `503` The channel this operation forwards through is unavailable.

### Example

```sh
curl -X POST 'https://api.manitu.de/v1/webhosting/web/permission/set' \
  -H 'X-API-Key: $API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"site_id":12345,"directory":"string"}'
```

## Example result

```json
{
  "workflow": "create",
  "workflow_id": "string",
  "status": "pending",
  "created_at": "2026-10-23T12:00:00+02:00",
  "started_at": "2026-10-23T12:00:00+02:00",
  "ended_at": "2026-10-23T12:00:00+02:00",
  "updated_at": "2026-10-23T12:00:00+02:00",
  "workflow_token": "eyJwYWdlIjoyfQ",
  "directory": "string"
}
```
