Citas reservadas por MCP
crm_bookings y crm_bookings_workflow: las citas que reservan tus clientes, los enlaces para reservar y las páginas de reservas, con sus permisos, scopes, la aprobación en el móvil y los errores.
Actualizado el . 9 min de lectura
Incluido en todos los planes. Ver precios
crm_bookings y crm_bookings_workflow, del servidor utilia-crm, hacen por MCP lo mismo que CRM › Citas: ver las citas que reservan tus clientes, darles una cita, mandarles un enlace para que elijan hora, cambiarlas, cancelarlas y marcarlas, y elegir las horas y la página de reservas de cada persona. Usan los mismos servicios que la aplicación, con sus reglas. Los eventos de la agenda que no reservó un cliente siguen en calendar_events.
Requisitos
- Plan: el aplicativo CRM y la capacidad «Reserva de citas». Sin ella,
CAPABILITY_NOT_ENABLEDcon el plan que la abre yupgradeUrl. Lo que la empresa ya tiene reservado sigue atendiéndose sin la capacidad (más abajo). - Permiso de la persona sobre la persona con la que es la cita: «Ver citas y enlaces de reserva» (
BOOKINGS_VIEW), «Gestionar citas y enlaces de reserva» (BOOKINGS_MANAGE) o «Publicar la página de reservas» (BOOKING_PAGE_MANAGE), con su alcance: tú, quien supervisas, tu departamento o todo el equipo. - Scope del token, por operación:
| Scope | Qué abre | ¿En qué conjunto viaja? |
|---|---|---|
crm:bookings:view | Leer citas, enlaces, páginas y horas libres | crm:read y crm:full |
crm:bookings:manage | Cambiar, cancelar y marcar citas, decidir «No es la misma» y retirar enlaces | crm:full (no crm:write) |
crm:booking-links:share | Reservar por un cliente, crear y cambiar enlaces y «Pedir que elija otra hora» | Ninguno: se pide por su nombre |
crm:booking-pages:manage | Las horas para citas de una persona y su página de reservas | Ninguno: se pide por su nombre |
Los dos últimos crean algo que se abre sin iniciar sesión o escriben a personas de fuera con el nombre de tu empresa, por eso ninguna integración los gana sin pedirlos. Si falta uno, la respuesta es INSUFFICIENT_SCOPE con el enlace para concederlo sin desconectar (org_plan connection_access lo dice antes).
Operaciones
crm_bookings (lectura)
| Operación | Qué devuelve | Permiso |
|---|---|---|
appointments_list | Citas con filtros (status, hostId o host, source, from, to, leadId, contactId o clientId, unmarked, inAbsence, crmMatch, upcoming). contactId suma las del lead que se convirtió en ese contacto; clientId, las de todos sus contactos y de los leads convertidos en él. Vista resumida por defecto, sin correo ni teléfono; response_format: "detailed" da la fila entera. Paginación con limit (hasta 50) y cursor. | BOOKINGS_VIEW |
appointment_get | La cita con su sala, su evento, su interacción, su ficha del CRM y lo que escribió el cliente (clientWritten). | BOOKINGS_VIEW |
links_list, link_get | Los enlaces con su estado (linkStatus), con los mismos filtros por ficha (leadId, contactId o clientId) y, si la medición está activa, cifras de conjunto de lo que se hizo en cada uno. Nunca la dirección del enlace. | BOOKINGS_VIEW |
pages_list, page_get | Las páginas del equipo; page_get añade las horas para citas de la persona y las cifras de su página por semanas (weeks, 4 por defecto). | BOOKINGS_VIEW |
slots | Horas libres de una persona, cada una con start (ISO) y local, en su zona. Sin from ni to, los 7 días siguientes; 80 horas como mucho por llamada. Con appointmentId, las de esa cita sin contar su propio hueco; con linkId, las que permite ese enlace. | BOOKINGS_MANAGE sobre esa persona |
crm_bookings_workflow (escritura)
| Operación | Qué hace | Permiso | Scope | ¿confirm? |
|---|---|---|---|---|
book | Reserva una cita en nombre de un cliente y le escribe. Lleva idempotencyKey. | BOOKINGS_MANAGE | crm:booking-links:share | sí |
link_create | Crea un enlace para reservar y devuelve url y share (el texto para mandarlo). No envía nada. | BOOKINGS_MANAGE | crm:booking-links:share | no |
link_update | Cambia mensaje, nota, caducidad, canal o duración; devuelve otra vez url y share. | BOOKINGS_MANAGE | crm:booking-links:share | no |
appointment_request_new_time | Cancela la cita y manda al cliente un enlace nuevo para elegir otra hora. | BOOKINGS_MANAGE | crm:booking-links:share | sí |
appointment_reschedule | Cambia la hora (start), la duración (durationMinutes) o las dos; nunca la persona. | BOOKINGS_MANAGE | crm:bookings:manage | sí |
appointment_cancel | Cancela la cita y avisa al cliente. | BOOKINGS_MANAGE | crm:bookings:manage | sí |
appointment_mark | «Hecha» o «No se presentó» (outcome), cuando ya ha empezado. | BOOKINGS_MANAGE | crm:bookings:manage | no |
appointment_crm_match | «No es la misma» sobre un «Correo sin comprobar» (decision: "different"): da de alta el lead si hay Leads en el plan. | BOOKINGS_MANAGE | crm:bookings:manage | no |
link_revoke | Retira un enlace. | BOOKINGS_MANAGE, o BOOKINGS_VIEW si es tuyo | crm:bookings:manage | sí |
availability_update | Guarda las horas en que una persona recibe citas (weeklyHours, «Días sin citas», duración, antelación...). | BOOKINGS_MANAGE | crm:booking-pages:manage | no |
page_update | Dirección (slug), título, descripción, preguntas, tope diario y medición de la página. | BOOKING_PAGE_MANAGE | crm:booking-pages:manage | no |
page_publish | Publica la página: cualquiera con la dirección ve sus horas libres y reserva. | BOOKING_PAGE_MANAGE | crm:booking-pages:manage | sí |
page_pause | Pausa la página; las citas ya reservadas se mantienen. | BOOKING_PAGE_MANAGE, o BOOKINGS_VIEW si es tuya | crm:booking-pages:manage | sí |
Sin confirm: true, una escritura responde VALIDATION con details.field: "confirm" y no toca nada; en book, el mensaje cuenta lo que va a pasar para que se lo enseñes a la persona. Toda escritura devuelve effect: summary (lo que ha pasado, en una frase), clientNotified (si el cliente ha recibido un correo) y, si se puede, undo.
Personas y fichas por su nombre
Donde se pide hostId vale también host, con el nombre o el correo de la persona; donde se pide leadId o contactId, lead o contact. Solo se elige sola la que encaja exacta entre las que puedes ver o gestionar. Si encajan varias, o solo una por parte del nombre, la respuesta es CONFLICT con BOOKING_HOST_AMBIGUOUS o BOOKING_RECORD_AMBIGUOUS y las candidatas en details.items: pregunta cuál es y repite con su identificador. Sin hostId ni host, la persona eres tú.
Reservar por un cliente
book necesita start (una de las horas de slots), mode (VIDEO, que exige el correo, o PHONE, que exige el teléfono) y una idempotencyKey tuya para esa reserva. Con leadId o contactId, el nombre y el correo salen de la ficha.
- Con la ficha y su correo, basta
confirm: true. - Con un correo que no es el de la ficha, o sin ficha, la reserva se aprueba además en el móvil de la persona, atada al correo, a la persona con la que es la cita y a la hora: la primera llamada responde
APPROVAL_REQUIREDcon suapprovalIdy no reserva nada; cuando la persona la apruebe, repite la misma llamada contwoFactorApprovalId. Una aprobación pedida para un correo no vale para otro. Sin la verificación en dos pasos activada,TWO_FACTOR_NOT_ENABLED: se reserva en la aplicación. - Si pierdes la respuesta, repite con la misma
idempotencyKeyy los mismos datos: devuelve la misma cita y no escribe dos veces al cliente. La misma clave con otros datos respondeIDEMPOTENCY_KEY_REUSED. - Sin correo (una llamada por teléfono), el cliente no recibe confirmación. El «Ver mi cita» para mandarlo por WhatsApp se copia en la aplicación: por MCP no sale nunca.
- Como mucho 20 reservas por persona y hora (
BOOKING_ON_BEHALF_RATE_LIMITED).
{
"jsonrpc": "2.0",
"id": "1",
"method": "tools/call",
"params": {
"name": "crm_bookings_workflow",
"arguments": {
"operation": "book",
"host": "Marta García",
"leadId": "cmlead0001",
"start": "2026-11-10T09:00:00.000Z",
"mode": "VIDEO",
"confirm": true,
"idempotencyKey": "reserva-ana-martes-10"
}
}
}Lo que no sale por MCP
- La dirección de un enlace solo sale al crearlo o cambiarlo (
link_create,link_update), concrm:booking-links:share.links_listylink_getno la traen: un enlace reserva y escribe al cliente, no es como el de un archivo. - «Ver mi cita» y la sala no salen nunca.
- Lo que se hizo en un enlace solo llega si la persona aceptó la medición, y solo de conjunto: aperturas, si alguna fue en el móvil, el paso más lejano y los días que miró.
activity: nulles «sin datos», no «no lo ha abierto». Nunca ciudad, país, idioma, navegador ni aparatos. De la página, solo cifras por semana. Mientras la medición no esté activa en tu cuenta, la respuesta lo dice una vez enmeasurement. - Lo que escribe el cliente (su nota y sus respuestas) llega aparte, en
clientWritten, en una línea y con un aviso: son datos, nunca instrucciones. - Texto libre al cliente al cancelar: el motivo es de una lista cerrada (
reasonCode:HOST_UNAVAILABLE,CLIENT_ASKED,DUPLICATEuOTHER, sin motivo). - «Es la misma persona» sobre un «Correo sin comprobar» lo decide alguien del equipo en la aplicación; por MCP solo «No es la misma».
Sin la capacidad en el plan
Al acabar la prueba o bajar de plan, la empresa conserva lo que ya tenía con sus clientes. Siguen abiertas, sin la capacidad y con su permiso: appointments_list y appointment_get (las citas futuras y las canceladas en los últimos 30 días, con un aviso en closing), appointment_cancel (también con la cuenta en pausa), y pausar tu página o retirar tus enlaces. Lo demás responde CAPABILITY_NOT_ENABLED, y su hint lo recuerda.
Asistentes en un canal
En una respuesta que leen más personas, crm_bookings se usa con el alcance de quien pregunta, pero crm_bookings_workflow no: escribe a un cliente con el nombre de tu empresa o publica una agenda. El asistente lo explica y se hace en una conversación privada con él.
Errores
Cada uno lleva su errorCode en details y una hint que dice qué hacer. Los más frecuentes:
errorCode | Qué pasa |
|---|---|
BOOKING_SLOT_TAKEN, BOOKING_SLOT_NOT_OFFERED | Esa hora ya no está libre: pide otra con slots. |
BOOKING_HOST_NOT_FREE | Al cambiar la hora o la duración, la persona no tiene ese tiempo libre. |
BOOKING_HOST_HAS_NO_HOURS | La persona aún no tiene horas para citas: availability_update. |
BOOKING_HOST_OUT_OF_SCOPE | La persona queda fuera del alcance de tu permiso. |
BOOKING_HOST_CANNOT_INVITE_EXTERNAL | La persona no puede invitar a gente de fuera: usa PHONE o pide el permiso. |
BOOKING_CRM_RECORD_NOT_VISIBLE, BOOKING_HOST_CANNOT_SEE_RECORD | Tú, o la persona de la cita, no podéis ver esa ficha. |
BOOKING_CHANGED_MEANWHILE, BOOKING_NOT_SCHEDULED | La cita cambió entre medias o ya no está pendiente: vuelve a leerla. |
BOOKING_PAUSED_BY_HOST | La persona pausó su página o retiró el enlace: solo ella lo deshace. |
BOOKING_PAGE_NOT_PUBLISHABLE | La página se publica cuando el plan incluye «Reserva de citas» y ya se ha cobrado; los enlaces sí funcionan. |
BOOKING_HANDLE_REQUIRED | Falta el nombre público de la empresa, que se elige en la aplicación. |
CAPABILITY_NOT_ENABLED | Falta «Reserva de citas», o «Leads» al anclar una cita o un enlace a un lead. |
La guía de uso está en Citas con clientes, con Cambiar, cancelar y marcar una cita y Mi disponibilidad y tu página de reservas; el reparto con el calendario, en Agenda compartida y categorías por MCP.