CodeGym /Cursos /ChatGPT Apps /Arquitectura del stack de ChatGPT Apps

Arquitectura del stack de ChatGPT Apps

ChatGPT Apps
Nivel 1 , Lección 1
Disponible

1. Introducción

Si miras una ChatGPT App simplemente como «otro servidor web más», muy pronto aparece un zoo arquitectónico: por un lado Next.js, por otro un servidor MCP, por otro un agente, en otro lugar un backend de commerce — y todo eso se confunde en la cabeza como un único gran «servidor».

Nos conviene mucho más aceptar desde el principio que es un pastel en capas:

  • arriba — ChatGPT UI, que no controlamos, pero al que nos adaptamos;
  • debajo — nuestro widget en Apps SDK (Next.js 16, React 19), que se renderiza en el chat;
  • aún más abajo — el servidor MCP con herramientas (tools/resources/prompts);
  • opcionalmente — una capa de agentes que orquesta escenarios complejos;
  • y en lo más bajo — tus servicios «terrenales»: BD, APIs externas, commerce/ACP (protocolo para escenarios de commerce), etc.

En el resumen del curso este recorrido puede dibujarse como una cadena:

User ChatGPT Widget Apps SDK MCP Gateway (Auth) Agent Service ACP / Stripe.

Nuestro objetivo ahora es convertir esta cadena en un modelo mental comprensible.

2. Esquema general del stack

Primero veremos la imagen completa y luego iremos capa por capa.

flowchart TD
    U[Usuario en ChatGPT] --> C["ChatGPT UI chat + panel de Apps"]
    C --> W["Widget de tu App (Apps SDK, Next.js)"]
    W --> M["Servidor MCP (tools/resources/prompts)"]
    M --> AG["Agente(s) (Agents SDK, orquestación)"]
    AG --> B["Backends y ACP BD, servicios, pasarela de pago"]

Es importante notar varias cosas.

En primer lugar, el usuario solo ve dos niveles: ChatGPT UI y tu widget. Todo lo que está debajo es «entre bambalinas».

En segundo lugar, el protocolo MCP no es una sigla aleatoria, sino un estándar oficial mediante el cual Apps SDK se comunica con tus herramientas: el servidor debe poder enumerar tools, aceptar solicitudes call_tool y devolver un enlace a un recurso de UI para renderizar en ChatGPT.

En tercer lugar, las capas de Agents y ACP son formalmente opcionales, pero en aplicaciones comerciales reales casi siempre aparecen: a veces hay que planificar un escenario de varios pasos, otras — aceptar pagos.

Ahora desglosamos cada capa por separado.

Insight: ChatGPT es un framework

La integración con ChatGPT no está en un solo lugar: está repartida por muchos puntos de integración. Para una persona desarrolladora se parece mucho a trabajar con un framework. El framework decide cuándo y dónde llamar a tu código; tú solo necesitas escribir las cosas correctas en los lugares correctos.

Con ChatGPT todo funciona exactamente así:

  • los widgets se registran mediante mcp-resources, GPT decide por sí mismo cuándo mostrarlos
  • mcp-tools — GPT decide por sí mismo cuándo invocarlos
  • product feed — se puede añadir al modelo mediante un mcp-tool, pero la opción estándar es a través de site register merchant
  • ACP/InstantCheckout — API separado
  • Autenticación — servidor de autenticación mcp separado.

3. Capa 1 — ChatGPT UI: nuestro «host»

ChatGPT UI es la interfaz de OpenAI para navegador (y móvil) donde el usuario mantiene el diálogo principal. Aquí hay un campo de entrada conocido, historial de mensajes, botones de selección de modelo y una pestaña con aplicaciones (Store/Composer).

Esta capa no la programamos. No tenemos acceso a su código, DOM ni estilos. Pero sí marca los límites:

  • aquí es donde el usuario «elige» tu aplicación explícitamente (a través de Store/Composer) o implícitamente (el modelo propone el App);
  • aquí es donde ChatGPT decide: responder solo con texto, llamar a tu tool, renderizar un widget o hacer todo a la vez;
  • aquí viven los patrones básicos de UX: widget inline, modo de pantalla completa, ventana PiP, etc. (en detalle en el módulo 8).

Desde un punto de vista práctico, conviene recordar: ChatGPT UI es nuestra aplicación host. Nos incrustamos dentro de ella, no al revés. El servidor de GPT cargará el código de tu widget en su servidor, lo limpiará de todo lo innecesario y solo entonces lo cargará en su chat desde su propio dominio.

4. Capa 2 — Apps SDK y widget (Next.js 16 dentro del chat)

La siguiente capa es tu código de UI, escrito en React/Next.js usando Apps SDK.

El modelo mental es sencillo: es como un mini‑SPA que se renderiza como un widget embebido en el chat. Pero con matices:

  • tu código funciona en sandbox: DOM limitado, reglas propias para las peticiones de red, objeto especial window.openai para comunicarse con ChatGPT (habrá una lección aparte sobre esto);
  • el widget no controla el flujo del diálogo: el usuario escribe en el chat general, el modelo decide cuándo llamar a tu App, y tú respondes solo dentro de tu «marco»;
  • Apps SDK se encarga de todo: sincronización del estado del widget con el historial del diálogo, procesamiento de resultados de tools, trabajo con MCP, etc.

Desde la perspectiva de un desarrollador de Next.js, esto se ve bastante familiar: hay páginas/componentes, hooks, props. Pero en lugar del clásico fetch('/api/...') con más frecuencia te apoyarás en herramientas (tools) descritas en el servidor MCP y en hooks especiales de Apps SDK (hablaremos de ellos más adelante en el curso).

Para concretar un poco, recordemos nuestro proyecto — el hipotético GiftGenius. Es una App que ayuda a elegir regalos según parámetros: para quién, con qué presupuesto, con qué motivo, etc.

Un mini fragmento del futuro UI (sin especificidades del SDK por ahora, solo como idea):

// GiftSummary.tsx — componente React sencillo de nuestra App
type GiftIdea = {
  id: string;
  title: string;
  price: number;
};

interface GiftSummaryProps {
  ideas: GiftIdea[];
}

export function GiftSummary({ ideas }: GiftSummaryProps) {
  return (
    <ul>
      {ideas.map((idea) => (
        <li key={idea.id}>
          {idea.title} — ${idea.price}
        </li>
      ))}
    </ul>
  );
}

Más adelante este componente recibirá ideas no del aire, sino del resultado de una herramienta del servidor MCP (ToolOutput), pero a nivel de arquitectura lo importante es otra cosa: todo ese código vive en la «segunda capa» y se ocupa solo de mostrar el estado.

5. Capa 3 — servidor MCP: el mundo de herramientas y datos

Ahora bajamos un nivel — a la parte del servidor.

Model Context Protocol (MCP) es un estándar que describe cómo un cliente LLM (ChatGPT, Apps SDK, Agents) se comunica con tu servidor. Define qué herramientas están disponibles, cuáles son sus esquemas de entrada/salida, cómo llamarlas y qué otros recursos/prompts se pueden cargar.

Un servidor MCP mínimo para Apps SDK debe saber hacer tres cosas:

  • devolver la lista de herramientas (List tools) con su JSON Schema y metadatos;
  • procesar llamadas a herramientas (Call tools): aceptar una solicitud call_tool, ejecutar la lógica de negocio y devolver un resultado estructurado;
  • devolver html, js, css, ... — opcionalmente, si la tool está asociada a un widget concreto que se deba mostrar.

Un punto importante: MCP es un protocolo independiente del transporte. Para ChatGPT Apps nos interesa su variante HTTP con implementación en streaming, pero los detalles del transporte y el formato de mensajes ya son tema del módulo de MCP (nivel 6). Por ahora basta con entender que Apps SDK «por abajo» habla precisamente con el servidor MCP, y no con endpoints REST arbitrarios.

A nivel arquitectónico, la capa MCP a menudo se ve como un microservicio aparte:

flowchart LR
    subgraph App["Tu ChatGPT App"]
      W["Widget (Next.js + Apps SDK)"]
      M["Servidor MCP (@modelcontextprotocol/sdk)"]
    end

    W <-- JSON-RPC over HTTP/SSE --> M
    M --> DB[(Catálogo de regalos)]
    M --> EXT[APIs externas]

Dentro del servidor MCP escribes código TypeScript/Node normal, usas bases de datos, colas, APIs de terceros, etc. El SDK oficial de MCP para TypeScript se encarga de la serialización JSON‑RPC, validación de esquemas y enrutado de llamadas.

Para nuestro GiftGenius, una de las herramientas MCP podría llamarse, por ejemplo, search_gifts. En TypeScript puede verse como una función normal:

// Pseudo‑código: lógica de negocio dentro del servidor MCP
export async function searchGifts(params: {
  recipient: string;
  budget: number;
}) {
  // aquí ya consultas la BD/el catálogo
  const items = await findGiftsInCatalog(params);
  return items.slice(0, 10);
}

Después la envolveremos en un MCP‑tool con la descripción de su esquema, pero lo principal es: esta capa es tu «backend normal», solo que habla con el mundo a través de MCP.

6. Capa 4 — Agents SDK: el cerebro de los escenarios complejos

No todas las aplicaciones necesitan agentes, pero en cuanto el escenario deja de ser «una llamada a una herramienta — una respuesta», la capa de agentes se vuelve muy útil.

Un agente es, en esencia, un proceso LLM controlado, que:

  • lee la petición del usuario y los hechos del historial del diálogo;
  • planifica la secuencia de pasos: qué herramientas invocar, en qué orden y con qué argumentos;
  • analiza los resultados, puede decidir «reinvocar una tool», «pedir una aclaración al usuario», «construir una respuesta más compleja»;
  • a veces conserva estado entre pasos (memoria, sesiones, checkpoints — eso ya es el nivel 12).

Agents SDK ofrece una forma estructurada de describir esos escenarios: qué tools están disponibles para el agente, cómo guardar y restaurar el estado, cómo limitar los ciclos, etc. Los agentes se ejecutan dentro del backend y te permiten usar la potencia de OpenAI como más te convenga, sin las limitaciones de los widgets de ChatGPT Apps.

En el contexto de nuestro stack, el agente suele residir en el backend entre la capa MCP y tus APIs de dominio. Puede usar APIs externas, funciones internas y MCP‑tools como «manos», y ocuparse él mismo del «cerebro».

Por ejemplo, el escenario de GiftGenius podría verse así:

  1. El usuario escribe «elige un regalo para mamá de hasta 50 $».
  2. ChatGPT invoca la herramienta search_gifts de tu aplicación.
  3. Detrás de search_gifts en el backend hay un Agente que decide primero aclarar un par de detalles (intereses, ocasión).
  4. El usuario detalla más preferencias.
  5. ChatGPT vuelve a invocar la herramienta search_gifts de tu aplicación con argumentos adicionales.
  6. El agente en el servidor puede llamar herramientas adicionales (por ejemplo, comprobación de disponibilidad).
  7. Devuelve a ChatGPT las opciones ya preparadas y, posiblemente, un enlace a un widget para la visualización.

Más adelante en el curso analizaremos en detalle el ciclo de ejecución del agente, idempotencia y seguridad, pero para la arquitectura general es importante: la capa de agentes es opcional, pero es un «cerebro» muy potente que te quita parte de la orquestación compleja.

7. Capa 5 — ACP/Backend: dinero, datos y preocupaciones terrenales

La capa más baja — tus servicios habituales:

  • bases de datos (catálogos de productos, usuarios, pedidos);
  • APIs externas (proveedores de pago, logística, SaaS de terceros);
  • protocolos especializados como ACP (Agentic Commerce Protocol) para escenarios de commerce e Instant Checkout.

ACP describe cómo ChatGPT y los agentes se comunican con tu backend de commerce: solicitudes para seleccionar SKU, crear una cesta, tramitar un pedido, devoluciones, webhooks de operaciones exitosas/erróneas, etc.

Para GiftGenius sería algo así:

  • la MCP‑tool search_gifts lee del feed de productos/BD;
  • el agente, al elegir un producto concreto, inicia un intent de commerce (mediante ACP);
  • tu backend compatible con ACP le dice a PaymentService: «cobramos», informa a ChatGPT del estado;
  • el usuario ve en ChatGPT que el pedido se ha tramitado, sin ir a un sitio externo.

Ahora que hemos pasado por las capas, veamos un escenario concreto end‑to‑end.

8. Escenario de extremo a extremo: cómo pasa la solicitud del usuario por todas las capas

Tomemos la petición: «Elige un regalo para mamá de hasta 50 dólares, le gusta leer y el té».

Desglosemos por pasos.

  1. El usuario escribe un texto en ChatGPT. Esta es la primera capa — ChatGPT UI. Para el usuario todo parece un chat normal.
  2. El modelo lee el historial del diálogo, los metadatos de tu App (descripciones, categorías, permisos) y decide que GiftGenius es un candidato pertinente. Según las reglas de discovery en Apps SDK, el modelo tiene en cuenta las descripciones textuales de las tools, la experiencia previa de uso, el contexto e incluso menciones de marca.
  3. ChatGPT o bien:
    • invoca directamente la herramienta de tu App sin UI (escenario tool‑first);
    • o propone en la respuesta: «Puedo usar GiftGenius para ayudar a elegir un regalo» e invoca tu tool.
  4. ChatGPT envía al servidor MCP una solicitud call_tool para la herramienta search_gifts. El servidor MCP, a su vez, ejecuta la lógica de negocio: consulta la BD/feed, filtra por presupuesto y preferencias y devuelve un JSON con una lista de productos adecuados.
  5. El resultado de la herramienta vuelve a ChatGPT. Puede:
    • usarlo simplemente como datos para una respuesta de texto («Aquí tienes 3 ideas de regalos...»), sin mostrar el widget;
    • o mostrar el widget, pasando el ToolOutput a tu componente para renderizar tarjetas de producto.
  6. Y solo en ese momento se inicia tu widget GiftGenius (Apps SDK) y tu código de Next.js se renderiza dentro del chat. El widget puede, por ejemplo, mostrar un formulario con campos de aclaración: «¿Para quién es el regalo?», «Presupuesto», «Intereses». El usuario puede hacer clic en botones o simplemente seguir escribiendo en el chat — el modelo lo sincronizará con la App.
  7. En cuanto el widget necesita datos reales (el catálogo de regalos), no hace fetch('https://my-backend/gifts') directamente. En su lugar, él mismo inicia la invocación de un MCP tool: ChatGPT vuelve a enviar al servidor MCP una solicitud call_tool para la herramienta search_gifts.
  8. Si el escenario es de varios pasos (hay que pedir aclaraciones, hacer ranking, comprobaciones de stock adicionales, proponer alternativas), la capa de agentes se encarga de la planificación, la gestión del workflow y la orquestación.
  9. Cuando el usuario decide «comprar» un producto concreto, ChatGPT inicia la compra mediante el protocolo ACP. El backend de commerce, a través de ACP e Instant Checkout, realiza la operación, responde con el estado, activa webhooks y ChatGPT muestra al usuario el estado final («Pedido realizado, aquí está el recibo»).

Desde el punto de vista del desarrollador, es estupendo que en cada nivel haya límites claros de responsabilidad. Y al mismo tiempo todas las capas se conectan mediante nuevos protocolos estandarizados (MCP, ACP), y no con los viejos y cansinos requests REST.

Todo esto es la imagen lógica: qué capas existen y cómo fluye la solicitud a través de ellas. A continuación nos interesará el lado físico: cómo pueden desplegarse exactamente estas capas en código e infraestructura — como un monolito de Next o como varios servicios (no hablamos de arquitecturas monolito vs microservicios).

9. Monolito Next.js vs arquitectura separada

Ahora la pregunta lógica: «¿Todo esto tiene que ser necesariamente un montón de servicios separados? ¿Puedo simplemente hacer un monolito Next.js y listo?»

Respuesta: puedes. En el curso iremos de lo simple a lo complejo. Al principio está perfectamente bien reunir «casi todo» en un solo repositorio e incluso en un mismo runtime:

flowchart LR
    U[ChatGPT] --> W["Next.js App (Apps SDK)"]
    W --> M["MCP endpoint (en el mismo Next.js)"]
    M --> DB[(BD/catálogo)]

Es decir, tu servidor Next.js (rutas de API o un servidor separado) simultáneamente:

  • sirve el widget de UI (páginas/componentes de Apps SDK),
  • implementa el endpoint MCP (JSON‑RPC sobre HTTP),
  • accede a la BD/APIs externas.

Esto es cómodo en modo dev y para las primeras versiones del App: menos piezas móviles, despliegue más sencillo.

Sin embargo, a medida que crece la funcionalidad surgen motivos para separar las capas:

  • el servidor MCP necesita escalarse aparte (muchas herramientas pesadas);
  • el backend financiero vive en su propio dominio, lo regulan otros equipos y requiere seguridad especial;
  • la lógica de agentes puede extraerse a una aplicación separada con su propio monitorizado y SLA.

Entonces el diagrama empieza a parecerse más a lo que ya vimos:

flowchart TD
    U[ChatGPT] --> W[Next.js + Apps SDK]
    W --> MG[MCP Gateway]
    MG --> M1[MCP Gifts Server]
    MG --> M2[MCP Analytics Server]
    M1 --> AG[Agent Service]
    AG --> ACP[Commerce/ACP Backend]

Aparece el concepto de MCP Gateway — la entrada común para ChatGPT. Enruta las llamadas a distintos servidores MCP, trabaja con APIs REST, gestiona autorización, límites de petición (rate limiting), etc.

Empezaremos escribiendo ejemplos con un escenario más monolítico, pero desde el principio organizaremos el código para que se pueda dividir en partes con relativa facilidad.

10. Dónde exactamente escribirás código (y qué delegas a otros)

Ya que hemos esbozado cómo pueden reunirse las capas en un monolito o una arquitectura distribuida, conviene fijar explícitamente en qué lugares escribirás código y qué quedará en manos de otros servicios/equipos.

Desde la perspectiva de un desarrollador de TypeScript/Next.js, es útil señalar claramente qué zonas controlas.

En el widget (Apps SDK + Next.js) tú:

  • escribes componentes React que muestran el estado de las herramientas y la entrada del usuario;
  • usas hooks de Apps SDK para leer ToolInput/ToolOutput y el estado del widget (widget state);
  • configuras el modo visual (inline/fullscreen/PiP, temas, tamaños — esto estará en el nivel 8);
  • interactúas con ChatGPT a través de window.openai para escenarios más avanzados (módulo aparte del curso).

En el servidor MCP tú:

  • describes tools/resources/prompts con el SDK de MCP;
  • implementas la lógica de negocio de las herramientas (básicamente funciones TypeScript normales que acceden a BD, APIs, etc.);
  • optimizas esquemas y respuestas para que el modelo pueda leerlos cómodamente (menos alucinaciones, más estructura).

En la capa de agentes (si usas Agents SDK) tú:

  • describes qué herramientas están disponibles para el agente y cuáles son sus objetivos;
  • configuras el ciclo de ejecución, memoria y control de bucles;
  • te aseguras de que el agente no haga tonterías ni caiga en una planificación infinita.

En ACP/backends tú:

  • o te integras con servicios de commerce existentes (Stripe, tu propia tienda con product feed, etc.);
  • o diseñas un backend nuevo que entienda ACP y sepa recibir y devolver pedidos.

Importante: rara vez la misma persona domina por completo todas las capas en un producto maduro. Pero en la fase de prototipo (y en este curso) esperamos que al menos puedas entender en qué lugar vive cada trozo de código.

11. Cómo la arquitectura afecta al UX y a la política de la plataforma

Aunque UX y políticas son módulos aparte, ya a nivel de arquitectura es importante entender cómo la separación de capas elegida afecta al UX y a los requisitos de la plataforma. Por eso haremos un par de observaciones por adelantado.

En primer lugar, sandbox. El widget no puede navegar por Internet sin control ni recopilar datos de usuario — todo pasa por herramientas controladas y permisos descritos en MCP/Store. La plataforma espera que describas honestamente qué datos y acciones necesita tu App y basará el discovery/las sugerencias del App en esas descripciones.

En segundo lugar, flujo de UX. Debido a que el modelo puede «olvidarse» temporalmente de tu App o, por el contrario, proponerla demasiado agresivamente, la arquitectura debe ser amigable a las interrupciones: si el agente no termina un workflow largo y el usuario cambia de tema, la aplicación debe soportarlo con calma. Los escenarios de varios pasos y la orquestación de workflows en el curso se construirán precisamente sobre MCP‑tools y la capa de agentes.

En tercer lugar, ventas. En cuanto tu App empieza a cobrar dinero, entran en vigor requisitos adicionales de seguridad, registro (logging), contratos ACP, etc. La forma en que separaste las capas (UI, MCP, Agents, ACP/Backend) influirá mucho en lo doloroso que sea pasar la revisión de la Store y la auditoría de seguridad.

Primeras conclusiones

Espero que hayas construido en tu cabeza un mapa panorámico:

  • las capas superiores (ChatGPT UI + Apps SDK) determinan cómo el usuario ve y siente tu App;
  • la capa intermedia (MCP) es la forma estándar de darle al modelo herramientas y datos;
  • las capas de agentes y commerce hacen que tu App no sea solo un «visor de datos», sino un producto completo con lógica y dinero.

En el segundo nivel empezaremos por lo más interesante: descargaremos la plantilla oficial de Apps SDK basada en Next.js, la ejecutaremos localmente y la conectaremos a ChatGPT en Dev Mode. Es decir, primero tocaremos con las manos la capa de Apps SDK/widget, y MCP/agentes de momento vivirán como stubs o como backend embebido.

Pero conviene mantener el esquema actual en mente ya ahora: es como mirar un monorepo y entender que la carpeta apps/ — es el UI, services/mcp — el protocolo, services/agent — el orquestador, y services/commerce — el dinero.

12. Errores típicos en la comprensión de la arquitectura del stack

Error nº 1: creer que una ChatGPT App = simplemente «un webhook hacia mi REST API».
Se puede hacer por costumbre del mundo de «bots»: el modelo simplemente envía peticiones POST a mi URL y luego ya veremos. En realidad, entre el modelo y tu código están Apps SDK y MCP. Necesitas describir herramientas, sus esquemas y comportamiento, y no simplemente «escuchar» peticiones HTTP arbitrarias.

Error nº 2: mezclar los niveles de UI y lógica de negocio.
Un antipatrón popular es llevar lógica de dominio compleja directamente al widget y hacer de la capa MCP un fino pasamuros. El resultado es un UI pesado, difícil de testear y poco reutilizable fuera de ChatGPT. Es mucho más sostenible mantener las reglas y el acceso a datos en el nivel MCP/agent, y dedicar el widget exclusivamente a la presentación y al interactivo sencillo.

Error nº 3: ignorar MCP y escribir «tu propio protocolo».
A veces surge la tentación: «¿para qué MCP?, simplemente devolveré JSON y el modelo se apañará». En demos cortas eso puede «funcionar» de forma sorprendente, pero pierdes de inmediato las capacidades estándar de discovery, inspección, autorización y soporte multi‑cliente que MCP y Apps SDK traen «de serie».

Error nº 4: construir toda la App alrededor de una sola capa.
Hay quien hace «todo en el agente», cargándolo con un montón de responsabilidades. Otros, por el contrario, intentan encajar todo en MCP‑tools. Otros construyen un monolito Next.js gigantesco. Es mejor aceptar que cada capa tiene su zona de responsabilidad: UI — presentación, MCP — acceso a datos/acciones, agente — orquestación, ACP/Backend — invariantes de dominio y dinero.

Error nº 5: subestimar el impacto de la arquitectura en la revisión de la Store y la seguridad.
Si tienes un único servidor que simultáneamente es el endpoint MCP, el recurso ACP, guarda secretos y lo registra todo «tal cual», la revisión de seguridad y de política de contenido puede alargarse. Una arquitectura separada con límites y protocolos claros simplifica mucho la vida en etapas posteriores.

1
Tarea
ChatGPT Apps, nivel 1, lección 1
Bloqueada
Simple Tabs Switcher
Simple Tabs Switcher
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION