1. Por qué merece la pena pensar en los entornos
En el desarrollo web habitual, tarde o temprano aparece el trío: desarrollo local, servidor de pruebas y entorno de producción. En el mundo de ChatGPT Apps es lo mismo, pero con un giro adicional: el cliente (ChatGPT) siempre está en la nube, incluso cuando desarrollas «en local».
Si todo gira solo en tu portátil bajo una dirección aleatoria de un túnel, aparecen varios efectos desagradables. Primero, la URL cambia constantemente y no recuerdas a qué endpoint está ligado ahora el Dev Mode. Segundo, el rendimiento y la red no se parecen a las condiciones reales. Tercero, el entorno local a menudo usa otras claves, otros servicios y en general «vive en una realidad paralela».
Por otro lado, vivir «siempre en prod» también es malo. Cualquier cambio puede romper de repente los flujos de los usuarios reales, especialmente si ya tienes integraciones tipo Stripe, OAuth o pagos vía ACP. Jurídica y políticamente también es problemático: experimentar con usuarios reales no es el mejor camino hacia el Store.
Por eso, el objetivo de esta lección es fijar en tu cabeza un esquema simple pero firme: existe local dev, existe staging, existe production y existe Dev Mode como forma de dirigir ChatGPT al entorno adecuado. Y no un gran «mi portátil con un túnel que a veces, de repente, se convierte en prod».
2. Particularidad de ChatGPT Apps: el cliente siempre está en la nube
En una SPA clásica a menudo arrancas tanto el cliente como el servidor en local: el navegador en localhost, el backend en localhost, y todo se comunica felizmente dentro de la misma máquina.
En ChatGPT Apps eso no ocurre. El cliente (ChatGPT + tu widget) siempre vive en la infraestructura de OpenAI. Incluso si el código de tu aplicación corre en tu portátil, la petición sigue este camino:
sequenceDiagram
participant User as Usuario
participant ChatGPT as ChatGPT (nube)
participant Tunnel as Túnel HTTPS
participant App as Tu Next.js + MCP
User->>ChatGPT: Mensaje / clic en el widget
ChatGPT->>Tunnel: Solicitud HTTPS al URL de la app
Tunnel->>App: Proxy hacia localhost
App-->>Tunnel: Respuesta (UI/JSON)
Tunnel-->>ChatGPT: Respuesta
ChatGPT-->>User: Chat actualizado + widget
Incluso cuando «solo pruebas en local», ya estás en un sistema distribuido: hay un cliente en la nube, hay red, hay un túnel y hay tu servidor local.
Esto es importante porque:
- El entorno local no es «todo lo tengo en local». Es «nube → túnel → servidor local».
- Cuando más tarde añadas staging y production, el esquema solo diferirá en adónde envía ChatGPT las peticiones: al túnel, al dominio de staging o al dominio de producción.
3. Local dev: cómo se ve tu esquema actual
Veamos cómo luce ese esquema general en tu caso.
Tras los módulos 2–6, lo más probable es que tengas algo así:
- Servidor de desarrollo de Next.js, arrancado con npm run dev (normalmente http://localhost:3000).
- Servidor MCP local (a menudo es un proceso aparte, por ejemplo http://localhost:2091).
- Túnel HTTPS (ngrok, Cloudflare Tunnel, etc.), que expone tu endpoint Next.js/HTTP hacia fuera en una dirección como https://abc123.ngrok.app.
A través del Dev Mode en ChatGPT indicas esa URL pública y ChatGPT empieza a acceder a tu aplicación. Todo esto es el entorno de local dev.
Propiedades principales de local dev:
- El entorno local proporciona un ciclo de feedback muy rápido. Cambias el código en VS Code, Next.js hace hot reload, el widget se actualiza en unos segundos.
- Aquí puedes romper lo que quieras, usar datos mock, claves de prueba, configuraciones raras.
- No hay usuarios reales; poca gente, aparte de ti, conoce esa URL.
Suele verse así:
graph LR
subgraph Dev Laptop
Next[Next.js dev server]
MCP[MCP server]
end
ChatGPT((ChatGPT Cloud))
Tunnel[[Túnel HTTPS]]
ChatGPT --> Tunnel --> Next
Next --> MCP
Para no confundirte más adelante entre local/staging/production, es útil que la propia aplicación «sepa» dónde está ejecutándose. Desde el punto de vista del código, conviene fijar explícitamente que estás en el entorno de desarrollo. El paso más simple es introducir un pequeño módulo de configuración del entorno.
Por ejemplo, creemos el archivo app/config/env.ts:
// app/config/env.ts
export type AppEnv = 'local' | 'staging' | 'production';
export const APP_ENV: AppEnv =
(process.env.NEXT_PUBLIC_APP_ENV as AppEnv) ?? 'local';
export const isProd = APP_ENV === 'production';
Aquí:
- Definimos un tipo enumerado de entornos.
- Leemos la variable NEXT_PUBLIC_APP_ENV (más adelante le darás valores distintos en dev/staging/prod).
- Por defecto asumimos que estamos en 'local', para que el desarrollo local funcione «out of the box».
Esto todavía no despliega nada, pero ya te da un punto de apoyo: tu código entiende en qué entorno se está ejecutando.
Luego puedes, por ejemplo, mostrar el entorno en el propio widget para no confundirte.
// app/components/EnvBadge.tsx
import { APP_ENV } from '../config/env';
export function EnvBadge() {
return <span>ENV: {APP_ENV}</span>;
}
Un badge tan pequeño ayuda mucho a no confundirse con «¿estoy ahora en staging o en prod?», sobre todo cuando el widget es idéntico por fuera.
4. Staging: el ensayo general del entorno de producción
El entorno de staging es «el ensayo del entorno de producción». Ya no es tu portátil con un servidor de desarrollo, sino un servidor remoto o un despliegue en Vercel al que se sube el código compilado.
Desde el punto de vista de ChatGPT, staging se ve casi como production: es un endpoint HTTPS cómodo y estable con un dominio del tipo https://staging.giftgenius.app, donde:
- el código ya está compilado (ha pasado npm run build);
- se usan variables de entorno parecidas a las de producción (mismos nombres, mismo formato) pero con claves de prueba;
- están disponibles los mismos servicios externos (Stripe sandbox, cuentas OAuth de prueba);
- la topología de red es parecida a la de producción (por ejemplo, el mismo tipo de base de datos y la misma región).
Para qué sirve staging en el contexto de ChatGPT Apps:
Primero, staging es el sitio ideal para ejecutar escenarios end‑to‑end. Por ejemplo: usuario en ChatGPT → ChatGPT lanza tu aplicación → el widget pregunta al usuario → se invoca una herramienta MCP que consulta una API externa → devuelve recomendaciones → el widget muestra el resultado. Ese escenario en local a través de un túnel aleatorio puede comportarse de una manera. En staging, de otra: allí la latencia, la red y los recursos están más cerca de la realidad.
Segundo, staging permite probar integraciones que da miedo ejecutar en local. Por ejemplo, pagos: Stripe, ACP/Instant Checkout, etc. En staging configuras claves de prueba, webhooks de prueba y ejecutas escenarios «en serio», pero sin dinero real.
Tercero, staging es un lugar de verificación en equipo. Si tienes varios desarrolladores, diseño, QA, producto, necesitan una URL común que no dependa de quién tiene el portátil encendido o de si a alguien se le ha caído el túnel.
Es útil imaginar staging así:
graph LR
ChatGPT((ChatGPT Cloud))
AppStaging["GiftGenius Staging https://staging.giftgenius.app"]
ChatGPT --> AppStaging
Y dentro de https://staging.giftgenius.app pueden estar corriendo Next.js, el servidor MCP, la base de datos de staging y todo lo demás.
En esta lección no entramos en los detalles del despliegue en Vercel; esa es materia de temas posteriores. Ahora basta con asumirlo así: staging es un entorno aparte, lo más parecido posible a producción en configuración y en cómo llega hasta él ChatGPT.
5. Production: servidor en vivo y usuarios reales
El entorno de producción es el lugar al que llegan usuarios reales y dinero real. Aquí ya no vale «hago un cambio rápido en main y a ver qué pasa»: cualquier modificación debe ser consciente, probada y, a ser posible, con capacidad de rollback.
El dominio de producción debe ser estable. No es una URL aleatoria de ngrok, sino un nombre normal tipo https://giftgenius.app o similar. Esta es la dirección que indicas en los ajustes de la App para el Store: cuando un usuario encuentra tu aplicación en el ChatGPT Store y la lanza, ChatGPT llamará precisamente a ese endpoint.
Suele exigirse más al entorno de producción:
- Estabilidad. Bajo porcentaje de errores, tiempos de respuesta previsibles, funcionamiento correcto bajo carga. En módulos posteriores hablaremos de SLO/SLI, pero de forma intuitiva es «la aplicación debe funcionar “casi siempre” y responder “casi siempre” rápido».
- Seguridad. Solo los secretos necesarios, permisos mínimos imprescindibles, manejo cuidadoso de PII y del dinero.
- Limitación de experimentos. Nada de «he vuelto a reiniciar el servidor de dev» a media jornada; experimentos vía feature flags, A/B o un entorno dev/staging separado, no trasteando el servidor de producción.
En términos de ChatGPT, producción ya no va de Dev Mode, sino de la App publicada: está disponible a los usuarios a través del Store o de los ajustes de la organización, pasa revisión y debe ser lo bastante fiable como para no dar mala imagen ante la moderación.
6. Dev Mode vs uso en prod de la App: qué está conectado con qué
Ahora, la confusión más habitual: el Dev Mode de ChatGPT no es «un entorno aparte». Es más bien un conmutador de rutas: a qué URL está mirando ChatGPT cuando pruebas la aplicación.
En Dev Mode puedes:
- conectar la app local vía túnel;
- conectar el entorno de staging;
- incluso apuntar temporalmente el Dev Mode a producción (lo cual normalmente no deberías hacer).
Formalmente, Dev Mode le dice a ChatGPT: «Aquí está el manifiesto de mi App, aquí la URL de mi endpoint MCP/Apps SDK. Úsalo cuando yo lance esta aplicación». Y puedes cambiar esa URL.
Tras publicar en el Store, tu App obtiene un endpoint oficial de producción. Ese será el que se use con usuarios reales, y no puedes cambiarlo sin más: necesitas una versión nueva, revisión, etc.
En la práctica, un esquema razonable para tu app de aprendizaje podría ser este:
graph TD
subgraph Dev Mode
DevApp["GiftGenius Dev App
(Dev Mode)"]
end
subgraph Store
ProdApp["GiftGenius
(Store App)"]
end
UserDev[Tú / equipo] --> DevApp
UserProd[Usuarios reales] --> ProdApp
DevApp -->|URL del túnel| LocalEnv[Local dev
https://abc123.ngrok.app]
DevApp -->|staging URL| StagingEnv[Staging
https://staging.giftgenius.app]
ProdApp -->|prod URL| ProdEnv[Production
https://giftgenius.app]
Configuras la app de Dev Mode GiftGenius Dev para que normalmente apunte a local dev (a través del túnel) y, cuando haga falta, a staging. La app de Store GiftGenius está ligada estrictamente a la URL de producción.
A veces se crea además una App aparte para QA, como GiftGenius Staging, que solo mira a la URL de staging. Es útil si tienes un gran equipo de testers; en el curso basta con una única App de dev.
Es importante acostumbrarse a pensar así: Dev Mode es tu sandbox personal para ti y tu equipo, donde puedes cambiar la URL, ajustar metadatos, reiniciar el túnel. La App de producción en el Store solo mira a producción y vive con reglas más estrictas.
7. Vincular ramas de Git, dominios y la App de ChatGPT
Los entornos no son solo servidores. También son ramas de código y configuraciones de la App en ChatGPT. Tarde o temprano querrás que, con un vistazo a la URL o al nombre de la App, puedas entender qué versión de código está corriendo allí.
Un enfoque mínimo y sencillo sería este.
Para desarrollar features concretas usas ramas feature/*, por ejemplo feature/new-recommendation-algo. Arrancas el código en local + túnel. El Dev Mode de ChatGPT suele mirar al mismo endpoint de dev, donde lanzáis por turnos las versiones locales. Una App separada por cada rama feature sería excesivo.
Para integrar features antes de una release puedes tener una rama develop o staging. Todo lo que esté en esa rama se despliega automáticamente al entorno de staging, por ejemplo a un Vercel preview URL del tipo https://giftgenius-staging.vercel.app. Para ello puedes crear una App de Dev Mode específica o reconfigurar periódicamente la App de Dev Mode general para que apunte a esa URL.
La rama main (o master) contiene solo código probado. Es la que se despliega a la URL de producción y está vinculada a la app de Store GiftGenius.
Podría verse más o menos así:
| Entorno | Rama de Git | URL | ChatGPT App |
|---|---|---|---|
| Local dev | |
|
GiftGenius Dev (Dev Mode) |
| Staging | |
|
GiftGenius Dev o GiftGenius Staging |
| Prod | |
|
GiftGenius (Store) |
¿Recuerdas APP_ENV de app/config/env.ts? Los valores 'local'/'staging'/'production' corresponden directamente a la columna «Entorno»: en local dev arrancas la app con APP_ENV=local, el despliegue de staging con APP_ENV=staging, y producción con APP_ENV=production.
Esta tabla no es burocracia, sino una forma de no depurar siguiendo el patrón «¿qué versión está corriendo ahora en este dominio?».
En el propio código puedes reforzar un poco este vínculo. Por ejemplo, mostrar no solo el ENV, sino también el commit/rama en el modo de depuración del widget:
// app/config/buildInfo.ts
export const BUILD_COMMIT = process.env.NEXT_PUBLIC_BUILD_COMMIT ?? 'dev';
export const BUILD_ENV = process.env.NEXT_PUBLIC_APP_ENV ?? 'local';
// app/components/BuildInfo.tsx
import { BUILD_COMMIT, BUILD_ENV } from '../config/buildInfo';
export function BuildInfo() {
return <small>Build: {BUILD_ENV}@{BUILD_COMMIT}</small>;
}
Si en el despliegue rellenas NEXT_PUBLIC_BUILD_COMMIT con el SHA del commit, el widget mostrará qué código exacto está funcionando ahora. En staging/prod esto a veces ahorra horas de depuración.
8. Mini práctica: dibuja el esquema de tus entornos
Antes de meternos en Vercel y logs, es útil «dibujar en una servilleta» el esquema de tus entornos. Puede ser un diagrama mermaid en el README.md, un boceto en una pizarra o incluso una imagen en una libreta.
Para nuestro GiftGenius de ejemplo, el esquema podría ser así:
graph TD
subgraph ChatGPT
DevMode["Dev Mode
(tú y el equipo)"]
Store["Store
(usuarios reales)"]
end
subgraph Servers
Local[Local dev
Túnel → localhost]
Staging[Staging
staging.giftgenius.app]
Prod[Production
giftgenius.app]
end
DevMode --> Local
DevMode --> Staging
Store --> Prod
Ejercicio útil para ti justo después de la lección:
- Enumera todos los entornos que ya tienes: local con túnel, quizá algún despliegue temprano en Vercel, etc.
- Anota al lado qué ramas de Git se despliegan allí.
- También, qué ChatGPT Apps (o conectores) miran a cada uno.
- Marca con flechas desde dónde llega ChatGPT a cada servidor.
Si no trabajas solo, crea un archivo architecture/environments.md en el repositorio. Reducirá de inmediato la probabilidad de «se nos ha caído el staging, pero nadie sabe cuál es esa URL».
Para enlazar esto con tu app, puedes crear ahora mismo en Dev Mode una App GiftGenius Dev y decidir: por defecto apunta al túnel del entorno local; cuando quieras probar un release completo, la reconfiguras temporalmente a la URL de staging. En las próximas lecciones aprenderás a desplegar staging/prod en Vercel y a vincularlo con variables de entorno.
Si resumimos todo en una idea: trata los entornos y el Dev Mode como el sistema de coordenadas de tu App. Local para desarrollo rápido, staging para el ensayo general, production para usuarios reales, y Dev Mode como tu conmutador entre ellos, no como un entorno mágico aparte.
9. Errores típicos al trabajar con entornos y Dev Mode
Error n.º 1: vivir solo con localhost + túnel y considerarlo producción.
Este enfoque parece cómodo: «¿para qué necesito staging y prod, si mi túnel funciona y ChatGPT se conecta?». Pero el túnel tiene una URL inestable, características de red distintas y todo el esquema depende de un único portátil. En cuanto necesites algo como un OAuth callback, Stripe webhooks o MCP Gateway, la ausencia de un staging/prod normal te traerá dolor.
Error n.º 2: confundir el Dev Mode con un entorno aparte.
Muchos piensan: «Tengo Dev Mode, así que ya tengo un entorno de dev». En realidad Dev Mode solo le dice a ChatGPT adónde ir: al túnel, a staging o incluso a prod. Dev Mode es una configuración del cliente, no del servidor. Los entornos de servidor (local/staging/prod) los creas tú: despliegas código, configuras dominios y variables de entorno.
Error n.º 3: apuntar el Dev Mode a producción para “probar un poco”.
Técnicamente es posible: puedes poner la URL de producción en Dev Mode y «jugar» con la App como si fuera local. El problema es que, de repente, pasas a probar con usuarios reales, datos reales y, quizá, dinero real. Cualquier error del tool o del widget puede provocar fallos a usuarios en vivo y quizá ni siquiera entiendas al principio de dónde viene. Mejor mantener Dev Mode en dev/staging y usar la App de Store para producción.
Error n.º 4: no tener un mapa claro «rama ↔ entorno ↔ URL ↔ App».
Si nadie en el equipo puede responder a la primera qué rama se despliega en staging, cuál es su URL y qué App de ChatGPT lo apunta, es una fuente segura de caos. Empiezan las historias de «a mí me funciona, en staging no, en prod otra cosa». Una tabla o un archivo markdown con ese mapa se amortiza con creces.
Error n.º 5: infravalorar la diferencia entre local dev y staging.
En local ejecutas un servidor de dev, tienes un conjunto de claves, un conjunto de servicios y una red. En staging el código ya está compilado, se ejecuta en otro entorno, con otros límites, timeouts y rutas. Si solo pruebas en local y mantienes staging «por cumplir», los bugs críticos saldrán en prod. Es importante acostumbrarse a la cadena: primero desarrollo local, luego verificación en staging y solo después release a producción.
Error n.º 6: intentar resolver todos los problemas con ChatGPT, ignorando el esquema de entornos.
A veces, ante problemas, los desarrolladores empiezan a «preguntar a ChatGPT qué pasó», en lugar de mirar el dibujo: qué App está ligada a qué URL, en qué entorno ha caído, dónde están los logs. Nuestro esquema de entornos de hoy es el fundamento de la próxima lección, donde depuraremos de forma sistemática: ver logs, usar el inspector de MCP y solo entonces culpar al modelo.
GO TO FULL VERSION