Desarrolladores

Sonny MCP Beta

Conecta asistentes de IA compatibles con MCP (Claude y cualquier cliente que hable el Model Context Protocol) a tu espacio de trabajo, con los mismos permisos y límites que la API pública.

Lee la guía de la API pública

Inicio rápido

  1. 01

    Añade Sonny a Claude

    En Claude o Cowork, añade un conector personalizado con la URL https://www.usesonny.com/api/mcp. Sonny admite el registro automático de clientes, así que no hay ningún ID ni secreto de cliente que copiar.

  2. 02

    Aprueba el acceso al espacio de trabajo

    Claude abre Sonny en tu navegador. Inicia sesión, revisa los permisos solicitados y elige el espacio de trabajo que quieres conectar. OAuth 2.1 con PKCE limita los tokens de acceso y de actualización resultantes a esa aprobación.

  3. 03

    Pide a tu asistente que use Sonny

    Las herramientas se describen solas, así que basta con algo como «Muestra mis conversaciones abiertas». Los asistentes ven qué herramientas son de solo lectura y cuáles son destructivas, así que un buen cliente pregunta antes de cambiar nada.

Claude Code

claude mcp add --transport http sonny https://www.usesonny.com/api/mcp

Configuración de cliente en JSON

{
  "mcpServers": {
    "sonny": {
      "url": "https://www.usesonny.com/api/mcp"
    }
  }
}

Compatibilidad con claves de API

Si un cliente no puede completar OAuth, crea una clave con permisos acotados en Ajustes → Desarrolladores y envíala como cabecera Authorization Bearer. Las claves de API siguen siendo totalmente compatibles para clientes de servidor a servidor y clientes antiguos.

"Authorization": "Bearer sonny_your_key"

Cómo mantiene Sonny seguras las llamadas a herramientas

Un espacio de trabajo, los permisos que elijas
Cada llamada se ejecuta dentro del espacio de trabajo elegido durante el consentimiento OAuth o del espacio de trabajo al que pertenece la clave de API. Una herramienta solo funciona si su credencial tiene el permiso necesario.
Anotaciones de herramientas fiables
Las herramientas de solo lectura se marcan como de solo lectura; las que actualizan o eliminan se marcan como destructivas para que tu cliente pueda pedir confirmación antes de actuar.
Las mismas reglas de negocio
Las herramientas ejecutan exactamente los mismos flujos que la API pública: el historial de auditoría, las notificaciones y los webhooks se comportan como si el cambio lo hubiera hecho un compañero.

Mantén a un asistente dentro de una sola bandeja

Los canales seleccionados en una clave de API se aplican automáticamente en todas las llamadas a herramientas. Las claves de API y las conexiones OAuth también siguen el acceso a canales actual del compañero conectado. En las conexiones OAuth o las claves con acceso a todos los canales, los espacios de trabajo suelen tener varios orígenes, uno por producto o marca. Haz que tu asistente llame una vez a list_sources para descubrirlos y que luego pase sourceId a list_conversations, así las preguntas sobre un producto solo devolverán las conversaciones de ese producto. Cada conversación también lleva su propio sourceId, así que los resultados se pueden verificar.

Ejecuta un ciclo de soporte de bajo coste

  1. Descubre los cambios: arranca con el feed duradero sync, guarda nextCursor después de procesar cada página y elimina los IDs de eventos duplicados. Para elegir trabajo, llama a list_conversations con sourceId, awaitingReply: true, snoozed: "false" y compact: true. Las notas internas no ocultan los mensajes de clientes sin responder.
  2. Lee solo el texto nuevo: para cada conversación con cambios, llama a list_messages con el ID de tu último mensaje o una marca de tiempo ISO en after, y pon includeHtml: false salvo que de verdad necesites el HTML del correo.
  3. Espera a imágenes y vídeos: cuando list_messages devuelva readsInProgress, haz la llamada indicada en su nextStep. Su waitSeconds retiene la respuesta hasta que estén listas las lecturas de imágenes y las transcripciones de vídeo, así que no hace falta esperar por tu cuenta.
  4. Carga el contexto del cliente: get_conversation devuelve identityVerified, los verifiedTraits firmados y la página de origen y el contexto del cliente de la conversación. Si tiene un contact.id, pasa ese ID a list_conversations para cargar las conversaciones anteriores del cliente.
  5. Actívalo cuando haga falta: usa un webhook filtrado por origen para message.created que active al agente al instante, y ponte al día con sync. El feed duradero funciona con independencia de la entrega de webhooks. Usa una credencial con acceso a todos los canales para crear el webhook y restringir sus IDs de origen; el agente mantiene su credencial de ejecución limitada a su origen.

Catálogo de herramientas

Todas las operaciones de la API pública están disponibles como herramientas. Junto a cada una se indica el permiso necesario.

get_connection_info
Read connection access
conversations:read
get_conversation_context
Read support context
conversations:read
list_conversation_checks
Read conversation checks
conversations:read
record_conversation_check
Record a conversation check
conversations:write
get_status
Check Sonny status
conversations:read
create_conversation
Create a conversation from a form
conversations:write
upload_attachment
Upload a message attachment
attachments:write
list_properties
List custom properties
contacts:read
get_contact_properties
Read contact properties
contacts:read
set_contact_property
Set a contact property
contacts:write
list_contact_memories
Read customer memories
contact-memory:read
create_contact_memory
Save a customer memory
contact-memory:write
delete_contact_memory
Remove a customer memory
contact-memory:write
get_report
Read a support report
reporting:read
sync
Read workspace changes
conversations:read
batch_update_conversations
Update conversations in a batch
conversations:write
list_members
List members
members:read
list_teams
List teams
members:read
list_tags
List tags
tags:read
create_tag
Create a tag
tags:write
get_tag
Get a tag
tags:read
update_tag
Update a tag
tags:write
delete_tag
Delete a tag
tags:write
add_conversation_tag
Add a conversation tag
conversations:write
remove_conversation_tag
Remove a conversation tag
conversations:write
list_contacts
List contacts
contacts:read
create_contact
Create a contact
contacts:write
get_contact
Get a contact
contacts:read
update_contact
Update a contact
contacts:write
archive_contact
Archive a contact
contacts:write
erase_contact
Permanently erase a contact
contacts:write
list_channels
List conversation channels
conversations:read
list_sources
List sources
conversations:read
list_conversations
List conversations
conversations:read
get_conversation
Get a conversation
conversations:read
update_conversation
Update a conversation
conversations:write
list_messages
List messages
messages:read
create_internal_note
Create an internal note
messages:write
edit_message
Edit a sent reply
messages:send
send_message
Send a reply to the customer
messages:send
list_webhooks
List webhook endpoints
webhooks:read
create_webhook
Create a webhook endpoint
webhooks:write
list_webhook_events
List webhook event types
webhooks:read
update_webhook
Update a webhook endpoint
webhooks:write
delete_webhook
Delete a webhook endpoint
webhooks:write
test_webhook
Queue a test event
webhooks:write
list_webhook_deliveries
List webhook deliveries
webhooks:read
retry_webhook_delivery
Retry a failed delivery
webhooks:write
list_kb_articles
List knowledge base articles
kb:read
create_kb_article
Create a knowledge base article
kb:write
get_kb_article
Get a knowledge base article
kb:read
update_kb_article
Update a knowledge base article
kb:write
delete_kb_article
Delete a knowledge base article
kb:write
list_kb_categories
List knowledge base categories
kb:read
create_kb_category
Create a knowledge base category
kb:write
update_kb_category
Update a knowledge base category
kb:write
delete_kb_category
Delete a knowledge base category
kb:write
get_csat_summary
Get CSAT scores
csat:read
list_csat_ratings
List CSAT ratings
csat:read
get_conversation_csat
Get a conversation's CSAT rating
csat:read
reorder_kb_articles
Reorder knowledge base articles
kb:write
upsert_kb_article
Sync a knowledge base article
kb:write
reorder_kb_categories
Reorder knowledge base categories
kb:write
upsert_kb_category
Sync a knowledge base category
kb:write
get_kb_category
Get a knowledge base category
kb:read
get_help_center
Get help center settings
kb:read
update_help_center
Update help center settings
kb:write
upload_kb_media
Upload a help center image
kb:write
list_kb_audiences
List audiences
kb:read
create_kb_audience
Create audience
kb:write
update_kb_audience
Update audience
kb:write
delete_kb_audience
Delete audience
kb:write

Flujos de trabajo con agentes

Clasifica, actúa y mantente sincronizado

REST y MCP comparten los mismos permisos y flujos de trabajo. Las credenciales solo pueden acotar tu acceso actual a canales; si quitas un canal de tu pertenencia, también se quita de tus integraciones.

Encuentra las conversaciones que requieren atención

Filtra por awaitingReply, unread, unassigned, assigneeId, agentGroupId, snoozed, priority o tagIds. awaitingReply ignora las notas internas; unread es específico del compañero autenticado. unassigned significa sin asignado individual, aunque haya un equipo asignado. Las etiquetas coinciden con cualquiera de los IDs enviados.

list_conversations({ status: "open", awaitingReply: true, compact: true, sort: "waitingSince", direction: "asc" })

Ordena por waitingSince, lastMessageAt, createdAt o prioridad de negocio, con direction asc o desc. Los IDs resuelven los empates. Si omites filtros, se mantienen compact=false y snoozed=any. En REST, tagIds acepta IDs separados por comas; MCP también acepta un array. waitingSince empieza en el primer mensaje entrante después de la última respuesta; los seguimientos y las notas internas no lo reinician. Ejecuta este análisis de la cola de espera de forma programada aunque no llegue ningún webhook, para que los hilos antiguos vuelvan a aparecer.

Ponte al día sin releer la bandeja

Usa sync con conversations:read. El feed duradero incluye cambios de conversaciones, etiquetas, mensajes, propiedades de contactos, memorias y registros de eliminación. Cada carga requiere además su propio permiso de lectura: los cuerpos de los mensajes necesitan messages:read y las memorias, contact-memory:read. Las credenciales restringidas solo reciben los canales permitidos.

  1. Empieza sin cursor, sigue nextCursor hasta que hasMore sea false y guarda ese cursor.
  2. Lee las listas actuales de conversaciones y contactos y el historial que necesites para tu estado inicial.
  3. Reproduce desde el cursor guardado para captar los cambios ocurridos durante esa lectura. Procesa cada página y guarda nextCursor.

Elimina duplicados por el id del evento: la reproducción es «al menos una vez», así que las acciones posteriores necesitan su propia protección contra duplicados. Una petición sin cursor cubre la última hora, no una instantánea completa. Los eventos se conservan 30 días; HTTP 410 resync_required significa que debes volver a cargar el estado. Vuelve a cargarlo también después de ampliar los permisos o el acceso a canales. Usa limit hasta 100 y maxBodyChars hasta 10 000 (500 por defecto). Pon compact=true para obtener los campos textPreview/textTruncated de los mensajes, limitados a 200 caracteres, en lugar de body/bodyTruncated. Los webhooks pueden activar a un agente; el feed sigue disponible sin suscripciones a webhooks o cuando la entrega de webhooks está atascada.

Registra las comprobaciones una vez y comparte el resultado

Antes de repetir una investigación, lee list_conversation_checks (GET /api/v1/conversations/{conversationId}/checks). Guarda un resultado con record_conversation_check (PUT a la misma ruta), indicando key, result, checkedBy y, opcionalmente, una reference para el ID o la URL de la tarjeta. Por ejemplo: key=product-version, result=Shopstar Go verified, checkedBy=Engineer, reference=card-X. Sonny registra el actorId autenticado y la marca de tiempo checkedAt. Reutilizar una key sustituye solo esa comprobación; es el estado actual, no un historial. Las lecturas necesitan conversations:read y las escrituras conversations:write, ambas limitadas al canal de la conversación. Estas llamadas no envían ninguna respuesta ni marcan al vendedor como respondido.

Asigna y actualiza el trabajo por lotes

Descubre los compañeros y equipos activos y asignables con list_members / list_teams (members:read). Las respuestas incluyen la disponibilidad y el acceso efectivo a canales, sin direcciones de correo. Usa conversations:write para cambiar status, priority, assigneeId, agentGroupId, snoozedUntil, snoozedUntilReply, addTagIds o removeTagIds.

batch_update_conversations({
  conversationIds: ["conversation_1", "conversation_2"],
  updates: { agentGroupId: "team_1", assignment: "round_robin" }
})

La asignación rotativa elige un miembro del equipo disponible que pueda acceder al canal de la conversación. Si no hay ningún miembro que cumpla los requisitos, una actualización individual devuelve 409 y un elemento del lote falla. Cada lote acepta hasta 100 IDs únicos y aplica un cambio de forma atómica por conversación. Revisa cada resultado { id, ok, error? }; algunos elementos pueden fallar. Los lotes usan el límite de peticiones actual, sin cobro ponderado por número de elementos.

Comparte el contexto del cliente con Sonny AI

Lista, guarda y elimina memorias de contactos con contact-memory:read/write. Indica tanto contactId como un sourceId accesible; el contacto debe tener una conversación en ese origen. Los datos guardados usan la misma validación, gestión de duplicados y límites que la aplicación, y se registran como memorias manuales.

Lee las definiciones de propiedades en /api/v1/properties y lee o define valores en /api/v1/contacts/{contactId}/properties. MCP ofrece list_properties, get_contact_properties y set_contact_property. Requieren contacts:read/write y acceso a todos los canales. Indica exactamente un propertyId o un propertyName, con un valor de cadena o null para borrarlo. Los valores de texto, número, URL, fecha y selección se validan según la definición del campo.

set_contact_property({ contactId: "contact_1", propertyName: "Plan", value: "Pro" })
list_contacts({ property: { Plan: "Pro" } })

Los filtros de propiedades coinciden con cadenas guardadas exactas; si hay varias propiedades, deben coincidir todas. Los valores escritos por la API se etiquetan como datos de la API en Co-Pilot y en el respondedor automático. Se siguen aplicando las reglas existentes de cliente verificado y de origen. Los valores de campos internos introducidos a mano siguen excluidos de este contexto de IA.

Lee los mismos informes que tu equipo

Con reporting:read, llama a get_report({ kind, filters }). Los tipos son overview, volume, response-times, agents, sources, tags, csat, ai, knowledge, leads y online-hours. overview combina recuentos, tiempos de respuesta y CSAT. Los filtros son period (de 1 a 365 días, 30 por defecto), fechas from/to emparejadas (to es exclusiva), granularity (day/month), source, assigneeId y tagId. source acepta all, all-chat, all-email, website:{id} o email:{id}.

Los informes usan las consultas del panel y las comprobaciones de acceso actuales. knowledge usa las fechas y los canales permitidos, independientemente del origen, el asignado o la etiqueta seleccionados. online-hours mide la presencia en el espacio de trabajo de los compañeros accesibles; sus recuentos de conversaciones siguen limitados por canal. Los endpoints /csat existentes mantienen su permiso csat:read independiente y pueden describir una población distinta.

Envía archivos con respuestas o notas internas

Concede attachments:write y sube un archivo de hasta 25 MB para una conversación. upload_attachment recibe conversationId, fileName, contentType y dataBase64. La respuesta contiene un id y expiresAt. Pasa hasta 10 attachmentIds a una respuesta o nota en el plazo de una hora. Cada subida está vinculada a tu usuario y a la conversación, y solo se puede usar una vez. Las subidas sin usar se eliminan cuando caducan.

send_message({ conversationId: "conversation_1", attachmentIds: ["upload_1"] })

Las respuestas requieren messages:send; las notas internas requieren messages:write y nunca llegan a los clientes. Se admiten mensajes solo con adjuntos. Las respuestas por correo incluyen los archivos que caben en el tamaño máximo del correo y enlaces de descarga para el resto; los correos de chat sin conexión incluyen enlaces a los archivos. Los enlaces enviados por correo siguen funcionando mientras exista el adjunto, así que los destinatarios pueden abrirlos más tarde. Reenviar el correo comparte el acceso a esos archivos. Consulta emailDeliveryStatus para ver los fallos de entrega.

Las lecturas de mensajes autorizadas incluyen downloadUrl, downloadExpiresAt, aiStatus, aiDescription y aiExtractedText, además de videoTranscripts para los vídeos enlazados (Loom, Vimeo y otros). Los enlaces de descarga duran 15 minutos; vuelve a leer el mensaje para obtener enlaces nuevos. Las nuevas subidas por API/MCP tienen almacenamiento privado. Los adjuntos más antiguos siguen siendo públicos y se marcan como access=legacy_public: su URL original no caduca. Leer un mensaje inicia la lectura de sus imágenes si el espacio de trabajo tiene Sonny AI. Las lecturas de imágenes y las transcripciones de vídeo terminan poco después de que llegue un mensaje: mientras alguna siga en curso, la respuesta empieza con readsInProgress, cuyo nextStep indica la llamada exacta que hay que hacer. Pasa waitSeconds (hasta 30) para esperarlas en una sola petición. Los mensajes del widget y en tiempo real para clientes nunca incluyen extracciones ni transcripciones.

Explora los contratos completos de peticiones y respuestas

Base de conocimiento

Sincroniza desde una fuente externa

Sincroniza artículos y categorías con IDs externos estables, importa Markdown o HTML, sube imágenes, define el orden y gestiona las audiencias de lectores. Repetir un upsert actualiza el contenido existente.

  1. Elige el sourceId de tu canal y concede kb:read y kb:write. Para el descubrimiento opcional, list_sources también necesita conversations:read.
  2. Crea la categoría y sincroniza un artículo como borrador. Revisa su formato y su acceso antes de publicarlo.
  3. Configura el acceso al centro de ayuda, publica y prueba la vista del lector. Usa paginación e IDs externos estables para las actualizaciones posteriores.
Sigue la guía completa de sincronización con MCP

Gestiona las audiencias de clientes

Crea grupos a partir de atributos de clientes verificados y aplícalos a un centro de ayuda, una categoría o un artículo. Deben cumplirse todas las restricciones heredadas. Las credenciales de la API y de MCP actúan como personal del equipo dentro de sus permisos; previsualiza y prueba una sesión real de cliente para comprobar el acceso de los lectores.

Configura y prueba las audiencias del centro de ayuda

Documentación relacionada