Postproxy

Publica en múltiples redes sociales con solo un MCP

Documentación

Servidor MCP de Postproxy

Servidor MCP (Protocolo de Contexto del Modelo) para integrar la API de Postproxy con Claude Code. Este servidor proporciona herramientas para publicar publicaciones, verificar estados y gestionar perfiles de redes sociales a través de Claude Code.

Instalación

Instalación Global

npm install -g postproxy-mcp

Instalación Local

npm install postproxy-mcp

Claude Code almacena la configuración del servidor MCP en ~/.claude/plugins/. Después de instalar postproxy-mcp, Claude detectará automáticamente el servidor al reiniciar.

Configuración

Registrar el Servidor MCP

Después de instalar postproxy-mcp, regístralo con Claude Code usando el comando claude mcp add:

claude mcp add --transport stdio postproxy-mcp --env POSTPROXY_API_KEY=your-api-key --env POSTPROXY_BASE_URL=https://api.postproxy.dev/api -- postproxy-mcp

Reemplaza your-api-key con tu clave API real de Postproxy.

La configuración se guardará automáticamente en ~/.claude/plugins/. Después de ejecutar este comando:

  1. Reinicia tu sesión de Claude Code
  2. Prueba la conexión preguntando a Claude: "Verifica mi estado de autenticación de Postproxy"
  3. Si las herramientas están disponibles, Claude podrá usarlas automáticamente

Alternativa: Configuración Interactiva

Para usuarios no técnicos, puedes usar el comando de configuración interactiva:

postproxy-mcp setup

o

postproxy-mcp-setup

Esto te guiará a través del proceso de configuración paso a paso y registrará el servidor usando claude mcp add automáticamente.

Herramientas Disponibles

Herramientas de Autenticación

auth_status

Verifica el estado de autenticación, la configuración de la API y la información del espacio de trabajo.

Parámetros: Ninguno

Devuelve:

{
  "authenticated": true,
  "base_url": "https://api.postproxy.dev/api",
  "profile_groups_count": 2
}

Resumen de la Cuenta

summary_get

Responde "¿cuál es el estado?" en una sola llamada: una instantánea de actividad para un período de tiempo en lugar de viajes de ida y vuelta separados de history_list / comments_list / dm_chats_list.

Parámetros:

  • window (cadena, opcional): 24h (predeterminado), 7d o 30d
  • from (cadena, opcional): Marca de tiempo ISO 8601 o fecha simple que inicia un rango explícito. Anula window, y los conteos de *_previous regresan null
  • to (cadena, opcional): Fin del rango explícito. Se establece por defecto a ahora cuando solo se proporciona from
  • profile_group_id (cadena, opcional): Informe sobre un solo grupo. Omítelo para cubrir todos los grupos a los que la clave puede acceder

Devuelve:

{
  "window": {
    "label": "24h",
    "from": "2026-08-17T09:00:00Z",
    "to": "2026-08-18T09:00:00Z",
    "previous_from": "2026-08-16T09:00:00Z",
    "backlog_from": "2026-07-19T09:00:00Z"
  },
  "posts": {
    "published": 4,
    "published_previous": 3,
    "failed": 1,
    "scheduled_ahead": 6,
    "next_scheduled_at": "2026-08-18T14:00:00Z",
    "by_platform": { "instagram": { "published": 4, "failed": 0 } }
  },
  "engagement": {
    "total": { "impressions": 48210, "likes": 1204 },
    "by_platform": { "instagram": { "impressions": 31002, "likes": 900 } },
    "posts_with_insights": 14
  },
  "comments": { "received": 96, "received_previous": 71, "awaiting_reply": 12, "by_platform": { "instagram": 61 } },
  "reviews": { "received": 7, "received_previous": 4, "awaiting_reply": 3 },
  "dms": { "inbound": 41, "outbound": 33, "chats_awaiting_reply": 5, "reply_window_closing": 2 },
  "api": { "calls": 812, "calls_previous": 640 }
}

Notas:

  • Los conteos de publicaciones son publicaciones, por lo que una publicación enviada a tres redes cuenta una vez y un hilo cuenta una vez. by_platform cuenta las entregas por red, por lo que un hilo de X con 3 elementos cuenta como 3 en twitter.
  • engagement es de por vida hasta la fecha para publicaciones publicadas en el período, no la interacción obtenida durante el mismo: suma la instantánea de estadísticas más reciente de cada publicación. Una publicación hecha hace minutos puede no tener instantánea aún y no estará en posts_with_insights. Las claves son las métricas normalizadas listadas en Campos de Estadísticas por Plataforma.
  • Los conteos de awaiting_reply describen el estado actual, no el período: no cambian cuando cambias window. Miran hacia atrás 30 días, devueltos como window.backlog_from. Un comentario cuenta como respondido solo cuando la respuesta proviene de ti (a través de Postproxy o del propio perfil); chats_awaiting_reply se deriva de las marcas de tiempo de los mensajes, ya que Postproxy no tiene estado de leído/no leído.
  • reply_window_closing cuenta los chats con menos de 6 horas restantes de su ventana de mensajería de 24 horas. Las redes sin ventana (Telegram, Bluesky) están excluidas.
  • engagement es null cuando los insights están desactivados para la cuenta; dms es null cuando los mensajes directos están desactivados.
  • Con alcance como cualquier otra herramienta: una clave con alcance de grupo informa solo su grupo.

Gestión de Perfiles

profile_groups_list

Lista todos los grupos de perfiles accesibles con tu clave API. Los grupos de perfiles son contenedores organizativos (por ejemplo, por marca o cliente) que contienen perfiles relacionados. Usa el id de un grupo para filtrar profiles_list por profile_group_id.

Parámetros: Ninguno

Devuelve:

{
  "profile_groups": [
    {
      "id": "grp123abc",
      "name": "Main Brand",
      "profiles_count": 4
    }
  ]
}

profiles_list

Lista todos los perfiles de redes sociales disponibles para publicar.

Parámetros:

  • profile_group_id (cadena, opcional): Si se proporciona, solo se devuelven los perfiles de este grupo (usa profile_groups_list para encontrar los IDs de grupo)

Devuelve:

{
  "profiles": [
    {
      "id": "profile-123",
      "name": "My Twitter Account",
      "platform": "twitter",
      "profile_group_id": "group-abc"
    }
  ]
}

profiles_placements

Lista las ubicaciones disponibles para un perfil. Para perfiles de Facebook, las ubicaciones son páginas de negocio. Para perfiles de LinkedIn, las ubicaciones incluyen el perfil personal y las organizaciones. Para perfiles de Pinterest, las ubicaciones son tableros. Para perfiles de Telegram, las ubicaciones son los canales a los que el bot puede publicar. Para perfiles de Google Business, las ubicaciones son las ubicaciones, devueltas como rutas de recursos completas (accounts/X/locations/Y) para pasar como location_id. Para perfiles de WhatsApp, las ubicaciones son los números de teléfono en la Cuenta de Negocio: el id de la ubicación es el phone_number_id que toda herramienta whatsapp_* y dm_chat_create acepta. Disponible para perfiles de facebook, linkedin, pinterest, telegram, google_business y whatsapp.

Parámetros:

  • profile_id (cadena, obligatorio): Hashid del perfil

Devuelve (ejemplo de LinkedIn):

{
  "placements": [
    {
      "id": null,
      "name": "Personal Profile"
    },
    {
      "id": "108520199",
      "name": "Acme Marketing"
    }
  ]
}

Notas:

  • Si no se especifica una ubicación al crear una publicación:
    • LinkedIn: se establece por defecto al perfil personal
    • Facebook: se establece por defecto a una página conectada aleatoria (si solo hay una página conectada, no es necesario establecer un ID de ubicación)
    • Pinterest: falla
    • Telegram: falla: chat_id es obligatorio en cada publicación
    • Google Business: falla: location_id es obligatorio en cada publicación y en cada herramienta google_business_*

profiles_stats

Obtén la serie temporal de seguidores/interacción para un perfil. Las instantáneas se capturan aproximadamente cada 23 horas, por lo que puedes graficar el crecimiento de seguidores y otras tendencias a lo largo del tiempo. Los campos stats son nativos de la plataforma (no normalizados): consulta Campos de Estadísticas por Plataforma en la sección post_stats para conocer la forma y las claves adicionales a nivel de perfil (followers_count, followersCount, etc.) por red.

Parámetros:

  • profile_id (cadena, obligatorio): Hashid del perfil
  • placement_id (cadena, condicional): Obligatorio para perfiles de facebook, linkedin, telegram y google_business. Obténlo de profiles_placements. Omítelo para instagram, threads, youtube, twitter, tiktok, pinterest y bluesky.
  • from (cadena, opcional): Marca de tiempo ISO 8601: solo incluye instantáneas registradas en o después de este momento
  • to (cadena, opcional): Marca de tiempo ISO 8601: solo incluye instantáneas registradas en o antes de este momento

Devuelve (ejemplo de LinkedIn):

{
  "data": {
    "profile_id": "prof_li_001",
    "platform": "linkedin",
    "placement_id": "108520199",
    "records": [
      { "stats": { "followerCount": 4500, "shareCount": 8, "likeCount": 80 }, "recorded_at": "2026-05-09T08:00:00Z" },
      { "stats": { "followerCount": 4520, "shareCount": 9, "likeCount": 90 }, "recorded_at": "2026-05-10T08:00:00Z" }
    ]
  }
}

Para redes sin ubicaciones (por ejemplo, Bluesky), omite placement_id:

{
  "data": {
    "profile_id": "prof_bsky_001",
    "platform": "bluesky",
    "placement_id": null,
    "records": [
      { "stats": { "followersCount": 8800, "postsCount": 40 }, "recorded_at": "2026-05-09T08:00:00Z" }
    ]
  }
}

Gestión de Publicaciones

post_publish

Publica una publicación en los perfiles de redes sociales especificados.

Parámetros:

  • content (cadena, obligatorio): Texto del contenido de la publicación

  • profiles (cadena[], obligatorio): Matriz de IDs de perfil (hashids) o nombres de plataforma (por ejemplo, "linkedin", "instagram", "twitter"). Al usar nombres de plataforma, publica en el primer perfil conectado para esa plataforma.

  • schedule (cadena, opcional): Hora programada ISO 8601

  • media (cadena[], opcional): Matriz de URLs de medios o rutas de archivos locales

  • idempotency_key (cadena, opcional): Clave de idempotencia para deduplicación

  • require_confirmation (booleano, opcional): Si es verdadero, devuelve un resumen sin publicar

  • draft (booleano, opcional): Si es verdadero, crea una publicación borrador que no se publicará automáticamente

  • queue_id (cadena, opcional): ID de cola para agregar la publicación. La cola asignará automáticamente un espacio de tiempo. No lo uses junto con schedule.

  • queue_priority (cadena, opcional): Prioridad al agregar a una cola: high, medium (predeterminado) o low

  • platforms (objeto, opcional): Parámetros específicos de la plataforma. La clave es el nombre de la plataforma (por ejemplo, "instagram", "youtube", "tiktok"), el valor es un objeto con opciones específicas de la plataforma. Consulta Referencia de Parámetros de Plataforma para la documentación completa.

    Ejemplo:

    {
      "instagram": {
        "format": "reel",
        "collaborators": ["username1", "username2"],
        "first_comment": "Link in bio!"
      },
      "youtube": {
        "title": "My Video Title",
        "privacy_status": "public"
      },
      "tiktok": {
        "privacy_status": "PUBLIC_TO_EVERYONE",
        "auto_add_music": true
      }
    }
    

Devuelve:

{
  "post_id": "job-123",
  "accepted_at": "2024-01-01T12:00:00Z",
  "status": "pending",
  "draft": true
}

Nota sobre publicaciones borrador: Si solicitas una publicación borrador (draft: true) pero la API devuelve draft: false, se incluirá un campo warning en la respuesta indicando que la API puede haber ignorado el parámetro de borrador. Esto puede ocurrir si la API no admite borradores con ciertos parámetros (por ejemplo, archivos adjuntos de medios) o bajo condiciones específicas. Verifica el campo warning en la respuesta para más detalles.

post_status

Obtén el estado de una publicación publicada por ID de trabajo.

Parámetros:

  • post_id (cadena, obligatorio): ID de publicación de la respuesta de post.publish

Devuelve:

{
  "post_id": "job-123",
  "overall_status": "complete",
  "draft": false,
  "status": "processed",
  "content": "Full post body as submitted...",
  "scheduled_at": "2024-01-02T09:00:00Z",
  "created_at": "2024-01-01T12:00:00Z",
  "source": "postproxy",
  "queue_id": null,
  "platforms": [
    {
      "platform": "twitter",
      "status": "published",
      "url": "https://twitter.com/status/123",
      "post_id": "123",
      "error": null,
      "attempted_at": "2024-01-01T12:00:00Z"
    }
  ]
}

scheduled_at es null para publicaciones publicadas inmediatamente. El url de la plataforma es el enlace permanente publicado (nulo hasta que se publique).

Valores de estado:

  • overall_status: "draft", "pending", "processing", "complete", "failed"
  • status de la plataforma: "pending", "processing", "published", "failed", "deleted"
  • error de la plataforma: Mensaje de error si la publicación falló (nulo si fue exitosa)

post_publish_draft

Publica una publicación borrador. Solo las publicaciones con estado draft: true se pueden publicar usando este endpoint.

Parámetros:

  • post_id (cadena, obligatorio): ID de publicación del borrador a publicar

Devuelve:

{
  "post_id": "job-123",
  "status": "processed",
  "draft": false,
  "scheduled_at": null,
  "created_at": "2024-01-01T12:00:00Z",
  "message": "Draft post published successfully"
}

post_delete

Elimina una publicación por ID de trabajo.

Parámetros:

  • post_id (cadena, obligatorio): ID de publicación a eliminar

Devuelve:

{
  "post_id": "job-123",
  "deleted": true
}

post_stats

Obtén instantáneas de estadísticas para una o más publicaciones. Devuelve todas las instantáneas coincidentes para que puedas ver tendencias a lo largo del tiempo. Admite filtrado por perfiles/redes y período de tiempo.

Parámetros:

  • post_ids (cadena[], obligatorio): Matriz de hashids de publicaciones (máximo 50)
  • profiles (cadena, opcional): Lista separada por comas de hashids de perfiles o nombres de red (por ejemplo, instagram,twitter o abc123,def456 o mixto)
  • from (cadena, opcional): Marca de tiempo ISO 8601: solo incluye instantáneas registradas en o después de este momento
  • to (cadena, opcional): Marca de tiempo ISO 8601: solo incluye instantáneas registradas en o antes de este momento

Devuelve:

{
  "data": {
    "abc123": {
      "platforms": [
        {
          "profile_id": "prof_abc",
          "platform": "instagram",
          "records": [
            {
              "stats": {
                "impressions": 1200,
                "likes": 85,
                "comments": 12,
                "saved": 8
              },
              "recorded_at": "2026-02-20T12:00:00Z"
            }
          ]
        }
      ]
    }
  }
}

Campos de estadísticas por plataforma:

PlataformaCampos
Instagramimpressions, likes, comments, saved, profile_visits, follows
Facebookimpressions, clicks, likes
Threadsimpressions, likes, replies, reposts, quotes, shares
Twitterimpressions, likes, retweets, comments, quotes, saved
YouTubeimpressions, likes, comments, saved
LinkedInimpressions
TikTokimpressions, likes, comments, shares
Pinterestimpressions, likes, comments, saved, outbound_clicks

Notas: Las historias de Instagram no devuelven estadísticas. Las estadísticas de TikTok requieren que la publicación tenga un ID público.

Gestión de Colas

queues_list

Lista todas las colas de publicación. Las colas programan automáticamente publicaciones en espacios de tiempo semanales recurrentes con ordenamiento basado en prioridad.

Parámetros:

  • profile_group_id (cadena, opcional): Filtra colas por grupo de perfiles

Devuelve:

{
  "queues": [
    {
      "id": "q1abc",
      "name": "Morning Posts",
      "description": "Daily morning content",
      "timezone": "America/New_York",
      "enabled": true,
      "jitter": 10,
      "profile_group_id": "pg123",
      "timeslots": ["Monday at 09:00 (id: 1)", "Wednesday at 09:00 (id: 2)"],
      "posts_count": 5
    }
  ]
}

queues_get

Obtén detalles de una sola cola de publicación, incluidos sus espacios de tiempo y el conteo de publicaciones.

Parámetros:

  • queue_id (cadena, obligatorio): ID de cola

queues_create

Crea una nueva cola de publicación con espacios de tiempo semanales. Parámetros:

  • profile_group_id (cadena, obligatorio): ID del grupo de perfiles al que conectar la cola (usa profiles_list para encontrarlo)
  • name (cadena, obligatorio): Nombre de la cola
  • description (cadena, opcional): Descripción opcional
  • timezone (cadena, opcional): Nombre de zona horaria IANA (p. ej. America/New_York). Predeterminado: UTC
  • jitter (número, opcional): Desfase aleatorio en minutos (0–60) aplicado a los horarios programados para patrones de publicación naturales. Predeterminado: 0
  • timeslots (matriz, opcional): Franjas horarias semanales iniciales. Cada objeto tiene day (0=domingo hasta 6=sábado) y time (formato HH:MM de 24 horas)

Ejemplo:

{
  "profile_group_id": "pg123",
  "name": "Weekday Mornings",
  "timezone": "America/New_York",
  "jitter": 10,
  "timeslots": [
    { "day": 1, "time": "09:00" },
    { "day": 2, "time": "09:00" },
    { "day": 3, "time": "09:00" },
    { "day": 4, "time": "09:00" },
    { "day": 5, "time": "09:00" }
  ]
}

queues_update

Actualiza la configuración, las franjas horarias o pausa/reanuda una cola. Los cambios en la zona horaria o las franjas horarias provocan la reorganización de todas las publicaciones en cola.

Parámetros:

  • queue_id (cadena, obligatorio): ID de la cola a actualizar
  • name (cadena, opcional): Nuevo nombre de la cola
  • description (cadena, opcional): Nueva descripción
  • timezone (cadena, opcional): Nombre de zona horaria IANA
  • enabled (booleano, opcional): Establecer en false para pausar la cola, true para reanudarla
  • jitter (número, opcional): Desfase aleatorio en minutos (0–60)
  • timeslots (matriz, opcional): Franjas horarias para añadir o eliminar. Para añadir: { "day": 1, "time": "09:00" }. Para eliminar: { "id": 42, "_destroy": true }.

queues_delete

Elimina una cola de publicación. Las publicaciones en la cola perderán su referencia a la cola, pero no se eliminarán.

Parámetros:

  • queue_id (cadena, obligatorio): ID de la cola a eliminar

queues_next_slot

Obtiene la siguiente franja horaria disponible para una cola.

Parámetros:

  • queue_id (cadena, obligatorio): ID de la cola

Devuelve:

{
  "next_slot": "2026-03-11T14:00:00Z"
}

Añadir publicaciones a una cola

Al publicar una publicación con post_publish, puedes añadirla a una cola en lugar de programarla manualmente:

  • queue_id (cadena, opcional): ID de la cola a la que añadir la publicación. La cola asignará automáticamente una franja horaria. No usar junto con schedule.
  • queue_priority (cadena, opcional): Nivel de prioridad: high, medium (predeterminado) o low. Las publicaciones de mayor prioridad obtienen franjas horarias más tempranas.

Ejemplo:

{
  "content": "Queued post content",
  "profiles": ["twitter", "linkedin"],
  "queue_id": "q1abc",
  "queue_priority": "high"
}

Gestión de comentarios

comments_list

Lista los comentarios de una publicación publicada. Devuelve comentarios de nivel superior paginados con respuestas anidadas.

Parámetros:

  • post_id (cadena, obligatorio): ID de la publicación
  • profile_id (cadena, obligatorio): ID del perfil para identificar de qué plataforma recuperar los comentarios
  • page (número, opcional): Número de página, indexado desde cero (predeterminado: 0)
  • per_page (número, opcional): Número de comentarios de nivel superior por página (predeterminado: 20)
  • from (cadena, opcional): Fecha/hora ISO 8601 — solo comentarios recibidos en o después de este punto
  • to (cadena, opcional): Fecha/hora ISO 8601 — solo comentarios recibidos en o antes de este punto

from/to filtran según cuándo Postproxy recibió el comentario, no según el posted_at de la plataforma (que no siempre está completo). Una fecha simple como 2026-03-25 significa el inicio del día de esa fecha. El filtro se aplica solo a comentarios de nivel superior: un comentario dentro del rango aún devuelve su matriz replies completa.

Devuelve:

{
  "total": 42,
  "page": 0,
  "per_page": 20,
  "data": [
    {
      "id": "cmt_abc123",
      "external_id": "17858893269123456",
      "body": "Great post!",
      "status": "synced",
      "author_username": "someuser",
      "like_count": 3,
      "is_hidden": false,
      "posted_at": "2026-03-25T10:00:00.000Z",
      "replies": [
        {
          "id": "cmt_def456",
          "body": "Thanks!",
          "author_username": "author",
          "parent_external_id": "17858893269123456"
        }
      ]
    }
  ]
}

Los objetos de comentario también pueden incluir una matriz attachments (multimedia en el comentario — image, video, audio, gif, external, file), cada uno con id, type, url, status y external_id. Se completa para Facebook, Threads y Bluesky; los comentarios de Instagram, YouTube y LinkedIn son solo texto. La matriz está vacía cuando no hay multimedia.

comments_get

Obtiene un solo comentario con sus respuestas.

Parámetros:

  • post_id (cadena, obligatorio): ID de la publicación
  • comment_id (cadena, obligatorio): ID del comentario (ID de Postproxy o ID externo de la plataforma)
  • profile_id (cadena, obligatorio): ID del perfil

comments_create

Crea un comentario o respuesta en una publicación publicada. El comentario se publica en la plataforma de forma asíncrona.

Parámetros:

  • post_id (cadena, obligatorio): ID de la publicación
  • profile_id (cadena, obligatorio): ID del perfil
  • text (cadena, obligatorio): Contenido de texto del comentario
  • parent_id (cadena, opcional): ID del comentario al que responder (ID de Postproxy o ID externo). Omitir para comentar en la propia publicación.

Devuelve:

{
  "id": "cmt_ghi789",
  "body": "Thanks for the feedback everyone!",
  "status": "pending",
  "external_id": null
}

El comentario se crea con status: "pending". Una vez publicado en la plataforma, pasa a "published". Si la publicación falla, pasa a "failed".

comments_delete

Elimina un comentario de la plataforma de forma asíncrona. Compatible con Instagram, Facebook, YouTube y LinkedIn. No compatible con Threads.

Parámetros:

  • post_id (cadena, obligatorio): ID de la publicación
  • comment_id (cadena, obligatorio): ID del comentario (ID de Postproxy o ID externo)
  • profile_id (cadena, obligatorio): ID del perfil

comments_edit

Edita el texto de un comentario que publicaste, de forma asíncrona. Solo compatible con Facebook y YouTube. Devuelve { accepted: true }; el resultado llega mediante los webhooks comment.edited / comment.edit_failed.

Parámetros:

  • post_id (cadena, obligatorio): ID de la publicación
  • comment_id (cadena, obligatorio): ID del comentario (ID de Postproxy o ID externo)
  • profile_id (cadena, obligatorio): ID del perfil
  • body (cadena, obligatorio): Nuevo texto del comentario

comments_hide

Oculta un comentario en la plataforma de forma asíncrona. Compatible con Instagram, Facebook y Threads.

Parámetros:

  • post_id (cadena, obligatorio): ID de la publicación
  • comment_id (cadena, obligatorio): ID del comentario
  • profile_id (cadena, obligatorio): ID del perfil

comments_unhide

Muestra un comentario previamente oculto. Compatible con Instagram, Facebook y Threads.

Parámetros:

  • post_id (cadena, obligatorio): ID de la publicación
  • comment_id (cadena, obligatorio): ID del comentario
  • profile_id (cadena, obligatorio): ID del perfil

comments_like

Da "me gusta" a un comentario en la plataforma de forma asíncrona. Actualmente solo compatible con Facebook.

Parámetros:

  • post_id (cadena, obligatorio): ID de la publicación
  • comment_id (cadena, obligatorio): ID del comentario
  • profile_id (cadena, obligatorio): ID del perfil

comments_unlike

Elimina un "me gusta" de un comentario. Actualmente solo compatible con Facebook.

Parámetros:

  • post_id (cadena, obligatorio): ID de la publicación
  • comment_id (cadena, obligatorio): ID del comentario
  • profile_id (cadena, obligatorio): ID del perfil

Soporte de plataformas

AcciónInstagramFacebookThreadsYouTubeLinkedIn
ListarSíSíSíSíSí
ResponderSíSíSíSíSí
EliminarSíSíNoSíSí
Ocultar/MostrarSíSíSíNoNo
Me gusta/No me gustaNoSíNoNoNo

Mensajes directos

Mensajería 1:1 (chats y mensajes) en perfiles con capacidad de DM. Compatible con Facebook (Messenger), Instagram (DMs), Telegram (DMs de bots), Bluesky y WhatsApp. Los envíos salientes se procesan de forma asíncrona (se devuelven con status: "pending"). La ventana de mensajería de 24 horas de Meta se aplica a Facebook/Instagram: un humano que responda a la consulta del propio participante puede pasar tag: "HUMAN_AGENT" para enviar fuera de ella (hasta 7 días, nunca para contenido promocional o automatizado); Telegram y Bluesky no tienen ventana. En WhatsApp, la ventana solo se reabre enviando una plantilla aprobada (template) o un texto category: "utility" — consulta Gestión de WhatsApp Business para el resto de la superficie de WhatsApp.

dm_chats_list

Lista los chats de un perfil, ordenados por actividad más reciente.

Parámetros:

  • profile_id (cadena, obligatorio): ID del perfil (Facebook, Instagram, Telegram, Bluesky o WhatsApp)
  • page (número, opcional): Número de página, indexado desde cero (predeterminado: 0)
  • per_page (número, opcional): Elementos por página (predeterminado: 20)
  • before / after (cadena, opcional): Filtros de marca de tiempo ISO 8601 en last_message_at

Los chats de WhatsApp también incluyen external_placement_id (el número de teléfono al que pertenece el chat), group (true para chats grupales) y within_messaging_window.

dm_chat_create

Busca o crea un chat para un participante (idempotente: devuelve el chat existente si ya hay uno). Úsalo antes de enviar un mensaje a un participante al que el perfil aún no ha escrito.

Parámetros:

  • profile_id (cadena, obligatorio): ID del perfil
  • participant_external_id (cadena, obligatorio): ID del participante en la plataforma (ID de usuario con ámbito IG, PSID de Facebook, ID de usuario de Telegram, DID de Bluesky o número de teléfono de WhatsApp con código de país — se eliminan los caracteres no numéricos)
  • placement_id (cadena, opcional): ID de ubicación de profiles_placements. Obligatorio en WhatsApp (el número de teléfono en el que está el chat); opcional en Facebook (ID de página)
  • participant_username (cadena, opcional)
  • participant_name (cadena, opcional)

Una conversación de WhatsApp completamente nueva no tiene ventana de mensajería abierta, por lo que el primer envío debe ser un template (consulta dm_message_send).

dm_chat_get

Obtiene un solo chat por ID de Postproxy o external_conversation_id de la plataforma.

Parámetros:

  • chat_id (cadena, obligatorio): ID del chat o ID de conversación externo

dm_messages_list

Lista los mensajes de un chat, del más reciente al más antiguo.

Parámetros:

  • chat_id (cadena, obligatorio): ID del chat o ID de conversación externo
  • page (número, opcional): Número de página, indexado desde cero (predeterminado: 0)
  • per_page (número, opcional): Elementos por página (predeterminado: 20)
  • direction (cadena, opcional): inbound o outbound
  • status (cadena, opcional): Filtrar por estado del mensaje

dm_message_send

Envía un mensaje saliente. Proporciona exactamente uno de body (texto), media (un solo adjunto) o — en WhatsApp — template, interactive, location o contacts. Parámetros:

  • chat_id (string, obligatorio): ID del chat o ID de conversación externo
  • body (string, opcional): Texto del mensaje (obligatorio cuando no se envía nada más; en WhatsApp también puede acompañar a media como pie de foto)
  • media (string[], opcional): Hasta un adjunto como URL o ruta de archivo local. No compatible con Bluesky. (El MCP remoto/Worker solo acepta URLs). Límites de WhatsApp: imagen 5MB jpeg/png, video 16MB mp4/3gpp, audio 16MB, documento 100MB.
  • tag (string, opcional): HUMAN_AGENT para enviar fuera de la ventana de 24 horas — la extiende a 7 días desde el último mensaje entrante del participante (solo Facebook/Instagram). Meta lo restringe a un humano que responda a la consulta propia del participante; usarlo para marketing, ofertas o re-enganche automatizado puede suspender la capacidad de mensajería de esa Página / cuenta de Instagram. Pasados los 7 días, Meta rechaza el envío y el mensaje cae en status: failed con el error de la plataforma en error_details.
  • reply_to_external_id (string, opcional): Telegram y WhatsApp — ID de mensaje de la plataforma (Telegram message_id, WhatsApp wamid) para citar / enhebrar debajo
  • reply_markup (objeto, opcional): Solo Telegram — payload de teclado en línea / de respuesta
  • quick_replies (objeto[], opcional): Solo Facebook e Instagram — hasta 13 chips pulsables sobre el compositor del participante. Cada { title, payload }.
  • buttons (objeto[], opcional): Solo Facebook e Instagram — hasta 3 botones adjuntos al mensaje. Cada { type: "web_url", title, url } o { type: "postback", title, payload }.
  • card (objeto, opcional): Solo Facebook e Instagram — campos adicionales para la tarjeta que lleva buttons (subtitle, image_url, default_action). Requiere buttons.
  • template (objeto, opcional): Solo WhatsApp — enviar una plantilla aprobada: { id | name, language, variables[], button_params[], header_media, header_location }. La única forma de enviar mensajes fuera de la ventana de 24 horas o de abrir una nueva conversación.
  • interactive (objeto, opcional): Solo WhatsApp — mensaje interactivo con forma de Meta (botones de respuesta, lista, cta_url, producto, flujo, solicitud de ubicación), se pasa sin cambios
  • location (objeto, opcional): Solo WhatsApp — { latitude, longitude, name, address }
  • contacts (objeto[], opcional): Solo WhatsApp — tarjetas de contacto con la forma de contacts de Meta
  • category (string, opcional): Solo WhatsApp — "utility" marca un envío de texto plano como un Envío Directo de utilidad que puede salir de la ventana sin plantilla
  • link_preview (booleano, opcional): Solo WhatsApp — false suprime la vista previa de URL en un mensaje de texto
  • voice_note (booleano, opcional): Solo WhatsApp — entregar un adjunto de audio OGG/Opus como nota de voz
  • filename (string, opcional): Solo WhatsApp — nombre visible para un adjunto de documento
Respuestas rápidas y botones

Solo Facebook Messenger e Instagram Direct — en Telegram usa reply_markup en su lugar (pasar estos devuelve un 422). Las respuestas rápidas son chips efímeros que desaparecen al tocarlos; los botones permanecen adjuntos al mensaje en el hilo.

quick_repliesbuttons
Máx. por envío133
titleobligatorio, ≤20 caracteresobligatorio, ≤20 caracteres
payloadobligatorio, ≤1000 caracteresobligatorio para postback, ≤1000 caracteres
url—obligatorio para web_url, debe ser https://
Necesita bodynosí, y body está limitado a 80 caracteres
Con mediasolo Facebookno permitido
{
  "chat_id": "chat_xyz789",
  "body": "What can I help with?",
  "quick_replies": [
    { "title": "Track order", "payload": "TRACK" },
    { "title": "Talk to support", "payload": "HELP" }
  ]
}
{
  "chat_id": "chat_xyz789",
  "body": "Nike Air Max",
  "card": { "subtitle": "$129 · Arriving Friday", "image_url": "https://cdn.example.com/shoe.png" },
  "buttons": [
    { "type": "web_url", "title": "Buy now", "url": "https://shop.example.com/p/air-max" },
    { "type": "postback", "title": "Notify me", "payload": "NOTIFY:air-max" }
  ]
}

Los botones se entregan como una plantilla genérica de Meta cuyo título del elemento es tu body — de ahí viene el límite de 80 caracteres. Instagram es más estricto que Messenger: entrega respuestas rápidas solo en un mensaje de texto plano, por lo que quick_replies con media o con buttons devuelve 422 allí.

Recepción de toques: un toque en un chip o un postback de botón llega como un mensaje entrante que lleva tapped_action: { "kind": "quick_reply" | "postback" | "callback_query", "payload": "...", "title": "..." }. Lée lo desde dm_messages_list / dm_message_get en lugar de buscar en platform_data. Los toques de rompehielos de Instagram y las consultas de callback de Telegram se normalizan al mismo campo.

Plantillas de WhatsApp y mensajes interactivos

Un número de WhatsApp solo puede enviar texto libre, medios, interactive, location y contacts mientras la ventana de 24 horas del participante esté abierta (within_messaging_window en el chat). Fuera de ella — incluida una conversación que inicies tú — envía una plantilla aprobada. variables rellenan los marcadores en orden (primero las variables de texto del encabezado, luego las del cuerpo, luego las variables del botón de URL dinámica) y deben coincidir con el variable_count de la plantilla de whatsapp_templates_list; el cuerpo renderizado se almacena en el mensaje.

{
  "chat_id": "chat_wa1",
  "template": {
    "name": "order_update",
    "language": "en_US",
    "variables": ["Ana", "ORD-12345"]
  }
}

Las plantillas con encabezado de medios toman header_media: { "link": "https://..." }; un encabezado de ubicación toma header_location; los botones de URL / código de copia / flujo toman button_params: [{ "index": 0, "sub_type": "url", "parameters": [{ "type": "text", "text": "12345" }] }].

Dentro de la ventana, interactive es el objeto propio de Meta — botones de respuesta (hasta 3), una lista (hasta 10 filas), una URL de CTA, una tarjeta de producto, un flujo o una solicitud de ubicación:

{
  "chat_id": "chat_wa1",
  "interactive": {
    "type": "button",
    "body": { "text": "Ready to confirm your booking?" },
    "action": {
      "buttons": [
        { "type": "reply", "reply": { "id": "confirm", "title": "Confirm" } },
        { "type": "reply", "reply": { "id": "reschedule", "title": "Reschedule" } }
      ]
    }
  }
}

Un toque regresa como un mensaje entrante cuyo body es el título tocado, con la respuesta id bajo platform_data.interactive. Los quick_replies / buttons de Facebook/Instagram devuelven 422 en WhatsApp, y template / interactive / location / contacts / category devuelven 422 en todas las demás redes.

dm_message_get

Obtén un solo mensaje por ID de Postproxy o external_id de la plataforma.

Parámetros:

  • message_id (string, obligatorio): ID del mensaje o ID externo

dm_message_edit

Edita un mensaje saliente enviado previamente. Solo Telegram. Proporciona body y/o reply_markup (pasa {} para limpiar el teclado); al menos uno es obligatorio.

Parámetros:

  • message_id (string, obligatorio): ID del mensaje o ID externo
  • body (string, opcional): Nuevo texto / pie de foto
  • reply_markup (objeto, opcional): Nuevo teclado (o {} para eliminarlo)

dm_message_react / dm_message_unreact

Añade o elimina la reacción de la cuenta de tu negocio en un mensaje. Facebook Messenger, Instagram Direct y WhatsApp.

Parámetros (dm_message_react):

  • message_id (string, obligatorio): ID del mensaje o ID externo
  • reaction (string, opcional): Reacción nombrada (por defecto love). Se ignora en WhatsApp
  • emoji (string, opcional): Emoji Unicode. Obligatorio en WhatsApp (cualquier emoji)

Parámetros (dm_message_unreact):

  • message_id (string, obligatorio)

dm_chat_archive / dm_chat_unarchive

Archiva (silencia) o desarchiva (reactiva el sonido) un chat. Solo Bluesky. Devuelve el chat con archived establecido.

Parámetros:

  • chat_id (string, obligatorio): ID del chat o ID de conversación externo

dm_chat_mark_read

Marca un chat como leído. En WhatsApp esto envía el recibo de lectura (ticks azules) para el mensaje entrante más reciente; en otras redes solo sella metadata.read_at. Devuelve el chat.

Parámetros:

  • chat_id (string, obligatorio): ID del chat o ID de conversación externo

dm_comment_private_reply

Envía un DM al autor de un comentario, en respuesta a ese comentario ("Respuestas Privadas" de Meta). Omite la ventana de 24 horas (comentarios de hasta 7 días de antigüedad) y crea/reutiliza un chat automáticamente. Una sola respuesta privada por comentario, en total. Solo Instagram y Facebook.

Parámetros:

  • post_id (string, obligatorio): ID de la publicación
  • comment_id (string, obligatorio): ID del comentario o ID externo
  • profile_id (string, obligatorio): ID del perfil (Instagram o Facebook)
  • text (string, obligatorio): Texto del DM
  • quick_replies (array, opcional): Hasta 13 chips — misma forma que dm_message_send
  • buttons (array, opcional): Hasta 3 botones — misma forma que dm_message_send; limita text a 80 caracteres
  • card (objeto, opcional): Estilo de tarjeta para buttons (subtitle, image_url, default_action)

Los elementos interactivos siguen las mismas reglas que dm_message_send — en Instagram, quick_replies y buttons son mutuamente excluyentes. Los adjuntos de medios no están disponibles en respuestas privadas.

Soporte de plataformas

AcciónFacebookInstagramTelegramBlueskyWhatsApp
Listar/Enviar/ObtenerSíSíSíSíSí
Adjunto de mediosSíSíSíNoSí (pie de foto permitido)
Editar mensajeNoNoSíNoNo
Reaccionar/Quitar reacciónSíSíNoNoSí (emoji)
Archivar/DesarchivarNoNoNoSíNo
Marcar como leído (recibo enviado)solo localsolo localsolo localsolo localSí
Respuesta privada a comentarioSíSíNoNoNo
tag (ventana de 24h)SíSín/an/aNo — usa template / category: utility
reply_to_external_idNoNoSíNoSí
reply_markupNoNoSíNoNo
quick_replies / buttons / cardSíSí (solo texto)NoNoNo — usa interactive
template / interactive / location / contactsNoNoNoNoSí
tapped_action en toques entrantesSíSíSíNoNo (ver platform_data.interactive)

Historial

history_list

Lista trabajos de publicación recientes.

Parámetros:

  • limit (número, opcional): Número máximo de trabajos a devolver (por defecto: 10)

Devuelve:

{
  "jobs": [
    {
      "post_id": "job-123",
      "content": "Full post body as submitted...",
      "content_preview": "Post content preview...",
      "created_at": "2024-01-01T12:00:00Z",
      "overall_status": "complete",
      "status": "processed",
      "scheduled_at": "2024-01-02T09:00:00Z",
      "draft": false,
      "source": "postproxy",
      "queue_id": null,
      "platforms_count": 2,
      "platforms": [
        {
          "platform": "twitter",
          "status": "published",
          "url": "https://x.com/user/status/123"
        }
      ]
    }
  ]
}

scheduled_at es null para publicaciones que se publicaron inmediatamente. status es el estado bruto de la API (draft, scheduled, processing, processed, …), mientras que overall_status resume los resultados de la plataforma en un solo veredicto.

Nota: La API de /posts de Postproxy no devuelve la identidad del perfil (ID o nombre del perfil) por plataforma — solo la red. Usa profiles_list para mapear redes a perfiles conectados.

Gestión del perfil de Google Business

Estas herramientas editan la ficha de negocio de Google en sí — horarios, atributos, servicios, menús de comida, enlaces de acción y fotos de perfil — en lugar de publicar publicaciones locales en ella (eso es post_publish con la plataforma google_business).

Se aplican tres reglas a cada herramienta de este grupo:

  1. location_id siempre es obligatorio. Es la ruta completa del recurso de Google accounts/X/locations/Y, devuelta por profiles_placements.
  2. Las actualizaciones están enmascaradas por campos. Cada escritura toma un array de fields que nombra exactamente lo que se está reemplazando. Cualquier cosa nombrada en fields pero ausente del payload se borra, y los objetos anidados se reemplazan por completo en lugar de fusionarse. Siempre lee antes de parchear.
  3. La disponibilidad varía según la categoría y la región. Los atributos, las listas de servicios, los menús de comida y los tipos de enlaces de acción difieren por ficha. Lista lo disponible primero; una ubicación que no es elegible devuelve 422.

Los payloads usan las formas propias de Google y claves en camelCase en ambas direcciones, por lo que una respuesta puede enviarse directamente de vuelta como cuerpo de solicitud.

HerramientaPropósito
google_business_location_getLeer la ficha: nombre, descripción, sitio web, teléfonos, categorías, dirección, horario, área de servicio, metadatos
google_business_location_updateActualizar campos de la ficha (title, websiteUri, phoneNumbers, categories, storefrontAddress, serviceArea, labels, latlng, openInfo, profile, storeCode)
google_business_categories_listResolver nombres de recursos de categoría (categories/gcid:*) para una región: necesario para cualquier parche categories
google_business_hours_updateEstablecer regularHours, specialHours y moreHours
google_business_attributes_getLeer los atributos actualmente configurados
google_business_attributes_availableListar qué atributos puede establecer esta ficha, con tipos de valor
google_business_attributes_updateEstablecer atributos
google_business_service_list_getLeer la lista de servicios
google_business_service_list_updateReemplazar la lista de servicios (requiere metadata.canModifyServiceList)
google_business_food_menus_getLeer menús de comida (solo categorías tipo restaurante)
google_business_food_menus_updateReemplazar menús de comida (requiere metadata.canHaveFoodMenus)
google_business_place_action_links_listListar botones de acción ("Reservar en línea", "Pedir en línea")
google_business_place_action_link_createAñadir un botón de acción
google_business_place_action_link_updateActualizar un botón de acción
google_business_place_action_link_deleteEliminar un botón de acción
google_business_media_listListar fotos y videos del perfil
google_business_media_createAñadir una foto o video
google_business_media_deleteEliminar una foto o video

Flujo típico

1. profiles_placements                    → get location_id
2. google_business_location_get           → read current state
3. google_business_attributes_available   → see what this listing accepts
4. google_business_attributes_update      → patch only what changed

Formas de valores de atributos

google_business_attributes_available devuelve un valueType por atributo, que determina la forma a enviar de vuelta:

valueTypeForma
BOOL{ "name": "attributes/offers_online_appointments", "values": [true] }
URL{ "name": "attributes/url_linkedin", "uriValues": [{ "uri": "https://..." }] }
ENUM{ "name": "attributes/preferred_messaging_service", "repeatedEnumValue": { "setValues": ["TOKEN"] } }

attribute_mask por defecto usa exactamente los nombres que envías, por lo que una actualización parcial nunca borra los atributos que omitiste.

Horario

Las horas aceptan cadenas "09:00" / "09:00:00" u objetos { "hours": 9, "minutes": 0 } de Google; ambos se normalizan antes de la llamada. Lee las horas actuales desde google_business_location_get; cada bloque nombrado en fields se reemplaza por completo.

{
  "fields": ["regularHours"],
  "regularHours": {
    "periods": [
      { "openDay": "MONDAY", "openTime": "09:00", "closeDay": "MONDAY", "closeTime": "18:00" }
    ]
  }
}

Medios

Google descarga el archivo desde media_url por sí mismo; no hay paso de carga, por lo que la URL debe ser accesible públicamente https (no una URL firmada de corta duración, no localhost). Las imágenes necesitan al menos 250×250 y como máximo 5MB. category por defecto es ADDITIONAL; usa COVER o LOGO solo cuando pretendas cambiar el encabezado o el logo del perfil.

Lectura de resultados vacíos

Google omite claves en lugar de devolver valores vacíos: una ficha sin atributos devuelve { "name": "..." } sin ninguna clave attributes, y lo mismo aplica a serviceItems, placeActionLinks y banderas booleanas como isPreferred. Trata lo ausente como vacío.

Analítica

La analítica de ubicaciones de Google Business llega a través de la herramienta estándar profiles_stats: pasa el location_id como placement_id. Las métricas son impresiones de Búsqueda y Maps (escritorio y móvil), clics en el sitio web, clics en llamadas, solicitudes de indicaciones, conversaciones, reservas, pedidos de comida y clics en menús de comida. Google Business no tiene recuento de seguidores, y Google no expone analítica por publicación para publicaciones locales.

Gestión de WhatsApp Business

Gestiona una Cuenta de WhatsApp Business conectada más allá de la bandeja de entrada: plantillas de mensajes, estado y registro del número de teléfono, perfil público de la empresa, nombre visible y nombre de usuario, usuarios bloqueados, grupos y reportes de conversión de Click-to-WhatsApp. Las conversaciones en sí pasan por las herramientas dm_* anteriores.

Cuatro reglas aplican a cada herramienta de este grupo:

  1. La Cuenta de WhatsApp Business (WABA) es el perfil; cada número de teléfono en ella es una ubicación. Las herramientas con ámbito de teléfono toman phone_number_id: la ubicación id de profiles_placements (sus metadatos llevan display_phone_number, quality_rating, messaging_limit_tier, name_status, platform_type).
  2. Las plantillas y el conjunto de datos de Conversiones son a nivel de WABA — esas herramientas toman solo profile_id.
  3. Mensajes de formato libre solo dentro de la ventana de 24h. Una vez que el último mensaje entrante de un participante tiene más de 24h (o la conversación es nueva), dm_message_send acepta solo una template APROBADA (o un texto category: "utility"). Una plantilla entregada reabre la ventana.
  4. Los números de coexistencia son limitados. Un número conectado con onboarding: "business_app" (aún en la app de WhatsApp Business en un teléfono) tiene menor rendimiento y no puede usar la API de Grupos; whatsapp_number_info reporta platform_type distinto de CLOUD_API para estos.

Las respuestas usan los nombres de campos propios de Meta donde se devuelven formas de Meta (components, interactive, campos del perfil de negocio).

HerramientaPropósito
whatsapp_templates_listListar plantillas sincronizadas (filtro name, language, status; refresh: true re-sincroniza desde Meta primero)
whatsapp_template_getUna plantilla con componentes, estado y variable_count
whatsapp_template_createEnviar una plantilla personalizada (components) o instanciar una de biblioteca (library_template_name)
whatsapp_template_updateCambiar components (de vuelta a revisión PENDIENTE) y/o message_send_ttl_seconds
whatsapp_template_deleteEliminar un idioma (language) o todo el nombre
whatsapp_template_library_getInspeccionar una plantilla de biblioteca de Meta antes de instanciarla
whatsapp_number_infoEstado en vivo del número + WABA: calificación de calidad, nivel de mensajería, estado del nombre, tipo de plataforma
whatsapp_number_registerRegistrar el número con la Cloud API usando su PIN de 6 dígitos
whatsapp_number_request_verification_codeCódigo de verificación por SMS / voz para un número no verificado
whatsapp_number_verifyEnviar el código de verificación
whatsapp_business_profile_getPerfil público: acerca de, dirección, descripción, correo, sitios web, vertical, foto
whatsapp_business_profile_updateActualizar esos campos (about ≤139, description ≤512, ≤2 sitios web)
whatsapp_business_profile_photo_updateReemplazar la foto del perfil (url o base64 data; JPEG/PNG ≤5MB)
whatsapp_display_name_getNombre visible verificado y estado de revisión
whatsapp_display_name_request_changeEnviar un nuevo nombre visible para revisión de Meta
whatsapp_username_get / _set / _delete / _suggestionsGestionar el nombre de usuario wa.me del número
whatsapp_blocked_users_list / whatsapp_blocked_user_statusQuién está bloqueado
whatsapp_users_block / whatsapp_users_unblockBloquear / desbloquear hasta 1000 números por llamada
whatsapp_groups_list / _create / _get / _update / _deleteGrupos que administra el número (solo números de Cloud API)
whatsapp_group_participants_add / _removeGestionar miembros (un grupo contiene 8)
whatsapp_group_invite_link_createEnlace de invitación nuevo (revoca el anterior)
whatsapp_group_join_requests_list / _approve / _rejectManejar solicitudes de unión en grupos que requieren aprobación
whatsapp_dataset_get / whatsapp_dataset_createConjunto de datos de Conversions API en la WABA
whatsapp_conversion_event_sendReportar un LeadSubmitted / Purchase / AddToCart / InitiateCheckout / ViewContent para una conversación de Click-to-WhatsApp

Flujo típico

1. profile_groups_initialize_connection   → platform: whatsapp (onboarding: api | business_app)
2. profiles_placements                    → get phone_number_id
3. whatsapp_templates_list                → find an APPROVED template and its variable_count
4. dm_chat_create                         → participant_external_id: phone, placement_id: phone_number_id
5. dm_message_send                        → template: { name, language, variables }
6. dm_messages_list                       → the reply opens a 24h window; free-form sends now work

Conexión de un número

profile_groups_initialize_connection con platform: "whatsapp" devuelve una URL de conexión. Pasa onboarding: "business_app" cuando el número vive en la app de WhatsApp Business en un teléfono (el usuario escanea un código QR; la app sigue funcionando junto con Postproxy y se importan hasta 6 meses de chats) o onboarding: "api" cuando el número está con otro proveedor o es completamente nuevo (movido a la Cloud API; ya no usable en la app). Omítelo y la página de conexión lo pregunta. Cada Cuenta de WhatsApp Business se convierte en un perfil y cada uno de sus números en una ubicación.

Plantillas

Meta revisa cada plantilla personalizada; una nueva es PENDING hasta que se aprueba, y solo las plantillas APPROVED pueden enviarse. Los marcadores de posición son {{1}}, {{2}}… (parameter_format: POSITIONAL, el predeterminado) o {{name}} (NAMED). variable_count en una plantilla es el número de variables que un envío debe llevar: marcadores de texto del encabezado, luego marcadores del cuerpo, luego uno por botón de URL dinámica. Las plantillas de biblioteca (whatsapp_template_library_get → whatsapp_template_create con library_template_name) omiten la revisión. Un nombre es único por idioma; eliminar por nombre sin language elimina todos los idiomas.

Conversiones

Las conversaciones que comienzan desde un anuncio de Click-to-WhatsApp llevan un ctwa_clid en el metadata del chat. Crea un conjunto de datos una vez (whatsapp_dataset_create), luego reporta resultados con whatsapp_conversion_event_send por chat_id o phone; un chat sin ctwa_clid capturado devuelve 422.

Ejemplos de Prompts

Aquí hay algunos ejemplos de prompts que puedes usar con Claude Code:

Verificar Autenticación

Check my PostProxy authentication status

Listar Perfiles

Show me all my available social media profiles

Publicar una Publicación

Usando IDs de perfil:

Publish this post: "Check out our new product!" to profiles ["profile-123"]

Usando nombres de plataforma:

Publish "Exciting news!" to linkedin and twitter

Publicar con Parámetros de Plataforma

Puedes usar parámetros específicos de plataforma para personalizar publicaciones en cada plataforma. El parámetro platforms acepta un objeto donde las claves son nombres de plataforma y los valores contienen opciones específicas de plataforma.

Ejemplos de Instagram

Publicación Regular con Colaboradores:

Publish to Instagram: "Amazing content!" to my Instagram account with collaborators username1 and username2

O con parámetros explícitos:

{
  "content": "Amazing content!",
  "profiles": ["instagram"],
  "media": ["https://example.com/image.jpg"],
  "platforms": {
    "instagram": {
      "format": "post",
      "collaborators": ["username1", "username2"],
      "first_comment": "What do you think? 🔥"
    }
  }
}

Reel de Instagram:

{
  "content": "Check out this reel! #viral",
  "profiles": ["instagram"],
  "media": ["https://example.com/video.mp4"],
  "platforms": {
    "instagram": {
      "format": "reel",
      "collaborators": ["collaborator_username"],
      "cover_url": "https://example.com/thumbnail.jpg",
      "audio_name": "Trending Audio",
      "first_comment": "Link in bio!"
    }
  }
}

Historia de Instagram:

{
  "profiles": ["instagram"],
  "media": ["https://example.com/story-image.jpg"],
  "platforms": {
    "instagram": {
      "format": "story"
    }
  }
}

Ejemplos de YouTube

Video de YouTube con Título y Privacidad:

Upload this video to YouTube with title "My Tutorial" and make it public

O con parámetros explícitos:

{
  "content": "This is the video description with links and details",
  "profiles": ["youtube"],
  "media": ["https://example.com/video.mp4"],
  "platforms": {
    "youtube": {
      "title": "My Tutorial: How to Build an API",
      "privacy_status": "public",
      "cover_url": "https://example.com/custom-thumbnail.jpg"
    }
  }
}

Video de YouTube No Listado:

{
  "content": "Video description",
  "profiles": ["youtube"],
  "media": ["https://example.com/video.mp4"],
  "platforms": {
    "youtube": {
      "title": "Private Tutorial",
      "privacy_status": "unlisted"
    }
  }
}

Ejemplos de TikTok

TikTok Público con Música Automática:

{
  "content": "Check this out! #fyp",
  "profiles": ["tiktok"],
  "media": ["https://example.com/video.mp4"],
  "platforms": {
    "tiktok": {
      "privacy_status": "PUBLIC_TO_EVERYONE",
      "auto_add_music": true,
      "disable_comment": false,
      "disable_duet": false,
      "disable_stitch": false
    }
  }
}

TikTok Solo para Seguidores con Etiqueta de IA:

{
  "content": "Special content for followers",
  "profiles": ["tiktok"],
  "media": ["https://example.com/video.mp4"],
  "platforms": {
    "tiktok": {
      "privacy_status": "FOLLOWER_OF_CREATOR",
      "made_with_ai": true,
      "brand_content_toggle": false
    }
  }
}

Ejemplos de Facebook

Publicación de Facebook con Primer Comentario:

{
  "content": "Check out our new product!",
  "profiles": ["facebook"],
  "media": ["https://example.com/product.jpg"],
  "platforms": {
    "facebook": {
      "format": "post",
      "first_comment": "Link to purchase: https://example.com/shop"
    }
  }
}

Historia de Facebook:

{
  "profiles": ["facebook"],
  "media": ["https://example.com/story-video.mp4"],
  "platforms": {
    "facebook": {
      "format": "story"
    }
  }
}

Publicación de Página de Facebook:

{
  "content": "Company announcement",
  "profiles": ["facebook"],
  "platforms": {
    "facebook": {
      "page_id": "123456789",
      "first_comment": "Visit our website for more details"
    }
  }
}

Ejemplos de LinkedIn

Publicación Personal de LinkedIn:

{
  "content": "Excited to share my latest article on AI",
  "profiles": ["linkedin"],
  "media": ["https://example.com/article-cover.jpg"]
}

Publicación de Empresa en LinkedIn:

{
  "content": "We're hiring! Join our team",
  "profiles": ["linkedin"],
  "media": ["https://example.com/careers.jpg"],
  "platforms": {
    "linkedin": {
      "organization_id": "company-id-12345"
    }
  }
}

Ejemplos de Bluesky

Publicación simple de Bluesky (menciones/etiquetas/enlaces con facetas automáticas):

{
  "content": "Hey @jay.bsky.team — check out our latest #ruby post: https://example.com/blog/post",
  "profiles": ["bluesky"]
}

No necesitas ningún marcado — Postproxy convierte automáticamente @handles, #tags y URLs en facetas del Protocolo AT, y genera una vista previa de tarjeta de enlace desde los metadatos Open Graph de la URL (cuando no hay medios adjuntos). Límite de 300 grafemas.

Ejemplos de Telegram

Publicación en canal de Telegram (formato HTML):

{
  "content": "<b>New release</b> — read more on our blog https://example.com/post",
  "profiles": ["telegram"],
  "platforms": {
    "telegram": {
      "chat_id": "-1001234567890",
      "parse_mode": "HTML",
      "disable_link_preview": true,
      "disable_notification": false
    }
  }
}

Usa profiles_placements contra tu perfil de Telegram para listar los chat_id de canales a los que el bot puede publicar. El bot debe agregarse al canal como administrador con permiso para publicar.

Ejemplos Multiplataforma

Mismo Contenido, Diferentes Plataformas:

{
  "content": "New product launch! 🚀",
  "profiles": ["instagram", "twitter", "linkedin"],
  "media": ["https://example.com/product.jpg"]
}

Video en Varias Plataformas con Parámetros Específicos:

{
  "content": "Product launch video",
  "profiles": ["instagram", "youtube", "tiktok"],
  "media": ["https://example.com/video.mp4"],
  "platforms": {
    "instagram": {
      "format": "reel",
      "first_comment": "Link in bio!"
    },
    "youtube": {
      "title": "Product Launch 2024",
      "privacy_status": "public",
      "cover_url": "https://example.com/yt-thumbnail.jpg"
    },
    "tiktok": {
      "privacy_status": "PUBLIC_TO_EVERYONE",
      "auto_add_music": true
    }
  }
}

Referencia de Parámetros de Plataforma

Instagram:

  • format: "post" | "reel" | "story"
  • collaborators: Matriz de nombres de usuario (máx. 10 para publicaciones, 3 para reels)
  • first_comment: Cadena - comentario para añadir después de publicar
  • cover_url: Cadena - URL de miniatura para reels
  • audio_name: Cadena - nombre de pista de audio para reels
  • trial_strategy: "MANUAL" | "SS_PERFORMANCE" - estrategia de prueba para reels
  • thumb_offset: Cadena - desplazamiento de miniatura en milisegundos para reels
  • user_tags: Matriz de { username, x, y, media_index } - etiqueta cuentas públicas de Instagram en cualquier formato (publicación, reel, historia). Las imágenes requieren x y y (flotantes 0.0–1.0 desde la esquina superior izquierda); los reels y diapositivas de video se etiquetan solo por nombre de usuario (las coordenadas se descartan); las historias aceptan coordenadas pero no las necesitan. media_index elige la diapositiva del carrusel (basado en 0, predeterminado 0). Un @ inicial se elimina. Coordenadas fuera de rango, un media_index más allá del último elemento multimedia, o una etiqueta de imagen que falte x/y se rechazan con un 422 que nombra la entrada. Las cuentas privadas y las cuentas con etiquetado desactivado se omiten silenciosamente por Instagram. YouTube:
  • title: String - título del video
  • privacy_status: "public" | "unlisted" | "private"
  • cover_url: String - URL de miniatura personalizada

TikTok:

  • privacy_status: "PUBLIC_TO_EVERYONE" | "MUTUAL_FOLLOW_FRIENDS" | "FOLLOWER_OF_CREATOR" | "SELF_ONLY"
  • photo_cover_index: Integer - índice de la foto a usar como portada (basado en 0)
  • auto_add_music: Boolean - habilitar música automática
  • made_with_ai: Boolean - marcar contenido como generado por IA
  • disable_comment: Boolean - deshabilitar comentarios
  • disable_duet: Boolean - deshabilitar dúos
  • disable_stitch: Boolean - deshabilitar stitches
  • brand_content_toggle: Boolean - marcar como asociación pagada (terceros)
  • brand_organic_toggle: Boolean - marcar como asociación pagada (marca propia)

Facebook:

  • format: "post" | "story"
  • first_comment: String - comentario para añadir después de publicar
  • page_id: String - ID de página para publicar en páginas de empresa

LinkedIn:

  • organization_id: String - ID de organización para publicaciones en páginas de empresa

Telegram:

  • chat_id: String, obligatorio — ID del canal/chat de destino (usa profiles_placements para listar)
  • parse_mode: "HTML" | "MarkdownV2" — omitir para texto plano
  • disable_link_preview: Boolean — suprimir tarjeta de vista previa de URL
  • disable_notification: Boolean — enviar en silencio (sin sonido de notificación)
  • Límite de caracteres: 4,096 solo texto; 1,024 para el pie de foto cuando hay medios adjuntos (el cuerpo se trunca más allá)
  • Medios: imágenes ≤10 MB (×10), video ≤50 MB (×10), documentos ≤50 MB (×1)
  • El bot debe ser miembro (preferiblemente administrador con permiso de publicación) del canal de destino

Bluesky:

  • No hay parámetros específicos de plataforma disponibles
  • Límite de caracteres: 300 grafemas (los emojis y secuencias combinadas cuentan como uno)
  • Detecta automáticamente menciones @handle.bsky.social, #hashtags y URLs y las convierte en facetas clicables
  • Genera una vista previa de tarjeta de enlace a partir de metadatos Open Graph cuando hay una URL presente y no hay medios adjuntos
  • Medios: imágenes ≤1 MB (×4), video ≤100 MB (×1, 1–60s)
  • Soporta hilos mediante el array estándar thread

Twitter/X y Threads:

  • No hay parámetros específicos de plataforma disponibles

Para documentación completa, consulta la Referencia de Parámetros de Plataforma.

Crear una Publicación Borrador

Create a draft post: "Review this before publishing" to linkedin

Publicar una Publicación Borrador

Publish draft post job-123

Verificar Estado de la Publicación

What's the status of job job-123?

Esto mostrará el estado detallado, incluyendo estado del borrador, errores específicos de la plataforma y resultados de publicación.

Eliminar una Publicación

Delete post job-123

Obtener Estadísticas de la Publicación

Show me the stats for post abc123
Get stats for posts abc123 and def456 filtered to Instagram only, from February 1st to today

Listar Ubicaciones

Show me the placements for my LinkedIn profile prof123

Gestión de Cola

Show me all my posting queues
Create a queue called "Weekday Mornings" for profile group pg123, timezone America/New_York, with timeslots Monday through Friday at 9am
Add a post to queue q1abc with high priority: "Check out our latest feature!"
Pause queue q1abc
What's the next available slot for queue q1abc?

Gestión de Comentarios

Show me the comments on post abc123 for my Instagram profile prof456
Reply to comment cmt_abc123 on post abc123 with "Thanks for the feedback!" using profile prof456
Hide comment cmt_abc123 on post abc123 for profile prof456

Mensajes Directos

List the DM chats for my Instagram profile prof456
Reply "Yes, we ship worldwide!" in chat chat_xyz789
Send a DM to the author of comment cmt_abc123 on post abc123 from profile prof456 saying "DM-ing you the details"
Open a WhatsApp chat with +1 310 555 0007 on number 1055512345 of profile prof_wa and send the order_update template in en_US with Ana and ORD-12345
Mark chat chat_wa1 as read and react to the last inbound message with 🔥

Gestión de WhatsApp Business

List the approved WhatsApp templates on profile prof_wa
Create a UTILITY template called appointment_reminder in en_US on profile prof_wa: "Hi {{1}}, your appointment is on {{2}} at {{3}}."
Show the quality rating and messaging tier for number 1055512345 on profile prof_wa
Update the WhatsApp business profile of number 1055512345 on prof_wa: about "Open Mon–Sat 9–18", website https://acme.example
Block +1 310 555 0099 on number 1055512345 of profile prof_wa
Report a Purchase of 49.90 USD for chat chat_wa1 on profile prof_wa with event id ord-9921

Ver Historial

Show me the last 5 posts I published

Solución de Problemas

El Servidor No Inicia

  • Verificar Clave API: Asegúrate de que POSTPROXY_API_KEY esté configurada al registrarse con claude mcp add
  • Verificar Versión de Node: Requiere Node.js >= 18.0.0
  • Verificar Instalación: Confirma que postproxy-mcp esté instalado y en PATH
  • Verificar Registro: Asegúrate de que el servidor esté registrado mediante claude mcp add y que la configuración esté guardada en ~/.claude/plugins/

Errores de Autenticación

  • AUTH_MISSING: La clave API no está configurada. Asegúrate de incluir --env POSTPROXY_API_KEY=... al ejecutar claude mcp add
  • AUTH_INVALID: La clave API no es válida. Verifica que tu clave API sea correcta.

Errores de Validación

  • TARGET_NOT_FOUND: Uno o más IDs de perfil no existen. Usa profiles_list para ver los perfiles disponibles.
  • VALIDATION_ERROR: El contenido o los parámetros de la publicación no son válidos. La API ahora devuelve mensajes de error detallados:
    • Errores 400: {"status":400,"error":"Bad Request","message":"..."}
    • Errores 422: {"errors": ["Error 1", "Error 2"]} - Array de mensajes de error de validación
    • Revisa el mensaje de error para problemas de validación específicos

Errores de API

  • API_ERROR: La API de Postproxy devolvió un error. Revisa el mensaje de error para más detalles.
  • Tiempo de espera agotado: La solicitud tardó más de 30 segundos. Verifica tu conexión de red y el estado de la API.

Errores de Plataforma

Al verificar el estado de la publicación con post_status, los errores específicos de la plataforma ahora están disponibles en el campo error de cada objeto de plataforma:

  • error: null - Publicación publicada exitosamente
  • error: "Error message" - Mensaje de error detallado de la API de la plataforma
  • Los errores comunes incluyen problemas de autenticación, límites de velocidad, violaciones de contenido, etc.

Problemas con Publicaciones Borrador

Si creas una publicación borrador (draft: true) pero recibes draft: false en la respuesta:

  • La respuesta incluirá un campo warning explicando que la API puede haber ignorado el parámetro de borrador
  • Esto puede ocurrir si:
    • La API no admite borradores con archivos adjuntos de medios
    • La API tiene limitaciones específicas para publicaciones borrador bajo ciertas condiciones
  • Revisa el campo warning en la respuesta para más detalles
  • Habilita el modo de depuración (POSTPROXY_MCP_DEBUG=1) para ver registros detallados sobre el manejo del parámetro de borrador

Modo de Depuración

Habilita el registro de depuración configurando POSTPROXY_MCP_DEBUG=1 al registrar el servidor:

claude mcp add --transport stdio postproxy-mcp --env POSTPROXY_API_KEY=your-api-key --env POSTPROXY_BASE_URL=https://api.postproxy.dev/api --env POSTPROXY_MCP_DEBUG=1 -- postproxy-mcp

Desarrollo

Compilar desde el Código Fuente

git clone https://github.com/postproxy/postproxy-mcp
cd postproxy-mcp
npm install
npm run build

Ejecutar en Modo de Desarrollo

npm run dev

Licencia

MIT