Conector de reservas de Center
Un servidor MCP público para asistentes personales de IA. Un asistente lo usa para ayudar a quien se lo pidió y solo reserva cuando esa persona lo aprueba.
Qué hace
- Encuentra negocios publicados en Center.
- Responde preguntas solo con los datos públicos de cada negocio.
- Consulta horarios libres.
- Reserva para la persona que inició sesión, con su aprobación.
Es distinto del servidor de encargos de Center de cada persona.
Punto de acceso y descubrimiento
https://app.center.com/mcp
Streamable HTTP: un mensaje JSON-RPC por POST, como application/json. GET y DELETE responden 405.
| Qué | Dónde |
|---|---|
| Punto de acceso MCP | https://app.center.com/mcp |
| Metadatos del recurso protegido (RFC 9728) | https://app.center.com/.well-known/oauth-protected-resource |
| Metadatos del recurso protegido (RFC 9728) | https://app.center.com/.well-known/oauth-protected-resource/mcp |
| Metadatos del servidor de autorización (RFC 8414), emisor https://app.center.com | https://app.center.com/.well-known/oauth-authorization-server |
| Punto de autorización (página de consentimiento, en inglés y español) | https://app.center.com/connect/authorize |
| Registro dinámico de clientes (RFC 7591) | https://app.center.com/v1/platform/connector/oauth/register |
| Token | https://app.center.com/v1/platform/connector/oauth/token |
| Revocación (RFC 7009) | https://app.center.com/v1/platform/connector/oauth/revoke |
Autorización (OAuth 2.1)
- Sin token bearer, POST /mcp responde 401 con un desafío WWW-Authenticate que indica los metadatos del recurso protegido y los permisos.
- El asistente lee los documentos de descubrimiento y se registra. Los clientes solo son públicos (token_endpoint_auth_method: none). Las redirecciones deben ser https, o http en loopback; deben coincidir exactamente, y una redirección loopback puede usar cualquier puerto.
- La persona abre la página de consentimiento. La solicitud debe llevar code_challenge con code_challenge_method=S256 (PKCE S256 es obligatorio; plain se rechaza), state y resource. Si lleva resource, debe ser https://app.center.com/mcp.
- La persona inicia sesión con un código de un solo uso que recibe por mensaje de texto en su teléfono. El inicio de sesión por correo aún no está disponible.
- La página de consentimiento nombra al asistente (tal como se registró), los permisos y exactamente lo que recibe un negocio cuando la persona reserva. La persona elige Permitir o No permitir.
- Un código de un solo uso (10 minutos) vuelve con state e iss (RFC 9207). El intercambio de token verifica el verificador PKCE y devuelve un token de acceso (1 hora) y un token de actualización (60 días). Los tokens de actualización rotan en cada uso; reutilizar uno anterior revoca todo el vínculo. Los tokens están ligados a https://app.center.com/mcp.
Las credenciales son opacas. Center solo guarda sus resúmenes SHA-256.
Permisos (scopes)
| Permiso | Herramientas |
|---|---|
businesses.read | search_businesses, get_business, find_available_slots, ask_business |
bookings.write | prepare_booking, confirm_booking, get_booking_status, cancel_booking, reschedule_booking |
Cualquier persona con sesión iniciada puede usar las herramientas de lectura. Una herramienta de reserva llamada sin bookings.write recibe HTTP 403 insufficient_scope y un desafío para ampliar permisos.
Herramientas
El conector solo ve negocios publicados. Cada resultado se arma campo por campo a partir del registro público.
search_businesses
- Lectura o escritura
- Lectura (
businesses.read) - Devuelve
- Solo negocios reales, publicados e indexables. De cada uno: id, handle, nombre, categoría, ciudad, resumen de calificaciones, rango de precios, servicios principales (precio y duración), si admite reservas en línea y la URL de su sitio.
- Efectos
- Ninguno.
- Anotaciones
readOnlyHint: sí,destructiveHint: no,idempotentHint: sí,openWorldHint: no
| Campo | Tipo | Significado |
|---|---|---|
query | string | Lo que busca la persona. |
near | string (ciudad) | {lat, lng} | Una ciudad o un punto. |
category (opcional) | string | Un tipo de negocio. |
when (opcional) | date o date-time | Cuándo quiere ir la persona. |
max_price (opcional) | number | Precio máximo, en unidades enteras de la moneda. |
language (opcional) | 'en' o 'es' | El idioma de la respuesta. |
get_business
- Lectura o escritura
- Lectura (
businesses.read) - Devuelve
- El perfil público: servicios con precio y duración, horario, dirección, teléfono, políticas (depósito y cancelación), servicios del local, idiomas, reseñas destacadas (4★ o más) y URL de fotos.
- Efectos
- Ninguno.
- Anotaciones
readOnlyHint: sí,destructiveHint: no,idempotentHint: sí,openWorldHint: no
| Campo | Tipo | Significado |
|---|---|---|
business_id | string | El negocio, de search_businesses. |
find_available_slots
- Lectura o escritura
- Lectura (
businesses.read) - Devuelve
- Horarios libres, cada uno con su precio actual, en la zona horaria del negocio. Nunca quién ocupa otro horario.
- Efectos
- Ninguno.
- Anotaciones
readOnlyHint: sí,destructiveHint: no,idempotentHint: no,openWorldHint: no
| Campo | Tipo | Significado |
|---|---|---|
business_id | string | El negocio. |
service_id | string | El servicio. |
from | date o date-time | Inicio del rango. |
to | date o date-time | Fin del rango. |
party (opcional) | integer | Cuántas personas. |
ask_business
- Lectura o escritura
- Lectura (
businesses.read) - Devuelve
- Una respuesta escrita solo con los datos publicados del negocio, en el idioma de la pregunta. Dice cuando no sabe.
- Efectos
- Ninguno.
- Anotaciones
readOnlyHint: sí,destructiveHint: no,idempotentHint: no,openWorldHint: no
| Campo | Tipo | Significado |
|---|---|---|
business_id | string | El negocio. |
question | string | La pregunta, en cualquier idioma. |
prepare_booking
- Lectura o escritura
- Escritura (aparta un horario) (
bookings.write) - Devuelve
- Una propuesta: proposal_id, el servicio exacto, el horario en la zona horaria del negocio, el total, las políticas, lo que recibirá el negocio (nombre y teléfono), expires_at y el texto del consentimiento para los mensajes de confirmación.
- Efectos
- Aparta el horario 5 minutos sin que nadie más lo vea. Cada persona aparta como máximo un horario por negocio; una nueva propuesta en el mismo negocio reemplaza la anterior.
- Anotaciones
readOnlyHint: no,destructiveHint: no,idempotentHint: no,openWorldHint: no
| Campo | Tipo | Significado |
|---|---|---|
business_id | string | El negocio. |
service_id | string | El servicio. |
start | fecha y hora (date-time) | El horario elegido. |
notes (opcional) | string | Una nota para el negocio. |
confirm_booking
- Lectura o escritura
- Escritura (
bookings.write) - Devuelve
- Un booking_ref estable, el horario y el estado.
- Efectos
- Reserva por el sistema de reservas del propio negocio, que avisa al negocio como con cualquier reserva de su sitio. Repetir la llamada devuelve la misma reserva.
- Anotaciones
readOnlyHint: no,destructiveHint: no,idempotentHint: sí,openWorldHint: no
| Campo | Tipo | Significado |
|---|---|---|
proposal_id | string | De prepare_booking. |
texts_consent | boolean | Si la persona aceptó los mensajes de confirmación, con el texto que devolvió prepare_booking. |
get_booking_status
- Lectura o escritura
- Lectura (reserva propia) (
bookings.write) - Devuelve
- Estado, servicio, horario, negocio y si todavía se puede cambiar.
- Efectos
- Ninguno.
- Anotaciones
readOnlyHint: sí,destructiveHint: no,idempotentHint: sí,openWorldHint: no
| Campo | Tipo | Significado |
|---|---|---|
booking_ref | string | De confirm_booking. |
cancel_booking
- Lectura o escritura
- Escritura (
bookings.write) - Devuelve
- El estado cancelado.
- Efectos
- Cancela la reserva, dentro del plazo de cancelación del propio negocio.
- Anotaciones
readOnlyHint: no,destructiveHint: sí,idempotentHint: sí,openWorldHint: no
| Campo | Tipo | Significado |
|---|---|---|
booking_ref | string | De confirm_booking. |
reason (opcional) | string | El motivo, para el negocio. |
reschedule_booking
- Lectura o escritura
- Escritura (
bookings.write) - Devuelve
- El nuevo horario.
- Efectos
- Cambia la reserva de horario. El mismo servicio, con el mismo personal.
- Anotaciones
readOnlyHint: no,destructiveHint: sí,idempotentHint: no,openWorldHint: no
| Campo | Tipo | Significado |
|---|---|---|
booking_ref | string | De confirm_booking. |
new_start | fecha y hora (date-time) | El nuevo horario. |
Un precio solo se indica cuando el dueño lo confirmó o viene de la página pública del propio negocio. Cualquier otro se muestra como "precio no publicado", nunca $0. Un negocio sin nada que reservar en línea devuelve booking_supported: false con cómo reservar (su enlace de reservas y su teléfono).
Depósitos
El conector no cobra pagos, y el dinero nunca pasa por un asistente. Cuando un servicio cobra un depósito o el precio completo al reservar, prepare_booking se niega con deposit_required. La negativa incluye el monto del depósito cuando está publicado, además de la página de reservas y el teléfono del negocio. No se aparta nada, y nada se reserva sin el depósito que exige el negocio.
Errores
- Sin token válido: HTTP 401 con el desafío de RFC 9728 (WWW-Authenticate: Bearer resource_metadata=…, scope=…).
- Falta un permiso: HTTP 403 insufficient_scope.
- Al pasar un límite: HTTP 429 con Retry-After y un error JSON-RPC cuyo data es {error: 'rate_limited', retry_after_seconds}.
- Una negativa de una herramienta es un resultado con isError: true y structuredContent: {error: <motivo>, message, …}.
Motivos:
invalid_argumentsbusiness_not_foundservice_not_foundservice_not_bookable_onlinebooking_not_supporteddeposit_requiredslot_unavailableproposal_not_foundproposal_expiredterms_changedbooking_not_foundcancel_window_passedalready_cancelledtest_account_real_businessbooking_unavailableask_unavailable
Límites de uso
Por minuto:
| Quién | Lecturas | ask_business | prepare_booking | Cada escritura de reserva |
|---|---|---|---|---|
| Por persona | 60 | 10 | 10 | 5 |
| Por cliente | 3000 | 300 | 300 | 150 |
Cada dirección puede hacer hasta 600 solicitudes por minuto a /mcp, porque los asistentes llaman desde direcciones compartidas.
Privacidad
- Los datos vienen solo del registro público del negocio. Ninguna herramienta lee los clientes, las reservas ni las conversaciones de un negocio.
- Los horarios son solo horarios libres: el conector nunca dice quién ocupa otro horario, nunca nombra a otro cliente y nunca da datos privados del personal.
- Cada persona ve, cancela y cambia solo las reservas que hizo con el conector. La reserva de cualquier otra persona responde booking_not_found.
Cuando la persona reserva, el negocio recibe el nombre de su cuenta de Center y su teléfono verificado. La página de consentimiento lo dice antes de que dé acceso.
Soporte y políticas
Preguntas o problemas: help@center.com
