instagram-mcp
instagram-mcp
Un servidor MCP remoto que permite a cada miembro del equipo publicar carruseles e imágenes individuales de Instagram directamente desde una conversación de Claude — a su propia cuenta profesional de Instagram, y a la de nadie más.
El token de portador identifica a la persona. La persona se asigna a exactamente una cuenta de Instagram en la base de datos. Ninguna herramienta toma nunca un id de cuenta de Instagram como parámetro, por lo que publicar en la cuenta de un compañero pasando el id equivocado es estructuralmente imposible.
La app de Meta se ejecuta en modo de desarrollo con cada miembro del equipo añadido como Instagram Tester — Sin Revisión de la App de Meta, sin flujo de inicio de sesión OAuth, sin pasar a producción. Esto es deliberado.
Conéctalo a Claude (envía esta sección a un compañero tal cual)
Necesitas dos cosas del admin: la URL del servidor y tu token de acceso personal (empieza con igmcp_). Guarda el token como una contraseña — cualquiera que lo tenga puede publicar en tu cuenta de Instagram.
En Claude, abre Configuración → Conectores → Añadir conector personalizado.
Pega esta URL:
https://YOUR-DEPLOYMENT.vercel.app/api/mcp(el admin te dará el nombre de host real)
Donde el conector pida autenticación, añade este encabezado — Nombre a la izquierda, valor a la derecha:
Authorization: Bearer igmcp_your_token_hereNombre del encabezado:
Authorization. Valor del encabezado: la palabraBearer, un espacio, luego tu token. Nada más.Guarda. En cualquier conversación, ahora puedes decir cosas como "publica estas 5 diapositivas como un carrusel con este pie de foto" y Claude subirá las imágenes y las publicará en tu cuenta.
Lo que puedes pedirle a Claude que haga:
Publicar un carrusel (2–10 imágenes, un pie de foto para toda la publicación)
Publicar una imagen individual
Comprobar cuántas publicaciones te quedan hoy (Instagram limita la publicación en la API a 100 por 24 h)
Comprobar el estado de tu token (tu conexión de Instagram se renueva automáticamente mucho antes de que expire; esto te indica si algo va mal)
Listar tus publicaciones recientes (solo las tuyas)
Si una publicación falla a mitad, solo pídele a Claude que intente la misma publicación de nuevo — el servidor retoma donde lo dejó y no publicará dos veces.
Incorporación de un nuevo miembro del equipo (admin)
Requisitos previos, uno por persona:
Su cuenta de Instagram debe ser una cuenta profesional (Empresarial o Creador).
En developers.facebook.com abre la app de Meta → Instagram → Configuración de API con inicio de sesión de Instagram → añade su cuenta como Instagram Tester. Deben aceptar la invitación (app de Instagram → Configuración → Permisos del sitio web → Aplicaciones y sitios web → Invitaciones de tester).
Genera un token de acceso de larga duración para su cuenta desde el panel de la app (el botón "Generate token" junto a la cuenta de tester). Copia el token y anota el id de usuario de la cuenta.
Luego agrégalos (desde tu máquina, en este repositorio, con .env.local rellenado):
npm run add-member -- --name "Ada" --ig-user-id 17840000000000000 --ig-username ada.builds
# pastes the long-lived IG token when prompted (kept out of shell history)El script verifica el token en vivo contra graph.instagram.com, se niega a agregar si el token pertenece a una cuenta diferente del id que pasaste, e imprime el token de portador igmcp_ del miembro una vez. Envíalo por un canal seguro junto con la sección "Conéctalo a Claude" de arriba.
Para revocar a alguien: establece revoked_at = now() en su fila en team_members. Su token comenzará a devolver 401 inmediatamente.
Arquitectura
instagram-mcp/
├── api/
│ ├── mcp.ts # MCP endpoint (Streamable HTTP), bearer auth wrapper
│ └── cron/refresh-tokens.ts # Vercel Cron target (daily; refreshes tokens nearing expiry)
├── src/
│ ├── auth.ts # bearer lookup → resolves the calling member
│ ├── crypto.ts # AES-256-GCM for IG tokens, SHA-256 for bearer hashes
│ ├── instagram.ts # containers, polling, publish, refresh, idempotent resume
│ ├── storage.ts # R2 uploads (per-member key prefix)
│ ├── db.ts # Supabase (service role)
│ ├── refresh.ts # refresh loop shared by cron + CLI
│ └── tools/ # one file per tool
├── scripts/
│ ├── add-member.ts # seeds a member, generates their bearer token
│ └── refresh-tokens.ts # manual run of the refresh loop
├── supabase/migrations/ # schema (already applied via the Supabase connector)
├── .env.example # every key, documented
└── README.mdDecisiones clave:
Transporte:
mcp-handlerv2 (adaptador MCP de Vercel) con@modelcontextprotocol/serverv2 — Solo HTTP Streamable; el transporte obsoleto HTTP+SSE se eliminó en v2, que es exactamente lo que queremos. Sin transporte hecho a mano.Host: todo se comunica con
https://graph.instagram.com(ruta de inicio de sesión de Instagram).graph.facebook.compertenece a la ruta de inicio de sesión de Facebook y falla con un error engañoso de análisis de token — la mayoría de los tutoriales se equivocan en esto.Autenticación:
Authorization: Bearer <token>en cada solicitud. El token se hashea (SHA-256), se busca y se vuelve a verificar con una comparación de tiempo constante; los tokens desconocidos y revocados devuelven 401 antes de cualquier procesamiento. Los tokens de Instagram se almacenan cifrados con AES-256-GCM en Postgres; los tokens de portador nunca se almacenan en bruto.Idempotencia: la clave de idempotencia (miembro + URLs de imágenes + pie de foto) se escribe en
postsantes de cualquier llamada a Meta. Los ids de los contenedores hijos se persisten a medida que se crean. Un reintento reutiliza los hijos FINALIZADOS, recrea solo los EXPIRADOS/ERROR, y volver a publicar el mismo id de contenedor padre es seguro (media_publishes idempotente por contenedor) — por lo que un carrusel a medio publicar nunca se duplica.Actualización de token: Vercel Cron se ejecuta diariamente; los tokens duran 60 días y cada uno se actualiza una vez que entra en una ventana de renovación de 25 días, por lo que una ejecución fallida recibe un nuevo intento cada 24h en lugar de un solo intento por mes. El fallo de un miembro nunca aborta el bucle; los fallos permanentes (acceso revocado, cambio de tipo de cuenta) marcan la fila y se muestran a través de
check_token_healthen lugar de reintentar para siempre.
Despliegue (admin)
npm install
npm run typecheck && npm test # 19 unit tests, live tests skip without creds
vercel login
vercel link # or create the project
# Set every var from .env.example in Vercel → Project → Settings → Environment Variables
vercel --prodLuego pon la URL de despliegue en la sección "Conéctalo a Claude" de arriba.
Supabase debe ser un proyecto dedicado que aloje solo este servidor — no un proyecto compartido con otra aplicación. team_members y posts son nombres genéricos y el cliente de rol de servicio tiene acceso completo a las tablas, por lo que compartir un esquema con un producto no relacionado es un riesgo de colisión (y de radio de explosión). Crea el proyecto bajo tu propia cuenta, luego aplica la migración en supabase/migrations/ a través del editor SQL o el conector MCP de Supabase.
El bucket R2 necesita acceso público habilitado (dominio personalizado o r2.dev) que coincida con R2_PUBLIC_BASE_URL.
Pruebas de aceptación en vivo
Con .env.local rellenado y al menos un miembro agregado:
LIVE_MEMBER_BEARER_TOKEN=igmcp_... npm test # upload + token health, no posting
LIVE_MEMBER_BEARER_TOKEN=igmcp_... LIVE_PUBLISH=1 npm test # ⚠ creates REAL posts
# add LIVE_MEMBER_BEARER_TOKEN_2=igmcp_... for the two-members-two-accounts testNotas operativas
El modo de fallo silencioso #1 es un token caducado — las publicaciones se detienen y nadie se da cuenta. El cron marca los fallos de forma ruidosa (no-200 → ejecución roja en el panel de Vercel) y
check_token_healthinforma los días hasta el vencimiento y los fallos de actualización por miembro.Instagram limita las publicaciones a 100 publicaciones por cuenta por 24h móviles;
get_publishing_limitlee el contador en vivo.Los contenedores caducan después de ~24h y hay un límite de ~50 contenedores pendientes por cuenta — otra razón por la que la ruta de reintento reutiliza contenedores en lugar de crear nuevos.
Mantén las diapositivas del carrusel con la misma relación de aspecto; Instagram recorta todo para que coincida con la primera diapositiva. Solo JPEG/PNG, ≤ 8 MB.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Boost posts and launch community growth campaigns from your AI assistant. OAuth, credit-billed.
Connect any AI agent to 11+ social platforms: schedule, publish & track posts via hosted MCP.
Publish, schedule and verify social posts across seven networks from your AI assistant.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Joyhacks/instagram-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server