Referencia de herramientas MCP
Herramientas, operaciones, scopes y permisos de los servidores MCP: aplicaciones externas y credenciales, CRM, Finanzas y RRHH.
Actualizado el . 80 min de lectura
Esta referencia reúne el contrato de las herramientas MCP que más usan los integradores: las cuatro del dominio de integraciones (aplicaciones externas, credenciales, ajustes de integración de la organización y estado del dominio), las ampliaciones del CRM, el servidor de Finanzas y el calendario laboral de RRHH. Para cada operación indica el permiso que necesita tu usuario, el scope que necesita el token y si exige confirmación.
Otras herramientas tienen página propia: Marketing, tickets, AI Studio y el buscador global y los avisos. Si es tu primera conexión, empieza por Primeros pasos con MCP.
Cómo se autoriza cada operación
Cada operación pasa por estas comprobaciones, en este orden. Las tablas de esta página dan, para cada una, el permiso, el scope y si exige confirm.
Qué comprueba el servidor en cada operación
Tu organización
Aplicativo en el plan
Ningún permiso ni scope lo sustituye.Si no: no se anuncia y se rechaza con MODULE_NOT_ENABLED o CAPABILITY_NOT_ENABLED.
El token
Scope de la operación
Ver la herramienta en tools/list no basta para ejecutar todas sus operaciones.Si no: INSUFFICIENT_SCOPE, que nombra el scope y el conjunto más pequeño que lo concede.
Tu usuario
Permiso de la operación
Si la tabla da dos permisos separados por «o», basta con uno.Si no: errorCode PERMISSION_DENIED con el nombre del permiso que falta.
La llamada · Opcional
Confirmación
Solo en las operaciones que borran, rotan secretos o no se pueden deshacer: confirm: true.Si no: se rechaza sin tocar nada.
Tu alcance
Ejecución
Sobre las filas que tu alcance te deja ver, igual que en la aplicación.
Aplicaciones externas y credenciales
Cuatro herramientas cubren el dominio de integraciones:
| Herramienta | Servidor | Operaciones | Para qué sirve |
|---|---|---|---|
integrations | utilia-work | 61 | Aplicaciones externas: ciclo de vida, persona responsable, renovación de claves sin cortes, OAuth saliente, webhooks, métricas de uso de la API, facturación por aplicación, los errores que reporta cada una, verificación del widget y el catálogo de aplicaciones (explorar, pedir que instalen y las instaladas) |
api_credentials | utilia-work | 17 | Claves de API de la organización (utk_) y credenciales personales y de aplicación |
org_integrations_settings | utilia-crm | 32 | Claves de API v1 de la organización, formularios de captación y otros ajustes de integración |
integrations_overview | utilia-work | 4 | Estado del dominio en una sola llamada y el diagnóstico de cada aplicación, de solo lectura |
En la aplicación, las aplicaciones externas se gestionan en Ajustes › Creadas por tu empresa, necesitas entrar con tu cuenta.
integrations
Es la herramienta con la que registras tu propia integración, la suscribes a eventos y vigilas su salud. También explora el catálogo de aplicaciones y gestiona las que tu empresa tiene instaladas.
| Operación | Qué hace | Permiso | Scope | confirm |
|---|---|---|---|---|
apps_list | Lista las aplicaciones externas de la organización, paginadas. Con deletedOnly: true, solo las eliminadas. | INTEGRATIONS_APPS_VIEW o EXTERNAL_APPS_VIEW | integrations:apps:view | no |
apps_get | Detalle de una aplicación. | INTEGRATIONS_APPS_VIEW o EXTERNAL_APPS_VIEW | integrations:apps:view | no |
apps_create | Crea una aplicación. Devuelve su clave y su secreto de webhook una sola vez. | INTEGRATIONS_APPS_MANAGE o EXTERNAL_APPS_CREATE | integrations:apps:manage | no |
apps_update | Cambia los datos descriptivos de la aplicación. | INTEGRATIONS_APPS_MANAGE o EXTERNAL_APPS_EDIT | integrations:apps:manage | no |
apps_delete | Elimina la aplicación: deja de funcionar y desaparece de la lista, pero se conserva todo y se puede restaurar. No se puede con suscripciones o cobros programados en marcha. | EXTERNAL_APPS_DELETE | integrations:apps:manage | sí |
apps_restore | Restaura una aplicación eliminada. Vuelve desactivada: actívala con apps_toggle_active. | EXTERNAL_APPS_DELETE | integrations:apps:manage | sí |
apps_delete_permanently | Borra la aplicación para siempre y conserva lo que obliga la ley: facturas, suscripciones, autorizaciones de cobro, tickets, fichas del CRM y archivos. Exige además confirmName, con su nombre exacto. | EXTERNAL_APPS_DELETE | integrations:apps:manage | sí |
apps_toggle_active | Activa o desactiva la aplicación sin borrarla. | INTEGRATIONS_APPS_MANAGE o EXTERNAL_APPS_EDIT | integrations:apps:manage | sí |
apps_regenerate_api_key | Renueva la clave de API de la aplicación. Con graceDays (1, 7 o 30) la anterior sigue valiendo esos días; con 0, el valor por defecto, deja de valer en el acto. | INTEGRATIONS_APPS_MANAGE o EXTERNAL_APPS_EDIT | integrations:apps:manage | sí |
apps_api_key_retire_previous | Retira ya la clave de API anterior: deja de valer en el acto. | INTEGRATIONS_APPS_MANAGE o EXTERNAL_APPS_EDIT | integrations:apps:manage | sí |
apps_api_key_advisory_dismiss | Descarta una recomendación de renovar la clave de API, con un motivo de 20 a 500 caracteres. No se puede deshacer. | INTEGRATIONS_APPS_MANAGE o EXTERNAL_APPS_EDIT | integrations:apps:manage | sí |
apps_set_responsible | Nombra la persona responsable de la aplicación. Solo un Super Administrador nombra a otra persona; el resto, solo a sí mismo. | INTEGRATIONS_APPS_MANAGE o EXTERNAL_APPS_EDIT | integrations:apps:manage | sí |
apps_list_responsible_candidates | Personas que se pueden nombrar responsables, con la misma regla. | INTEGRATIONS_APPS_MANAGE o EXTERNAL_APPS_EDIT | integrations:apps:manage | no |
apps_update_scopes | Sustituye el conjunto entero de scopes de la aplicación y deja el cambio en el registro de auditoría. Añadir scopes críticos de datos personales exige el rol Super Administrador y un reason de al menos 20 caracteres. | INTEGRATIONS_APPS_MANAGE o EXTERNAL_APPS_EDIT | integrations:apps:manage | sí |
apps_get_stats | Resumen de la aplicación: clave, webhook, usuarios externos y entregas. | INTEGRATIONS_APPS_VIEW o EXTERNAL_APPS_VIEW | integrations:apps:view | no |
apps_list_users | Usuarios externos que ha registrado la aplicación. | INTEGRATIONS_APPS_VIEW o EXTERNAL_APPS_VIEW | integrations:apps:view | no |
apps_oauth_get | Configuración OAuth saliente de la aplicación. | INTEGRATIONS_APPS_VIEW, EXTERNAL_APPS_VIEW u OAUTH_APPS_VIEW | integrations:apps:view | no |
apps_oauth_enable | Activa el OAuth saliente. | OAUTH_APPS_MANAGE o INTEGRATIONS_APPS_MANAGE | integrations:apps:manage | sí |
apps_oauth_update | Cambia la configuración OAuth. | OAUTH_APPS_MANAGE o INTEGRATIONS_APPS_MANAGE | integrations:apps:manage | no |
apps_oauth_disable | Desactiva el OAuth saliente y conserva el historial de tokens. | OAUTH_APPS_MANAGE o INTEGRATIONS_APPS_MANAGE | integrations:apps:manage | sí |
apps_oauth_regenerate_secret | Renueva el secreto de cliente OAuth. | OAUTH_APPS_MANAGE o INTEGRATIONS_APPS_MANAGE | integrations:apps:manage | sí |
apps_webhooks_get_config | Configuración actual del webhook. | INTEGRATIONS_APPS_VIEW o EXTERNAL_APPS_VIEW | integrations:apps:webhooks:view | no |
apps_webhooks_update_config | Cambia webhookUrl, webhookEvents y webhookEnabled. | INTEGRATIONS_WEBHOOKS_MANAGE o EXTERNAL_APPS_EDIT | integrations:apps:webhooks:manage | no |
apps_webhooks_regenerate_secret | Renueva la clave con la que se firman los avisos. Con graceDays (1, 7 o 30), cada aviso lleva también la firma de la anterior esos días. | INTEGRATIONS_WEBHOOKS_MANAGE o EXTERNAL_APPS_EDIT | integrations:apps:webhooks:manage | sí |
apps_webhooks_secret_cutover | Indica que el servidor ya usa la clave de firma nueva: X-Utilia-Signature pasa a ir firmada con ella. | INTEGRATIONS_WEBHOOKS_MANAGE o EXTERNAL_APPS_EDIT | integrations:apps:webhooks:manage | sí |
apps_webhooks_secret_retire_previous | Retira ya la clave de firma anterior: deja de enviarse su firma. | INTEGRATIONS_WEBHOOKS_MANAGE o EXTERNAL_APPS_EDIT | integrations:apps:webhooks:manage | sí |
apps_webhooks_secret_advisory_dismiss | Descarta una recomendación de renovar la clave de firma, con un motivo de 20 a 500 caracteres. No se puede deshacer. | INTEGRATIONS_WEBHOOKS_MANAGE o EXTERNAL_APPS_EDIT | integrations:apps:webhooks:manage | sí |
apps_webhooks_test | Envía una entrega de prueba, firmada igual que las reales. Si los webhooks están desactivados, no envía nada y lo dice. Con secret: 'current' prueba la clave nueva: primero un aviso con una firma falsa y después otro firmado solo con la vigente. Con event (por ejemplo, INVOICE_CREATED), envía una muestra de ese evento con su forma real, marcada con livemode: false y meta.test: true, que no queda en el historial de entregas. | INTEGRATIONS_WEBHOOKS_MANAGE o EXTERNAL_APPS_EDIT | integrations:apps:webhooks:manage | no |
apps_webhooks_list_deliveries | Historial de entregas, con filtros. | INTEGRATIONS_APPS_VIEW o EXTERNAL_APPS_VIEW | integrations:apps:webhooks:view | no |
apps_webhooks_get_delivery | Detalle de una entrega. | INTEGRATIONS_APPS_VIEW o EXTERNAL_APPS_VIEW | integrations:apps:webhooks:view | no |
apps_webhooks_retry_delivery | Vuelve a encolar una entrega FAILED o FAILED_PERMANENTLY. | INTEGRATIONS_WEBHOOKS_MANAGE o EXTERNAL_APPS_EDIT | integrations:apps:webhooks:manage | sí |
apps_webhooks_list_supported_events | Catálogo de eventos a los que se puede suscribir. | INTEGRATIONS_APPS_VIEW o EXTERNAL_APPS_VIEW | integrations:apps:webhooks:view | no |
apps_metrics_requests | Serie temporal de peticiones a la API externa. | INTEGRATIONS_METRICS_VIEW o EXTERNAL_APPS_VIEW | integrations:apps:metrics:view | no |
apps_metrics_latency | Latencia agregada (p50, p95 y p99). | INTEGRATIONS_METRICS_VIEW o EXTERNAL_APPS_VIEW | integrations:apps:metrics:view | no |
apps_metrics_errors | Errores por código de estado. | INTEGRATIONS_METRICS_VIEW o EXTERNAL_APPS_VIEW | integrations:apps:metrics:view | no |
apps_metrics_top_endpoints | Endpoints más usados. | INTEGRATIONS_METRICS_VIEW o EXTERNAL_APPS_VIEW | integrations:apps:metrics:view | no |
apps_metrics_webhooks_health | Salud de los webhooks de la aplicación. | INTEGRATIONS_METRICS_VIEW o EXTERNAL_APPS_VIEW | integrations:apps:metrics:view | no |
apps_billing_get_config | Configuración de facturación de la aplicación. | INTEGRATIONS_BILLING_MANAGE o EXTERNAL_APPS_VIEW | integrations:apps:billing:view | no |
apps_billing_update_config | Activa o desactiva la facturación de la aplicación. | INTEGRATIONS_BILLING_MANAGE o EXTERNAL_APPS_EDIT | integrations:apps:billing:manage | sí |
apps_billing_list_invoices | Facturas generadas para la aplicación. | INTEGRATIONS_BILLING_MANAGE o EXTERNAL_APPS_VIEW | integrations:apps:billing:view | no |
apps_billing_list_payments | Cobros de la aplicación. | INTEGRATIONS_BILLING_MANAGE o EXTERNAL_APPS_VIEW | integrations:apps:billing:view | no |
apps_widget_identity_get | Modo de la verificación de identidad del widget (OFF, REPORT o REQUIRED) y si la aplicación tiene secreto del widget. El secreto no sale nunca por aquí. | EXTERNAL_APPS_VIEW | integrations:apps:view | no |
apps_widget_identity_update | Cambia el modo de la verificación. Con REQUIRED y sin secreto, el widget deja de identificar a nadie. | EXTERNAL_APPS_EDIT | integrations:apps:manage | sí |
apps_widget_identity_regenerate_secret | Genera o renueva el secreto del widget; el anterior deja de valer en el acto. El secreto se devuelve una sola vez. Pide confirmación en el móvil. | EXTERNAL_APPS_EDIT | integrations:apps:manage | sí |
catalog_list | Fichas del catálogo de aplicaciones que puede instalar tu empresa, con búsqueda y categoría, y la dirección de cada ficha. | Ninguno: basta Integraciones en el plan | integrations:apps:view | no |
catalog_get | Una ficha del catálogo, con sus permisos, sus aplicativos y su dirección. Las «Solo con el enlace» se abren con su dirección exacta. | Ninguno: basta Integraciones en el plan | integrations:apps:view | no |
catalog_request_install | Pide que instalen una aplicación, con un mensaje opcional: avisa a quien puede instalar. Pedirla otra vez no es un error. | Ninguno: basta Integraciones en el plan | integrations:apps:manage | sí |
installations_list | Las aplicaciones instaladas en tu empresa, con su estado, su persona responsable, lo que piden y, en las de pago, su suscripción (el importe, solo con SETTINGS_ORGANIZATION_VIEW). | INTEGRATIONS_APPS_INSTALL o EXTERNAL_APPS_VIEW | integrations:apps:view | no |
installations_get | Detalle de una instalada, con su suscripción si es de pago (el importe, solo con SETTINGS_ORGANIZATION_VIEW). | INTEGRATIONS_APPS_INSTALL o EXTERNAL_APPS_VIEW | integrations:apps:view | no |
installations_uninstall | Desinstala una aplicación, con un motivo opcional que se le cuenta al desarrollador. Pierde el acceso en el acto; lo que creó se queda. | INTEGRATIONS_APPS_INSTALL | integrations:apps:manage | sí |
installations_change_responsible | Cambia la persona responsable de una instalada. Tiene que tener los permisos que usa la aplicación y no ver más datos que quien la nombra. | INTEGRATIONS_APPS_INSTALL | integrations:apps:manage | sí |
installations_cancel_subscription | Cancela la suscripción de una aplicación de pago: sigue funcionando hasta el final del periodo pagado o de la prueba y no se renueva; con un pago pendiente, termina ya. No se devuelve nada. Deshacerlo se hace en la pantalla. | INTEGRATIONS_APPS_INSTALL o SETTINGS_ORGANIZATION_EDIT | integrations:apps:manage | sí |
apps_errors_list | Grupos de errores que ha reportado una aplicación o, sin id, todas las activas de la organización. Por defecto, los activos. | EXTERNAL_APPS_ERRORS_VIEW | integrations:apps:errors:view | no |
apps_errors_get | Detalle de un grupo de errores (id de la aplicación y hash). | EXTERNAL_APPS_ERRORS_VIEW | integrations:apps:errors:view | no |
apps_errors_stats | Cifras y salud de los errores, de una aplicación o de todas. | EXTERNAL_APPS_ERRORS_VIEW | integrations:apps:errors:view | no |
apps_errors_resolve | Resuelve un grupo, con una nota opcional. Si el error vuelve a ocurrir, se reabre solo. | EXTERNAL_APPS_ERRORS_MANAGE | integrations:apps:errors:manage | no |
apps_errors_reopen | Reabre un grupo resuelto. | EXTERNAL_APPS_ERRORS_MANAGE | integrations:apps:errors:manage | no |
apps_errors_silence | Silencia un grupo de 1 a 672 horas. | EXTERNAL_APPS_ERRORS_MANAGE | integrations:apps:errors:manage | no |
apps_errors_unsilence | Le quita el silencio. | EXTERNAL_APPS_ERRORS_MANAGE | integrations:apps:errors:manage | no |
apps_errors_bulk | Resuelve, reabre o silencia varios grupos de una vez. | EXTERNAL_APPS_ERRORS_MANAGE | integrations:apps:errors:manage | no |
apps_errors_link | Crea un ticket de soporte o una tarea de Gestión de proyectos desde el error y los deja vinculados. Exige además poder crear en el destino. | EXTERNAL_APPS_ERRORS_MANAGE | integrations:apps:errors:manage | no |
Instalar una aplicación del catálogo no se hace por MCP: exige que una persona vea la ficha, acepte sus permisos y elija la persona responsable. Tampoco comprar una de pago, cambiar de plan, reactivar la suscripción ni pagar un cobro pendiente: piden consentimiento y pago en pantalla. Las fichas que publica una cuenta de desarrollador se gestionan en el servidor de desarrolladores, no aquí. catalog_list y catalog_get devuelven la dirección de la ficha para que el asistente te ofrezca abrirla. Lo que hace la empresa está en Explorar e instalar aplicaciones.
Las renovaciones (apps_regenerate_api_key, apps_webhooks_regenerate_secret y apps_widget_identity_regenerate_secret) piden a la persona, si tiene la verificación en dos pasos, que las confirme en el móvil: la primera llamada responde APPROVAL_REQUIRED con un número, la persona elige ese número en la aplicación y la llamada se repite igual, con twoFactorApprovalId. Por MCP nunca se aceptan códigos. La aplicación de iPhone que hay hoy en la App Store todavía no aprueba estas confirmaciones; hasta que llegue la próxima versión, quien tenga la verificación activada renueva las claves desde la ficha de la aplicación, con su código. La clave nueva se devuelve una sola vez y no se guarda en ninguna parte.
El SDK de JavaScript no tiene todavía un método para apps_update_scopes (appsUpdate solo cambia los datos descriptivos): para sustituir los scopes de una aplicación, invoca la herramienta por JSON-RPC.
Ejemplo: crear una aplicación y configurar su webhook. Los SDK necesitan una sesión OAuth autorizada para el servidor utilia-work, como se explica en Primeros pasos con MCP.
const created = await sdk.mcp.integrations.appsCreate({
name: 'Mi integración',
slug: 'mi-integracion',
description: 'Integración personalizada.',
websiteUrl: 'https://miempresa.com',
});
await sdk.mcp.integrations.appsWebhooksUpdateConfig(created.app.id, {
webhookUrl: 'https://miempresa.com/webhooks/utilia',
webhookEnabled: true,
webhookEvents: ['TICKET_CREATED', 'INVOICE_PAID'],
});
const test = await sdk.mcp.integrations.appsWebhooksTest(created.app.id);
console.log(test.success ? `Entregado: ${test.statusCode}` : test.error);Cómo verificar en tu servidor la firma de las entregas se explica en Firma HMAC de los webhooks.
api_credentials
Gestiona las claves de API de tu organización. Con ella un asistente de IA puede hacer todo lo que se hace en Ajustes, Claves de API, con las mismas reglas y, para lo delicado, con tu confirmación en el móvil.
Claves de API de la organización (utk_, 10). Son las de Claves de API de la organización: cada una actúa en nombre de una persona responsable y nunca puede más que ella. Las operaciones org_keys_* llaman al mismo servicio que la pantalla, así que se aplican igual:
- la persona responsable;
- el techo de permisos y el plan de cada módulo;
- la regla de que solo un Super Administrador nombra responsable a otra persona;
- el modo restringido y la auditoría.
| Operación | Qué hace | Permiso | Scope | confirm |
|---|---|---|---|---|
org_keys_list | Lista las claves, con persona responsable, permisos y estado. | API_CREDENTIALS_VIEW o API_CREDENTIALS_MANAGE | integrations:credentials:view | no |
org_keys_get | Ficha de una clave, con lo que puede hacer hoy módulo a módulo. | API_CREDENTIALS_VIEW o API_CREDENTIALS_MANAGE | integrations:credentials:view | no |
org_keys_usage | Peticiones de las últimas 24 horas y 7 días, por hora y por ruta. | API_CREDENTIALS_VIEW o API_CREDENTIALS_MANAGE | integrations:credentials:view | no |
org_keys_catalog | Módulos que se pueden dar a una clave para una persona (responsibleUserId). | API_CREDENTIALS_MANAGE | integrations:credentials:view | no |
org_keys_candidates | A quién se puede nombrar persona responsable. | API_CREDENTIALS_MANAGE | integrations:credentials:view | no |
org_keys_create | Crea una clave con name, permissionMode (ALL, READ_ONLY o RESTRICTED con moduleAccess) y, si quieres, responsibleUserId, expiresAt, rateLimitPerHour y description. La clave sale entera una sola vez. Pide confirmación en el móvil. | API_CREDENTIALS_MANAGE | integrations:credentials:manage | sí |
org_keys_update | Cambia nombre, descripción, límite, permisos, caducidad o persona responsable. Estrechar no pide nada; ampliar permisos, alargar o quitar la caducidad o cambiar de responsable piden confirmación en el móvil. | API_CREDENTIALS_MANAGE | integrations:credentials:manage | no |
org_keys_rotate | Renueva la clave. graceDays dice cuántos días sigue valiendo la anterior: 1, 7 o 30, o 0 para cortarla en el acto. Pide confirmación en el móvil. | API_CREDENTIALS_MANAGE | integrations:credentials:manage | sí |
org_keys_end_transition | La anterior de una renovación deja de valer ya. | API_CREDENTIALS_MANAGE | integrations:credentials:manage | sí |
org_keys_revoke | Revoca la clave y su anterior al momento, con un reason opcional. | API_CREDENTIALS_MANAGE, o ser su persona responsable | integrations:credentials:manage | sí |
Crear, cambiar y renovar exigen además Integraciones en el plan; ver y revocar, no. La persona responsable puede revocar su clave aunque no gestione claves, pero el asistente necesita el scope integrations:credentials:manage, y ese scope solo puede autorizarlo quien gestiona claves. Si no lo tiene, que la revoque desde la pantalla.
Lo que fabrica o amplía acceso se confirma en el móvil. Crear, renovar, ampliar permisos, alargar o quitar la caducidad y cambiar de responsable siguen el ciclo de siempre:
- La primera llamada devuelve
errorCode: APPROVAL_REQUIRED. - El móvil enseña qué clave es, a nombre de quién y con qué permisos.
- Cuando la persona lo aprueba, repites la misma llamada, con los mismos datos y con
twoFactorApprovalId.
La confirmación solo vale para esa clave con esos datos: una instrucción escondida en un documento no basta para fabricar una clave. Sin la verificación en dos pasos activada, estas operaciones se rechazan con TWO_FACTOR_NOT_ENABLED.
Las operaciones generales (list, get, get_usage, rotate y revoke) no tocan estas claves. list no las enseña y avisa de cuántas hay; las demás remiten a su operación org_keys_*.
Credenciales personales y de aplicación (7). Son las credenciales de un usuario (PERSONAL) y las recortadas de una aplicación externa (EXTERNAL_APP). Las de cuenta de servicio (SERVICE_ACCOUNT) ya no se crean, porque no sirven para entrar en ningún sitio. Para conectar un programa, usa org_keys_create. Al rotar, el secreto nuevo se muestra una sola vez y el anterior sigue valiendo 24 horas.
| Operación | Qué hace | Permiso | Scope | confirm |
|---|---|---|---|---|
list | Lista credenciales con filtros por tipo, estado y aplicación. | API_CREDENTIALS_MANAGE | integrations:credentials:view | no |
get | Detalle de una credencial. | API_CREDENTIALS_MANAGE | integrations:credentials:view | no |
get_usage | Uso de la credencial: peticiones, último uso y veces que tocó el límite. | API_CREDENTIALS_MANAGE | integrations:credentials:view | no |
create | Crea una credencial. Devuelve el secreto una sola vez. Pide confirmación en el móvil. | API_CREDENTIALS_MANAGE | integrations:credentials:manage | sí |
rotate | Renueva el secreto; el anterior sigue valiendo 24 horas. Pide confirmación en el móvil. | API_CREDENTIALS_MANAGE | integrations:credentials:manage | sí |
revoke | Revoca la credencial al momento, sin gracia. | API_CREDENTIALS_MANAGE | integrations:credentials:manage | sí |
scopes_catalog | Catálogo de scopes v2 disponibles. | API_CREDENTIALS_MANAGE | integrations:credentials:view | no |
Estas siete aceptan también SETTINGS_ORGANIZATION_EDIT en lugar de API_CREDENTIALS_MANAGE: basta con uno de los dos.
Reglas de create y rotate:
- Nadie da a una credencial lo que no tiene. Si no eres Super Administrador, solo puedes conceder scopes cuyo permiso tienes. Si pides alguno más, la llamada se rechaza con
errorCode: CREDENTIAL_SCOPE_AUTHORITY_EXCEEDEDy el mensaje dice cuáles sobran. El acceso total (*) solo lo concede el Super Administrador. Esto se comprueba antes de pedir la confirmación, para que nadie apruebe en el móvil algo que se va a rechazar. - Confirmación en el móvil, con el mismo ciclo de
APPROVAL_REQUIREDytwoFactorApprovalId. Exige tener la verificación en dos pasos activada. - Con la organización en modo restringido no se crea ninguna credencial; consultarlas y revocarlas sigue funcionando.
const { secret, previousValidUntil } = await sdk.mcp.apiCredentials.rotate(
credentialId,
{ reason: 'Rotación trimestral' },
);
console.log('Secreto nuevo:', secret);
console.log('El anterior vale hasta:', previousValidUntil);org_integrations_settings
Agrupa ajustes de integración de la organización anteriores al dominio de aplicaciones externas. Vive en el servidor utilia-crm. Si vienes de una versión antigua de los SDK, esta herramienta es la que antes se llamaba integrations: consulta la guía de migración.
La herramienta aparece en tools/list con los conjuntos crm:read, crm:full, dev:read o dev:full, o con cualquier scope de lectura del CRM, pero cada operación exige además su propio scope, que es el de la tabla.
Claves de API v1 de la organización (8). Además del permiso, la clave tiene que haberla creado tu usuario y pertenecer a tu organización.
| Operación | Qué hace | Permiso | Scope | confirm |
|---|---|---|---|---|
api_keys_list | Lista tus claves de API v1. | INTEGRATIONS_APPS_VIEW o API_CREDENTIALS_MANAGE | integrations:credentials:view | no |
api_keys_get | Detalle de una clave. | INTEGRATIONS_APPS_VIEW o API_CREDENTIALS_MANAGE | integrations:credentials:view | no |
api_keys_create | Crea una clave con name y, si quieres, description, rateLimit (llamadas por hora, de 10 a 10.000; 100 si lo omites) y expiresAt. Devuelve la clave una sola vez. Pide confirmación en el móvil. | API_CREDENTIALS_MANAGE, con alcance «Todo» | integrations:credentials:manage | sí |
api_keys_toggle | Activa o desactiva una clave. | API_CREDENTIALS_MANAGE | integrations:credentials:manage | no |
api_keys_delete | Borra una clave. | API_CREDENTIALS_MANAGE | integrations:credentials:manage | sí |
api_keys_regenerate | Renueva la clave y devuelve el valor nuevo una sola vez. Pide confirmación en el móvil. | API_CREDENTIALS_MANAGE | integrations:credentials:manage | sí |
api_keys_get_notifications | Avisos configurados por departamento. | INTEGRATIONS_APPS_VIEW o API_CREDENTIALS_MANAGE | integrations:credentials:view | no |
api_keys_update_notifications | Cambia los destinatarios de esos avisos. | API_CREDENTIALS_MANAGE | integrations:credentials:manage | no |
api_keys_create y api_keys_regenerate siguen las mismas reglas de confirmación que api_credentials: la primera llamada devuelve APPROVAL_REQUIRED, se repite con twoFactorApprovalId tras aprobar en el móvil, y sin la verificación en dos pasos activada se rechazan con TWO_FACTOR_NOT_ENABLED. Con la organización en modo restringido no se crea ninguna clave.
Por compatibilidad con las integraciones anteriores al 28 de agosto de 2026, un token con scopes del CRM o del dominio de trabajo puede leer las claves aunque no lleve integrations:credentials:view. Para gestionarlas hay que pedir siempre integrations:credentials:manage.
Formularios de captación (11). Se corresponden con Ajustes › CRM › Formularios de captación, necesitas entrar con tu cuenta.
| Operación | Qué hace | Permiso | Scope | confirm |
|---|---|---|---|---|
lead_forms_list | Lista los formularios de la organización. | LEAD_FORMS_VIEW | crm:lead-forms:view | no |
lead_forms_get | Detalle de un formulario. | LEAD_FORMS_VIEW | crm:lead-forms:view | no |
lead_forms_create | Crea un formulario. | LEAD_FORMS_CREATE | crm:lead-forms:manage | no |
lead_forms_update | Cambia los campos, el vínculo con el CRM o los webhooks del formulario. | LEAD_FORMS_EDIT | crm:lead-forms:manage | no |
lead_forms_delete | Borra el formulario; las respuestas recibidas se conservan. | LEAD_FORMS_DELETE | crm:lead-forms:manage | sí |
lead_forms_publish | Publica el formulario. | LEAD_FORMS_PUBLISH | crm:lead-forms:manage | no |
lead_forms_pause | Pausa el formulario. | LEAD_FORMS_EDIT | crm:lead-forms:manage | no |
lead_forms_archive | Archiva el formulario sin borrar su historial. | LEAD_FORMS_EDIT | crm:lead-forms:manage | no |
lead_forms_unarchive | Devuelve a borrador un formulario archivado y conserva su slug. | LEAD_FORMS_EDIT | crm:lead-forms:manage | no |
lead_forms_get_stats | Estadísticas agregadas. | LEAD_FORMS_VIEW | crm:lead-forms:view | no |
lead_forms_get_snippet | Fragmento HTML y JavaScript para insertar el formulario en tu web. | LEAD_FORMS_VIEW | crm:lead-forms:view | no |
integrations_overview
Da el estado del dominio de integraciones en una sola llamada, pensado para un copiloto o un panel. Es de solo lectura y su respuesta se guarda en caché 30 segundos por organización y operación. health, quickstart y app_diagnosis leen del mismo diagnóstico que la pestaña Pruebas de cada aplicación y que GET /external/v1/diagnostics, así que no se contradicen.
| Operación | Qué devuelve | Permiso | Scope |
|---|---|---|---|
status | Cifras agregadas: aplicaciones, credenciales por tipo, entregas de las últimas 24 horas y catálogo de eventos. | INTEGRATIONS_OVERVIEW_VIEW o EXTERNAL_APPS_VIEW | integrations:overview:view |
health | Salud: cuántas aplicaciones hay en cada estado (appsByStatus), las que hay que revisar (appsNeedingAttention, hasta 10), la peor parada, las llamadas de las últimas 24 horas, errores críticos abiertos, entregas fallidas y reintentos pendientes. Su veredicto es healthy, degraded o critical. | INTEGRATIONS_OVERVIEW_VIEW o EXTERNAL_APPS_VIEW | integrations:overview:view |
quickstart | La siguiente acción recomendada (nextAction), lo que queda pendiente (missingConfig) y, aparte, lo que conviene saber sin ser un paso pendiente (recommendations). | INTEGRATIONS_OVERVIEW_VIEW o EXTERNAL_APPS_VIEW | integrations:overview:view |
app_diagnosis | El diagnóstico de una aplicación, con appId (de integrations.apps_list): veredicto, qué puede llamar, hallazgos con quién los arregla, pasos siguientes y recorrido. | EXTERNAL_APPS_VIEW | integrations:overview:view |
app_diagnosis exige EXTERNAL_APPS_VIEW, el mismo permiso que la ficha de la aplicación en el panel: con permisos personalizados, INTEGRATIONS_OVERVIEW_VIEW solo da el resumen. Busca la aplicación dentro de tu organización: si no está o está eliminada, responde APP_NOT_FOUND, exista o no en otra. Su respuesta tiene la forma de GET /external/v1/diagnostics, con la voz de quien administra la organización: «Concede el permiso…» en vez de «Pide a un administrador…». Se llama con tools/call; en los SDK, appDiagnosis(appId) (app_diagnosis) llega con la 4.6.0.
{
"jsonrpc": "2.0",
"id": "1",
"method": "tools/call",
"params": {
"name": "integrations_overview",
"arguments": { "operation": "app_diagnosis", "appId": "ckapp1234567890" }
}
}const status = await sdk.mcp.integrationsOverview.status();
const health = await sdk.mcp.integrationsOverview.health();
console.log(`Aplicaciones activas: ${status.apps.active}/${status.apps.total}`);
if (health.overall !== 'healthy') {
console.warn('La peor parada:', health.worstApp?.appName, health.worstApp?.verdict);
for (const app of health.appsNeedingAttention) {
console.warn(`${app.appName}: ${app.status}`);
}
}Los campos son los de la respuesta del servidor: la peor parada va en worstApp (appId, appName, errorRate, lastErrorAt, status y verdict) y las que hay que revisar, en appsNeedingAttention. Los tipos de los SDK con estos nombres, y app_diagnosis como método, llegan con la 4.6.0: con una versión anterior, worstApp.name siempre llegaba vacío y en Python status() fallaba al validar (Versiones y compatibilidad).
Qué cuenta quickstart como pendiente y qué solo recomienda:
missingConfig(pasos que faltan): que no haya ninguna aplicación; que una aplicación activa con permisos de facturas tenga la facturación apagada, que va primero y nombra las aplicaciones, porque cada factura que intenten emitir se rechaza conBILLING_NOT_ENABLED; cada bloqueo del diagnóstico de las aplicaciones activas, con las aplicaciones que lo tienen; y que haya aplicaciones que envían facturas por correo sin ningún dominio de envío verificado.recommendations(no son pasos pendientes): lo que el plan no incluye, porque no se arregla configurando; los avisos del diagnóstico de cada aplicación; y los avisos a tu servidor, que son opcionales porque una aplicación que solo llama a la API funciona sin ellos.
nextAction sigue este orden: crear la primera aplicación; activar la facturación apagada, con la operación apps_billing_update_config de integrations (solo un Super Administrador, con un motivo de al menos 20 caracteres); el primer bloqueo de una aplicación, que remite a app_diagnosis; verificar un dominio de envío; y, con todo lo necesario hecho, los avisos a tu servidor como opcionales.
Es el mismo diagnóstico que resume en una línea el bloque Estado de la ficha de cada aplicación (Panel de aplicaciones externas).
Permisos por rol
De los seis roles de UTILIA OS, solo dos traen permisos de integraciones por defecto: Super Administrador, todos, y Gerente, los de consulta y los de gestionar los errores de las aplicaciones. Vendedor, Asistente, Visualizador y Comercial Externo («Otros roles» en la figura) no traen ninguno.
Permisos de integraciones por rol
| Scope | Super Administrador | Gerente | Otros roles |
|---|---|---|---|
| Aplicaciones externas | |||
| integrations:apps:viewINTEGRATIONS_APPS_VIEW o EXTERNAL_APPS_VIEW | Sí | Sí | No |
| integrations:apps:manageINTEGRATIONS_APPS_MANAGE o EXTERNAL_APPS_EDIT (OAuth saliente: ver el pie) | Sí | No | No |
| integrations:apps:webhooks:viewINTEGRATIONS_APPS_VIEW o EXTERNAL_APPS_VIEW | Sí | Sí | No |
| integrations:apps:webhooks:manageINTEGRATIONS_WEBHOOKS_MANAGE o EXTERNAL_APPS_EDIT | Sí | No | No |
| integrations:apps:metrics:viewINTEGRATIONS_METRICS_VIEW o EXTERNAL_APPS_VIEW | Sí | Sí | No |
| integrations:apps:billing:viewINTEGRATIONS_BILLING_MANAGE o EXTERNAL_APPS_VIEW | Sí | Sí | No |
| integrations:apps:billing:manageINTEGRATIONS_BILLING_MANAGE o EXTERNAL_APPS_EDIT | Sí | No | No |
| integrations:apps:errors:viewEXTERNAL_APPS_ERRORS_VIEW | Sí | Sí | No |
| integrations:apps:errors:manageEXTERNAL_APPS_ERRORS_MANAGE | Sí | Sí | No |
| Credenciales | |||
| integrations:credentials:viewAPI_CREDENTIALS_MANAGE | Sí | No | No |
| integrations:credentials:manageAPI_CREDENTIALS_MANAGE | Sí | No | No |
| Estado del dominio | |||
| integrations:overview:viewINTEGRATIONS_OVERVIEW_VIEW o EXTERNAL_APPS_VIEW | Sí | Sí | No |
- Aplicaciones externasintegrations:apps:viewINTEGRATIONS_APPS_VIEW o EXTERNAL_APPS_VIEWSí
- integrations:apps:manageINTEGRATIONS_APPS_MANAGE o EXTERNAL_APPS_EDIT (OAuth saliente: ver el pie)Sí
- integrations:apps:webhooks:viewINTEGRATIONS_APPS_VIEW o EXTERNAL_APPS_VIEWSí
- integrations:apps:webhooks:manageINTEGRATIONS_WEBHOOKS_MANAGE o EXTERNAL_APPS_EDITSí
- integrations:apps:metrics:viewINTEGRATIONS_METRICS_VIEW o EXTERNAL_APPS_VIEWSí
- integrations:apps:billing:viewINTEGRATIONS_BILLING_MANAGE o EXTERNAL_APPS_VIEWSí
- integrations:apps:billing:manageINTEGRATIONS_BILLING_MANAGE o EXTERNAL_APPS_EDITSí
- integrations:apps:errors:viewEXTERNAL_APPS_ERRORS_VIEWSí
- integrations:apps:errors:manageEXTERNAL_APPS_ERRORS_MANAGESí
- Credencialesintegrations:credentials:viewAPI_CREDENTIALS_MANAGESí
- integrations:credentials:manageAPI_CREDENTIALS_MANAGESí
- Estado del dominiointegrations:overview:viewINTEGRATIONS_OVERVIEW_VIEW o EXTERNAL_APPS_VIEWSí
- Aplicaciones externasintegrations:apps:viewINTEGRATIONS_APPS_VIEW o EXTERNAL_APPS_VIEWSí
- integrations:apps:manageINTEGRATIONS_APPS_MANAGE o EXTERNAL_APPS_EDIT (OAuth saliente: ver el pie)No
- integrations:apps:webhooks:viewINTEGRATIONS_APPS_VIEW o EXTERNAL_APPS_VIEWSí
- integrations:apps:webhooks:manageINTEGRATIONS_WEBHOOKS_MANAGE o EXTERNAL_APPS_EDITNo
- integrations:apps:metrics:viewINTEGRATIONS_METRICS_VIEW o EXTERNAL_APPS_VIEWSí
- integrations:apps:billing:viewINTEGRATIONS_BILLING_MANAGE o EXTERNAL_APPS_VIEWSí
- integrations:apps:billing:manageINTEGRATIONS_BILLING_MANAGE o EXTERNAL_APPS_EDITNo
- integrations:apps:errors:viewEXTERNAL_APPS_ERRORS_VIEWSí
- integrations:apps:errors:manageEXTERNAL_APPS_ERRORS_MANAGESí
- Credencialesintegrations:credentials:viewAPI_CREDENTIALS_MANAGENo
- integrations:credentials:manageAPI_CREDENTIALS_MANAGENo
- Estado del dominiointegrations:overview:viewINTEGRATIONS_OVERVIEW_VIEW o EXTERNAL_APPS_VIEWSí
- Aplicaciones externasintegrations:apps:viewINTEGRATIONS_APPS_VIEW o EXTERNAL_APPS_VIEWNo
- integrations:apps:manageINTEGRATIONS_APPS_MANAGE o EXTERNAL_APPS_EDIT (OAuth saliente: ver el pie)No
- integrations:apps:webhooks:viewINTEGRATIONS_APPS_VIEW o EXTERNAL_APPS_VIEWNo
- integrations:apps:webhooks:manageINTEGRATIONS_WEBHOOKS_MANAGE o EXTERNAL_APPS_EDITNo
- integrations:apps:metrics:viewINTEGRATIONS_METRICS_VIEW o EXTERNAL_APPS_VIEWNo
- integrations:apps:billing:viewINTEGRATIONS_BILLING_MANAGE o EXTERNAL_APPS_VIEWNo
- integrations:apps:billing:manageINTEGRATIONS_BILLING_MANAGE o EXTERNAL_APPS_EDITNo
- integrations:apps:errors:viewEXTERNAL_APPS_ERRORS_VIEWNo
- integrations:apps:errors:manageEXTERNAL_APPS_ERRORS_MANAGENo
- Credencialesintegrations:credentials:viewAPI_CREDENTIALS_MANAGENo
- integrations:credentials:manageAPI_CREDENTIALS_MANAGENo
- Estado del dominiointegrations:overview:viewINTEGRATIONS_OVERVIEW_VIEW o EXTERNAL_APPS_VIEWNo
API_CREDENTIALS_MANAGE solo lo trae el rol Super Administrador: un Gerente no gestiona credenciales aunque su token lleve el scope.
Conjuntos de scopes:
| Conjunto | Incluye | Para quién |
|---|---|---|
integrations:full | Los siete integrations:apps:* e integrations:overview:view. No incluye credenciales. | Clientes OAuth que gestionan aplicaciones externas |
api_credentials:full | integrations:credentials:view e integrations:credentials:manage | Clientes OAuth dedicados a credenciales |
admin:full | dev:full, integrations:full y api_credentials:full | Administración avanzada |
dev:full | Todo el dominio de trabajo, soporte, integraciones y credenciales | Quien opera todo el servidor utilia-work |
Eventos y conexiones con otros módulos
Tu aplicación puede suscribirse, en webhookEvents, a eventos de todo el ecosistema. El catálogo completo, con el contenido de cada aviso, está en Avisos: contenido y catálogo de eventos, y apps_webhooks_list_supported_events lo devuelve por MCP. Algunos ejemplos:
- Leads:
LEAD_CREATED,LEAD_QUALIFIED,LEAD_DISQUALIFIEDyLEAD_CONVERTED. Un formulario de captación crea un lead en el CRM, y con él llegaLEAD_CREATED. - Clientes y contactos:
CLIENT_CREATED,CLIENT_UPDATEDyCONTACT_CREATED. - Facturas y presupuestos:
INVOICE_PAID,INVOICE_PAYMENT_FAILED,INVOICE_REFUNDEDyBUDGET_SIGNED. - Tickets de soporte:
TICKET_CREATED,TICKET_REPLIED,TICKET_RESOLVEDyTICKET_CONVERTED. - Archivos:
FILE_UPLOADED. - Errores de tu aplicación:
ERROR_REPORTED,ERROR_RESOLVEDyERROR_REOPENED. Tu aplicación los reporta enPOST /api/external/v1/errors/report; se agrupan por huella,ERROR_REPORTEDse emite la primera vez yintegrations_overview: healthlos tiene en cuenta en su veredicto.
Cada aviso lleva la versión de su contenido en la cabecera X-Utilia-Schema-Version y en payload.meta.schemaVersion. Los eventos broadcast llegan a todas las aplicaciones suscritas; los directed, solo a la aplicación dueña del recurso.
La facturación por aplicación se apoya en el módulo de Finanzas: sus facturas y cobros se consultan con apps_billing_list_invoices y apps_billing_list_payments, y los eventos INVOICE_PAID, INVOICE_PAYMENT_FAILED e INVOICE_REFUNDED te avisan del resultado de cada cobro.
CRM (servidor utilia-crm)
Las herramientas canónicas del CRM tienen operaciones que comparten reglas con la API externa (/external/v1/leads y /external/v1/clients). Esta sección recoge las que más usan los integradores.
Cualificar, descartar y convertir leads; desactivar clientes
| Herramienta | Operación | Qué hace | Permiso | Scope | confirm |
|---|---|---|---|---|---|
crm_leads | set_qualified | Pasa el lead a QUALIFIED. Idempotente. | LEADS_EDIT | crm:leads:update | no |
crm_leads | set_disqualified | Pasa el lead a LOST. Es la única baja lógica de un lead por esta vía. | LEADS_EDIT | crm:leads:update | no |
crm_leads | convert_to_contact | Crea un contacto y, si lo pides, una oportunidad, y deja el lead como CONVERTED. Exige un motivo de al menos 20 caracteres. | LEADS_CONVERT | crm:leads:convert o crm:leads:update | sí |
crm_clients | deactivate | Pasa el cliente a INACTIVE: deja de poder recibir facturas y conserva su historial. No existe un borrado real. | CLIENTS_EDIT | crm:clients:update | sí |
Los conjuntos crm:write y crm:full incluyen crm:leads:update y crm:clients:update.
El motivo de set_qualified y de set_disqualified viaja en reason, y se guarda en las notas internas del lead. set_qualified acepta también notes como alias heredado, que es el que usan hoy los métodos setQualified y set_qualified de los SDK; si llegan los dos, manda reason.
Anotar un correo sin enviarlo
crm_interactions_quick: log_email deja constancia de un correo saliente en el historial del cliente, pero no envía nada. Su respuesta trae delivered: false, que es su estado normal, no un fallo. to y body son obligatorios, y con scheduledFor la interacción queda programada en vez de completada.
Anotar no es avisar. Si un asistente usa log_email para «avisar al cliente», dará por comunicado algo que nadie ha recibido. Los correos de verdad salen por las herramientas que los envían: el presupuesto con crm_budgets, la factura con crm_invoices, la campaña con marketing_campaigns.
Grupos de empresas
El CRM agrupa empresas bajo una matriz, en dos niveles: matriz y filiales.
get y list de crm_clients devuelven parentClientId, hierarchyRole (PARENT, SUBSIDIARY o STANDALONE) y parent { id, name }; el nombre de la matriz solo llega si la matriz está dentro de tu alcance. list acepta los filtros parentClientId y hierarchyRole, y la búsqueda por texto encuentra las filiales también por el nombre de su matriz, solo entre las matrices que puedes ver.
Operaciones de grupo en crm_clients_info:
| Operación | Qué hace | Permiso | Scope |
|---|---|---|---|
list_group | Filiales visibles de la matriz, con sus datos básicos. | CLIENTS_VIEW | crm:clients:view |
get_group_stats | Consolidado del grupo, solo sobre la matriz: contactos, proyectos, oportunidades, presupuestos, facturas y tickets de las empresas visibles. Los importes llegan solo con los permisos financieros correspondientes. | CLIENTS_VIEW | crm:clients:view |
link_subsidiary | Vincula una filial a su matriz. | CLIENTS_MANAGE_HIERARCHY | crm:clients:update |
unlink_subsidiary | Desvincula una filial de su matriz. | CLIENTS_MANAGE_HIERARCHY | crm:clients:update |
list_group_assignments | Asignaciones del grupo (id es la matriz): empresas visibles y personas con su asignación en cada empresa ({ clientId, role, isPrimary }). Las personas desactivadas no salen. | CLIENTS_VIEW | crm:clients:view |
assign_group | Asigna hasta 20 personas (userIds) a las empresas del grupo (id es la matriz). role es opcional y vale ASSIGNED por defecto; targetClientIds acota las empresas. Las asignaciones que ya existen conservan su rol y su condición de responsable principal, la operación es idempotente y las empresas fuera de tu alcance se omiten como skippedOutOfScope. Devuelve summary (companiesTargeted, skippedOutOfScope, created y alreadyAssigned) y el desglose por empresa. | CLIENTS_ASSIGN | crm:clients:update |
crm_clients acepta parentClientId en create y en update, y en los dos casos exige CLIENTS_MANAGE_HIERARCHY sobre las dos empresas. En create, el permiso se comprueba antes de crear y el vínculo se aplica después del alta: si el vínculo falla, el cliente queda creado y el error lo dice con su identificador. En update, la jerarquía se procesa primero y, si no puedes gestionarla, no se aplica ningún cambio.
convert_to_invoice de crm_budgets acepta receiverClientId (alias receiver_client_id) para emitir la factura a la matriz del cliente del presupuesto en lugar de a la propia empresa; cualquier otro receptor se rechaza. Pide el aplicativo Finanzas en el plan de la organización, los tres permisos BUDGETS_EDIT, INVOICES_VIEW e INVOICES_CREATE (con receptor alternativo, además acceso a la matriz) y los tres scopes crm:budgets:update, crm:invoices:view y crm:invoices:create; con issueDirectly, también crm:invoices:issue. Ningún scope de lectura basta.
Campos personalizados
Cada organización define campos personalizados para clientes, contactos, leads y oportunidades. crm_clients, crm_contacts, crm_leads y crm_opportunities exponen ese catálogo y permiten escribir sus valores.
list_custom_fields devuelve el catálogo activo de la entidad de la herramienta. Consúltalo antes de escribir para conocer las claves válidas y sus tipos.
| Herramienta | Permiso | Scope |
|---|---|---|
crm_clients | CLIENTS_VIEW, CUSTOM_FIELDS_VIEW o CUSTOM_FIELDS_MANAGE | crm:clients:view o crm:custom-fields:view |
crm_contacts | CONTACTS_VIEW, CUSTOM_FIELDS_VIEW o CUSTOM_FIELDS_MANAGE | crm:contacts:view o crm:custom-fields:view |
crm_leads | LEADS_VIEW, CUSTOM_FIELDS_VIEW o CUSTOM_FIELDS_MANAGE | crm:leads:view o crm:custom-fields:view |
crm_opportunities | OPPORTUNITIES_VIEW, CUSTOM_FIELDS_VIEW o CUSTOM_FIELDS_MANAGE | crm:opportunities:view o crm:custom-fields:view |
Cada campo trae key, label, type (TEXT, NUMBER, DATE, BOOLEAN, SELECT, MULTISELECT, CURRENCY, URL, EMAIL o PHONE), description, isRequired, isMultiline, sortOrder y, en las listas, sus options activas ({ value, label }).
Para escribir valores, create y update aceptan customFields con la forma { clave: valor }. El servicio valida el tipo, la obligatoriedad, la opción y el formato, y sus errores llegan legibles. Los valores vuelven también en get y list.
{
"operation": "update",
"id": "cli_123",
"customFields": {
"sector_vertical": "retail",
"fecha_alta_manual": "2026-07-01",
"cliente_estrategico": true
}
}Escribir valores exige el scope de escritura de la entidad (crm:clients:update, crm:contacts:create...); crm:custom-fields:view solo lee el catálogo. Crear, editar, reordenar, archivar o eliminar campos se hace con crm_settings (apartado siguiente).
Configuración del CRM
crm_settings configura lo mismo que Ajustes > CRM en la aplicación: las etapas del embudo de ventas, el catálogo de campos personalizados de clientes, contactos, leads y oportunidades, los motivos de pérdida y la puntuación de leads. Usa los mismos servicios, validaciones y registros de auditoría que la aplicación.
| Operaciones | Permiso | Scope |
|---|---|---|
list_pipelines | OPPORTUNITIES_VIEW, PIPELINES_VIEW o PIPELINES_MANAGE | crm:settings:view, crm:pipelines:view o crm:opportunities:view |
update_pipeline, create_stage, update_stage, reorder_stages, delete_stage | PIPELINES_MANAGE | crm:settings:manage |
list_custom_fields | CUSTOM_FIELDS_VIEW o CUSTOM_FIELDS_MANAGE | crm:settings:view o crm:custom-fields:view |
create_custom_field, update_custom_field, reorder_custom_fields, delete_custom_field | CUSTOM_FIELDS_MANAGE | crm:settings:manage |
list_loss_reasons | OPPORTUNITIES_VIEW, LEADS_VIEW o CRM_SETTINGS_MANAGE | crm:settings:view, crm:opportunities:view o crm:leads:view |
create_loss_reason, update_loss_reason, delete_loss_reason | CRM_SETTINGS_MANAGE | crm:settings:manage |
get_lead_scoring, preview_lead_scoring | CRM_SETTINGS_MANAGE | crm:settings:view |
update_lead_scoring | CRM_SETTINGS_MANAGE | crm:settings:manage |
Las lecturas aceptan también crm:settings:manage. Ningún conjunto concede crm:settings:manage, tampoco crm:full: se pide por su nombre.
Cómo usarla:
- Plan. Toda la herramienta pide el aplicativo CRM. Las etapas y los motivos de pérdida piden además Oportunidades, y la puntuación, Leads. Los campos de leads y de oportunidades piden la capacidad de su ficha.
- Los borrados exigen
confirm: true. Sin él no se ejecuta nada y la respuesta (errorCode: CONFIRMATION_REQUIRED) explica qué pasará con los datos. delete_stage: si la etapa tiene oportunidades,moveToStageIdes obligatorio y se mueven todas a esa etapa; las abiertas registran el cambio en su historial y su probabilidad no cambia. Un embudo conserva siempre dos etapas.list_pipelinesdaopportunityCountpor etapa. Si no indicaspipelineId, se usa el embudo por defecto.delete_custom_field: sin valores, se borra. Activo y con valores, no se puede borrar: archívalo conupdate_custom_fieldeisArchived: true, que conserva los valores. Archivado y con valores, se borra y su valor se quita de todos los registros. Las operaciones de campos pidenentityType(CLIENT,CONTACT,LEADuOPPORTUNITY);keyytypeno cambian después de crear el campo, y una opción con valores se archiva, no se elimina.delete_loss_reason: un motivo en uso o del sistema se archiva y las oportunidades lo conservan; uno propio sin uso se borra.update_lead_scoringsustituye la configuración entera: lee antes conget_lead_scoring.preview_lead_scoringdice cuántos leads quedarían calientes, templados y fríos con unos umbrales, sin guardar nada.
Automatizaciones del CRM
crm_automations gestiona las automatizaciones sobre leads y oportunidades. Solo trabaja con automatizaciones del CRM, y marketing_automations, solo con las de Marketing: ningún token de un lado ve ni toca las del otro.
| Operaciones | Permiso | Scope |
|---|---|---|
list, get, describe_catalog, validate, list_templates, list_runs, get_run, stats | CRM_AUTOMATIONS_VIEW | crm:automations:view |
create, update, replace_steps, delete, activate, pause, bulk_set_status, test_trigger, duplicate, add_step, update_step, remove_step, create_from_template, retry_run, cancel_run | CRM_AUTOMATIONS_MANAGE | crm:automations:manage |
Cómo usarla:
- El orden recomendado es
describe_catalog,validate,createyactivateconconfirm: true. describe_catalogdevuelve los disparadores y acciones disponibles con su configuración, los límites del validador y los datos reales de tu organización: etapas de cada embudo, formularios de captación activos, etiquetas y estados de lead y de oportunidad. Así no hay que adivinar claves.validatecomprueba una definición entera sin guardar nada, con los mismos validadores que el guardado y la activación, y devuelvevalid,problemsynotesen castellano.- Las automatizaciones nacen en borrador.
activateexigeconfirm: truey revalida todos los pasos;deletetambién exigeconfirm: true. updateconstepsyreplace_stepssustituyen el flujo entero: solo en borrador o en pausa, y cancelan las ejecuciones en curso. Las ramas de un pasoCONDITIONviajan enbranchTrueOrderybranchFalseOrder. Para un paso suelto,add_step,update_stepyremove_step.bulk_set_statusactiva o pausa hasta 25 automatizaciones a la vez y devuelve el resultado de cada una enresultsysummary: un fallo no detiene al resto y reintentar solo los fallidos es seguro. Para activar exigeconfirm: true.test_triggerprueba el flujo con un contacto, como el botón «Probar flujo» de la aplicación. CondryRun: true(por defecto) solo simula; condryRun: falsecrea una ejecución de prueba real, marcada como prueba y fuera de las métricas. La prueba se hace siempre sobre un contacto, aunque el disparador sea de lead o de oportunidad.duplicatecrea una copia en borrador con el nombre «X (copia)» o el que indiques.- En el CRM, el paso
SEND_EMAILexige ademásEMAIL_MARKETING_VIEW, porque usa las plantillas de Marketing. create_from_templateaceptacrm-lead-cooling-alert,crm-form-lead-welcome,crm-negotiation-follow-up-taskycrm-unresponsive-lead-reassign, que también devuelvelist_templates.- Lo que cambies por MCP se refleja solo en la página de automatizaciones del CRM que tengas abierta.
marketing_automations tiene las mismas operaciones de eficiencia: validate con EMAIL_MARKETING_VIEW y marketing:automations:view; replace_steps y bulk_set_status con EMAIL_MARKETING_EDIT, y duplicate con EMAIL_MARKETING_CREATE, las tres con marketing:automations:manage.
Analítica y cualificación de leads
crm_leads_stats es de solo lectura. Pide LEADS_VIEW y el scope crm:leads:view, y cada persona agrega solo las filas que vería en un listado. El período se indica con days (de 1 a 366, 90 por defecto) y se calcula en la zona horaria de la organización.
| Operación | Qué devuelve |
|---|---|
funnel | Cifras del embudo de lead a oportunidad y a cliente: leads nuevos, contactados, cualificados y convertidos, tasas de conversión y reparto por etapa. |
sources | Conversión por source, por utm_source, por campaña y por formulario de captación. El valor estimado solo llega con LEADS_VIEW_FINANCIALS. |
response_time | Tiempo hasta la primera respuesta: media, mediana, percentil 90, porcentaje sin respuesta y tramos (menos de 1, 4, 24 y 72 horas, y más). |
En crm_leads:
set_temperaturefija la temperatura del lead a mano (temperature) o la devuelve al cálculo automático (auto: true, incompatible contemperature). Fijarla marcatemperatureIsManual, y la puntuación deja de recalcularla. PideLEADS_EDITycrm:leads:update.listacepta los filtrostemperature,scoreMinyscoreMax(de 0 a 100),source,industry,leadFormIdyutmSource.getincluyeprofileScore,behaviorScore,temperatureIsManualyfirstContactedAt.
Motivos de pérdida y analítica de oportunidades
crm_opportunities: list_loss_reasonsdevuelve el catálogo de motivos de pérdida de la organización (id,label,sortOrder,isSystem,isArchived,requiresCompetitor,requiresDetaileinUseCount); conincludeArchived: trueincluye los archivados. PideOPPORTUNITIES_VIEWoLEADS_VIEWy el scopecrm:opportunities:viewocrm:leads:view.crm_opportunities_workflow: loseaceptalossReasonId, que tiene preferencia sobre el texto librelostReason: el servidor valida el motivo, aplica sus exigencias de competidor y detalle y copia su etiqueta alostReason. Acepta tambiénpostMortemNotes, para lo aprendido.
crm_opportunities_stats tiene tres análisis más, con period (30d, 90d o 365d; 90d por defecto) y el scope crm:opportunities:view:
| Operación | Qué devuelve | Permiso |
|---|---|---|
funnel | Embudo por etapa de las oportunidades del período: cuántas alcanzaron cada etapa, conversión respecto a la anterior, tiempo en cada etapa (las reaperturas no inflan las cifras), desenlaces y tasa de cierre. Acepta pipelineId. | OPPORTUNITIES_VIEW |
loss_reasons | Pérdidas del período: motivos más frecuentes, con una fila «OTHER», desglose por etapa (byStage) y por comercial (byOwner) y competidores más citados. Los importes solo llegan con OPPORTUNITIES_VIEW_FINANCIALS. | OPPORTUNITIES_VIEW |
by_owner | Clasificación de comerciales: ganadas, perdidas, abandonadas, tasa de éxito y días típicos hasta el cierre. El valor ganado y el importe medio solo llegan con permiso financiero. | OPPORTUNITIES_VIEW_TEAM_PIPELINE |
Los nombres antiguos analytics_loss_reasons y analytics_top_contributors son operaciones obsoletas: ya no se anuncian en tools/list, pero siguen respondiendo con el mismo contrato que loss_reasons y by_owner hasta el 8 de enero de 2027, con un aviso en _notices.deprecatedOperation que nombra la sustituta.
Contraseñas de aplicación de otra persona
La herramienta observability del servidor utilia-crm deja ver y retirar las contraseñas de aplicación con las que una persona de tu organización conecta la unidad de red del Gestor de archivos. Es lo mismo que el bloque Contraseñas de aplicación de su ficha en Ajustes › Usuarios.
| Operación | Qué hace | Permiso | Scope | confirm |
|---|---|---|---|---|
webdav_app_passwords_list_user | Lista las contraseñas de aplicación vigentes de la persona userId: nombre, primeros caracteres, fecha de creación y último uso. Nunca devuelve la contraseña. | SETTINGS_SESSIONS_VIEW | org:observability:view | no |
webdav_app_passwords_revoke_user | Retira una contraseña de aplicación de la persona (con appPasswordId) o todas (sin él). Deja de valer al momento y la persona recibe un aviso. | SETTINGS_SESSIONS_REVOKE | org:observability:manage | sí |
sessions_revoke_user | Cierra todas las sesiones de una persona y retira también sus contraseñas de aplicación. | SETTINGS_SESSIONS_REVOKE | org:observability:manage | sí |
Las dos primeras exigen además el Gestor de archivos en el plan y el permiso concedido sobre toda la organización (alcance Todo). Quien no es Super Administrador solo ve y retira las de las personas que puede administrar: un Gerente con estos permisos, las de Vendedor, Asistente, Visualizador y Comercial Externo. Una persona de otra organización responde como si no existiera.
Seguridad y privacidad de la organización
La herramienta org_security_privacy del servidor utilia-crm hace lo mismo que Ajustes › Seguridad y Ajustes › Privacidad, con los mismos permisos y las mismas reglas. Ningún conjunto concede sus scopes: se piden por su nombre.
Cada escritura exige confirm: true y la confirmación en el móvil, así que la persona necesita tener activada la verificación en dos pasos: la primera llamada devuelve APPROVAL_REQUIRED con el número que hay que elegir en la aplicación, y después se repite la misma llamada con twoFactorApprovalId. La confirmación solo vale para esa operación con esos mismos datos.
| Operaciones | Qué hacen | Quién | Scope |
|---|---|---|---|
security_get, security_preview_outbound_domains | Leer los ajustes de seguridad y ver qué webhooks y rutas de envío quedarían fuera con una lista de dominios. | Super Administrador | org:security:view |
security_get_status | El estado que ve toda la plantilla: modo restringido y bloqueo de pantalla. | Cualquiera | org:security:view o org:settings:view |
security_set_two_factor_required, security_set_two_factor_required_advisors, security_set_two_factor_email_fallback, security_set_inactivity_lock, security_set_export_rate_limit, security_set_restricted_mode, security_set_outbound_domains | Los siete interruptores de la pantalla de Seguridad. security_set_two_factor_required exige la verificación en dos pasos a quien administra y security_set_two_factor_required_advisors, a la asesoría (activado de serie). | Super Administrador | org:security:manage |
retention_get, retention_update | Plazos de conservación de datos. | PRIVACY_RETENTION_MANAGE | org:privacy:view / org:privacy:manage |
portal_activity_get, portal_activity_update | Registro de actividad de los contactos en el portal. Exige el Portal del cliente en el plan. | PRIVACY_RETENTION_MANAGE | org:privacy:view / org:privacy:manage |
dsar_list, dsar_summary, dsar_get | Bandeja de solicitudes de derechos de protección de datos. | PRIVACY_RIGHTS_VIEW | org:privacy:view |
dsar_create, dsar_require_identity_check, dsar_verify_identity, dsar_start, dsar_extend, dsar_execute_export, dsar_execute_erasure, dsar_complete, dsar_reject | Tramitar una solicitud, incluida la supresión de los datos de la persona, que no se puede deshacer. | PRIVACY_RIGHTS_MANAGE | org:privacy:manage |
incidents_list, incidents_summary, incidents_provider_notices, incidents_get | Registro de incidentes de seguridad de la organización y avisos del proveedor de la plataforma. | PRIVACY_INCIDENTS_VIEW | org:privacy:view |
incidents_create, incidents_update, incidents_assess, incidents_mark_aepd_notified, incidents_mark_subjects_notified, incidents_close | Registrar, valorar, notificar y cerrar un incidente de seguridad. | PRIVACY_INCIDENTS_MANAGE | org:privacy:manage |
export_request, export_status | Pedir la exportación de todos los datos de la organización y seguirla. Para pedirla hace falta la verificación en dos pasos; el archivo se descarga desde Ajustes › Organización › General. | Super Administrador | org:privacy:export (export_status también con org:privacy:view) |
Las respuestas no llevan nunca el enlace de descarga de una exportación: indican downloadAvailable cuando está lista.
Finanzas (servidor utilia-finance)
El servidor utilia-finance (POST https://os.utilia.ai/api/mcp/finance,
nombre en el intercambio inicial: UTILIA Finance MCP) es el propietario canónico
de la facturación, la tesorería y la fiscalidad de UTILIA OS. Expone
25 herramientas: 11 de facturación, tesorería y fiscalidad (con
nombres y scopes crm:invoices:*, crm:treasury:* y crm:fiscal:*
heredados de su origen en el CRM) y 14 exclusivas con scopes finance:*.
La autorización OAuth usa el recurso /api/mcp/finance (ver
Descubrimiento de OAuth) y los
scopes se documentan en
Scopes y recursos.
Estas 11 herramientas se publicaban también en el servidor utilia-crm.
Desde el 8 de julio de 2026 esas copias están obsoletas: dejan de anunciarse en
el tools/list del servidor CRM, aunque siguen respondiendo a
tools/call con el mismo nombre, esquema y permisos hasta su retirada
definitiva (prevista para el 8 de enero de 2027). Para cualquier flujo financiero
conecta este servidor.
Próximamente: tesorería, informes, comisiones, impuestos y contabilidad
Desde el 14 de octubre de 2026 estas herramientas están en «Próximamente»: las estamos validando con especialistas antes de ponerlas a tu disposición, y hasta entonces no están disponibles para tu organización.
- Tesorería:
treasury. - Impuestos:
fiscal, salvoconfig_get,retention_rates_getyretention_rates_update(configuración fiscal y retenciones, que siguen disponibles), yfiscal_capture. - Contabilidad:
accounting,accounting_journal,accounting_ledger,accounting_assets,accounting_closeysuppliers: accounting_accounts. - Comisiones:
commissionsycommissions_admin. - Informes:
finance_reports, salvosummary(el resumen de Finanzas).
Vale igual para sus copias del servidor utilia-crm. Una llamada a cualquiera
de ellas responde que la función estará disponible próximamente, con el mismo
texto que la aplicación (por ejemplo, «El apartado Tesorería estará disponible
próximamente.»). No es un bloqueo de plan ni de permisos: no se resuelve
ampliando el plan ni concediendo scopes, así que no la reintentes. Las tablas
de abajo describen su contrato para cuando estén disponibles.
Facturación
| Herramienta | Operaciones principales | Scopes |
|---|---|---|
crm_invoices (canónica) | list, get, create, update, delete, duplicate, get_stats, get_next_number, previewTaxCoherence. create admite type: "SIMPLIFIED" (factura simplificada, con su propia serie y destinatario opcional: sin datos sale a nombre de «Consumidor final») y list filtra por type | crm:invoices:view (lectura), crm:invoices:create/update/delete |
crm_invoices_workflow | issue, cancel, mark_paid, mark_partial_paid, cancelRefund, refund_manual (devolución registrada fuera de la pasarela de UTILIA, ver más abajo); y el cobro con tarjeta: charge, charge_confirm, refund_create, payment_intent_cancel, payment_intents_list | crm:invoices:issue, crm:invoices:cancel, crm:invoices:refund-cancel; refund_manual y el cobro con crm:invoices:update, y la lectura de intentos con crm:invoices:view. Las cinco del cobro exigen además el aplicativo Pagos con tarjeta (Stripe) |
crm_invoices_rectifications | create_rectification, create_credit_note, update_legal_metadata | crm:invoices:create, crm:invoices:update |
crm_invoices_pdf | generate, get_url, regenerate, preview, draft_preview, email_preview (devuelven URL firmada, nunca binario) | crm:invoices:view, crm:invoices:export |
crm_invoices_email_templates | CRUD de plantillas, set_default, preview, variables_list | crm:invoices:view, crm:invoices:update |
crm_invoices_scheduled_charges | list, get, get_logs, schedule, update, cancel, retry_now | crm:invoices:view, crm:invoices:update |
crm_subscriptions | CRUD, pause/resume/cancel/reactivate, generate_now, upcoming_charge (supervisión humana); check_readiness (comprobación previa del cobro, solo lectura); create admite billingContact | crm:invoices:view (lectura y check_readiness, que también admite crm:invoices:update), crm:invoices:update; billingContact exige además finance:billing-contacts:manage |
crm_mandates | list, get, list_for_client, link_mandate, revoke (supervisión humana) | crm:invoices:view, crm:invoices:update |
Cobros recurrentes: comprobación previa y contacto de facturación
Un cobro recurrente con automation: "AUTO" emite y envía cada factura solo,
pero solo puede enviarla si el cliente tiene un contacto de facturación
principal y activo. Sin él, la factura se emite y el correo se omite. Por eso
crm_subscriptions comprueba antes de cada cobro si la factura podrá
emitirse, llegar al cliente y cobrarse, con las mismas reglas que la ficha del
cobro recurrente en la aplicación.
check_readiness (solo lectura, no guarda nada) tiene dos formas:
- Con
id: comprueba una suscripción guardada. ExigeRECURRING_INVOICES_VIEWsobre su cliente, comoget. - Con
clientIdyautomation(AUTOoDRAFT), y opcionalmenteinvoiceType(STANDARDoSIMPLIFIED),paymentMethod,bankIbanychargeMode(MANUALoAUTO_STRIPE): comprueba los datos de un alta ANTES de crearla. Exige poder crear cobros recurrentes para ese cliente (RECURRING_INVOICES_CREATEcon su alcance).
Las dos van con el scope crm:invoices:view o con crm:invoices:update (para
quien solo puede crear cobros). Devuelven readiness y un
nextStep general:
| Campo | Qué contiene |
|---|---|
ready | true si no hay ninguna incidencia. |
canIssue | true si ninguna incidencia impide emitir la factura. |
issues[] | Las incidencias, primero las que impiden emitir. Cada una con code, severity, message, missingFields (en las de datos fiscales), suggestedEmails (en BILLING_CONTACT_MISSING) y nextStep, la llamada exacta que la arregla. |
checkedAt | Momento de la comprobación (ISO 8601). |
severity es BLOCKING cuando la factura no podrá emitirse y WARNING
cuando se emitirá, pero no se enviará, no se cobrará sola o le faltará un dato
de pago. Los códigos son:
code | Gravedad | Qué falta | El nextStep propone |
|---|---|---|---|
ISSUER_DATA_INCOMPLETE | BLOCKING | Datos fiscales de tu organización | organization_settings (update_general, update_addresses) del servidor utilia-crm |
CLIENT_FISCAL_DATA_INCOMPLETE | BLOCKING | Nombre o razón social, dirección, ciudad o código postal del cliente, en facturas ordinarias | crm_clients: update del servidor utilia-crm |
CLIENT_TAX_ID_MISSING | WARNING | NIF del cliente, en facturas ordinarias | crm_clients: update |
BILLING_CONTACT_MISSING | WARNING | Contacto de facturación principal, con automation: "AUTO" | billing_contacts: create con role: "PRIMARY"; antes de crear, data.billingContact |
BILLING_CONTACTS_OPTED_OUT | WARNING | Los contactos principales desactivaron el correo de facturas en su portal | Otro contacto con billing_contacts: create |
TRANSFER_IBAN_MISSING | WARNING | IBAN para el pago por transferencia | data.bankIban de la suscripción o finance_settings: update_billing |
AUTO_CHARGE_NOT_AUTHORIZED | WARNING | Autorización del cliente para el cobro con tarjeta | crm_mandates: request_signature (correo real al cliente) o link_mandate |
AUTO_CHARGE_DISABLED | WARNING | Cobro automático activado en la organización | finance_settings: update_finance_comms o pasar el cobro a MANUAL |
Los nextStep nunca inventan datos: lo que tiene que confirmar la persona va
como marcador entre ángulos (por ejemplo, '<NIF>'). El único valor real que
proponen es el primero de suggestedEmails, los correos que se pueden dar de
alta como contacto de facturación: el de la ficha del cliente, si el usuario
tiene CLIENTS_VIEW, y los de sus contactos del CRM, si tiene
CONTACTS_VIEW, cada uno con su alcance. Es una sugerencia: confírmala con
la persona antes de usarla.
billingContact en create. data.billingContact (email y name
opcional) garantiza, antes de generar la primera factura y en la misma
transacción que la suscripción, un contacto de facturación principal y activo
del cliente con ese correo: lo crea o, si ya existía, lo reactiva y lo pasa a
principal. Es la doble puerta de siempre:
- El usuario necesita
BILLING_CONTACTS_MANAGE. Sin él, la respuesta es un403conerrorCode: "BILLING_CONTACTS_MANAGE_REQUIRED"y no se crea nada. - El token necesita
finance:billing-contacts:manage(también lo concedefinance:full; en el servidorutilia-crm, donde sigue la copia obsoleta, valecrm:clients:update). Sin él, la respuesta esINSUFFICIENT_SCOPEantes de crear nada.crm:invoices:updatepermite crear el cobro, no el contacto, yfinance:writetampoco lo concede.
Lo que devuelven las demás operaciones:
createyupdatedevuelvenreadiness(con elnextStepde cada incidencia;nullsi no se pudo calcular) ywarnings, lo que se guardó distinto de lo pedido. Por ejemplo, el cobro con tarjeta guardado como manual porque la organización tiene apagado el cobro automático, o un contacto de facturación que ya existía y se ha reactivado como principal.- El
nextStepdecreatedice qué hacer después. Si la primera factura se emitió pero el correo se omitió por falta de contacto, indica el orden: primerobilling_contacts: createy despuéscrm_invoices_workflow: sendconconfirm: true. Enviarla antes volvería a omitir el correo. getdevuelvereadinesssi la suscripción estáACTIVEoPAUSED, ynullen las demás.listdevuelvereadinessIssueCodesen cada fila: los códigos de la comprobación de las suscripcionesACTIVEoPAUSED, calculados por lote. Lista vacía si no falta nada o si la suscripción ya no factura.
Flujo recomendado para un alta con automation: "AUTO":
{ "operation": "check_readiness", "clientId": "cli_123", "automation": "AUTO" }Si devuelve BILLING_CONTACT_MISSING, confirma el correo con la persona y
pásalo en el alta:
{
"operation": "create",
"data": {
"name": "Mantenimiento web",
"clientId": "cli_123",
"automation": "AUTO",
"startDate": "2026-11-01",
"lines": [{ "name": "Cuota mensual", "unitPrice": 65, "taxType": "IGIC_7" }],
"billingContact": { "email": "administracion@cliente.es" }
}
}La misma comprobación está en la API REST interna:
GET /api/finance/recurring-invoices/:id/readiness y
POST /api/finance/recurring-invoices/readiness, y el listado
GET /api/finance/recurring-invoices trae readinessIssueCodes en cada fila.
Campos fiscales de las líneas (IGIC: exención y comerciante minorista)
Las líneas de crm_invoices (create/update) y de los presupuestos
(crm_budgets, servidor utilia-crm) aceptan campos fiscales adicionales:
taxType: en el sistema IGIC admite, además de los tipos con porcentaje, los valoresEXEMPT(exenta) yNOT_SUBJECT(no sujeta).igicOperationType: clasificación de la línea en el régimen especial del comerciante minorista del IGIC. En ventas:IGIC_RETAIL(venta minorista exenta; exigetaxType: "EXEMPT"y la causa minorista la aplica el motor por defecto) oIGIC_GENERAL. Exige que la organización tenga el régimen declarado en su configuración fiscal (igicRetailerModedistinto deIGIC_RETAILER_NONE).exemptionReason: causa estructurada de la exención, obligatoria contaxType: "EXEMPT"en IGIC salvo en el régimen del pequeño empresario. Valores:EXEMPT_IGIC_RETAILER,EXEMPT_IGIC_INTERNAL,EXEMPT_EXPORT,EXEMPT_OTHERyEXEMPT_IGIC_SMALL_BUSINESS(régimen del pequeño empresario del IGIC, con la mención «Exención franquicia fiscal»). La causa decide la mención legal que se imprime en la factura. Dentro de un periodo del régimen del pequeño empresario, el motor pone esa causa en las líneas exentas sin causa de un documento IGIC y rechaza las líneas IGIC con cuota, tambiénIGIC_0. El estado del régimen se consulta confinance_settings: get_small_business_regime.exemptionNote: texto explicativo de la exención (máximo 300 caracteres), obligatorio conexemptionReason: "EXEMPT_OTHER"; viaja a la mención legal impresa.
En presupuestos, estos campos se propagan a la factura o a la suscripción al
convertir. Las líneas de gasto (expenses) aceptan también
igicOperationType con un tercer valor propio, IGIC_COMMON (gasto común a
las dos actividades); en un gasto clasificado como IGIC_RETAIL la cuota de
IGIC soportada no es deducible.
Tesorería y fiscalidad
| Herramienta | Operaciones principales | Scopes |
|---|---|---|
treasury (canónica) | Próximamente. Lecturas: cash_position, accounts_list, transactions_list, reconcile_suggestions, forecast, aging_report, cash_flow_report, alerts_list, connection_status, sync_logs, import_batches_list, transactions_export. Escrituras (todas exigen confirm: true): cuentas (account_create/update/delete/set_default/activate/deactivate), movimientos manuales (transaction_create/update/delete; los importados del banco son inmutables), importaciones (import_csv, import_norma43, import_batch_revert), conciliación (transaction_reconcile/unmatch/ratify/revert_reconciliation/exclude), reglas (reconciliation_rule_*), asiento sin factura (transaction_create_journal_entry), force_sync y recurrentes de la previsión (recurring_pattern_*). Convención de signo: el importe de ingresos y gastos se guarda siempre en positivo (el tipo marca la dirección); solo las transferencias llevan signo (positivo entra en la cuenta, negativo sale). No mueve dinero ni conecta/desconecta bancos. | crm:treasury:view, crm:treasury:reconcile, crm:treasury:sync, crm:treasury:export |
fiscal_capture | Próximamente. Insumos: adjustments_*, modules_*, attributions_*, foreign_assets_*, irpf_activity_get; rectificativas recibidas: expense_rectification_get/save/save_many. Bajas con confirm y supervisión humana. | crm:fiscal:view/manage; las rectificativas requieren además los scopes de gastos indicados abajo |
fiscal (canónica) | Próximamente, salvo config_get y retention_rates_get/update. calendar, pending, models_list, calculate, mark_filed, manual_file, pay, periods_*, coherence, catalog, config_get, alerts_list, vat_registry(_export), official_file/pdf (el fichero sigue el diseño del organismo del modelo: AEAT para los estatales, Agencia Tributaria Canaria para el 415), investment_goods_list, investment_good_get/create/update/prorrata/dispose/delete, retention_rates_get/update, sii_batches_list/batch_download | crm:fiscal:view, crm:fiscal:calculate, crm:fiscal:file, crm:fiscal:manage (bienes de inversión escritura y retention_rates_update exigen crm:fiscal:manage; dispose/delete/retention_rates_update con supervisión humana) |
Captura de rectificativas recibidas
fiscal_capture permite consultar y guardar los hechos fiscales de una
rectificativa recibida asociada a un gasto. La captura conserva la referencia
original, la causa, las fechas, la elección de período y las pruebas de deducción.
No modifica los importes del gasto ni el documento original, no genera pagos o
asientos y no presenta declaraciones.
| Operación | Argumentos | Permisos del usuario (todos) | Scopes del token (todos) |
|---|---|---|---|
expense_rectification_get | expenseId | TAX_MODELS_VIEW + EXPENSES_VIEW | crm:fiscal:view + finance:expenses:view |
expense_rectification_save | expenseId, input | TAX_MODELS_CREATE + EXPENSES_VIEW + EXPENSES_EDIT | crm:fiscal:manage + finance:expenses:view + finance:expenses:update |
expense_rectification_save_many | items: 1–25 elementos con expenseId e input | Los mismos que el guardado individual, en cada elemento | Los mismos que el guardado individual |
Se requieren el aplicativo finance y la capacidad finance.tax_models. Mientras Impuestos esté en «Próximamente», fiscal_capture no está disponible para tu organización.
El servicio comprueba los permisos y el alcance de cada gasto y referencia;
ser Super Administrador no sustituye los scopes del token ni el plan. Las listas
OR del catálogo no reemplazan estas comprobaciones conjuntas. No se ha añadido
una excepción para tokens antiguos. finance:read y finance:write por sí
solos no conceden crm:fiscal:manage; solicita los scopes necesarios.
El SDK usa POST /api/mcp/finance con el token OAuth autorizado para ese
servidor. No hay ruta REST externa equivalente.
Ejemplo de input sin confirmar, conservado para revisión:
{
"expectedRevision": null,
"cause": "RETURN",
"causeOccurredOn": null,
"causeKnownOn": null,
"original": { "expenseId": "expense-original" },
"amountRepresentation": "DIFFERENCE_SIGNED",
"settlement": {
"route": "UNRESOLVED",
"targetFiscalPeriodId": null,
"reimbursementEvidenceIds": []
},
"evidenceFileIds": [],
"confirm": false
}Envía expectedRevision: null en la primera captura; para editar, consulta
la captura y usa su revisión. Las fechas y referencias que admiten null
deben enviarse explícitamente: omitirlas no equivale a desconocerlas.
confirm es un booleano y no acepta "false" como texto. Confirmar requiere
fechas reales y hechos explícitos; no acredita automáticamente su efecto fiscal.
original acepta exactamente una referencia: { expenseId } o
{ external: { number, issuedOn, supplierTaxId, evidenceFileId } }.
Una referencia externa puede guardarse para revisión; no prueba por sí sola
que el cálculo esté cubierto. Los archivos deben pertenecer a la organización
y ser accesibles al actor. No se aceptan invoiceId, autoría, organización,
sellos ni importes del gasto en esta captura recibida.
deduction es opcional; si lo envías debe contener originalUse,
originalFiscalPeriodId, evidenceFileIds, previousAdjustmentReferences y
allocations. Cada asignación lleva originalTaxId, previouslyDeducted y
deductibleAfterCorrection, con importes decimales como cadenas, por ejemplo
"210.00". No deduzcas estos hechos de la deducibilidad actual del gasto.
En recibidas, reimbursementEvidenceIds debe estar vacío.
Consulta y guardado devuelven la misma vista:
{ capture: { id, revision, confirmedAt } | null, input: objeto | null, status: "COMPLETE" | "REVIEW_REQUIRED", reasons: string[] }.
Sin captura, capture e input son null. Revisa siempre status y
reasons: conservar los hechos no habilita todas las ramas fiscales ni
supone que una declaración esté lista para exportar.
En JavaScript, usando como input el objeto anterior:
const { data: actual } = await sdk.mcp.fiscalCapture.getExpenseRectification(expenseId);
const { data: guardada } = await sdk.mcp.fiscalCapture.saveExpenseRectification(
expenseId, { ...input, expectedRevision: actual.capture?.revision ?? null },
);
const { data: lote } = await sdk.mcp.fiscalCapture.saveExpenseRectifications([
{ expenseId, input: { ...input, expectedRevision: guardada.capture?.revision ?? null } },
]);En Python, entrada es el diccionario del ejemplo; los mismos métodos
están disponibles sin await en UtiliaSDKSync:
from utilia_sdk.mcp.fiscal_capture_types import ExpenseRectificationInput, ExpenseRectificationBatchItem
actual = await sdk.mcp.fiscal_capture.get_expense_rectification(expense_id)
entrada["expectedRevision"] = actual.capture.revision if actual.capture else None
guardada = await sdk.mcp.fiscal_capture.save_expense_rectification(
expense_id, ExpenseRectificationInput.model_validate(entrada),
)
lote = await sdk.mcp.fiscal_capture.save_expense_rectifications([
ExpenseRectificationBatchItem(expense_id=expense_id, input=ExpenseRectificationInput.model_validate(entrada)),
])El lote es secuencial y parcial: un fallo no revierte los elementos guardados
ni impide procesar los siguientes. Devuelve succeeded, failed y
summary: { total, ok, failed }. Cada éxito lleva index y
data: { expenseId, id, revision, status, reasons }; cada fallo lleva
index, code y message. Usa el índice para identificar la entrada que
falló. El resumen no incluye hechos externos, fotografías de datos ni historial.
Para un reintento, conserva los mismos hechos y expectedRevision.
Cada intento vuelve a comprobar el acceso y la equivalencia en el servicio;
no hay atomicidad del lote ni una cola o recibo adicional. Un cambio de hechos,
revisión o contexto fiscal puede dar conflicto y exigir una nueva consulta.
Los errores fiscales estables son VAT_RECTIFICATION_CAPTURE_INVALID,
VAT_RECTIFICATION_CAPTURE_CONFLICT, VAT_RECTIFICATION_EFFECTS_REVIEW_REQUIRED
y VAT_RECTIFICATION_PERIOD_LOCKED. En llamadas individuales viajan en
errorCode y en error.code; el SDK JS conserva errorCode y Python
error_code. En el lote viajan en failed[].code. Los fallos de acceso usan
INSUFFICIENT_SCOPE, FORBIDDEN o NOT_FOUND, sin datos de otra organización.
Contabilidad
| Herramienta | Operaciones principales | Scopes |
|---|---|---|
accounting (canónica) | Próximamente. overview, kpis, alerts, setup, plan de cuentas (accounts_*, seed_pgc), ejercicios (fiscal_year*), unidades de negocio (business_units_list, business_unit_create/update/delete) | finance:accounting:view/create/update/delete |
accounting_journal | Próximamente. Asientos (list, create, update, delete), plantillas, contabilize_invoice/expense/payment, post, cancel, reassign_business_unit (reimputa la unidad de negocio de líneas de asientos contabilizados, sin tocar cuentas ni importes) | finance:accounting:* + finance:accounting:post para post/cancel; reassign_business_unit con finance:accounting:update |
accounting_ledger | Próximamente. account_ledger, trial_balance, balance_sheet, income_statement, export_account, business_unit_report (Resultado por unidad de negocio: modos result/full, nivel unit/parent, fila «Sin asignar») | finance:accounting:view, finance:accounting:export |
accounting_assets | Próximamente. Activos CRUD, dispose, depreciation_generate/post/reverse | finance:accounting:* + finance:accounting:post para dotaciones |
accounting_close | Próximamente. close_preview, close, reopen, cuentas anuales y capturas, legalización (legalization_get/export) | finance:accounting:close, finance:accounting:export |
Gastos, proveedores, pagos e informes
| Herramienta | Operaciones principales | Scopes |
|---|---|---|
expenses (canónica) | CRUD, stats, export, submit, approve, reject, pay, revert_to_draft, bulk_submit/approve/pay/delete | finance:expenses:view/create/update/delete + finance:expenses:approve |
suppliers | CRUD, create_many, update_many, search_by_tax_id, expense_summary, check_duplicate, deduplicate_preview, deduplicate, merge | finance:suppliers:view/create/update/delete (los lotes, el de su operación suelta; merge, el de borrado) |
suppliers (personas de contacto) | list_contacts, get_contact, contact_stats, create_contact, update_contact, delete_contact | finance:supplier-contacts:view/manage (datos personales de terceros: fuera de finance:read y finance:write) |
suppliers (actividad) | list_interactions, get_interaction, log_interaction, log_interactions_many, update_interaction, delete_interaction, get_interaction_thread, list_interaction_activities, list_interaction_attachments, attach_to_interaction, remove_interaction_attachment, schedule_meeting, complete_meeting, cancel_meeting | finance:suppliers:interactions:read/manage (contenido de correos: fuera de finance:read y finance:write) |
suppliers (vínculos) | list_tasks, list_payments, get_counterpart | El scope del recurso consultado: crm:tasks:view, finance:payments:view y crm:clients:view. El de documentos sí está incluido en finance:read y finance:full; los dos del CRM requieren autorización aparte |
finance_payments (canónica) | list (acepta supplierId), get, stats, logs, check_duplicate, upload, update, delete, restore, promote_to_expense, resolve_duplicate, reprocess, export | finance:payments:view/update/delete + finance:payments:reprocess/export; upload (subir un justificante ya guardado en el gestor de archivos) acepta finance:payments:create o finance:payments:update; crear un gasto desde un documento exige además los scopes de gastos indicados abajo |
finance_reports (canónica, solo lectura) | summary (el resumen de Finanzas del periodo: ingresos, gastos, resultado, pendiente de cobro y de pago e impuestos). Próximamente: cash_flow_forecast, burn_rate, recurring_patterns, aging, vat_summary, profitability y export (balance, pérdidas y ganancias o flujo de efectivo) | finance:reports:view |
Crear un gasto desde un documento digitalizado exige varios scopes a la vez.
promote_to_expense requiere finance:payments:view,
finance:expenses:create y finance:expenses:approve.
La conversión solicita un gasto aprobado; si el documento está en otra divisa,
el gasto queda en borrador hasta confirmar su importe en euros. No registra
un pago al proveedor.
En resolve_duplicate, action: 'keep_both' conserva el documento como una
factura distinta y crea el gasto con la misma regla. Exige los tres scopes
anteriores y finance:payments:update. action: 'discard' exige
finance:payments:view, finance:payments:update y finance:payments:delete.
Ambas acciones requieren confirm: true. Estos scopes se suman a los permisos
y al alcance del usuario y al acceso de su organización a Finanzas.
Los conjuntos finance:read y finance:write no conceden el scope de aprobación.
Los vínculos del proveedor exigen el scope del otro lado. list_tasks
devuelve tareas del CRM, list_payments documentos de Finanzas y
get_counterpart la identidad de un cliente, así que un token de proveedores
no basta: hace falta además el scope de aquello que se lee. La conjunción sale
sola, porque los scopes que hacen VISIBLE la herramienta siguen siendo solo de
Finanzas. list_tasks exige también el aplicativo CRM en el plan, no solo
Finanzas. get_counterpart exige los CUATRO permisos de los dos lados
(CLIENTS_VIEW, SUPPLIERS_VIEW y los dos de datos sensibles) y devuelve
null sin decir por qué: el mismo null cubre «no tiene NIF», «ninguno casa»
y «queda fuera de tu alcance», porque distinguirlos convertiría la operación en
un comprobador de NIF ajeno. En list_payments y en finance_payments con
supplierId, el NIF leído del documento (supplierNif) solo viaja con
SUPPLIERS_VIEW_SENSITIVE: sin ese permiso la clave no existe en la fila.
Cobro con tarjeta, comisiones y ajustes
| Herramienta | Operaciones principales | Scopes |
|---|---|---|
billing_contacts | CRUD de destinatarios de facturación (list, list_by_client, get, create, update, delete) | finance:billing-contacts:view/manage |
payment_methods | list, stripe_readiness, setup_intent, set_default, delete | finance:payment-methods:view/manage. Toda la herramienta exige Finanzas y Pagos con tarjeta (Stripe) |
commissions | Próximamente. list, by_agent, by_invoice, summary, profit_analysis, approve, cancel | finance:commissions:view/approve |
commissions_admin | Próximamente. Reglas y agentes CRUD, assign_client/unassign_client, liquidaciones (settlement_generate/approve/pay) | finance:commissions:view/manage/liquidate |
finance_settings | get_fiscal, get_billing, get_regime, get_finance_comms, update_billing, update_regime (configuración fiscal completa: taxpayerType, cashCriterionEnabled, recargo de equivalencia, igicRetailerMode (régimen especial del comerciante minorista del IGIC: IGIC_RETAILER_NONE/IGIC_RETAILER_MIXED/IGIC_RETAILER_PURE; distinto de NONE exige régimen canario y es incompatible con el recargo de equivalencia), siiEnabled + siiEnrollmentReason, invoicesToPublicAdmin, analyticAccountsByCounterparty), update_fiscal, update_finance_comms (cobro automático y avisos al cliente), get_stripe (estado de los pagos con tarjeta, solo lectura); y el régimen del pequeño empresario del IGIC: get_small_business_regime (lectura), open_small_business_period y update_small_business_period (con confirm: true) | finance:settings:view/update |
El cobro con tarjeta exige su propio aplicativo
Además del scope del token y del permiso del usuario, estas operaciones
exigen que la organización tenga contratado el aplicativo «Pagos con
tarjeta (Stripe)», que a su vez exige Finanzas. Sin él la respuesta
es un error de aplicativo no habilitado, y no lo arregla ningún permiso ni
ningún scope. Alcanza a la herramienta payment_methods entera, a
crm_invoices_workflow en charge, charge_confirm, refund_create,
payment_intent_cancel y payment_intents_list, a
crm_clients_info: stripe_readiness y a finance_settings: get_stripe.
No lo exigen, y es deliberado: refund_manual (la devolución
registrada fuera de la pasarela), refunds_list y
cancel_refund_preview (que listan también las manuales), y mark_paid
y mark_partial_paid (el registro manual de un cobro). Registrar una
devolución en efectivo no necesita pasarela y exigirla sería falso.
refund_manual registra una devolución hecha fuera de la pasarela de
UTILIA OS. Su source dice por dónde: MANUAL_BANK (transferencia),
MANUAL_CASH (efectivo) o EXTERNAL_GATEWAY («Pasarela de pago
externa»: la devolución ya se hizo en una pasarela ajena a UTILIA OS, por
ejemplo la cuenta de Stripe propia de la empresa). Con
EXTERNAL_GATEWAY:
- UTILIA OS no mueve dinero: solo registra la devolución.
referenceNumberes obligatorio: el identificador de la devolución en esa pasarela (por ejemplo,re_...), hasta 120 caracteres sin espacios, que no puede repetirse en la organización.- Solo se puede devolver lo que se cobró fuera de la pasarela de UTILIA OS. Lo cobrado con ella se devuelve con
refund_create. methoddice cómo devolvió el dinero la pasarela externa (CARD, por defecto,TRANSFERoCASH) y decide la cuenta de tesorería del asiento.
Con createRectifyingInvoice: true, tanto refund_create como
refund_manual emiten además la rectificativa por diferencias. El código
lo decide el servidor: R1 para la ordinaria y la simplificada con
destinatario identificado, R5 para la simplificada sin destinatario. Si
no se puede calcular exacta al céntimo, el reembolso se rechaza sin
registrar nada.
El régimen especial del pequeño empresario o profesional (REPEP) del
IGIC se gestiona con tres operaciones de finance_settings:
| Operación | Qué hace | Permiso del usuario |
|---|---|---|
get_small_business_regime | Si el régimen está vigente hoy, el periodo actual y el historial, si la organización puede declararlo y por qué no, el umbral de volumen del año y del siguiente, y los trimestres en los que no se presenta el modelo 420 | El de lectura de la pantalla fiscal (facturas, gastos, presupuestos o TAX_MODELS_VIEW) |
open_small_business_period | Declara un periodo con startsOn, endsOn opcional, entryReason, endReason y notes. Exige confirm: true | TAX_MODELS_CREATE |
update_small_business_period | Cierra o corrige el periodo periodId: para cerrarlo, endsOn y endReason; endsOn: null lo deja vigente. Exige confirm: true | TAX_MODELS_CREATE |
Solo pueden declararlo los autónomos con un régimen fiscal canario. Los periodos no se pueden solapar ni contradecir ventas IGIC ya emitidas (eso se corrige con rectificativas), y las escrituras devuelven avisos no bloqueantes. UTILIA OS nunca abre, cierra ni mueve un periodo por su cuenta: avisa, y lo decide la persona.
finance_settings: get_stripe es de solo lectura. Devuelve si la pasarela está disponible, si la organización puede cobrar
y por qué no, el estado de la cuenta conectada, su país y su divisa, y
los requisitos que Stripe tiene pendientes, ya traducidos al
castellano. Con eso el copiloto puede responder «tu cuenta está
conectada pero le falta este documento», que antes no podía responder en
absoluto.
Lo que no hay, y no es un olvido: ni alta ni desconexión por MCP. El
alta exige que una persona teclee en un formulario alojado por Stripe con
verificación de identidad, así que ofrecerla sería prometer lo que no hay.
Y la desconexión es en la práctica irreversible: rehacerla obliga a repetir
el alta entera, y eso no debe estar a un mensaje de distancia. Es el mismo
criterio de payment_methods: setup_intent.
Divergencia de permiso dentro de la herramienta: get_stripe acepta
configurar los pagos con tarjeta o verlos, en lugar del permiso de
ajustes de Finanzas que gobierna al resto de sus operaciones.
La facturación electrónica (Facturae, UBL y envíos a FACe) está retirada desde el 6 de julio de 2026: la herramienta invoices_einvoicing no se publica en tools/list y, si se invoca por su nombre, responde que no está disponible.
Operaciones bajo supervisión humana
Estas operaciones están anotadas con supervisedByHuman en el catálogo:
el cliente MCP debe pedir confirmación expresa al usuario antes de
ejecutarlas. Los scopes del token limitan el dominio finance operación a
operación: el servidor comprueba en cada llamada que el token porta el
scope granular de la operación y la deniega con un error explícito si no
lo lleva. La autorización final exige además que el usuario dueño del
token tenga el permiso correspondiente en UTILIA OS: scope y permiso son
condiciones independientes y ambas deben cumplirse. Las operaciones de
esta tabla exigen scopes que quedan fuera de los conjuntos finance:read y
finance:write (las acciones post, close, approve, delete,
manage, reprocess, submit y liquidate hay que concederlas
explícitamente o usar finance:full).
| Herramienta | Operaciones supervisadas | Scope que las habilita |
|---|---|---|
accounting_journal | Próximamente. post, cancel (contabilizar y anular asientos); reassign_business_unit (reimputa la unidad de negocio de líneas ya contabilizadas) | finance:accounting:post; reassign_business_unit con finance:accounting:update |
accounting_assets | Próximamente. dispose, depreciation_post, depreciation_reverse | finance:accounting:post |
accounting_close | Próximamente. close, reopen (cierre y reapertura del ejercicio) | finance:accounting:close |
expenses | approve, reject, bulk_approve (finance:expenses:approve); bulk_delete (finance:expenses:delete); pay, bulk_submit, bulk_pay (finance:expenses:update) | ver detalle por operación |
finance_payments | reprocess (reanaliza el documento con IA) y delete/restore | finance:payments:reprocess, finance:payments:delete |
payment_methods | setup_intent, set_default, delete | finance:payment-methods:manage |
commissions | Próximamente. approve, cancel | finance:commissions:approve |
commissions_admin | Próximamente. settlement_generate, settlement_approve, settlement_pay | finance:commissions:liquidate |
fiscal | Próximamente, salvo retention_rates_update. mark_filed, manual_file, pay, period_close, period_reopen (crm:fiscal:file); investment_good_dispose, investment_good_delete, retention_rates_update (crm:fiscal:manage) | ver detalle por operación |
crm_subscriptions, crm_mandates | las escrituras de las dos herramientas (cobros recurrentes y autorizaciones de cobro); sus lecturas van con crm:invoices:view, y check_readiness, con crm:invoices:view o crm:invoices:update | crm:invoices:update |
Las filas marcadas con Próximamente son de funciones en «Próximamente»: ver el aviso del principio de esta sección.
Dos operaciones mueven dinero real: crm_invoices_workflow: charge, que cobra con la tarjeta guardada del cliente, y refund_create, que devuelve por la pasarela. Las dos exigen confirm: true, el aplicativo de pagos con tarjeta y su permiso (INVOICES_CHARGE para cobrar, STRIPE_PAYMENTS_REFUND para devolver). Fuera de ellas, ninguna herramienta de este servidor mueve dinero ni desconecta bancos. Los presupuestos (crm_budgets*) son un documento comercial previo a la venta y viven solo en el servidor utilia-crm.
RRHH: festivos y calendario laboral
La herramienta attendance del servidor utilia-rrhh (POST https://os.utilia.ai/api/mcp/rrhh) decide qué festivos cuentan para tu empresa a partir de su ámbito territorial. Las mismas operaciones siguen publicadas por compatibilidad en workplace, del servidor utilia-crm, con el prefijo attendance_.
Un festivo cuenta para la empresa si su clave de ámbito (scopeKey) está en la lista de la empresa. Sin comunidad autónoma elegida, esa lista es ['ES', 'COMPANY']: solo cuentan los festivos nacionales y los propios de la empresa.
| Operación | Qué hace | Scope |
|---|---|---|
holidays_scope_get | Comunidad autónoma, isla y municipio de la empresa, las claves de ámbito que salen de ahí y los valores admitidos para elegirlos. | hr:attendance:view |
holidays_set_scope | Fija el ámbito. region es obligatoria, en formato ISO 3166-2; island solo vale con ES-CN; locality es el municipio tal y como se escribe. | hr:attendance:manage |
holidays_import | Carga el calendario oficial de un año dentro del ámbito de la empresa. Es idempotente y devuelve created, skipped y total. | hr:attendance:manage |
holidays_list con applicable | true: solo los festivos que cuentan para la empresa. false: solo los de otros ámbitos. Sin el filtro: todos. | hr:attendance:view |
Las cuatro exigen además el permiso ATTENDANCE_MANAGE_HOLIDAYS y el aplicativo RRHH contratado. Cada festivo devuelve scopeKey, scopeLabel (su rótulo en castellano) y applicable.
{
"jsonrpc": "2.0",
"id": "1",
"method": "tools/call",
"params": {
"name": "attendance",
"arguments": {
"operation": "holidays_set_scope",
"region": "ES-CN",
"island": "GC",
"locality": "Las Palmas de Gran Canaria"
}
}
}Lo que conviene saber:
- Los festivos municipales no se cargan: los publica cada ayuntamiento y no hay una fuente que los cubra.
holidays_importlo dice en el camponoticede su respuesta; se añaden a mano conholidays_create. - El ámbito no se pasa al cargar: sale del que tiene declarado la empresa.
- Una isla fuera de Canarias se rechaza con un error
400. - Elegir el ámbito y cargar el año son escrituras: cambian qué días descuentan jornada a toda la plantilla, así que un token de solo lectura no puede hacerlas.
- Quitar los festivos de otros ámbitos no se puede hacer por MCP. Es un borrado irreversible y solo está en Ajustes › RRHH › Festivos, necesitas entrar con tu cuenta, con vista previa y confirmación.
En los SDK, la superficie es sdk.mcp.attendance.holidays: getScope(), setScope(), import() y list() en JavaScript, y get_scope(), set_scope(), import_year() y list() en Python.
Cambios de contrato de septiembre de 2026
Si tu integración es anterior al 2 de septiembre de 2026, revisa esta sección
Esos días cambió el contrato de varias herramientas: algunas llamadas que funcionaban dejan de hacerlo y algunos datos que viajaban por defecto dejan de viajar.
Los conjuntos de escritura ya no borran en el gestor de archivos
dev:write y crm:write dejan de poder eliminar archivos, versiones y carpetas: para borrar hace falta dev:files:full o crm:files:delete. Ninguno de los dos conjuntos de escritura prometía borrar, igual que ya excluían el resto de los borrados del producto. A cambio, dev:write incluye ahora dev:files:manage, para que los tokens existentes sigan pudiendo crear carpetas y renombrar archivos.
Los datos bancarios y fiscales tienen scope propio
| Scope | Qué autoriza | Dónde está |
|---|---|---|
finance:suppliers:view-sensitive | Ver el NIF, el NIF-IVA, el IBAN, el SWIFT y el banco de los proveedores. | En finance:full. Fuera de finance:read y finance:write. |
crm:clients:view-sensitive | Ver el NIF, el límite de crédito y el descuento pactado de los clientes. | En crm:full. Fuera de crm:read y crm:write. |
La pantalla de autorización los muestra con su nombre y con aviso, porque con el IBAN de un proveedor se puede desviar un pago y las condiciones pactadas con un cliente son información comercial reservada.
Sin el scope, esas claves no existen en la respuesta: no llegan vacías ni nulas, porque un nulo en un campo fiscal se leería como «esta empresa no tiene NIF». Si tu integración compara candidatos lado a lado, tiene que tolerar la clave ausente. Los tokens emitidos antes del 2 de septiembre de 2026 conservan esos datos hasta el 2 de marzo de 2027; las autorizaciones nuevas no los conceden sin nombrarlos.
El recorte afecta a:
suppliers:list,get,search_by_tax_id,check_duplicate,deduplicate_preview,merge,list_payments,createyupdate.finance_payments:list,get,check_duplicateyupdate.crm_clients:list,get,create,update,check_duplicate,deduplicate_previewymerge, y el historial decrm_clients_info. En la previa y en la fusión de clientes se retira además el NIF-IVA, que solo se publica ahí. Los recuentos de cada ficha viajan siempre.- El volcado del reconocimiento de documentos (
extractedData): el recorte cubre trece nombres de clave a cualquier profundidad (el NIF, el NIF-IVA, el IBAN, la cuenta, el SWIFT y el BIC del proveedor, con sus variantes).receiverNif, que es el NIF de tu propia organización, no se recorta. check_duplicatedefinance_paymentsy desuppliers: sinSUPPLIERS_VIEW_SENSITIVE, el NIF desaparece decandidatesy deexpenseCandidates. La detección de duplicados funciona igual, porque se basa en el número, la fecha, el importe y la confianza.
create_many y update_many no aparecen porque cada elemento vuelve en versión corta, sin esos campos.
Archivos: permiso para vincular y scope por tipo de ficha
crm_files_management gobierna upload, link, unlink y bulk_link con FILE_MANAGER_LINK_CRM en lugar de CLIENTS_EDIT, porque admite fichas de varios módulos: las siete del CRM (client, contact, lead, project, opportunity, budget e interaction) y la del proveedor (supplier). El rol Asistente pierde esas cuatro operaciones por MCP, que tampoco podía hacer desde la aplicación.
Cada tipo de ficha exige además su propio scope, comprobado por parámetro:
| Ficha | Leer | Escribir |
|---|---|---|
| Las siete del CRM | El de la herramienta | El de la herramienta |
supplier | finance:suppliers:view | finance:suppliers:update |
get_linked_entities recorta también la lista que devuelve: un token del CRM no ve el nombre del proveedor al que cuelga un archivo. El gestor de archivos añade fm_virtual_folders: get_suppliers_tree, con el árbol de la carpeta virtual «Proveedores», y admite supplier en get_entity_files, link_files, unlink_file y unlink_files.
expenses: document_attach ya no copia el justificante: recibe el identificador de un archivo del gestor al que tengas acceso y lo cuelga del gasto. Sigue exigiendo confirm: true porque sustituye el justificante anterior. expenses: document_get añade source (file o legacy), fileId, fileName, mimeType y size; en los justificantes históricos, el tipo y el tamaño llegan nulos. El archivo queda compartido entre el gestor y el gasto, y un justificante no se puede retirar, solo sustituir.
Scopes nuevos
| Scope | Qué autoriza |
|---|---|
finance:suppliers:view-sensitive | Datos bancarios y fiscales del proveedor. |
crm:clients:view-sensitive | Datos fiscales y económicos del cliente. |
crm:lead-forms:view | Ver los formularios de captación. |
org:notifications:view y org:notifications:manage | Avisos y preferencias de aviso de la persona que autorizó el token. |
crm:portal:view y crm:portal:manage | Ver y gestionar el acceso de terceros al portal del cliente con portal_access. La lectura queda fuera de crm:read y la gestión fuera de crm:write; las dos están en crm:full. |
crm:clients:merge | Fusionar clientes duplicados: crm_clients: deduplicate y merge. |
crm:contacts:merge | Fusionar contactos duplicados: crm_contacts: deduplicate y merge. |
crm:leads:merge | Fusionar leads duplicados: crm_leads: merge. |
Los scopes de fusión se piden siempre por su nombre
Ninguno de los tres está dentro de crm:read ni de crm:write, y tampoco dentro de crm:full. Fusionar archiva o borra fichas y reescribe sus referencias sin vuelta atrás desde la aplicación, así que ninguna autorización antigua lo concede sin que el titular lo apruebe. Si tu aplicación fusiona, añade el scope a los que pide.
Las previas por reglas (deduplicate_preview de clientes y contactos) son lecturas y se piden con el scope de ver. La previa de merge, en cambio, la ejecuta la misma operación destructiva y exige el scope de fusionar.
Operaciones nuevas
Fusión de duplicados en el CRM:
crm_clients: deduplicate_preview: grupos de clientes duplicados según las reglas (mismo NIF; sin NIF, mismo correo, mismo dominio o mismo nombre y ciudad), con el superviviente propuesto, los recuentos de cada ficha y lo que se movería. No escribe nada: bastaCLIENTS_VIEWycrm:clients:view. Si alguna ficha de un grupo queda fuera de tu alcance de fusión, el grupo entero se omite.crm_clients: deduplicate: fusiona esos grupos. Exigeconfirm: true,CLIENTS_MERGEycrm:clients:merge.survivorIdselige quién sobrevive en cada grupo (hasta 500) ygroupIdsacota los grupos (hasta 100); los que ya no son duplicados vuelven enignoredGroupIdssin error.crm_clients: merge: fusiona las fichas que eliges a mano, de 1 a 20 duplicadas; es la salida cuando el NIF está mal escrito en una y ninguna regla las junta. Sinconfirmdevuelve la previa condryRun: truey no escribe nada, pero exige igualmente el permiso y el scope de fusionar. La ficha que sobrevive recibe contactos, oportunidades, proyectos, presupuestos, tareas, facturas, autorizaciones de cobro, accesos al portal, archivos, carpetas e interacciones, y rellena sus campos vacíos con los datos de las demás.- Dos opciones de
mergeexigen alcance total sobre el permiso de fusionar:allowDifferentTaxId, que une dos NIF distintos (nunca si las dos fichas tienen facturas emitidas), yallowPortalAccessMerge, que deja que los interlocutores externos de una empresa vean los documentos de la otra. crm_contactsycrm_leadstienen el mismo juego de operaciones con sus propios scopes. En contactos, dos fichas con usuario del portal no se pueden unir, y si alguna no puede recibir correos, la que sobrevive tampoco podrá.crm_leads: find_duplicateslista los grupos de leads duplicados con su tipo de coincidencia, su puntuación y el valor que los une, conLEADS_VIEWycrm:leads:view.check_duplicatehace lo contrario: contrasta un candidato antes de darlo de alta, yexcludeLeadIdevita que una ficha se detecte a sí misma al editarla.crm_contacts: search_by_emaillocaliza un contacto activo por su correo principal o secundario, sin distinguir mayúsculas. Devuelve como mucho uno, yfound: falsetanto si no hay ninguno como si el que hay queda fuera de tu alcance.
Proveedores:
suppliers: accounting_accounts: subcuentas contables 400 del proveedor. Exige Finanzas con la capacidad de Contabilidad, los permisos de ver contabilidad y de ver proveedores, y el scopefinance:accounting:view. Está en «Próximamente», como la Contabilidad.suppliers: createyupdateaceptanlogoFileId, el identificador de una imagen del gestor. En la edición, omitirlo deja el logotipo como está y enviarlo a nulo lo retira.- La actividad del proveedor (
get_interaction_thread,list_interaction_activities,list_interaction_attachments,log_interactions_many,attach_to_interaction,remove_interaction_attachment,schedule_meeting,complete_meeting,cancel_meetingy los filtros nuevos delist_interactions) se explica en La actividad de un proveedor, sin salir del copiloto.
CRM y calendario:
crm_clients: get_counterpart: el proveedor que comparte NIF con el cliente, o nada. Exige los dos aplicativos y los cuatro permisos de los dos lados, sensibles incluidos; si falta cualquiera, la respuesta es «no encontrado», igual que si el cliente no existiera.calendar_events_workflow: get_unifiedaceptasourcespara acotar el calendario unificado a algunas de sus catorce fuentes.supplier_meetingexige además el scope de la actividad del proveedor.- Personas de fuera de la organización en un evento.
calendar_eventsencreateyupdate, ycalendar_events_workflowenadd_attendees, aceptanexternalAttendees(lista de{ email, name? }, hasta 50) yexternalMessage. Cada persona recibe por correo la fecha, la hora y el lugar del evento con el archivo de calendario y, si el evento tiene videollamada (y Meet está en el plan), el enlace para entrar. Invitar nunca crea una videollamada. Enupdatese añaden, nunca sustituyen. Exige el permisoCALENDAR_INVITEoCALENDAR_EDIT, ser quien creó el evento (o administrador) y el scopedev:calendar:inviteodev:calendar:update. Si el correo de alguien no puede salir, queda invitado «por enviar» y la respuesta lo dice. Todo se comprueba antes de guardar nada. Un correo que pertenece a la organización se invita como interno, y a quien ya estaba invitado no se le vuelve a escribir. calendar_events_workflow: remove_external_attendeeyresend_external_invitationretiran a esas personas (reciben el aviso de cancelación) o les reenvían la invitación. Se identifican poremail, porinvitationIdo con una listaexternalAttendees, varias en una llamada; el reenvío respeta el margen de cinco minutos entre correos a la misma persona. ExigenCALENDAR_INVITEoCALENDAR_EDITy el mismo scope (y Meet en el plan para las invitaciones de un evento con videollamada).calendar_events: getdevuelveexternalAttendeescon su estado yhasVideoLink, yhasVideoCalldel evento.
Dos herramientas transversales nuevas, search y notifications, tienen página propia.
Los SDK
Los SDK cubren estos cambios desde la versión 2.27.0. Dos avisos:
- El mensaje de los errores de una herramienta ya no se pierde. El SDK lee las tres formas de error que conviven y añade la pista al mensaje.
- El error del SDK trae
errorCodeydetails.errorCodees el código exacto de la herramienta ydetails, su detalle:requiredScopescuando falta un scope,fieldcuando falta un parámetro,resourceyretryAfterSeconds.code, en cambio, sigue siendoVALIDATION_ERRORen los errores de herramienta, también en la versión actual: para distinguir un «no encontrado» de una regla de negocio, miraerrorCode.
Cambios de contrato de octubre de 2026
Desde el 20 de octubre de 2026, todas las herramientas comparten la misma forma de responder, de paginar y de rechazar, y se añaden operaciones que hasta ahora solo existían en la aplicación.
Errores con motivo
Los rechazos por plan, permisos, scope o reglas de negocio llegan como resultado de la herramienta (isError: true), no como error del protocolo. Una llamada mal formada (una herramienta que no existe en el servidor o parámetros que no cumplen su esquema) sí puede responder con el error JSON-RPC -32602. En los resultados, además del mensaje, error.details.errorCode dice el motivo y error.hint, qué hacer:
errorCode | Cuándo |
|---|---|
MODULE_NOT_ENABLED | El plan no incluye el aplicativo. Trae el plan que lo incluye, si existe. |
CAPABILITY_NOT_ENABLED | El aplicativo está contratado, pero no la capacidad. Es el mismo código que en la API REST. |
FEATURE_COMING_SOON | La función está en «Próximamente». No trae plan destino. |
PERMISSION_DENIED | Tu usuario no tiene el permiso. requiredPermissions da el código y el nombre que ves en la aplicación. |
INSUFFICIENT_SCOPE | Al token le falta un scope. Trae requiredScopes y grantedScopes. |
APPROVAL_REQUIRED | La operación se confirma en el móvil. Trae el reto en approval; repite la misma llamada con twoFactorApprovalId. No es un fallo. |
TWO_FACTOR_NOT_ENABLED | La operación exige tener activada la verificación en dos pasos (ver más abajo). |
TOOL_RETIRED | La herramienta está retirada. El mensaje dice cuál usar y con qué operación. |
Listados más ligeros y con cursor
Los listados de las herramientas principales (clientes, contactos, leads, oportunidades, proyectos, tareas e interacciones del CRM, calendar_events, tickets, issues, projects, ai_studio, chat_channels, chat_messages, las de Marketing, crm_invoices, crm_subscriptions y el gestor de archivos, entre otras) aceptan:
response_format:concise(por defecto) da los campos con los que se identifica y decide cada fila;detailed, la fila completa de siempre. La vista resumida nunca enseña nada que la completa no enseñaría.limitcon un máximo declarado en su esquema ycursor.offsetypagese siguen aceptando donde existían.
La respuesta trae las filas en items y la paginación en pageInfo (nextCursor, hasMore, pageSize, responseFormat y detailHint). nextCursor es nulo en la última página.
{
"name": "crm_clients",
"arguments": { "operation": "list", "limit": 50, "response_format": "concise" }
}Si leías la clave antigua del listado
Algunas herramientas devolvían las filas dos veces, en items y en una clave propia (clients, contacts, leads, tickets, campaigns...). Esa copia ya no llega a un asistente de IA. Si tu código la leía directamente, lee items. Los SDK de UTILIA no notan el cambio: se identifican con la cabecera X-Utilia-SDK y siguen recibiendo la fila completa y la clave antigua.
Avisos, siguiente paso y reintentos
_notices: avisos que no son error.ignoredFieldslista los parámetros que la herramienta no conoce, con el nombre válido más parecido;deprecatedOperationavisa de que la operación es obsoleta y nombra la sustituta;reauthorizationdice qué scope pedir al volver a autorizar cuando la llamada solo ha pasado por una compatibilidad que caduca.nextSteps: las creaciones y los cambios de estado de los flujos principales sugieren el paso siguiente comotool,operation,whyy, si hace falta,args(presupuesto creado, generar el PDF y enviarlo; ticket de error, convertirlo en elemento de trabajo). Solo aparecen los pasos que tu plan, tus permisos y el token permiten.idempotencyKeyyclientOperationIdson intercambiables. Si la herramienta declara uno, el otro se acepta en su lugar, también dentro de los elementos de un lote. Si mandas los dos con valores distintos, la llamada se rechaza.
Operaciones obsoletas
No se anuncian en tools/list, pero siguen respondiendo hasta el 8 de enero de 2027 con un aviso en _notices.deprecatedOperation. Cambia a la sustituta:
| Herramienta | Obsoleta | Sustituta |
|---|---|---|
crm_tasks | bulk_delete | delete_many |
crm_opportunities_stats | analytics_loss_reasons, analytics_top_contributors | loss_reasons, by_owner |
crm_budget_files | request_signature, generate_signing_link | force_send_signature |
organization_settings | update | La escritura de su sección: update_general, update_addresses, update_contact, update_billing, update_branding... |
organization_settings | get_public | get_branding, get_contact o get_regional (o get_full con permiso de ver los ajustes) |
workplace (servidor CRM) | attendance_* | attendance del servidor utilia-rrhh |
Herramientas retiradas
Responden con errorCode: TOOL_RETIRED sin ejecutar nada, y el mensaje da la operación equivalente:
| Retirada | Usa | Operaciones que cambian de nombre |
|---|---|---|
crm_budgets_workflow | crm_budgets | Ninguna. |
crm_budgets_pdf | crm_budgets | generate → pdf_generate, get_job_status → pdf_get_job_status, get_url → pdf_get_url, get_preview → pdf_get_preview, regenerate → pdf_regenerate |
crm_reports_custom | crm_reports | execute → execute_custom |
crm_budgets_items | crm_budgets_structure | Las de líneas llevan el sufijo _item o _items: list → list_items, add → add_item, add_many → add_items_many... |
crm_budgets_sections | crm_budgets_structure | Las de secciones llevan el sufijo _section o _sections: list → list_sections, create → create_section... |
crm_budget_attachments | crm_budget_files | list → list_attachments, get → get_attachment, link → link_attachment, update → update_attachment, unlink → unlink_attachment, link_many → link_attachments_many |
crm_budget_signers | crm_budget_files | list → list_signers, get → get_signer, verify → verify_signature; request_signature y generate_signing_link → force_send_signature. El resto se llama igual. |
Verificación en dos pasos para lo más delicado
En la aplicación, quien no tiene la verificación en dos pasos confirma las acciones delicadas con su contraseña o con la sesión abierta. Desde un asistente de IA no hay ninguna de las dos, así que estas operaciones exigen tenerla activada y se confirman en el móvil:
- Crear y renovar credenciales y claves de API:
api_credentials(create,rotate,org_keys_createyorg_keys_rotate) yorg_integrations_settings(api_keys_create,api_keys_regenerate). También ampliar una clave de la organización conorg_keys_update(más permisos, más caducidad o cambiar de responsable). - En
team_management: dar el rol Super Administrador, conceder permisos críticos (sueltos, por lotes, al copiar los de otra persona o al aplicar una plantilla), cambiar el correo de acceso de otra persona y dar, ampliar o devolver el acceso de la asesoría (advisors_invite,advisors_updatecuando amplía lo que ve o añade un responsable, yadvisors_restore). - Todas las escrituras de
org_security_privacy(ver Seguridad y privacidad de la organización).
Sin la verificación en dos pasos, la llamada se rechaza con TWO_FACTOR_NOT_ENABLED antes de pedir nada al móvil. Con ella, sigue el ciclo de APPROVAL_REQUIRED y twoFactorApprovalId. La aplicación no cambia.
Scopes nuevos de octubre
Ninguno entra en un conjunto, salvo crm:settings:view: se piden por su nombre y la persona los ve nombrados al autorizar.
| Scope | Qué autoriza (texto de la pantalla de consentimiento) |
|---|---|
org:team:permissions:manage | Conceder y retirar permisos a las personas del equipo, también al darlas de alta, copiar los de otra persona, crear, cambiar y aplicar plantillas de permisos, y dar, ampliar o devolver el acceso de la asesoría. |
org:team:credentials:manage | Cambiar la contraseña o el correo de acceso de otras personas, reenviarles el correo de alta y consultar el estado de sus enlaces para crear la contraseña. |
crm:settings:view | Ver la configuración del CRM: embudos y etapas de venta, campos personalizados, motivos de pérdida y puntuación de leads. Entra en crm:read y crm:full. |
crm:settings:manage | Cambiar la configuración del CRM: crear, editar, reordenar y eliminar etapas de venta, campos personalizados y motivos de pérdida, y cambiar la puntuación de leads. |
org:security:view | Ver los ajustes de seguridad de la organización: verificación en dos pasos, bloqueo de pantalla, modo restringido, límite de exportaciones y dominios salientes. |
org:security:manage | Cambiar los ajustes de seguridad de la organización. Exige tener activada la verificación en dos pasos y cada cambio se confirma en el móvil. |
org:privacy:view | Ver los plazos de conservación de datos, las solicitudes de derechos de protección de datos, el registro de incidentes de seguridad y los ajustes de la actividad de los contactos en el portal. |
org:privacy:manage | Cambiar los plazos de conservación, tramitar las solicitudes de derechos (también suprimir los datos de una persona), gestionar los incidentes de seguridad y decidir si se registra la actividad de los contactos en el portal. Exige la verificación en dos pasos y cada cambio se confirma en el móvil. |
org:privacy:export | Pedir la exportación de todos los datos de la organización. Exige la verificación en dos pasos y se confirma en el móvil. |
finance:custom-fields:manage | Crear, editar, reordenar y eliminar los campos personalizados de los proveedores y de sus personas de contacto. Eliminar un campo archivado quita sus valores de todas las fichas. |
org:team:manage ya no concede permisos ni toca contraseñas
org:team:manage cubre ahora solo el alta, la edición, la activación, la desactivación y el archivo de personas, y los departamentos. Conceder permisos pide org:team:permissions:manage, y las contraseñas y el correo de alta, org:team:credentials:manage. Hasta el 27 de enero de 2027, un token con org:team:manage puede seguir haciéndolo, con un aviso _notices.reauthorization: vuelve a autorizar tu aplicación con los scopes nuevos antes de esa fecha. Del mismo modo, cambiar los campos personalizados de proveedores ya no viaja en finance:settings:update ni en finance:full.
Operaciones nuevas de octubre
Gestión del equipo (team_management, servidor utilia-crm), igual que Ajustes › Usuarios y Ajustes › Permisos:
| Operaciones | Qué hacen | Permiso | Scope |
|---|---|---|---|
presets_list, presets_get | Plantillas de permisos de la organización. | SETTINGS_USERS_PERMISSIONS_EDIT | org:team:view o org:team:permissions:manage |
presets_create, presets_update, presets_delete, presets_apply | Crear, cambiar, borrar y aplicar una plantilla a una persona. Aplicarla reemplaza sus permisos personalizados. | SETTINGS_USERS_PERMISSIONS_EDIT con alcance «Todo» | org:team:permissions:manage |
users_copy_permissions | Copiar los permisos de otra persona. También reemplaza los que tenía. | SETTINGS_USERS_PERMISSIONS_EDIT con alcance «Todo» | org:team:permissions:manage |
roles_default_permissions | Qué permisos trae cada rol por defecto. | SETTINGS_PERMISSIONS_VIEW | org:team:view |
users_get_password_tokens | Estado de los enlaces de alta y de restablecimiento de contraseña de una persona: cuándo se generaron, si se usaron y cuándo caducan. Nunca devuelve el enlace. | SETTINGS_USERS_VIEW | org:team:credentials:manage |
users_resend_setup_email | Reenviar el correo de alta, que invalida los enlaces anteriores. | SETTINGS_USERS_EDIT | org:team:credentials:manage |
users_offboard_preview | Qué lleva una persona antes de darla de baja (empresas, oportunidades, tickets...), lo que se resuelve solo y los destinatarios sugeridos. | SETTINGS_USERS_DEACTIVATE o SETTINGS_USERS_DELETE | org:team:view |
users_offboard | Dar de baja traspasando su cartera a otra persona (reassignAllTo) o por categorías (assignments). Exige confirm: true. | SETTINGS_USERS_DEACTIVATE o SETTINGS_USERS_DELETE | org:team:manage |
Nadie modifica sus propios permisos por esta vía, y los permisos protegidos solo los concede, retira o reemplaza un Super Administrador. users_deactivate y users_delete siguen dando de baja sin traspasar nada, y lo avisan.
Acceso de asesoría
La misma herramienta da acceso a la persona de la asesoría o gestoría de la empresa, igual que el bloque «Tu asesoría» de Ajustes › Usuarios. No ocupa usuario del plan: cuenta en los accesos de asesoría. Lo que ve se decide por áreas, cada una con su nivel y con su aplicativo en el plan:
Área (areas) | Qué comparte | Niveles (level) |
|---|---|---|
finance | Contabilidad y fiscalidad | read (consultar y descargar) o manage (también registrar) |
labor | Laboral | read (consultar y descargar) |
documents | Documentos: una carpeta compartida (folderId, o newFolderName para crearla) | read (ver y descargar) o upload (también subir) |
chat | Chat de grupo con sus responsables en la empresa | participate (escribir en sus conversaciones) |
Dentro de las áreas que se comparten, overrides afina permiso a permiso (permission y enabled) con los códigos de advisors_catalog. Solo se comparte lo que quien da acceso tiene con alcance «Todo».
| Operaciones | Qué hacen | Permiso | Scope |
|---|---|---|---|
advisors_list, advisors_get | Las personas de la asesoría con sus áreas y su cupo; la ficha con sus ajustes y sus permisos efectivos. | SETTINGS_ADVISORS_MANAGE o SETTINGS_USERS_VIEW | org:team:view |
advisors_catalog | Qué áreas, niveles y ajustes puedes dar, según el plan y lo que tienes tú. | SETTINGS_ADVISORS_MANAGE | org:team:view |
advisors_invite | Dar acceso: alta, responsables (contactUserIds, de 1 a 10, y primaryContactUserId, el principal; por defecto, quien invita), carpeta compartida, chat de grupo con los responsables e invitación. Se confirma en el móvil. | SETTINGS_ADVISORS_MANAGE | org:team:manage y org:team:permissions:manage |
advisors_update | Cambiar áreas, ajustes, despacho o responsables. Las áreas, los ajustes y la lista de responsables (contactUserIds) se sustituyen enteros; primaryContactUserId cambia el principal. El campo antiguo contactUserId se sigue aceptando. Si amplía lo que ve o añade un responsable, se confirma en el móvil; quitar uno o cambiar el principal, no. | SETTINGS_ADVISORS_MANAGE | org:team:manage; con areas, overrides o responsables (contactUserIds, primaryContactUserId o contactUserId), además org:team:permissions:manage |
advisors_resend_invitation | Reenviar la invitación a quien todavía no ha entrado. | SETTINGS_ADVISORS_MANAGE | org:team:manage |
advisors_revoke | Quitar acceso: cierra sus sesiones y deja de compartir su carpeta. Exige confirm: true. | SETTINGS_ADVISORS_MANAGE | org:team:manage |
advisors_restore | Volver a dar acceso. Se confirma en el móvil. | SETTINGS_ADVISORS_MANAGE | org:team:manage y org:team:permissions:manage |
users_create y users_update no dan ni quitan el rol ASESORIA: responden ADVISOR_ROLE_IMMUTABLE y remiten a advisors_invite. Los errores propios son los de Ajustes: QUOTA_EXCEEDED_ADVISOR_SEATS (cupo lleno), MODULE_NOT_ENABLED (área fuera del plan), PERMISSION_NOT_ALLOWED_FOR_ADVISOR, GRANT_AUTHORITY_EXCEEDED, ADVISOR_EMAIL_EXISTS y ADVISOR_FOLDER_IN_TRASH.
En advisors_update, la carpeta que ya tiene no hace falta reenviarla: sin folderId ni newFolderName se conserva. La misma carpeta con el mismo nivel se queda tal cual, también si está en «Eliminados recientemente»; cambiar el nivel de Documentos con la carpeta allí responde ADVISOR_FOLDER_IN_TRASH (409): restáurala o elige otra.
Ajustes de la organización (organization_settings, servidor utilia-crm). Cada bloque exige su aplicativo en el plan:
| Operaciones | Qué hacen | Aplicativo | Permiso |
|---|---|---|---|
get_invoice_brand, update_invoice_brand, update_invoice_brand_full, upload_invoice_watermark_image | Diseño del PDF de facturas por tipo (ordinaria, rectificativa, nota de crédito) y su marca de agua. update_invoice_brand cambia un tipo; _full las reemplaza todas. | Finanzas | SETTINGS_ORGANIZATION_VIEW para leer, SETTINGS_ORGANIZATION_EDIT para cambiar |
get_billing_suggestions, apply_billing_suggestions | Datos fiscales sugeridos a partir de los de facturación de tu suscripción. Aplicarlos solo rellena los vacíos. | Ninguno | SETTINGS_ORGANIZATION_VIEW / SETTINGS_ORGANIZATION_EDIT |
get_external_ai, update_external_ai | Permitir o no el envío de datos a proveedores de IA externos. Cambiarlo es solo del Super Administrador, y desactivarlo, que pausa todas las funciones de IA, exige confirm: true. | Ninguno | Ninguno para leer, SETTINGS_ORGANIZATION_EDIT para cambiar |
get_meet_recording_notice, update_meet_recording_notice | Párrafo propio que se añade al aviso de grabación y transcripción de las reuniones. | Meet | MEET_MANAGE (con alcance «Todo» para cambiarlo) |
get_copilot_recording_notice, update_copilot_recording_notice | Párrafo propio que se añade al aviso que acepta quien usa Call Copilot. | Call Copilot | CALL_COPILOT_MANAGE (con alcance «Todo» para cambiarlo) |
Las lecturas piden org:settings:view (el aviso de Meet acepta también crm:meet:view) y las escrituras, org:settings:update.
Otras herramientas:
portal_access: list_portal_permissionsdice qué permisos del portal del cliente se pueden conceder. PidePORTAL_MANAGE_PERMISSIONS,PORTAL_INVITE_USERoPORTAL_MANAGE_CLIENT_ACCESS, ycrm:portal:view.suppliers(servidorutilia-finance) gestiona los campos personalizados de los proveedores y de sus personas de contacto:list_custom_fields,create_custom_field,update_custom_field,reorder_custom_fieldsydelete_custom_field. Leer pide el permiso de ver proveedores o de ver los campos; escribir,CUSTOM_FIELDS_MANAGEyfinance:custom-fields:manage.tickets_workflow: convert_to_issueconvierte un ticket en elemento de trabajo; los detalles, en Herramientas MCP de tickets.ai_studio: usesustituye las variables de un prompt y suma un uso; ver Herramienta MCP de AI Studio.crm_settingsyorg_security_privacyson herramientas nuevas: ver Configuración del CRM y Seguridad y privacidad de la organización.
Gestor de archivos: Eliminados recientemente
Desde el 22 de octubre de 2026, lo que una persona elimina por MCP ya no se destruye en el acto: pasa 30 días en «Eliminados recientemente», igual que en la aplicación, y después se borra para siempre con su contenido, sus miniaturas y sus versiones. Las operaciones de borrado se llaman igual; cambia lo que responden:
fm_files_manage:deleteybatch_deleterespondenoutcome: "TRASHED"conpurgeAfter(fecha ISO del borrado definitivo);deleteañaderetentionDays. Si el archivo sigue en uso en un sitio que la persona no puede editar,outcome: "IN_USE", como hasta ahora, con los sitios enreferencedBy(enbatch_delete, en elerrorde ese archivo).physicallyDeletedse mantiene por compatibilidad y llega afalse.remove_from_folderybatch_remove_from_folderrespondenoutcome: "REMOVED"si el archivo sigue en otros sitios y"TRASHED", conpurgeAfter, si esa carpeta era su última ubicación.fm_folders_manage:delete, con o sincascade, manda la carpeta a «Eliminados recientemente» con lo que solo estaba en ella, y respondeoutcome: "TRASHED"ypurgeAfter.fm_virtual_folders:unlink_fileyunlink_filesexigenconfirm: truecuando quitar el vínculo deja el archivo sin ningún sitio y lo manda a «Eliminados recientemente».
Tres operaciones nuevas recorren «Eliminados recientemente» (en el servidor utilia-crm, por ejemplo):
| Operación | Qué hace | Permiso | Scope |
|---|---|---|---|
fm_files: list_trash | Lista lo que la persona puede ver, de lo más reciente a lo más antiguo. Admite query (por nombre), limit (20 por defecto, hasta 100) y cursor. Devuelve items, pageInfo, retentionDays y purgeableCount. | FILE_MANAGER_VIEW | Cualquiera de lectura o escritura de archivos: crm:files:view, crm:files:upload, crm:files:delete, dev:files:view, dev:files:manage o dev:files:full |
fm_files_manage: restore | Devuelve cada elemento a sus carpetas y fichas si siguen existiendo y la persona puede editarlas; si no, a Inicio. | FILE_MANAGER_VIEW | crm:files:upload, crm:files:delete, dev:files:manage o dev:files:full |
fm_files_manage: purge | Lo borra para siempre. Exige confirm: true. | FILE_MANAGER_DELETE_FOLDER | crm:files:delete o dev:files:full |
restore y purge reciben un elemento (id, con kind: "folder" si es una carpeta; file por defecto) o un lote de hasta 50 en items: [{ kind, id }]. Una carpeta se restaura o se borra entera, con lo que se eliminó con ella. La respuesta trae results elemento a elemento, con outcome (RESTORED o FAILED al restaurar; PURGED, QUEUED o FAILED al borrar), errorCode y message, y failedItems si alguno falla. restore añade restoredTo (dónde ha quedado), renamedTo (si una carpeta cambió de nombre por estar el suyo ocupado) y uploadedBy. QUEUED cuenta como hecho: ya no se puede restaurar y termina de borrarse en cuanto responde el almacenamiento.
Qué ve y qué puede borrar cada persona lo decide el mismo servicio que la aplicación. Ve lo que eliminó y lo que subió; lo que eliminaron otras personas, solo con FILE_MANAGER_MANAGE_TRASH («Gestionar lo que eliminan otros») y dentro de su alcance. Borrar antes de tiempo es de quien lo subió (o creó la carpeta), del Super Administrador y de ese permiso; quien eliminó algo ajeno puede restaurarlo, pero no borrarlo. Lo que tiene bloqueado el acceso de la IA no aparece en list_trash y responde como inexistente. «Eliminar todo» no se publica por MCP: una destrucción masiva sin vuelta atrás se queda en la aplicación.
errorCode | Cuándo |
|---|---|
TRASH_ITEM_NOT_FOUND | No está en «Eliminados recientemente» o la persona no puede verlo. |
TRASH_ITEM_EXPIRED | Se le acabó el plazo y se está borrando. |
TRASH_ITEM_INSIDE_FOLDER | Se eliminó con su carpeta: restaura o borra la carpeta. |
TRASH_ITEM_CONTENT_GONE | Su contenido ya no existe en el almacenamiento y no se puede restaurar. |
TRASH_RESTORE_NO_DESTINATION | La carpeta de origen ya no existe o no se puede editar, y la persona no puede crear carpetas en Inicio. |
TRASH_RESTORE_CONFLICT | Otro archivo activo usa ya el mismo contenido: restáuralo o elimínalo antes. |
TRASH_PURGE_FORBIDDEN | Solo quien lo subió, el Super Administrador o quien gestiona lo que eliminan otros pueden borrarlo antes de tiempo. |
Al eliminar siguen las negativas de siempre, con su errorCode: FILE_IS_WORM_PROTECTED (la copia de lo que recibió el cliente), FILE_IS_ISSUED_INVOICE_ORIGINAL, FILE_IS_VAT_ACCREDITATION_EVIDENCE y, para carpetas, FOLDER_IS_SYSTEM. La guía de uso está en Eliminar y recuperar archivos.
Si quien conecta la IA es de la asesoría
Una persona de la asesoría trabaja solo en la carpeta que la empresa le comparte, y su IA tiene las mismas reglas que ella en la aplicación y en la unidad de red:
- Eliminar, mover, renombrar o sustituir (
delete,batch_delete,remove_from_folder,batch_remove_from_folder,move,batch_move,rename,upload_version,restore_version,delete_version,edit_content,patch): solo con el nivel «También subir» y solo lo que subió o metió ella en su carpeta compartida. Lo de la empresa es de solo lectura para ella, y nada sale de su carpeta: mover fuera, o a Inicio, se niega. - «Eliminados recientemente»:
list_trashsolo trae lo que ella eliminó de su carpeta compartida;restorelo devuelve solo a esa carpeta y, si la carpeta no está disponible (la empresa la ha eliminado o ya no la comparte), falla conTRASH_RESTORE_NO_DESTINATION.purgenunca: respondeTRASH_PURGE_FORBIDDEN. Con «Ver y descargar», la lista llega vacía.
errorCode | Cuándo |
|---|---|
ADVISOR_DELETE_NOT_ALLOWED | La asesoría intenta eliminar o sacar de una carpeta algo que no subió ni metió ella, algo de fuera de su carpeta compartida, o tiene «Ver y descargar». 403. |
ADVISOR_FILE_READ_ONLY | La asesoría intenta mover, renombrar o sustituir lo que no es suyo, o mover algo fuera de su carpeta compartida. 403. |
Solo se explica la negativa sobre lo que la asesoría ve (su carpeta o lo que subió ella); un archivo de la empresa que no ve responde como siempre, sin decir que existe.
Referencias
- Primeros pasos con MCP.
- Migración del MCP de integraciones de v1 a v2, si tu integración usaba la antigua herramienta
integrations. - Poner al día una cartera de clientes: lotes, logotipos, fusión con previa y espejo incremental.
- Scopes y recursos de OAuth.
- Buscador global y avisos por MCP.
- Herramienta MCP de tickets.