# Hacer cambios

> Cómo van las escrituras: simular, enseñar el diff, confirmar con expected_version, resolver version_conflict y encontrar cada cambio en la auditoría.

Un asistente nunca cambia tu configuración en un solo paso. Cada escritura de configuración se simula primero, ves el diff, y solo una segunda llamada con la versión que viste la aplica. Si otra persona cambió la zona entretanto, no se aplica nada.

## Los argumentos de cada escritura

| Argumento | Qué es |
|---|---|
| `zone` | La zona, por dominio o por id |
| `reason` | Obligatorio, de 1 a 500 caracteres. Queda en la versión y en la auditoría |
| `confirm` | `false` por defecto: simular. `true`: aplicar |
| `expected_version` | La versión de la zona que devolvió la simulación. Obligatorio con `confirm: true` |

## Simular, revisar, confirmar

1. **Simular.** Con `confirm` falso (el valor por defecto) la herramienta ejecuta la escritura como prueba y **no aplica nada**. Devuelve `applied: false`, `current_version` (la versión actual de la zona), `new_version`, el plan completo (`plan`: diferencias y avisos) y qué llamar después. Si ya pasas `expected_version`, también se comprueba.
2. **Enseñar el diff.** El asistente tiene que enseñarte el plan antes de confirmar; las instrucciones del servidor y la descripción de cada herramienta se lo indican. Lee el diff: es exactamente lo que va a cambiar.
3. **Confirmar con la versión.** Con `confirm: true` la herramienta exige `expected_version` (sin ella, error `expected_version_required`) y se la envía a la API como `If-Match`. Si va bien: `applied: true`, `version` (la nueva) y `result` (la respuesta REST).


## Conflictos de versión

Si la zona cambió después de la simulación, no se aplica nada: la herramienta responde `version_conflict` (HTTP 412) con la `current_version`, y el texto pide volver a simular y revisar el plan nuevo.

```json
{"error":{"code":"version_conflict","message":"the configuration changed: the current version is 2"},"current_version":2,"status":412}
```

## Ejemplo

**Tú:** añade `www` apuntando a 192.0.2.10 en example.com

1. El asistente llama a `create_record` con `{"zone":"example.com","type":"A","name":"www","content":"192.0.2.10","reason":"alta de www desde MCP"}` y recibe:

   ```text
   Simulation only: nothing was applied. The zone is at version 1; applying creates version 2: 1 change:
   add "records[id=…]": {"content":"192.0.2.10",…,"name":"www.example.com",…,"type":"A"}
   To apply, call create_record again with the same arguments, confirm=true and expected_version=1.
   ```
2. Te enseña el cambio y tú confirmas.
3. Llama otra vez con `"confirm": true, "expected_version": 1` y recibe `Applied: the zone is now at version 2.`
4. Una segunda escritura con `expected_version: 1` falla con `version_conflict (HTTP 412): the configuration changed: the current version is 2` y la indicación de volver a simular.


## Excepciones

- `add_zone` no tiene versión previa: se confirma sin `expected_version`.
- `revert_zone` simula contra la versión actual si no se da `expected_version`.
- `check_zone` y `agent_readiness_scan` no cambian configuración: sin motivo ni confirmación.
- `purge_cache`, `create_origin_cert`, `revoke_origin_cert` y las de egress no son configuración versionada: `confirm=false` comprueba, `confirm=true` actúa, sin `expected_version`.

## Errores

Un fallo es un resultado con `isError: true` cuyo `structuredContent` es el sobre de error de la API más el estado HTTP, con los mismos códigos y mensajes que la API: `invalid` (con `field`), `reason_required`, `forbidden`, `not_found` (también para zonas de otra organización o fuera del ámbito del token), `zone_exists`, `missing_certs`, `org_suspended`, `unavailable`, etc. Los argumentos que no cumplen el esquema, como un tipo de registro desconocido o un motivo vacío, se rechazan antes de llamar a la API.

## Auditoría e historial

Los cambios hechos por MCP se auditan como los de la API: actor `token:<id>` y, en los datos de la entrada, `"channel": "mcp"` además de `reason`, `version` y `from_version`. El historial de versiones de la zona muestra el mismo actor y motivo. El propio asistente puede leerlos con `audit_log`, `zone_history` y `zone_diff`.

## Deshacer un cambio

`revert_zone` restaura la configuración de una versión anterior (registros, ajustes de borde y reglas) como una versión **nueva**; es destructiva porque deshace los cambios hechos después de esa versión. Sigue el mismo protocolo simular → confirmar, así que ves el diff antes de que se restaure nada.
