# MCP agent permissions

What an MCP agent can do: its human's permissions, scope by project and VPS, read-only mode and operations that are always forbidden.

Source: https://ardumaker.com/en/docs/permisos-mcp/

- Category: AI and agents
- Status: Available
- Requirements: An ArduMaker account that authorizes the agent; An agent connected to the MCP server (see [MCP server](https://ardumaker.com/en/docs/servidor-mcp))
- MCP tools (Read only): `ver_contexto_inicial`

## What can you do with it?

- Restrict an agent to certain projects and, separately, to certain VPS.
- Keep an agent read-only: it neither sees nor can call tools that modify data.
- Change the scope or mode from `/me` without reconnecting the agent, effective on its next call.
- Revoke one agent or all of them at once, instantly.
- Know in advance what the agent can edit or delete in a project, and why not.

## When should you use it?

- When connecting a new agent: start with the minimum scope, and read-only if it only has to diagnose.
- When an agent is going to work on a single VPS or a single project.
- If you suspect a credential leaked: revoke.

## How does it work in ArduMaker?

An agent's permission is the sum of three layers. All three end in “no”, but the reason differs and the answer says which:

| Layer | What it decides | Reason returned |
| --- | --- | --- |
| The person who authorized | The agent acts as that person: role in the company, in each project and access to each VPS (including the VPS allowed and excluded member lists) | `the human who authorized this agent is not an admin of this project` |
| The session | The scope chosen when approving: projects, VPS and read-only | `this agent was authorized with read-only scope` |
| MCP rules | Operations no agent can perform, whatever its scope | `no MCP agent can ever do this, whatever its scope` |

### Scope

- When approving, choose “all projects” or a list, and separately “all VPS” or a list. Each id is validated against what the person can see: an agent cannot get more access than its human.
- The scope is not frozen in the token: it is resolved live on every call. Reducing it from `/me` applies to the next call.
- A restricted scope with no ids is not accepted: to leave an agent without access, revoke it.

### Read-only

- The tool list only includes those that declare they only read.
- If it still calls one that writes, the call is rejected with `sin_permiso` and `reintentable: false`, and recorded as a rejection.
- The same rule applies to what the agent could touch through the REST API (terminals, Docker): a read-only agent does not modify a VPS by any path.
- When read-only is turned off, write tools work right away; a client that already loaded the list may need to reload it.

### What no agent can do

- Delete a whole project.
- Add or remove project members, or change their role.
- Create, edit or delete an attachment marked as secret (reading it is allowed if the person can).
- Delete a whole VPS.
- Create, edit or delete project roles, or change who has which permissions.
- Create, edit or sign a project's policies.
- Read or touch a project's finances: budgets, client payments, what each collaborator is paid and their receipts.
- Send WhatsApp messages to real numbers (sandbox only).

## What actually changes?

- The connection stores the scope (`alcance_todos`, `proyectos_permitidos`, `alcance_todos_vps`, `vps_permitidos`) and `solo_lectura`.
- Revoking marks the connection as revoked and also cuts the refresh token chain: the agent loses access instantly and cannot renew.
- Closing all sessions revokes every agent of the person.

## Guards and restricted tools

Some operations are allowed but require a confirmation in the arguments, so it is clear what is being destroyed:

| Operation | Guard |
| --- | --- |
| Critical DNS record (MX, NS, A/AAAA at the apex) | `confirmado=true`; without it, 409 |
| Delete a Linux user | `confirmacion` with the exact name; never `root` |
| Command with a destructive shape (`rm -rf`, `mkfs`, `shutdown`, `DROP DATABASE`…) | 409 with what matched; resend with `confirmado=true`. It guards against accidents, it is not a security boundary |
| `userdel` or `deluser` through the shell | Always rejected: the path is `eliminar_usuario_vps` |
| Delete a critical systemd service | Protected names (`ssh`, `nginx`, `docker`, `mysql`, `postgresql`…) |

There are also tools only for system administrators (internal bug inbox and school requests). They only show up if whoever authorized is a system admin, and that is checked live on every call: if the role is removed, the agent loses it instantly.

## Diagram

**Can the agent do this?**

```text
Does it exist over MCP? (if not: `never allowed`)
  ↓
Is the session read-only? (if it writes: rejection)
  ↓
Is it in scope? (allowed project and VPS)
  ↓
Can the person? (company, project and VPS role)
  ↓
Does it require confirmation? (`confirmado` / `confirmacion`)
```

## Expected result

- `ver_contexto_inicial` returns the scope (`solo_lectura`, `todos_los_proyectos`, `todos_los_vps`) and `nunca_permitido`.
- When viewing a project or task, the answer includes a permissions block with `editar`, `borrar` and, if something is `false`, the `motivo`.
- In `/me` each connection shows its scope, whether it is active and whether token reuse was detected (`reuse_detected_at`).

## Errors and troubleshooting

| Answer | Cause | What to do |
| --- | --- | --- |
| `sin_permiso` because of read-only | The session does not write | Tell the person: they turn it off in `/me`; retrying does not help |
| `sin_permiso` (403) | The person lacks that permission, or the resource is out of scope | Ask for the permission or widen the scope |
| `sin_permiso` (430) | System admin tool and whoever authorized is not one | There is no path |
| `conflicto` (409) | A guard's confirmation is missing | Review and resend with the confirmation |
| PATCH 400 in `/me` | Unknown field, invalid type or restricted scope with no ids | Fix the request |
| PATCH 409 in `/me` | The connection is revoked | Authorize again |

## MCP access

The scope is decided on the authorization screen and edited in `/me` (connected agents); there are no MCP tools to change the agent's own permissions. From the agent, `ver_contexto_inicial` is the way to know them before planning. More detail at [/mcp/docs](https://ardumaker.com/en/mcp/docs).

## Related features

- [MCP server](https://ardumaker.com/en/docs/servidor-mcp/)
- [Agent audit](https://ardumaker.com/en/docs/auditoria-de-agentes/)
- [Roles and permissions](https://ardumaker.com/en/docs/roles-y-permisos/)
- [Sessions and devices](https://ardumaker.com/en/docs/sesiones-y-dispositivos/)
