Construir un ChatGPT App con Apps SDK: implementación de MCP·OAuth y notas del proceso de revisión
Hola, soy yeonghyeon, lidero el desarrollo de 3Min API.
Durante las últimas semanas he estado trabajando en el registro de 3Min API en ChatGPT Apps. Tuvimos un rechazo, lo corregimos y finalmente aprobaron la app — y por el camino enviamos el mismo código a Claude Connectors. Este artículo es para otros desarrolladores que están recorriendo el mismo camino. He intentado reunir qué hace falta implementar, dónde suelen producirse los rechazos y qué ocurre realmente durante la revisión en un solo sitio.
He dejado fuera, a propósito, todo lo relacionado con un proveedor cloud o un stack de despliegue concretos. El registro de ChatGPT Apps sigue el mismo flujo independientemente de lo que tengas debajo.
Resumen — ChatGPT Apps y el MCP que lo sustenta
ChatGPT Apps es el modelo de extensión de OpenAI que te permite invocar servicios externos desde dentro de ChatGPT. Los usuarios añaden tu app desde la pantalla de ChatGPT y, dentro del flujo de conversación, pueden invocar directamente las herramientas que expone tu backend.
La base es Model Context Protocol (MCP). MCP es una especificación abierta para conectar LLMs con herramientas externas — define cómo se listan las herramientas y cómo se invocan de forma segura. ChatGPT Apps es uno de los clientes que corren sobre MCP, y Claude Connectors de Anthropic está construido sobre la misma especificación. Es decir, si implementas un servidor MCP correctamente una vez, cubres ambos ecosistemas. Nosotros enviamos el mismo código a los dos directorios, y las definiciones de herramientas y el flujo de autenticación se comparten tal cual.
Por qué nos convertimos en herramienta en vez de construir nuestro propio chatbot
Al principio sí valoramos hacer nuestro propio chatbot. Pero dando un paso atrás, los usuarios ya estaban contando su contexto de negocio a ChatGPT o Claude. Si construimos otro chatbot más, esa misma persona tiene que volver a explicar la misma historia desde cero.
Así que cambiamos de dirección. Añadimos 3Min API como una herramienta a la IA que ya estás usando. El mismo ChatGPT al que le has estado contando tus problemas de negocio puede ahora decir "te lo dejo montado en 3Min API" y hacerlo de verdad. Seguimos valorando un chatbot propio, pero la prioridad es convertirnos en herramienta.
Implementación
Elección del SDK — solo el SDK estándar de MCP
OpenAI ofrece un SDK específico para ChatGPT Apps, pero no fuimos por ese camino. Nuestro servidor depende de una sola pieza: el SDK estándar de MCP (@modelcontextprotocol/sdk). El motivo es sencillo — el mismo servidor tiene que ser reconocido tanto por ChatGPT Apps como por Claude Connectors. Manteniéndonos en el SDK estándar, el código no se bifurca cuando uno de los ecosistemas se actualiza, y podemos enviar el mismo build a los dos directorios.
Las especificaciones de OpenAI están documentadas en Build your MCP server y Connect from ChatGPT. Ambos describen, desde la perspectiva del cliente, cómo ChatGPT reconoce y llama a tu servidor — si implementas un servidor MCP estándar con cuidado, los requisitos de OpenAI se cumplen de forma natural.
Autenticación — OAuth 2.1 como base, API Key como camino auxiliar en el mismo servidor
Para ChatGPT Apps, la respuesta práctica es OAuth 2.1, vía única. La guía oficial de OpenAI lo dice con claridad: "ChatGPT does not support … custom API keys or customer-provided mTLS certificates". Si vas a publicar en el directorio de ChatGPT Apps, con OAuth 2.1 bien implementado es suficiente (también se permite el modo anónimo noauth para herramientas que no tocan datos del usuario, pero para herramientas como la nuestra, que trabajan con los endpoints y los logs de la cuenta del usuario, OAuth es obligatorio).
Dicho esto, si quieres que el mismo servidor MCP funcione también desde clientes locales como Cursor, Claude Code o Gemini CLI, la cosa cambia. El entorno local es un sitio donde el propio usuario puede guardar sus claves directamente, y allí el flujo OAuth se vuelve pesado. Por eso elegimos OAuth 2.1 como autenticación base para ChatGPT Apps y Claude Connectors, y añadir además un camino de API Key sobre el mismo servidor. La misma definición de herramientas funciona bajo ambos modos de autenticación.
OAuth 2.1 — base para ChatGPT Apps y Claude Connectors
Los clientes que corren en entornos gestionados no pueden esperar que los usuarios manejen claves a mano, y la política de OpenAI tampoco deja otra opción. Para que los clientes reconozcan correctamente el servidor, hay que cumplir los siguientes estándares.
- RFC 7591 — OAuth Dynamic Client Registration. Los clientes se registran ellos mismos.
- RFC 8414 — Authorization Server Metadata. Los endpoints de autenticación se exponen en
/.well-known/oauth-authorization-server. - RFC 9728 — Protected Resource Metadata. Metadatos del propio recurso MCP.
- RFC 7636 PKCE — challenge S256 que evita la interceptación del authorization code.
El flujo es el estándar. Registro dinámico del cliente → el usuario se autentica y se emite un authorization code (un solo uso, expira en 10 minutos) → intercambio del token con verificación PKCE → access token (1 hora) más refresh token (30 días, con rotación). Cuando el access token caduca, se renueva con el refresh token, y el propio refresh token también rota en cada renovación, para reducir el riesgo de robo.
La parte a la que dedicamos más atención fue garantizar que el code se consume de forma atómica una sola vez. El authorization code es un recurso muy valioso para un atacante, así que en el paso del intercambio del token hicimos que el code se reclame con una sola sentencia update, evitando cualquier race condition.
API Key — un camino auxiliar para usar el mismo código desde CLI/IDE
ChatGPT Apps llega por OAuth, pero queríamos que la misma definición de herramientas funcionara también desde clientes MCP locales como Cursor, Claude Code, Gemini CLI o Smithery, así que añadimos un camino adicional con API Key. En entornos locales el usuario puede guardar su propia clave, y enviarla con la cabecera x-api-key es el enfoque más limpio. Emitimos claves por usuario con el prefijo tm_mcp_ y mantenemos, por clave, el estado activo/inactivo y la última hora de uso.
Las 8 herramientas que exponemos y sus marcas de permisos
3Min API expone 8 herramientas a ChatGPT/Claude. Cada herramienta tiene que declarar tres anotaciones estándar de MCP. Primero, los significados.
| anotación | significado | ejemplo en true |
|---|---|---|
readOnlyHint | ¿Solo lectura? (no cambia datos) | Consultar logs/estadísticas |
destructiveHint | ¿Puede causar cambios irreversibles? | Editar/borrar un endpoint |
openWorldHint | ¿Habla con el mundo exterior o produce efectos secundarios? | Enviar un webhook externo |
Aplicando estos tres valores a nuestras 8 herramientas:
| herramienta | resumen | readOnly | destructive | openWorld |
|---|---|---|---|---|
help | Consulta de la guía del servicio | true | false | false |
endpoints | CRUD/despliegue de endpoints | false | true | false |
api_call | Invocación de un endpoint | false | true | true |
logs | Logs de llamadas y búsqueda | true | false | false |
stats | Estadísticas de uso | true | false | false |
collaborators | Claves de colaboración/invitaciones | false | true | true |
subscription | Información de suscripción | true | false | false |
archives | Descarga de archivos | true | false | true |
Áreas que dejamos fuera a propósito
Acciones como borrar la cuenta en sí, cambiar el método de pago o emitir/revocar las claves de autenticación MCP — todo lo que, ante un consentimiento erróneo, no se puede deshacer o que toca directamente el sistema de autenticación — no las hemos expuesto como herramientas. Dejarlas a criterio del LLM convierte una sola llamada equivocada en un incidente de seguridad, y tampoco encaja con la dirección que recomienda la guía de revisión de ChatGPT Apps.
Pruebas — conviene ejecutar los dos caminos de autenticación
Antes de enviar, probamos ambos caminos.
- Camino OAuth — En ChatGPT web, activamos el modo desarrollador en Settings → Apps & Connectors → Advanced settings y registramos la URL de nuestro servidor MCP con 'Create app'. ChatGPT lee automáticamente el
/.well-known/...de nuestro servidor para reconocer los metadatos OAuth, así que puedes recorrer tú mismo la pantalla de consentimiento hasta llegar a llamadas reales a las herramientas. - Camino API Key — Añadimos el servidor MCP a Claude Code, Cursor y Gemini CLI, y verificamos las llamadas a las herramientas. También nos registramos en Smithery para confirmar la presencia en el directorio.
El código es el mismo en ambos caminos, pero OAuth tiene que pasar además los metadatos well-known, la pantalla de consentimiento y la renovación de tokens, así que es un escalón más complicado. Antes de enviar, te recomiendo ejecutar al menos el paso en el que el ChatGPT real conecta con tu servidor y se descarga la lista de herramientas.
Envío a revisión — cosas que aprendimos tras un rechazo
El envío en sí es asumible siguiendo la guía oficial de OpenAI (app-submission-guidelines) y haciéndole preguntas a ChatGPT por el camino. Pero durante el formulario, ChatGPT conecta de verdad con tu servidor para traerse la lista de herramientas, así que tu producción tiene que estar en línea en el momento del envío. También hay que aportar credenciales de prueba (correo/contraseña, o una cuenta separada de revisión) para que los revisores de OpenAI puedan llamar a las herramientas ellos mismos.
Aviso 1 — marca los permisos de las herramientas de forma conservadora
Es la causa más habitual de rechazo. En nuestro primer envío dejamos openWorldHint en false en tres herramientas que hablan con el exterior (api_call, collaborators, archives), y por eso nos rechazaron. Tras corregirlo, pasó.
De esas tres, archives emite una URL externa de descarga, así que openWorldHint=true es evidente. Las otras dos son menos directas: api_call dispara tráfico externo a través de webhooks definidos por el usuario, y collaborators envía correos de invitación a colaboradores. Llegan al exterior, pero de forma indirecta, lo justo para hacerte dudar. A posteriori, marcar las dos como true de forma conservadora era lo correcto.
El razonamiento es simple. Una vez rechazado, esperas otras dos semanas aproximadamente para la siguiente revisión. Si una herramienta tiene cualquier flujo que toque el exterior, no dudes — márcala true. En coste de tiempo es la opción más barata. Lista los efectos secundarios que produce cada herramienta una a una, comprueba si alguno sale fuera de tu sistema, y las marcas se acaban colocando solas.
Aviso 2 — las capturas no son "pantallazos", son "trabajo sobre plantilla"
El formulario de envío incluye un campo de capturas que muestra cómo se ve tu app dentro de ChatGPT. Capturar por tu cuenta y subirlo se rechaza sin excepción. Para este paso OpenAI ofrece una guía clara, y el enlace está dentro de la propia interfaz de envío. Así funciona:
- En el paso de las capturas dentro del formulario, el enlace de la guía te lleva a un archivo Figma oficial de OpenAI.
- Tienes que copiar la plantilla de capturas de ese Figma a tu propio espacio de trabajo de Figma.
- Después pegas la pantalla real de tu app dentro de ChatGPT en el sitio designado de la plantilla. La proporción, los márgenes y la composición ya están definidos en la plantilla — tú solo rellenas el contenido.
- Por último exportas el tablero terminado como imagen y la subes en el formulario de envío.
Es decir, lo que se envía no es una captura cruda, sino la pantalla de tu app colocada dentro del marco que define OpenAI. Justo antes de enviar, repasa la guía una vez más y sigue exactamente lo que indica. Si saltas este paso y subes capturas tuyas, el envío se rechaza directamente.
Notas de la revisión — incluso tras la aprobación, queda un paso
Desde el envío hasta el resultado pasaron unas dos semanas o más. Si te rechazan y reenvías tras corregir, espera una espera parecida otra vez. Puedes ver el estado en el panel de desarrolladores de OpenAI, y recibes un correo cuando rechazan o aprueban.
La aprobación no significa que ya esté en producción. También tienes que pulsar el botón Publish en el panel para que empiece a aparecer a los usuarios normales.
Una cosa más justo después del lanzamiento. Que un usuario añada tu app no significa que ChatGPT vaya a usar tus herramientas en cada conversación. Incluso en temas relevantes, vas a ver muchas respuestas que no invocan ninguna herramienta. En esos casos conviene avisar al usuario de que llame explícitamente a tu app con una mención @. Pasar ese consejo dispara mucho la tasa de uso de las herramientas.
Claude Connectors — dónde estamos
Claude Connectors corre sobre el mismo MCP. Apenas hizo falta trabajo extra de código. El proceso de revisión, eso sí, está menos pulido que el de OpenAI. No hay un panel para seguir el estado del envío, y nosotros llevamos casi un mes sin recibir aprobación ni rechazo. Vale la pena enviar a ambos a la vez, pero planifica los plazos en torno a OpenAI para ir sobre seguro.
Pruébalo
Si quieres probar las herramientas MCP de 3Min API dentro de ChatGPT, o ver cómo lo hemos publicado, basta con buscar "3Min API" en la pantalla de añadir apps de ChatGPT Apps e instalarlo. Tras autenticarte una vez, menciona @3Min API en tus conversaciones para invocar las herramientas.
Si quieres probarlo desde un cliente MCP local (Claude Code, Cursor, etc.), inicia sesión y ve a Configuración → Integración con IA para emitir una API Key, y empieza directamente. Los detalles por herramienta y los ejemplos de llamada están recogidos en la Guía de Integración con IA.
Espero que esto sirva de pequeño atajo para quienes recorren el mismo camino.
Related Posts
Ahora puedes crear APIs dentro de ChatGPT — 3Min API se ha unido a ChatGPT Apps
3Min API se ha sumado a ChatGPT Apps. Sin escribir código ni alquilar un servidor, puedes crear APIs, probarlas e invitar a colaboradores desde dentro de tus conversaciones de ChatGPT. Lo recorremos con un pequeño escenario de un negocio de venta de vino.
Gestiona tus APIs con IA: Presentamos el soporte MCP
3Min API ahora es compatible con MCP — conecta tu asistente de IA para gestionar endpoints, revisar logs y más a través de una conversación natural.
¿Qué es JSON? Guía básica para dueños de pequeños negocios
Una guía introductoria a JSON que cierra la historia del dueño de la tienda de vino. Partiendo de una hoja de cálculo, recorre la estructura recursiva de claves, valores, objetos y arrays, y termina con una práctica para hoy mismo: escribir un evento de tu propio negocio como JSON. Sin conocimientos previos.