Facturiadocs
MCP / IA

Confirmaciones de dos pasos

Cuándo la aprobación del cliente MCP no basta, qué herramientas se pueden poner tras un segundo cerrojo y cómo se completa una acción pendiente.

El default: ejecución directa

Cuando un agente llama emit_document, emite.

Facturia no interpone su propio paso de aprobación, porque la UI de aprobación de herramientas del cliente MCP — eso que te muestra «Claude quiere llamar emit_document, ¿permitir?» — es el humano en el ciclo. Agregar una segunda confirmación del lado de Facturia sobre eso, para cada escritura, sería redundante en la enorme mayoría de las llamadas y derrotaría la mitad del punto de una interfaz de agente.

Dónde eso no alcanza

Existen dos modos de falla distintos, y la aprobación del cliente solo resuelve uno:

El agente intenta hacer algo que la persona no pidió. Lo resuelve el paso de aprobación del propio cliente — para eso existe exactamente.

La persona aprueba por reflejo todo lo que su cliente de chat le pregunta, y algo con consecuencia financiera real — declarar un formulario tributario, un reclamo irreversible — sale porque alguien hizo clic en «permitir» en piloto automático y no porque haya revisado deliberadamente esa cifra. La aprobación del cliente no resuelve esto: es el mismo clic en ambos casos.

require_confirmation ataca el segundo.

Encenderlo

Es una bandera por empresa en automation_settings, al lado de auto_emit_46 y compañía. Viene apagada, como toda automatización.

curl -X PATCH https://api.facturia.cl/v1/empresas/emp_01K2R6.../automation_settings \
  -H "Authorization: Bearer $FACTURIA_KEY" -H "Content-Type: application/json" \
  -d '{"require_confirmation": true}'

Es un campo REST, no un ajuste solo de MCP: los llamadores REST y el panel ven y controlan la misma bandera. La API REST descrita en el resto de esta documentación no cambia de comportamiento por encenderla.

Qué herramientas toca

emit_document, file_f29, emit_tipo46 y reclaim_received_document — el conjunto «emitir / declarar / reclamar».

Toda otra escritura (accept_received_document, y confirm_action misma) sigue siendo directa aunque la bandera esté encendida: aceptar ya coincide con el default legal que ocurriría por silencio de todas formas, así que ponerle un cerrojo no protege nada.

Cómo se ve

// → file_f29
{ "empresa": "77928532-4", "period": "2026-07", "confirm_total_payable": 1373000 }

// ← pending_confirmation (la empresa tiene require_confirmation: true)
{
  "status": "pending_confirmation",
  "confirmation_id": "conf_01K2SD3P7Q",
  "confirmation_url": "https://facturia.cl/confirm/conf_01K2SD3P7Q",
  "action": "file_f29",
  "summary": "File F29 for período 2026-07 — CLP 1.373.000 payable, due 2026-08-20.",
  "expires_at": "2026-08-14T14:45:00Z"
}

// … después, en la misma conversación o en otra …
// → confirm_action
{ "confirmation_id": "conf_01K2SD3P7Q" }

// ← el recurso que la llamada original habría devuelto directamente
{ "id": "f29fil_01K2RD9K3M8T", "object": "f29_filing", "period": "2026-07", "status": "queued", "declared": { "total_payable": 1373000 } }

Los dos caminos para completarla

Ambos son de primera clase, y el primero es el mecanismo que de verdad derrota el modo de falla 2:

El dueño de la cuenta abre confirmation_url en facturia.cl y confirma directo, sin cliente MCP, sin agente y sin transcripción de chat en el medio.

O, en conversación, el agente llama confirm_action(confirmation_id) una vez que la persona dio el visto bueno explícito, en la misma sesión o en una posterior.

`confirm_action` es idempotente

Una segunda llamada contra un id ya confirmado reproduce el resultado original en vez de ejecutar dos veces — la misma garantía que Idempotency-Key le da a un llamador REST.

Un confirmation_id vence a los 15 minutos sin recoger. Vencido, devuelve confirmation_expired y el llamador vuelve a hacer el borrador.

Sandbox: siempre directo

Trampa

`require_confirmation` no aplica en modo test, aunque esté encendida

Las empresas de sandbox son siempre de ejecución directa, incondicionalmente. No hay plata ni tráfico al SII que proteger en modo test, así que la bandera solo agregaría fricción al único flujo que existe justamente para no tener ninguna.

Si estás probando el doble paso, pruébalo contra una empresa live con la bandera encendida — en sandbox no lo vas a ver nunca.

Los estados que no son errores

Dos comportamientos de esta capa que conviene tener claros en el cliente:

  • Límite de tasa y confirmación pendiente no son fallas. El equivalente a un 429 y las respuestas pending_confirmation son resultados ordinarios de la herramienta con un campo status claro, no errores lanzados. Un agente debería leerlos y decidir qué decir a continuación, no tratarlos como algo roto.
  • Cada descripción de herramienta declara sus propios modos de falla probables. Un agente que elige entre emit_document y draft_document, o que decide si es seguro reintentar tras un sii_error, nunca debería tener que consultar documentación externa a media conversación. Por eso retriable viaja en cada motivo de rechazo.

En esta página