Los agentes de codificación ahora crean aplicaciones web funcionales: un panel de control, una página de producto, un prototipo que un equipo de producto quiere probar. La forma más rápida de revisar ese trabajo es abrir la aplicación, usarla, solicitar un cambio y verificar el resultado. Ese ciclo funciona bien cuando la aplicación sigue ejecutándose donde el agente la edita, por lo que cada cambio se muestra en el navegador en cuestión de segundos. Cuando la aplicación debe copiarse y deployarse en otro lugar primero, cada cambio espera una implementación, y la revisión se ralentiza a ese ritmo.
Amazon Bedrock AgentCore es una plataforma para crear, conectar y optimizar agentes a escala, con su elección de framework de agente y modelo de fundación (FM). AgentCore runtime, una capacidad de Amazon Bedrock AgentCore, ejecuta cada sesión de agente en su propia microVM aislada. Con Session endpoints, puede abrir una aplicación que se ejecuta en esa sesión desde su propio navegador. Los Session Endpoints dan a cada sesión una URL autenticada que reenvía cada método HTTP de la solicitud, ruta, cadena de consulta y cuerpo, y conexiones WebSocket, a los puertos que permite. Puede ver la página actualizarse mientras el agente guarda cada archivo.
En esta publicación, implementa un agente de codificación que mantiene un sitio web de Vite en ejecución en su sesión, luego abre una página local con un chat en la izquierda y el sitio web en vivo en la derecha. Le pide al agente que cambie el sitio a un tema de color oscuro, sigue sus pasos mientras se transmiten, y ve el sitio web cambiar sin una actualización. Finalmente, ve qué sucede internamente: un segundo puerto en la misma sesión, y las solicitudes que el Session endpoint rechaza.
La muestra completa, incluyendo el cuaderno que sigue esta publicación, se encuentra en la carpeta 14-remote-access del repositorio de GitHub de agentcore-samples.
Cómo funcionan los Session endpoints
Cada sesión obtiene su propio Session endpoint, y seis detalles dan forma a cómo lo utiliza.
Tú eliges a qué puertos llega. Estableces allowedPorts cuando llamas a CreateAgentRuntime: 1–5 entradas, cada una un solo puerto o un rango dentro de 8000–12000, excluyendo los puertos de plataforma reservados. Permitir un puerto no inicia un servidor, así que tu aplicación debe escuchar en él, vinculado a 0.0.0.0.
La URL llega con la sesión. La respuesta de InvokeAgentRuntime la lleva en el encabezado X-Amzn-Bedrock-AgentCore-Runtime-Session-Endpoint-Url, que los SDK que la modelan exponen como sessionEndpointUrl.
Cada solicitud está autenticada. Para un runtime que utiliza AWS Identity and Access Management (IAM), cada solicitud HTTP, flujo HTTP/2 y apretón de manos WebSocket lleva una firma de Signature Version 4 (SigV4). El llamador también necesita bedrock-agentcore:InvokeAgentRuntimeProxy en el runtime y su punto final de runtime. Para un runtime con un autorizador de token Web JSON (JWT) de entrada, cada solicitud lleva un token portador en su lugar. Conocer la URL no otorga acceso.
El nombre de host selecciona el puerto. Tu cliente se conecta en el puerto 443 independientemente del puerto de destino, y un prefijo en el nombre de host elige el puerto dentro de la sesión:
https://8090--<session-endpoint-id>.runtime.bedrock-agentcore.<region>.on.aws/index.html
https://8081--<session-endpoint-id>.runtime.bedrock-agentcore.<region>.on.aws/status
Lleva los protocolos que habla tu servidor. Las solicitudes HTTP/1.1 y HTTP/2, incluidos los eventos enviados por el servidor y gRPC, y las conexiones WebSocket pasan a través. Este recorrido utiliza HTTP/1.1 y WebSocket.
Está limitado a una sola sesión. La URL necesita credenciales en cada solicitud y dura solo tanto como la sesión, así que úsala para compilar, probar y revisar lo que produce tu agente. Para servir una aplicación a tus usuarios, despliégala en un servicio de hosting como AWS Amplify Hosting.
Un navegador no puede agregar una firma SigV4 o un token de portador a las solicitudes que una página realiza por sí sola, por lo que el cliente de punto de conexión de sesión en el SDK de bedrock-agentcore puede abrir un punto de conexión local en su máquina. Su navegador abre http://localhost:8088, y el punto de conexión local agrega sus credenciales a cada solicitud y handshake de WebSocket antes de reenviarla.
Un punto de conexión de sesión es diferente de un punto de conexión de runtime, que el runtime de AgentCore ya proporciona. Utilice un punto de conexión de runtime, como DEFAULT, para llegar a su agente, que controla qué versión de él llegarán los llamadores. InvokeAgentRuntime llama a resolver a través de él, por lo que puede mantener el desarrollo y la producción en diferentes versiones y promocionar o revertir sin cambiar a los llamadores. Utilice un punto de conexión de sesión para ver qué ejecuta su agente en su sesión, como una vista previa web. Es una URL autenticada que solo alcanza los puertos que permite, funciona con cualquier versión que ejecute la sesión y deja de funcionar cuando termina la sesión. Para obtener la documentación completa, consulte Conectar a sesiones de runtime a través de un punto de conexión de sesión.
Visión general de la solución
La muestra tiene cuatro partes. Un agente de codificación se ejecuta en la sesión en el puerto 8080 y edita los archivos del sitio web con cuatro herramientas: lista, lectura, escritura y edición. El agente inicia un servidor de desarrollo Vite en el puerto 8090, que sirve el sitio web y envía cada cambio guardado al navegador a través de su WebSocket de recarga en caliente. En su máquina, PreviewApp sirve la página de vista previa, envía sus solicitudes a InvokeAgentRuntime y abre un punto de conexión local para el sitio web. Como muestra la Figura 1, la página de vista previa carga el sitio web desde el servidor de desarrollo Vite en el puerto 8090 a través del punto de conexión local y el punto de conexión de sesión, y envía sus solicitudes a través de InvokeAgentRuntime al agente en el puerto 8080. Los números muestran el orden de los pasos para una solicitud.
Figura 1: Arquitectura de la solución
Antes del paso 1, PreviewApp ya ha llamado a InvokeAgentRuntime una vez para iniciar la sesión, lo que inicia el agente y el servidor de desarrollo de Vite. PreviewApp lee la URL del punto de conexión de la sesión de esa respuesta y abre un punto de conexión local en el puerto 8090. Los pasos numerados en la Figura 1 siguen entonces una solicitud de cambio:
- El panel del sitio de la página de vista previa carga el sitio web desde el punto de conexión local en
localhost:8088. El punto de conexión local agrega sus credenciales a cada solicitud y el apretón de manos de WebSocket, y las reenvía al punto de conexión de la sesión. El punto de conexión de la sesión verifica la firma y el puerto contra allowedPorts, y luego las reenvía al servidor de desarrollo de Vite en el puerto 8090. La página mantiene el WebSocket de recarga en caliente de Vite abierto.
- Envías un mensaje desde el panel de chat.
PreviewApp lo envía a InvokeAgentRuntime como una llamada de API de AWS estándar firmada con sus credenciales de AWS, y el runtime lo entrega al agente en el puerto 8080. Los pasos del agente se transmiten de regreso al panel de chat a medida que trabaja.
- El agente llama a Claude Haiku 5.5 en Amazon Bedrock para decidir qué cambiar.
- El agente lee los archivos del sitio y guarda los que cambia. El servidor de desarrollo de Vite sirve esos archivos y los vigila para detectar cambios.
- Cuando se guarda un archivo, Vite envía el cambio a través del WebSocket abierto en el paso 1, de regreso a través del punto de conexión de la sesión y el punto de conexión local, y el panel del sitio se actualiza sin necesidad de recargar.
- Desde el cuaderno,
PreviewApp lee la ruta /status del agente en el puerto 8081 a través del mismo punto de conexión de la sesión. Solo cambia el puerto.
El puerto 8080 no está en allowedPorts, porque InvokeAgentRuntime alcanza el agente sin pasar por el punto de conexión de la sesión.
Requisitos previos
Para seguir el recorrido, necesitas:
- Una cuenta de AWS en una región de AWS donde estén disponibles los puntos de conexión de sesión de AgentCore runtime, con credenciales configuradas.
- Permisos para crear un rol de AWS Identity and Access Management (IAM), cargar en Amazon Simple Storage Service (Amazon S3), y crear un runtime, más
bedrock-agentcore:InvokeAgentRuntime y bedrock-agentcore:InvokeAgentRuntimeProxy en ese runtime y su DEFAULT punto de conexión de runtime. Para obtener más detalles, consulte Permisos de IAM para AgentCore runtime.
- Python 3.10 o posterior, con
bedrock-agentcore 1.25.2 o posterior y boto3 1.43.122 o posterior.
- Git, para clonar el repositorio de ejemplo, y un entorno Jupyter, como JupyterLab o Visual Studio Code con la extensión Jupyter, para ejecutar el cuaderno.
- Acceso a Claude Haiku 5.5 en Amazon Bedrock. Para obtener información sobre la disponibilidad de modelos por región, consulte Disponibilidad regional por modelos.
- Node.js 22 o posterior con
npm, que el script de implementación utiliza para empaquetar el agente y el sitio web.
El ejemplo implementa el agente como un archivo zip en Amazon S3 con implementación de código directa para Node.js, por lo que no necesita Docker ni un repositorio Amazon Elastic Container Registry (Amazon ECR). Los puntos de conexión de sesión funcionan con runtimes de microVM, no con el tipo de cómputo de instancias, y las URL de los puntos de conexión de sesión son accesibles a través de HTTPS público. No se admite AWS PrivateLink para conexiones entrantes.
Implementar el agente y su sitio web
Primero, implementa el runtime, y la configuración que elija aquí decide qué puertos puede alcanzar el punto de conexión de sesión. El script de implementación empaqueta el agente en un archivo, agrega el sitio web y sus dependencias para el sistema Linux en Arm64 del runtime, carga el zip en Amazon S3 y crea el runtime.
El siguiente fragmento de deploy.py muestra las dos configuraciones que importan para esta publicación. protocolConfiguration indica dónde el agente escucha InvokeAgentRuntime, y allowedPorts enumera los puertos que el punto de conexión de sesión puede alcanzar: 8090 para el sitio web y 8081 para la ruta de estado del agente. El puerto 8080 no está en la lista, porque InvokeAgentRuntime alcanza el agente sin él. Para la configuración de puertos y rutas, consulte Configure el puerto de servicio y la ruta de invocación de su agente.
agentRuntimeArtifact={"codeConfiguration": {
"code": {"s3": {"bucket": code_bucket(), "prefix": S3_PREFIX}},
"runtime": "NODE_22",
"entryPoint": ["app.js"],
}},
protocolConfiguration={"serverProtocol": "HTTP", "port": 8080, "path": "/invocations"},
allowedPorts=[{"port": 8090}, {"port": 8081}],
La configuración de Vite del sitio web hace que el servidor de desarrollo sea accesible desde el punto de conexión de sesión. Escucha en 0.0.0.0 en el puerto 8090 y no restringe el encabezado Host (server.allowedHosts es true), porque las solicitudes llegan bajo un nombre de host que el runtime asigna en lugar de localhost. El punto de conexión de sesión autentica cada solicitud antes de que llegue al servidor, por lo que el servidor no necesita su propia comprobación de host.
Para implementar el runtime:
1. Clone el repositorio de ejemplo y cambie a la carpeta de ejemplo:
git clone https://github.com/awslabs/agentcore-samples.git
cd agentcore-samples/01-features/02-host-your-agent/01-runtime/03-advanced/16-session-endpoints
2. Abra session_endpoints_preview.ipynb desde la carpeta de ejemplo.
3. Ejecute la celda de instalación, que instala las dependencias de Python.
4. Ejecute la celda %run deploy.py. La implementación tarda unos minutos, principalmente esperando a que el runtime alcance el estado READY.
Abrir la vista previa
Con el runtime listo, inicia la vista previa. Una llamada hace tres cosas: inicia una sesión (que inicia el sitio web), abre un punto de conexión local para el puerto 8090 y sirve la página de vista previa en localhost:8087.
from preview_app import PreviewApp
app = PreviewApp().start()
print("Open", app.url)
Dentro de start(), las llamadas que utilizan puntos de conexión de sesión son breves. La primera llamada InvokeAgentRuntime devuelve la URL en un encabezado de respuesta, session_endpoint_url la lee, y el cliente del punto de conexión de sesión abre un punto de conexión local para el puerto 8090:
answer = client.invoke_agent_runtime(
agentRuntimeArn=runtime_arn, runtimeSessionId=session_id,
payload=json.dumps({"prompt": ""}).encode(), contentType="application/json",
)
endpoint = client.session_endpoint_client(session_endpoint_url(answer))
local = endpoint.open_local_endpoint(port=8090, local_port=8088).start()
Para abrir la vista previa:
- Ejecute la celda que inicia
PreviewApp.
- Abra el enlace impreso,
http://localhost:8087, en su navegador.
La página muestra el sitio web a la derecha, servido desde el puerto 8090 en la sesión, y una guía breve con solicitudes sugeridas a la izquierda.
Solicite al agente un cambio
Ahora solicita un cambio y observa cómo llega. Cada prompt va al agente a través de InvokeAgentRuntime. El agente lee los archivos que necesita, escribe los que cambia y reporta cada paso a medida que sucede. Cuando se guarda un archivo, el servidor de desarrollo de Vite envía el cambio a través de su WebSocket, a través del endpoint de sesión y el endpoint local, y el sitio web se actualiza en su lugar.
Para solicitar un cambio:
- En la página de vista previa, elige Cambiar este sitio web a un tema de color de cafetería oscuro.
- Sigue los pasos del agente en el panel de chat a medida que lee y guarda archivos.
- Observa el panel del sitio. Cambia cuando el agente guarda la hoja de estilo, y un banner nombra el archivo del que provino el cambio.
El siguiente video muestra la página de vista previa mientras el agente trabaja en varias solicitudes. Elegir una solicitud sugerida la envía al agente, el panel de chat enumera cada archivo que el agente lee y guarda, y el panel del sitio a la derecha se actualiza sin refrescar, desde el tema oscuro hasta un botón de pedido adelantado de color verde.
Figura 2: La página de vista previa mientras el agente trabaja
Los pasos se transmiten porque el agente responde con eventos enviados por el servidor cuando se le solicita. Puedes enviar los mismos prompts desde Python con app.ask, que lee el flujo con iter_events desde el SDK de bedrock-agentcore. La página abierta se actualiza de la misma manera:
for event in app.ask("Make the Order ahead button green"):
if "step" in event:
print(" ", event["step"])
elif "done" in event:
print(event["done"]["reply"])
La salida de este script de Python debería parecerse a la siguiente:
Looking at the site's files
Reading src/main.js
Reading src/style.css
Reading index.html
Saved src/style.css
The Order ahead button is now green instead of brown, with white text kept for contrast. You can see it in the hero section, just below the "Small batch coffee, roasted every morning" heading at the top of the page.
Alcanzar un segundo puerto en la misma sesión
El sitio web no es el único servidor al que puedes acceder. El agente sirve /status en el puerto 8081, que enumera cada prompt y los archivos que cambió. El mismo endpoint de sesión lo alcanza, y la única diferencia es el argumento de puerto.
status = app.endpoint.request("GET", "/status", port=8081)
print("GET /status on port 8081: HTTP", status.status)
for edit in status.json()["edits"]:
print(" ", edit["prompt"], "->", ", ".join(edit["files"]))
La salida de este script de Python debería parecerse a la siguiente:
GET /status on port 8081: HTTP 200
Make the Order ahead button green -> src/style.css
Qué rechaza el endpoint de sesión
Cuando el runtime rechaza una solicitud, responde con un estado HTTP, un cuerpo vacío y un código de error en un encabezado de respuesta, para que puedas distinguir sus rechazos de los errores que devuelve tu aplicación. El cuaderno envía una solicitud a un puerto fuera de allowedPorts y una solicitud sin credenciales, y el runtime rechaza ambas con 403 AccessDenied.
La siguiente tabla enumera los rechazos que es probable que encuentres mientras construyes con puntos de conexión de sesión.
| Solicitud |
Respuesta del runtime |
Un puerto que no está en allowedPorts |
403 AccessDenied |
| Una solicitud sin credenciales válidas |
403 AccessDenied o 401 AuthenticationRequired |
| Un puerto permitido sin nada escuchando en él |
502 PortNotReachable |
| Una URL cuya sesión ya no existe |
404 SessionNotFound |
Cómo se protege el acceso a tu sesión
El runtime elimina sus propios encabezados de autenticación antes de enviar una solicitud, para que el sitio web no reciba tu firma. Las solicitudes se registran en AWS CloudTrail como eventos InvokeAgentRuntimeProxy, con el origen de eventos bedrock-agentcore.amazonaws.com. El punto de conexión local actúa con tus credenciales, por lo que limita quién puede usarlo. Escucha solo en 127.0.0.1, responde solo a solicitudes dirigidas a su propia dirección local y rechaza las conexiones WebSocket abiertas por páginas de otros orígenes. Ejecuta el punto de conexión local solo mientras usas la vista previa. Para obtener más información, consulte Registro de solicitudes de puntos de conexión de sesión en CloudTrail.
Los controles de acceso no separan el sitio web del agente. Ambos se ejecutan en la misma sesión, así que da al rol de ejecución solo los permisos que el agente necesita. Si el runtime reemplaza el cómputo de la sesión, las conexiones abiertas se cierran y los cambios del agente pueden no sobrevivir a menos que la sesión use almacenamiento persistente. Consulte Configuraciones del sistema de archivos para AgentCore runtime si necesita que los archivos sobrevivan al cómputo.
Las herramientas de archivos del agente resuelven cada ruta dentro de la carpeta del sitio y rechazan rutas fuera de ella, por lo que una solicitud no puede hacer que el agente cambie otros archivos en la sesión. Si otras personas pueden enviar solicitudes a su agente de codificación, considere Amazon Bedrock Guardrails para filtrar solicitudes y respuestas dañinas, y revise los cambios del agente antes de publicarlos.
Limpieza
Para evitar cargos continuos, detenga la vista previa y elimine los recursos creados por la muestra. El sitio web que el agente editó vive en la sesión, por lo que se elimina con la sesión.
Para limpiar:
1. Ejecute la celda de detención y presione Enter cuando el cuaderno lo solicite. Esto detiene la página de vista previa, el punto de conexión local y la sesión.
2. Ejecute la celda %run cleanup.py, que elimina el runtime, el código cargado y el rol de IAM.
Conclusión
Los puntos de conexión de sesión le brindan acceso autenticado a las aplicaciones en una sesión de runtime de AgentCore desde sus propias herramientas a través de HTTP/1.1, HTTP/2 y WebSocket, en los puertos que permita. En esta publicación, implementó un agente de codificación con un sitio web de Vite en su sesión, abrió el sitio web en vivo en su navegador a través de un punto de conexión local, solicitó al agente un tema oscuro y vio el cambio llegar cuando el agente guardó el archivo. También alcanzó un segundo puerto en la misma sesión y confirmó lo que el punto de conexión de sesión rechaza.
Para avanzar, ejecute el cuaderno con su propio sitio en la carpeta del sitio, o cambie las herramientas del agente para que coincidan con la forma en que funciona su agente de codificación. Para el conjunto completo de opciones, incluidos rangos de puertos, OAuth, HTTP/2 y gRPC, consulte Conectar a sesiones de runtime a través de un punto de conexión de sesión.
Para cambiar el puerto o la ruta que InvokeAgentRuntime utiliza en su propio agente, consulte Configure el puerto de servicio y la ruta de invocación de su agente. Si su agente también necesita ejecutar comandos de compilación o prueba en la misma sesión, consulte Ejecutar comandos de shell en sesiones de runtime de AgentCore. Para implementar su propio agente de Node.js desde un archivo zip de la misma manera que este ejemplo, consulte Implementación de código directo para Node.js. Para todo lo demás que ofrece el servicio, comience con Hospedar agente o herramientas con Amazon Bedrock AgentCore runtime y encuentre más ejemplos en el repositorio de GitHub de agentcore-samples.
Acerca del autor
Coding agents now build working web apps: a dashboard, a product page, a prototype that a product team wants to try. The fastest way to review that work is to open the app, use it, ask for a change, and check the result. That loop works well when the app keeps running where the agent edits it, so each change shows up in the browser within seconds. When the app must be copied out and deployed somewhere else first, every change waits for a deployment, and the review slows down to that pace.
Amazon Bedrock AgentCore is a platform to build, connect, and optimize agents at scale, with your choice of agent framework and foundation model (FM). AgentCore runtime, a capability of Amazon Bedrock AgentCore, runs each agent session in its own isolated microVM. With Session endpoints, you can open an app running in that session from your own browser. Session Endpoints give each session an authenticated URL that forwards each request’s HTTP method, path, query string, and body, and WebSocket connections, to the ports you allow. You can watch the page update as the agent saves each file.
In this post, you deploy a coding agent that keeps a Vite website running in its session, then open one local page with a chat on the left and the live website on the right. You ask the agent to switch the site to a dark color theme, follow its steps as they stream in, and watch the website change without a refresh. Finally, you look at what happens internally: a second port in the same session, and the requests the Session endpoint refuses.
The complete sample, including the notebook this post follows, is in the 14-remote-access folder of the agentcore-samples GitHub repo.
How Session endpoints work
Each session gets its own Session endpoint, and six details shape how you use it.
You choose which ports it reaches. You set allowedPorts when you call CreateAgentRuntime: 1–5 entries, each a single port or a range within 8000–12000, excluding the reserved platform ports. Allowing a port doesn’t start a server, so your application must listen on it, bound to 0.0.0.0.
The URL arrives with the session. The InvokeAgentRuntime response carries it in the X-Amzn-Bedrock-AgentCore-Runtime-Session-Endpoint-Url header, which SDKs that model it expose as sessionEndpointUrl.
Every request is authenticated. For a runtime that uses AWS Identity and Access Management (IAM), each HTTP request, HTTP/2 stream, and WebSocket handshake carries a Signature Version 4 (SigV4) signature. The caller also needs bedrock-agentcore:InvokeAgentRuntimeProxy on the runtime and its runtime endpoint. For a runtime with an inbound JSON Web Token (JWT) authorizer, each request carries a bearer token instead. Knowing the URL doesn’t grant access.
The host name selects the port. Your client connects on port 443 regardless of the target port, and a prefix on the host name chooses the port inside the session:
https://8090--<session-endpoint-id>.runtime.bedrock-agentcore.<region>.on.aws/index.html
https://8081--<session-endpoint-id>.runtime.bedrock-agentcore.<region>.on.aws/status
It carries the protocols your server speaks. HTTP/1.1 and HTTP/2 requests, including server-sent events and gRPC, and WebSocket connections all pass through. This walkthrough uses HTTP/1.1 and WebSocket.
It’s scoped to one session. The URL needs credentials on every request and lasts only as long as the session, so use it to build, test, and review what your agent produces. To serve an app to your users, deploy it to a hosting service such as AWS Amplify Hosting.
A browser can’t add a SigV4 signature or a bearer token to the requests a page makes on its own, so the Session endpoint client in the bedrock-agentcore SDK can open a local endpoint on your machine. Your browser opens http://localhost:8088, and the local endpoint adds your credentials to each request and WebSocket handshake before forwarding it.
A Session endpoint is different from a runtime endpoint, which AgentCore runtime already provides. Use a runtime endpoint, such as DEFAULT, to reach your agent, which controls which version of it callers will reach. InvokeAgentRuntime calls resolve through it, so you can keep development and production on different versions and promote or roll back without changing callers. Use a Session endpoint to see what your agent runs in its session, such as a web preview. It’s an authenticated URL that reaches only the ports you allow, works with whichever version the session runs, and stops working when the session ends. For complete documentation, refer to Connect to runtime sessions through a session endpoint.
Solution overview
The sample has four parts. A coding agent runs in the session on port 8080 and edits the website’s files with four tools: list, read, write, and edit. The agent starts a Vite development server on port 8090, which serves the website and pushes each saved change to the browser over its hot-reload WebSocket. On your machine, PreviewApp serves the preview page, sends your prompts to InvokeAgentRuntime, and opens a local endpoint for the website. As Figure 1 shows, the preview page loads the website from the Vite development server on port 8090 through the local endpoint and the Session endpoint, and sends your prompts through InvokeAgentRuntime to the agent on port 8080. The numbers show the order of the steps for one request.
Figure 1: Solution architecture
Before step 1, PreviewApp has already called InvokeAgentRuntime once to start the session, which starts the agent and the Vite development server. PreviewApp read the Session endpoint URL from that response and opened a local endpoint for port 8090. The numbered steps in Figure 1 then follow one request for a change:
- The site pane of the preview page loads the website from the local endpoint on
localhost:8088. The local endpoint adds your credentials to each request and the WebSocket handshake, and forwards them to the Session endpoint. The Session endpoint checks the signature and the port against allowedPorts, then forwards them to the Vite development server on port 8090. The page keeps the Vite hot-reload WebSocket open.
- You send a prompt from the chat pane.
PreviewApp sends it to InvokeAgentRuntime as a standard AWS API call signed with your AWS credentials, and the runtime delivers it to the agent on port 8080. The agent’s steps stream back to the chat pane as it works.
- The agent calls Claude Haiku 5.5 in Amazon Bedrock to decide what to change.
- The agent reads the site’s files and saves the ones it changes. The Vite development server serves those files and watches them for changes.
- When a file is saved, Vite pushes the change over the WebSocket opened in step 1, back through the Session endpoint and the local endpoint, and the site pane updates without a refresh.
- From the notebook,
PreviewApp reads the agent’s /status route on port 8081 through the same Session endpoint. Only the port changes.
Port 8080 isn’t in allowedPorts, because InvokeAgentRuntime reaches the agent without going through the Session endpoint.
Prerequisites
To follow the walkthrough, you need:
- An AWS account in an AWS Region where AgentCore runtime Session endpoints are available, with credentials configured.
- Permissions to create an AWS Identity and Access Management (IAM) role, upload to Amazon Simple Storage Service (Amazon S3), and create a runtime, plus
bedrock-agentcore:InvokeAgentRuntime and bedrock-agentcore:InvokeAgentRuntimeProxy on that runtime and its DEFAULT runtime endpoint. For details, refer to IAM permissions for AgentCore runtime.
- Python 3.10 or later, with
bedrock-agentcore 1.25.2 or later and boto3 1.43.122 or later.
- Git, to clone the sample repo, and a Jupyter environment, such as JupyterLab or Visual Studio Code with the Jupyter extension, to run the notebook.
- Access to Claude Haiku 5.5 in Amazon Bedrock. For model availability by Region, refer to Regional availability by models.
- Node.js 22 or later with
npm, which the deployment script uses to package the agent and the website.
The sample deploys the agent as a zip file in Amazon S3 with direct code deployment for Node.js, so you don’t need Docker or an Amazon Elastic Container Registry (Amazon ECR) repository. Session endpoints work with microVM runtimes, not with the Instances compute type, and Session endpoint URLs are reachable over public HTTPS. AWS PrivateLink isn’t supported for inbound connections.
Deploy the agent and its website
First, you deploy the runtime, and the configuration you choose here decides which ports the Session endpoint can reach. The deployment script bundles the agent into one file, adds the website and its dependencies for the runtime’s Linux on Arm64 system, uploads the zip to Amazon S3, and creates the runtime.
The following excerpt from deploy.py shows the two settings that matter for this post. protocolConfiguration says where the agent listens for InvokeAgentRuntime, and allowedPorts lists the ports the Session endpoint can reach: 8090 for the website and 8081 for the agent’s status route. Port 8080 isn’t in the list, because InvokeAgentRuntime reaches the agent without it. For the port and path settings, refer to Configure your agent’s serving port and invocation path.
agentRuntimeArtifact={"codeConfiguration": {
"code": {"s3": {"bucket": code_bucket(), "prefix": S3_PREFIX}},
"runtime": "NODE_22",
"entryPoint": ["app.js"],
}},
protocolConfiguration={"serverProtocol": "HTTP", "port": 8080, "path": "/invocations"},
allowedPorts=[{"port": 8090}, {"port": 8081}],
The website’s Vite configuration makes the development server reachable from the Session endpoint. It listens on 0.0.0.0 at port 8090 and doesn’t restrict the Host header (server.allowedHosts is true), because requests arrive under a host name the runtime assigns rather than localhost. The Session endpoint authenticates every request before it reaches the server, so the server doesn’t need its own host check.
To deploy the runtime:
1. Clone the sample repo and change to the sample folder:
git clone https://github.com/awslabs/agentcore-samples.git
cd agentcore-samples/01-features/02-host-your-agent/01-runtime/03-advanced/16-session-endpoints
2. Open session_endpoints_preview.ipynb from the sample folder.
3. Run the install cell, which installs the Python dependencies.
4. Run the %run deploy.py cell. Deployment takes a few minutes, mostly waiting for the runtime to reach the READY status.
Open the preview
With the runtime ready, you start the preview. One call does three things: it starts a session (which starts the website), opens a local endpoint for port 8090, and serves the preview page on localhost:8087.
from preview_app import PreviewApp
app = PreviewApp().start()
print("Open", app.url)
Inside start(), the calls that use Session endpoints are short. The first InvokeAgentRuntime call returns the URL in a response header, session_endpoint_url reads it, and the Session endpoint client opens a local endpoint for port 8090:
answer = client.invoke_agent_runtime(
agentRuntimeArn=runtime_arn, runtimeSessionId=session_id,
payload=json.dumps({"prompt": ""}).encode(), contentType="application/json",
)
endpoint = client.session_endpoint_client(session_endpoint_url(answer))
local = endpoint.open_local_endpoint(port=8090, local_port=8088).start()
To open the preview:
- Run the cell that starts
PreviewApp.
- Open the printed link,
http://localhost:8087, in your browser.
The page shows the website on the right, served from port 8090 in the session, and a short guide with suggested requests on the left.
Ask the agent for a change
Now you ask for a change and watch it arrive. Each prompt goes to the agent through InvokeAgentRuntime. The agent reads the files it needs, writes the ones it changes, and reports each step as it happens. When a file is saved, the Vite development server pushes the change over its WebSocket, through the Session endpoint and the local endpoint, and the website updates in place.
To ask for a change:
- On the preview page, choose Switch this website to a dark coffee-house color theme.
- Follow the agent’s steps in the chat pane as it reads and saves files.
- Watch the site pane. It changes when the agent saves the stylesheet, and a banner names the file the change came from.
The following video shows the preview page while the agent works through several requests. Choosing a suggested request sends it to the agent, the chat pane lists each file the agent reads and saves, and the site pane on the right updates without a refresh, from the dark theme to a green Order ahead button.
Figure 2: The preview page as the agent works
The steps stream because the agent answers with server-sent events when you ask it to. You can send the same prompts from Python with app.ask, which reads the stream with iter_events from the bedrock-agentcore SDK. The open page updates in the same way:
for event in app.ask("Make the Order ahead button green"):
if "step" in event:
print(" ", event["step"])
elif "done" in event:
print(event["done"]["reply"])
The output of this Python script should resemble the following:
Looking at the site's files
Reading src/main.js
Reading src/style.css
Reading index.html
Saved src/style.css
The Order ahead button is now green instead of brown, with white text kept for contrast. You can see it in the hero section, just below the "Small batch coffee, roasted every morning" heading at the top of the page.
Reach a second port in the same session
The website isn’t the only server you can reach. The agent serves /status on port 8081, which lists each prompt and the files it changed. The same Session endpoint reaches it, and the only difference is the port argument.
status = app.endpoint.request("GET", "/status", port=8081)
print("GET /status on port 8081: HTTP", status.status)
for edit in status.json()["edits"]:
print(" ", edit["prompt"], "->", ", ".join(edit["files"]))
The output of this Python script should resemble the following:
GET /status on port 8081: HTTP 200
Make the Order ahead button green -> src/style.css
What the Session endpoint refuses
When the runtime refuses a request, it answers with an HTTP status, an empty body, and an error code in a response header, so you can tell its refusals from errors your application returns. The notebook sends a request to a port outside allowedPorts and a request without credentials, and the runtime refuses both with 403 AccessDenied.
The following table lists the refusals you’re likely to meet while you build with Session endpoints.
| Request |
Response from the runtime |
A port that isn’t in allowedPorts |
403 AccessDenied |
| A request without valid credentials |
403 AccessDenied or 401 AuthenticationRequired |
| An allowed port with nothing listening on it |
502 PortNotReachable |
| A URL whose session no longer exists |
404 SessionNotFound |
How access to your session is protected
The runtime removes its own authentication headers before it forwards a request, so the website doesn’t receive your signature. Requests are recorded in AWS CloudTrail as InvokeAgentRuntimeProxy events, with the event source bedrock-agentcore.amazonaws.com. The local endpoint acts with your credentials, so it limits who can use it. It listens on 127.0.0.1 only, answers only requests addressed to its own local address, and refuses WebSocket connections opened by pages from other origins. Run the local endpoint only while you use the preview. For more information, see Log session endpoint requests in CloudTrail.
The access controls don’t separate the website from the agent. Both run in the same session, so give the execution role only the permissions the agent needs. If the runtime replaces the session’s compute, open connections close, and the agent’s edits might not survive unless the session uses persistent storage. Refer to File system configurations for AgentCore runtime if you need the files to outlast the compute.
The agent’s file tools resolve every path inside the site folder and refuse paths outside it, so a prompt can’t make the agent change other files in the session. If other people can send prompts to your coding agent, consider Amazon Bedrock Guardrails to filter harmful prompts and responses, and review the agent’s changes before you publish them.
Clean up
To avoid ongoing charges, stop the preview and delete the resources the sample created. The website the agent edited lives in the session, so it goes with the session.
To clean up:
1. Run the stop cell, and press Enter when the notebook asks. This stops the preview page, the local endpoint, and the session.
2. Run the %run cleanup.py cell, which deletes the runtime, the uploaded code, and the IAM role.
Conclusion
Session endpoints give you authenticated access to the applications in an AgentCore runtime session from your own tools over HTTP/1.1, HTTP/2, and WebSocket, on the ports you allow. In this post, you deployed a coding agent with a Vite website in its session, opened the live website in your browser through a local endpoint, asked the agent for a dark theme, and watched the change arrive as the agent saved the file. You also reached a second port in the same session and confirmed what the Session endpoint refuses.
To go further, run the notebook with your own site in the site folder, or change the agent’s tools to match how your coding agent works. For the full set of options, including port ranges, OAuth, HTTP/2, and gRPC, refer to Connect to runtime sessions through a session endpoint.
To change the port or path that InvokeAgentRuntime uses in your own agent, refer to Configure your agent’s serving port and invocation path. If your agent also needs to run build or test commands in the same session, refer to Execute shell commands in AgentCore runtime sessions. To deploy your own Node.js agent from a zip file the way this sample does, refer to Direct code deployment for Node.js. For everything else the service offers, start with Host agent or tools with Amazon Bedrock AgentCore runtime, and find more examples in the agentcore-samples GitHub repo.
About the author