

# Get started with AgentCore Runtime
<a name="runtime-getting-started"></a>

You can use the following tutorials to get started with Amazon Bedrock AgentCore Runtime.

The [AgentCore CLI](https://github.com/aws/agentcore-cli) is a Command Line Interface (CLI) that simplifies the infrastructure setup for containerizing and deploying an agent to an AgentCore Runtime.

**Topics**
+ [

# Get started with the AgentCore CLI
](runtime-get-started-cli.md)
+ [

# Get started with the AgentCore CLI in TypeScript
](runtime-get-started-cli-typescript.md)
+ [

# Get started without the AgentCore CLI
](getting-started-custom.md)
+ [

# Get started with Amazon Bedrock AgentCore Runtime direct code deployment
](runtime-get-started-code-deploy.md)
+ [

# Get started with bidirectional streaming using WebSocket
](runtime-get-started-websocket.md)

# Get started with the AgentCore CLI
<a name="runtime-get-started-cli"></a>

This tutorial shows you how to use the [AgentCore CLI](https://github.com/aws/agentcore-cli) to create, deploy, and invoke a Python agent on Amazon Bedrock AgentCore Runtime.

The AgentCore CLI is a command-line tool that scaffolds agent projects, deploys them to Amazon Bedrock AgentCore Runtime, and invokes them. You can use the CLI with popular Python agent frameworks such as [Strands Agents](https://strandsagents.com/latest/documentation/docs/) , LangChain/LangGraph, Google ADK, and OpenAI Agents. This tutorial uses Strands Agents.

For information about the HTTP protocol that the agent uses, see [HTTP protocol contract](runtime-http-protocol-contract.md).

**Topics**
+ [

## Prerequisites
](#prerequisites)
+ [

## Step 1: Install the AgentCore CLI
](#setup-project)
+ [

## Step 2: Create your agent project
](#create-agent)
+ [

## Step 3: Test your agent locally
](#configure-agent)
+ [

## Step 4: Enable observability for your agent
](#enable-observability)
+ [

## Step 5: Deploy to Amazon Bedrock AgentCore Runtime
](#deploy-runtime)
+ [

## Step 6: Test your deployed agent
](#test-deployed-agent)
+ [

## Step 7: Invoke your deployed agent
](#invoke-programmatically)
+ [

## Step 8: Clean up
](#stop-session-or-clean-up)
+ [

## Find your resources
](#find-resources)
+ [

## Common issues and solutions
](#common-issues)
+ [

## Advanced options (Optional)
](#advanced-options)

## Prerequisites
<a name="prerequisites"></a>

Before you start, make sure you have:
+  ** AWS Account** with credentials configured. To configure your AWS credentials, see [Configuration and credential file settings in the AWS CLI.](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html) 
+  **Node.js 20\$1** installed. The AgentCore CLI is distributed as an npm package.
+  **Python 3.10\$1** installed. The generated agent code is Python.
+  ** AWS CDK** installed. The CLI uses the AWS CDK to deploy resources. For information, see [Getting started with the AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html).
+  ** AWS Permissions** : To create and deploy an agent with the AgentCore CLI, you must have appropriate permissions. For information, see [Use the AgentCore CLI](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-permissions.html#runtime-permissions-cli).
+  **Model access** : Anthropic Claude Sonnet 4.0 [enabled](https://docs.aws.amazon.com/bedrock/latest/userguide/model-access-modify.html) in the Amazon Bedrock console (if using Bedrock as the model provider). For information about using a different model with Strands Agents, see the *Model Providers* section in the [Strands Agents SDK](https://strandsagents.com/latest/documentation/docs/) documentation.

## Step 1: Install the AgentCore CLI
<a name="setup-project"></a>

Install the AgentCore CLI globally:

```
npm install -g @aws/agentcore
```

Verify the installation:

```
agentcore --help
```

You should see output similar to the following:

```
Usage: agentcore [options] [command]

Build and deploy Agentic AI applications on AgentCore

Options:
  -V, --version                output the version number
  -h, --help                   Display help

Commands:
  add [subcommand]             Add resources (agent, evaluator, online-eval,
                               memory, identity, target)
  dev|d [options]              Launch local development server with hot-reload.
  deploy|p [options]           Deploy project infrastructure to AWS via CDK.
  create [options]             Create a new AgentCore project
  evals                        View past eval run results.
  fetch                        Fetch access info for deployed resources.
  help                         Display help topics
  invoke|i [options] [prompt]  Invoke a deployed agent endpoint.
  logs|l [options]             Stream or search agent runtime logs.
  package|pkg [options]        Package agent artifacts without deploying.
  pause                        Pause an online eval config.
  remove [subcommand]          Remove resources from project config.
  resume                       Resume a paused online eval config.
  run                          Run on-demand evaluation.
  status|s [options]           Show deployed resource details and status.
  traces|t                     View and download agent traces.
  update [options]             Check for and install CLI updates
  validate [options]           Validate agentcore/ config files.
```

## Step 2: Create your agent project
<a name="create-agent"></a>

Use the `agentcore create` command to scaffold a new agent project:

**Example**  

1. Pass flags directly to create a project non-interactively:

   ```
   agentcore create --name MyAgent --framework Strands --protocol HTTP --model-provider Bedrock --memory none
   ```

   To accept all defaults (Python, Strands, Bedrock, no memory), use the `--defaults` flag:

   ```
   agentcore create --name MyAgent --defaults
   ```

1. Run `agentcore create` without flags to launch the interactive wizard:

   ```
   agentcore create
   ```

1. Enter your project name:  
![\[Create wizard: enter project name\]](http://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/images/tui/common-create-name.png)

1. Choose your agent framework and model provider:  
![\[Create wizard: select framework\]](http://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/images/tui/common-create-framework.png)

1. Review your configuration and confirm:  
![\[Create wizard: review and confirm\]](http://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/images/tui/common-create-confirm.png)

The `agentcore create` command accepts the following flags:
+  `--name` – The project name (alphanumeric, starts with a letter, max 36 characters).
+  `--framework` – The agent framework. Supported values: `Strands` , `LangChain_LangGraph` , `GoogleADK` , `OpenAIAgents`.
+  `--protocol` – The protocol mode. Supported values: `HTTP` (default), `MCP` , `A2A`.
+  `--build` – The build type. Supported values: `CodeZip` (default), `Container`.
+  `--model-provider` – The model provider. Supported values: `Bedrock` , `Anthropic` , `OpenAI` , `Gemini`.
+  `--memory` – Memory configuration. Supported values: `none` , `shortTerm` , `longAndShortTerm`.

The command generates a project directory with the following structure:

```
MyAgent/
  agentcore/
    agentcore.json        # Project and agent configuration
    aws-targets.json      # AWS account and region targets
    .env.local            # Local environment variables (gitignored)
  app/
    MyAgent/
      main.py             # Agent entrypoint
      pyproject.toml      # Python dependencies
  README.md
```

The `agentcore/agentcore.json` file contains your project and agent configuration. The `app/MyAgent/main.py` file contains starter agent code using your selected framework.

## Step 3: Test your agent locally
<a name="configure-agent"></a>

Before deploying to AWS, test your agent locally using the development server. First, change into the project directory:

```
cd MyAgent
```

If you selected a model provider that requires an API key (OpenAI, Anthropic, or Gemini), make sure the key is configured in `agentcore/.env.local`.

Start the local development server:

**Example**  

1. 

   ```
   agentcore dev
   ```

1. Run `agentcore` to open the TUI home screen, then navigate to the dev server option:

   ```
   agentcore
   ```  
![\[Dev server TUI with inline chat prompt\]](http://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/images/tui/common-dev-server.png)

The `agentcore dev` command:
+ Automatically creates a Python virtual environment and installs dependencies
+ Starts a local server that mimics the AgentCore Runtime environment
+ Runs on `http://localhost:8080` by default (use `-p` to change the port)

In a separate terminal, invoke your local agent:

```
agentcore dev "Hello, tell me a joke"
```

Passing a prompt sends it to the running local development server. Use `--stream` to see the response streamed in real time.

## Step 4: Enable observability for your agent
<a name="enable-observability"></a>

 [Amazon Bedrock AgentCore Observability](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability.html) helps you trace, debug, and monitor agents that you host in Amazon Bedrock AgentCore Runtime. First enable CloudWatch Transaction Search by following the instructions at [Enabling Amazon Bedrock AgentCore runtime observability](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability-configure.html#observability-configure-builtin) . To observe your agent, see [View observability data for your Amazon Bedrock AgentCore agents](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability-view.html).

After you deploy your agent, you can use the AgentCore CLI to stream logs and view traces:

```
# Stream agent logs
agentcore logs

# List recent traces
agentcore traces list
```

## Step 5: Deploy to Amazon Bedrock AgentCore Runtime
<a name="deploy-runtime"></a>

Deploy your agent to Amazon Bedrock AgentCore Runtime:

**Example**  

1. 

   ```
   agentcore deploy
   ```

1. Run `agentcore deploy` to start deployment. The CLI shows the deployment progress as it builds and deploys your project:

   ```
   agentcore deploy
   ```  
![\[Deploy progress: CloudFormation resource creation and deployment status\]](http://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/images/tui/common-deploy-progress.png)

To preview the deployment without making changes, use the `--plan` flag:

```
agentcore deploy --plan
```

The `agentcore deploy` command:
+ Reads your `agentcore/agentcore.json` and `agentcore/aws-targets.json` configuration
+ Packages your agent code (as a CodeZip archive or Docker container, depending on your build type)
+ Uses the AWS CDK to synthesize and deploy CloudFormation resources
+ Creates the necessary AWS resources (IAM roles, Amazon Bedrock AgentCore Runtime, etc.)

Use `-v` for verbose output that shows resource-level deployment events. Use `-y` to auto-confirm the deployment without a prompt.

If the deployment fails, check for [common issues](#common-issues).

## Step 6: Test your deployed agent
<a name="test-deployed-agent"></a>

After deployment completes, invoke your deployed agent:

**Example**  

1. 

   ```
   agentcore invoke "Tell me a joke"
   ```

   You can also pass the prompt with the `--prompt` flag, specify a runtime with `--runtime` , or stream the response in real time with `--stream` :

   ```
   agentcore invoke --prompt "Tell me a joke" --stream
   ```

   To maintain a conversation across multiple invocations, use the `--session-id` flag:

   ```
   agentcore invoke --session-id my-session "What else can you tell me?"
   ```

1. Run `agentcore` to open the TUI home screen, then select the invoke option to chat with your deployed agent:

   ```
   agentcore
   ```  
![\[Invoke TUI screen showing chat interface\]](http://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/images/tui/common-invoke-chat.png)

If you see a joke in the response, your agent is running in Amazon Bedrock AgentCore Runtime and can be invoked. If not, check for [common issues](#common-issues).

## Step 7: Invoke your deployed agent
<a name="invoke-programmatically"></a>

**Example**  

1. Invoke your deployed agent with a prompt:

   ```
   agentcore invoke --runtime MyAgent "Hello, what can you do?"
   ```

   Stream the response in real time:

   ```
   agentcore invoke --runtime MyAgent "Tell me a joke" --stream
   ```

   Run `agentcore invoke` without a prompt to open the interactive chat TUI, which streams responses by default and maintains your session automatically.

1. You can also invoke the agent using the AWS SDK [InvokeAgentRuntime](https://docs.aws.amazon.com/bedrock-agentcore/latest/APIReference/API_InvokeAgentRuntime.html) operation. To get the ARN of your deployed agent, use the `agentcore status` command:

   ```
   agentcore status
   ```

   Use the following boto3 (AWS SDK for Python) code to invoke your agent. Replace *Agent ARN* with the ARN of your agent. Make sure that you have `bedrock-agentcore:InvokeAgentRuntime` permissions. Create a file named `invoke_agent.py` and add the following code:

   ```
   import json
   import uuid
   import boto3
   
   agent_arn = "Agent ARN"
   prompt = "Tell me a joke"
   
   # Initialize the Amazon Bedrock AgentCore client
   agent_core_client = boto3.client('bedrock-agentcore')
   
   # Prepare the payload
   payload = json.dumps({"prompt": prompt}).encode()
   
   # Invoke the agent
   response = agent_core_client.invoke_agent_runtime(
       agentRuntimeArn=agent_arn,
       runtimeSessionId=str(uuid.uuid4()),
       payload=payload,
       qualifier="DEFAULT"
   )
   
   content = []
   for chunk in response.get("response", []):
       content.append(chunk.decode('utf-8'))
   print(json.loads(''.join(content)))
   ```

   Open a terminal window and run the code with the following command:

   ```
   python invoke_agent.py
   ```

   If successful, you should see a joke in the response. If the call fails, check the logs using `agentcore logs` or view them in Amazon CloudWatch.
**Note**  
If you plan on integrating your agent with OAuth, you can’t use the AWS SDK to call `InvokeAgentRuntime` . Instead, make a HTTPS request to `InvokeAgentRuntime` . For more information, see [Authenticate and authorize with Inbound Auth and Outbound Auth](runtime-oauth.md).

## Step 8: Clean up
<a name="stop-session-or-clean-up"></a>

If you no longer want to host the agent in Amazon Bedrock AgentCore Runtime, remove the deployed AWS resources. First, remove all resources from your local configuration:

**Example**  

1. 

   ```
   agentcore remove all
   ```

1. Run `agentcore` to open the TUI home screen, then select the remove option to choose which resources to remove:

   ```
   agentcore
   ```  
![\[Remove resource selection TUI\]](http://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/images/tui/common-remove-resource.png)

Then deploy again to tear down the AWS resources:

**Example**  

1. 

   ```
   agentcore deploy
   ```

1. From the AgentCore CLI home screen, select `deploy` to apply the removal and tear down AWS resources:  
![\[Deploy progress: CloudFormation resource deletion and teardown status\]](http://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/images/tui/common-deploy-teardown.png)

The `remove all` command resets the `agentcore/agentcore.json` configuration file while preserving `agentcore/aws-targets.json` and deployment state. The subsequent `deploy` detects the removed resources and tears down the corresponding AWS resources.

## Find your resources
<a name="find-resources"></a>

After deployment, you can check the status of your resources by using the AgentCore CLI:

**Example**  

1. 

   ```
   agentcore status
   ```

1. Run `agentcore` and select `status` to view a live dashboard of all deployed resources:

   ```
   agentcore
   ```  
![\[AgentCore CLI TUI status dashboard\]](http://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/images/tui/common-status-dashboard.png)

You can also view your resources in the AWS Console:


| Resource | Location | 
| --- | --- | 
|   **Agent Logs**   |  CloudWatch → Log groups → `/aws/bedrock-agentcore/runtimes/{agent-id}-DEFAULT`   | 
|   **CloudFormation Stack**   |  CloudFormation → Stacks → search for your project name  | 
|   **IAM Role**   |  IAM → Roles → Search for "BedrockAgentCore"  | 
|   **S3 Assets (CodeZip)**   |  S3 → Buckets → CDK staging bucket  | 

## Common issues and solutions
<a name="common-issues"></a>

Common issues and solutions when getting started with the AgentCore CLI. For more troubleshooting information, see [Troubleshoot Amazon Bedrock AgentCore Runtime](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-troubleshooting.html).

 **Permission denied errors**   
Verify your AWS credentials and permissions:  
+ Verify AWS credentials: `aws sts get-caller-identity` 
+ Check you have the required policies attached
+ Review caller permissions policy for detailed requirements

 **Model access denied**   
Enable model access in the Bedrock console:  
+ Enable Anthropic Claude 4.0 in the Bedrock console
+ Make sure you’re in the correct AWS Region (us-west-2 by default)

 **CDK deployment errors**   
Check CDK setup and permissions:  
+ Make sure you have bootstrapped your AWS account for CDK: `cdk bootstrap` 
+ Verify your caller permissions include CloudFormation and CDK access
+ Use `agentcore deploy -v` for verbose output to identify the failing resource

 **Port 8080 in use (local only)**   
Find and stop processes that are using port 8080:  
Use `lsof -ti:8080` to get a list of processes using port 8080.  
Use `kill -9 PID` to stop the process. Replace *PID* with the process ID.  
Alternatively, start the dev server on a different port: `agentcore dev -p 3000` 

 **Region mismatch**   
Verify the AWS Region with `aws configure get region` and make sure the region in `agentcore/aws-targets.json` matches where your resources should be deployed.

 **Configuration validation errors**   
Validate your configuration files:  
Use `agentcore validate` to check for syntax or schema errors in `agentcore/agentcore.json` and related configuration files.

## Advanced options (Optional)
<a name="advanced-options"></a>

After creating your agent project with `agentcore create` , you can extend it by using the `agentcore add` commands. For the full CLI reference, see the [AgentCore CLI documentation](https://github.com/aws/agentcore-cli).

### Build types
<a name="deployment-modes"></a>

When creating your project, choose a build type that fits your needs:

 **CodeZip (default)**   
Your agent code is packaged as a zip archive and uploaded to S3. This is the simplest option and does not require Docker:  

```
agentcore create --name MyAgent --framework Strands --model-provider Bedrock --memory none --build CodeZip
```

 **Container**   
Your agent code is packaged as a Docker container image. Use this option when you need custom system-level dependencies or a specific base image:  

```
agentcore create --name MyAgent --framework Strands --model-provider Bedrock --memory none --build Container
```

### Add resources to your project
<a name="custom-execution-role"></a>

You can add additional resources to your project after creation:

```
# Add another agent to the same project
agentcore add agent --name SecondAgent --language Python --framework Strands --model-provider Bedrock

# Add a memory store for conversational context
agentcore add memory --name MyMemory --strategies SEMANTIC

# Add an API key credential for external services
agentcore add credential --name MyApiKey --type api-key --api-key your-api-key
```

After adding resources, run `agentcore deploy` to provision the new resources in AWS.

### Why ARM64?
<a name="why-arm64"></a>

Amazon Bedrock AgentCore Runtime runs on ARM64 (AWS Graviton). The AgentCore CLI handles architecture compatibility automatically for both the CodeZip and Container build types. For Container builds, only images built for ARM64 will work when deployed to Amazon Bedrock AgentCore Runtime.

# Get started with the AgentCore CLI in TypeScript
<a name="runtime-get-started-cli-typescript"></a>

This tutorial shows you how to use the AgentCore CLI ( [agentcore-cli](https://github.com/aws/agentcore-cli) ) to deploy a TypeScript agent to an Amazon Bedrock AgentCore Runtime.

The AgentCore CLI is a command-line tool that you can use to create, develop, and deploy AI agents to an Amazon Bedrock AgentCore Runtime. This tutorial shows you how to create and deploy a TypeScript agent using the [bedrock-agentcore](https://www.npmjs.com/package/bedrock-agentcore) SDK.

For information about the HTTP protocol that the agent uses, see [HTTP protocol contract](runtime-http-protocol-contract.md).

**Topics**
+ [

## Prerequisites
](#ts-prerequisites)
+ [

## Step 1: Install the AgentCore CLI and create a project
](#ts-setup-project)
+ [

## Step 2: Create your TypeScript agent
](#ts-create-agent)
+ [

## Step 3: Review your project configuration
](#ts-configure-agent)
+ [

## Step 4: Test your agent locally
](#ts-test-locally)
+ [

## Step 5: Enable observability for your agent
](#ts-enable-observability)
+ [

## Step 6: Deploy to Amazon Bedrock AgentCore Runtime
](#ts-deploy-runtime)
+ [

## Step 7: Test your deployed agent
](#ts-test-deployed-agent)
+ [

## Step 8: Invoke your agent programmatically
](#ts-invoke-programmatically)
+ [

## Step 9: Stop session or clean up
](#ts-stop-session-or-clean-up)
+ [

## Find your resources
](#ts-find-resources)
+ [

## Common issues and solutions
](#ts-common-issues)
+ [

## Advanced: Streaming responses
](#ts-streaming-responses)

## Prerequisites
<a name="ts-prerequisites"></a>

Before you start, make sure you have:
+  ** AWS Account** with credentials configured. To configure your AWS credentials, see [Configuration and credential file settings in the AWS CLI.](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html) 
+  **Node.js 20\$1** installed
+  **Docker** (or [Podman](https://podman.io) or [Finch](https://runfinch.com) ) installed. A container runtime is required for building and testing your TypeScript agent locally. A local container runtime is not required for `agentcore deploy` because AWS CodeBuild builds the image remotely.
+  ** AWS Permissions** : To create and deploy an agent with the AgentCore CLI, you must have appropriate permissions. For information, see [Use the AgentCore CLI](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-permissions.html#runtime-permissions-cli).
+  **Model access** : If your agent uses Amazon Bedrock models, ensure the required models are [enabled](https://docs.aws.amazon.com/bedrock/latest/userguide/model-access-modify.html) in the Amazon Bedrock console.

## Step 1: Install the AgentCore CLI and create a project
<a name="ts-setup-project"></a>

Install the AgentCore CLI globally:

```
npm install -g @aws/agentcore
```

Verify installation:

```
agentcore --help
```

To deploy a TypeScript agent, use container-based deployment. Create a project without a default agent. You will add a TypeScript container agent in the next step.

**Example**  

1. 

   ```
   agentcore create --name MyTsAgent --no-agent
   ```

1. Run `agentcore create` without flags to launch the interactive wizard. Select "No" when asked to add an agent — you will add a TypeScript container agent in the next step:

   ```
   agentcore create
   ```  
![\[Create wizard: enter project name\]](http://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/images/tui/common-create-name.png)

This command creates a project directory with the following structure:

```
MyTsAgent/
  agentcore/
    agentcore.json
    aws-targets.json
```

Change into the project directory:

```
cd MyTsAgent
```

## Step 2: Create your TypeScript agent
<a name="ts-create-agent"></a>

This tutorial uses the [Strands Agents](https://strandsagents.com/latest/) framework, which is currently the supported framework for TypeScript agents deployed to AgentCore Runtime.

Add a TypeScript agent to your project using the bring-your-own-code (BYO) workflow with container-based deployment:

**Example**  

1. 

   ```
   agentcore add agent --name TsAgent --type byo --build Container --language TypeScript --framework Strands --model-provider Bedrock --code-location app/TsAgent
   ```

1. Run `agentcore add agent` to launch the interactive wizard. Select **Bring my own code** as the agent type:

   ```
   agentcore add agent
   ```

1. Select **Bring my own code** as the agent type:  
![\[Add agent wizard: select BYO type\]](http://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/images/tui/runtime-ts-add-agent-byo.png)

1. Set the code location for your agent:  
![\[Add agent wizard: code location\]](http://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/images/tui/runtime-ts-add-agent-code.png)

1. Review the configuration and confirm:  
![\[Add agent wizard: review and confirm\]](http://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/images/tui/runtime-ts-add-agent-confirm.png)

This command registers a TypeScript agent in `agentcore/agentcore.json` and creates a code directory for your agent at `app/TsAgent/`.

Initialize the TypeScript project inside the agent code directory:

```
cd app/TsAgent
npm init -y
```

Install the required packages:
+  **bedrock-agentcore** - The Amazon Bedrock AgentCore SDK for building AI agents in TypeScript
+  **@strands-agents/sdk** - The [Strands Agents](https://strandsagents.com/latest/) SDK
+  **@opentelemetry/auto-instrumentations-node** - OpenTelemetry instrumentation for observability
+  **typescript** - TypeScript compiler

```
npm install bedrock-agentcore @strands-agents/sdk @opentelemetry/auto-instrumentations-node --legacy-peer-deps
npm install --save-dev typescript @types/node tsx
```

**Note**  
The `--legacy-peer-deps` flag resolves peer dependency conflicts between `@strands-agents/sdk` and `@opentelemetry/auto-instrumentations-node` . This is safe and does not affect runtime behavior.

Create a `tsconfig.json` file with the following content:

```
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "outDir": "./dist",
    "rootDir": ".",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "declaration": true
  },
  "include": ["*.ts"],
  "exclude": ["node_modules", "dist"]
}
```

Update your `package.json` to add the required configuration:

```
{
  "name": "ts-agent",
  "version": "1.0.0",
  "type": "module",
  "main": "dist/agent.js",
  "scripts": {
    "build": "tsc",
    "start": "node dist/agent.js",
    "dev": "npx tsx --watch agent.ts"
  },
  "engines": {
    "node": ">=20.0.0"
  },
  "dependencies": {
    "bedrock-agentcore": "^0.2.0",
    "@strands-agents/sdk": "^0.1.5",
    "@opentelemetry/auto-instrumentations-node": "^0.56.0"
  },
  "devDependencies": {
    "@types/node": "^22.0.0",
    "typescript": "^5.5.0",
    "tsx": "^4.0.0"
  }
}
```

Create an `agent.ts` file with your agent code:

```
import { BedrockAgentCoreApp } from 'bedrock-agentcore/runtime';
import { Agent } from '@strands-agents/sdk';

// Create a Strands agent
const agent = new Agent();

// Create and start the server
const app = new BedrockAgentCoreApp({
  invocationHandler: {
    process: async (payload, context) => {
      const prompt = (payload as { prompt?: string }).prompt ?? 'Hello!';
      console.log(`Session ${context.sessionId} - Received prompt:`, prompt);

      const result = await agent.invoke(prompt);
      return result;
    }
  }
});

app.run();
```

Create a `Dockerfile` in the `app/TsAgent/` directory. Container-based deployment uses a multi-stage Docker build: the builder stage compiles TypeScript to JavaScript, and the production stage runs only the compiled output. The image runs as a non-root user for security, and exposes port 8080 (HTTP), port 8000 (MCP), and port 9000 (A2A). OpenTelemetry instrumentation is included automatically at startup.

```
FROM node:20-slim AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY ..
RUN npm run build

FROM node:20-slim
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package*.json ./

RUN useradd -m -u 1000 bedrock_agentcore
USER bedrock_agentcore

EXPOSE 8080 8000 9000
CMD ["node", "--require", "@opentelemetry/auto-instrumentations-node/register", "dist/agent.js"]
```

Create a `.dockerignore` file to exclude unnecessary files from the Docker build context:

```
node_modules
dist
.git
*.log
```

Build locally to verify that your TypeScript code compiles. The container build will also run this step during deployment.

```
npm run build
```

Return to the project root directory:

```
cd ../..
```

## Step 3: Review your project configuration
<a name="ts-configure-agent"></a>

The `agentcore create` and `agentcore add agent` commands generated the configuration files for your project. Open `agentcore/agentcore.json` to review the configuration:

```
{
  "name": "MyTsAgent",
  "version": 1,
  "agents": [
    {
      "type": "AgentCoreRuntime",
      "name": "TsAgent",
      "build": "Container",
      "entrypoint": "main.py",
      "codeLocation": "app/TsAgent/",
      "runtimeVersion": "PYTHON_3_12",
      "protocol": "HTTP",
      "networkMode": "PUBLIC"
    }
  ]
}
```

**Note**  
For container-based deployments, the `runtimeVersion` and `entrypoint` fields are present in the configuration but are not used at deployment time. The container image (via its `Dockerfile CMD` ) defines the actual runtime and entrypoint. The CLI sets these to Python defaults regardless of language.

You can also review your deployment target in `agentcore/aws-targets.json` :

```
[]
```

Before deploying, you must configure at least one deployment target. Open `agentcore/aws-targets.json` and add your AWS account and Region:

```
[
  {
    "name": "default",
    "account": "123456789012",
    "region": "us-west-2"
  }
]
```

Replace *123456789012* with your AWS account ID and update the Region as needed.

To validate that your configuration is correct, run:

```
agentcore validate
```

## Step 4: Test your agent locally
<a name="ts-test-locally"></a>

Before deploying to AWS, test your agent locally using the development server:

**Example**  

1. 

   ```
   agentcore dev
   ```

   If your project has multiple runtimes, use `--runtime` to start a specific runtime directly:

   ```
   agentcore dev --runtime TsAgent
   ```

   In a separate terminal, invoke your agent against the local dev server:

   ```
   agentcore dev "Hello, tell me a joke"
   ```

1. Run `agentcore` to open the TUI home screen, then navigate to the dev server option:

   ```
   agentcore
   ```  
![\[Dev server TUI with inline chat prompt\]](http://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/images/tui/common-dev-server.png)
+ For container agents, this command builds the Docker image and runs the container locally with your source directory mounted for hot reload. Your AWS credentials are forwarded automatically to the container.
+ The server runs on `http://localhost:8080` by default. Use the `--port` flag to specify a different port.

**Note**  
If your project has multiple runtimes, `agentcore dev` opens an interactive selection menu. Use `agentcore dev --runtime TsAgent` to skip the menu and start a specific runtime directly.

## Step 5: Enable observability for your agent
<a name="ts-enable-observability"></a>

 [Amazon Bedrock AgentCore Observability](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability.html) helps you trace, debug, and monitor agents that you host in Amazon Bedrock AgentCore Runtime. First enable CloudWatch Transaction Search by following the instructions at [Enabling Amazon Bedrock AgentCore runtime observability](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability-configure.html#observability-configure-builtin) . To observe your agent, see [View observability data for your Amazon Bedrock AgentCore agents](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability-view.html).

After deploying your agent, you can stream logs and view traces using the AgentCore CLI:

```
agentcore logs --runtime TsAgent --since 1h
```

```
agentcore traces list --runtime TsAgent
```

## Step 6: Deploy to Amazon Bedrock AgentCore Runtime
<a name="ts-deploy-runtime"></a>

Deploy your agent to AgentCore Runtime:

**Example**  

1. 

   ```
   agentcore deploy
   ```

1. Run `agentcore deploy` to start deployment. The CLI shows the deployment progress as it builds and deploys your project:

   ```
   agentcore deploy
   ```  
![\[Deploy progress: CloudFormation resource creation and deployment status\]](http://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/images/tui/common-deploy-progress.png)

You can preview the deployment before confirming by using the `--plan` flag:

```
agentcore deploy --plan
```

The `agentcore deploy` command:
+ Builds your container image using AWS CodeBuild and pushes it to Amazon ECR
+ Creates necessary AWS resources (IAM roles, ECR repository, etc.) using AWS CDK
+ Deploys your agent to Amazon Bedrock AgentCore Runtime
+ Configures CloudWatch logging

In the output from `agentcore deploy` note the following:
+ The Amazon Resource Name (ARN) of the agent. You need it to invoke the agent with the [InvokeAgentRuntime](https://docs.aws.amazon.com/bedrock-agentcore/latest/APIReference/API_InvokeAgentRuntime.html) operation.
+ The location of the logs in Amazon CloudWatch Logs

To check the status of your deployed resources, run:

**Example**  

1. 

   ```
   agentcore status
   ```

1. Run `agentcore` to open the TUI home screen, then select the status option to view your deployed resources dashboard:

   ```
   agentcore
   ```  
![\[Status dashboard TUI showing deployed resource details\]](http://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/images/tui/common-status-dashboard.png)

If the deployment fails check for [common issues](#ts-common-issues).

## Step 7: Test your deployed agent
<a name="ts-test-deployed-agent"></a>

Test your deployed agent:

**Example**  

1. 

   ```
   agentcore invoke "tell me a joke"
   ```

   To stream the response in real time, use the `--stream` flag:

   ```
   agentcore invoke --stream "tell me a joke"
   ```

1. Run `agentcore` to open the TUI home screen, then select the invoke option to chat with your deployed agent:

   ```
   agentcore
   ```  
![\[Invoke TUI screen showing chat interface\]](http://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/images/tui/common-invoke-chat.png)

If you see a response, your agent is now running in an Amazon Bedrock AgentCore Runtime and can be invoked. If not, check for [common issues](#ts-common-issues).

## Step 8: Invoke your agent programmatically
<a name="ts-invoke-programmatically"></a>

You can invoke the agent using the AWS SDK [InvokeAgentRuntime](https://docs.aws.amazon.com/bedrock-agentcore/latest/APIReference/API_InvokeAgentRuntime.html) operation. To call `InvokeAgentRuntime` , you need the ARN of the agent that you noted in Step 6. You can also find the ARN by running `agentcore status`.

Create a file named `invoke-agent.ts` and add the following code:

```
import {
  BedrockAgentCoreClient,
  InvokeAgentRuntimeCommand
} from '@aws-sdk/client-bedrock-agentcore';
import { randomUUID } from 'crypto';

const agentArn = 'Agent ARN';
const prompt = 'Tell me a joke';

// Initialize the Amazon Bedrock AgentCore client
const client = new BedrockAgentCoreClient({ region: 'us-west-2' });

// Invoke the agent
const command = new InvokeAgentRuntimeCommand({
  agentRuntimeArn: agentArn,
  runtimeSessionId: randomUUID(),
  payload: JSON.stringify({ prompt }),
  contentType: 'application/json',
  qualifier: 'DEFAULT',
});

const response = await client.send(command);
const textResponse = await response.response?.transformToString();

console.log('Response:', textResponse);
```

Run the code with the following command:

```
npx tsx invoke-agent.ts
```

If successful, you should see a response from your agent. If the call fails, check the logs that you noted in [Step 6: Deploy to Amazon Bedrock AgentCore Runtime](#ts-deploy-runtime).

**Note**  
If you plan on integrating your agent with OAuth, you can’t use the AWS SDK to call `InvokeAgentRuntime` . Instead, make a HTTPS request to `InvokeAgentRuntime` . For more information, see [Authenticate and authorize with Inbound Auth and Outbound Auth](runtime-oauth.md).

## Step 9: Stop session or clean up
<a name="ts-stop-session-or-clean-up"></a>

To stop the running session before the configurable `IdleRuntimeSessionTimeout` (defaulted at 15 minutes) and save on any potential runaway costs, execute: `StopRuntimeSession` 

Create a file named `stop-runtime-session.ts` with the following content:

 **Example** 

```
import {
  BedrockAgentCoreClient,
  StopRuntimeSessionCommand
} from '@aws-sdk/client-bedrock-agentcore';
import { randomUUID } from 'crypto';

const client = new BedrockAgentCoreClient({ region: 'us-west-2' });
const agentArn = 'Agent ARN';
const command = new StopRuntimeSessionCommand({
  agentRuntimeArn: agentArn,
  runtimeSessionId: randomUUID(),
  qualifier: 'DEFAULT',
});

const response = await client.send(command);
console.log('Session stopped:', response);
```

Run the code with the following command:

```
npx tsx stop-runtime-session.ts
```

If you no longer want to host the agent in the AgentCore Runtime, remove all resources from your project configuration and then deploy to tear down the AWS resources:

**Example**  

1. 

   ```
   agentcore remove all --yes
   agentcore deploy
   ```

1. Run `agentcore` to open the TUI home screen, then select the remove option to choose which resources to remove:

   ```
   agentcore
   ```  
![\[Remove resource selection TUI\]](http://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/images/tui/common-remove-resource.png)

## Find your resources
<a name="ts-find-resources"></a>

After deployment, view your resources in the AWS Console:


| Resource | Location | 
| --- | --- | 
|   **Agent Logs**   |  CloudWatch → Log groups → `/aws/bedrock-agentcore/runtimes/{agent-id}-DEFAULT`   | 
|   **Container Image**   |  Amazon ECR → Repositories → Search for your agent name  | 
|   **Deployed Status**   |  Run `agentcore status` to see all deployed resources  | 
|   **IAM Role**   |  IAM → Roles → Search for "BedrockAgentCore"  | 

## Common issues and solutions
<a name="ts-common-issues"></a>

Common issues and solutions when getting started with the AgentCore CLI for TypeScript. For more troubleshooting information, see [Troubleshoot Amazon Bedrock AgentCore Runtime](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-troubleshooting.html).

 **Container runtime not found**   
Install Docker, Podman, or Finch. For Docker, ensure Docker Desktop is running. Verify your container runtime is available by running `docker info` (or the equivalent command for your container runtime).

 **Dockerfile not found**   
Ensure a `Dockerfile` exists in your agent’s code directory (for example, `app/TsAgent/Dockerfile` ). The container build requires a Dockerfile in the directory specified by `codeLocation` in `agentcore/agentcore.json`.

 **Container image exceeds size limit**   
Use multi-stage builds to reduce the final image size, minimize installed packages, and review your `.dockerignore` file to exclude unnecessary files from the build context.

 **Permission denied errors**   
Verify your AWS credentials and permissions:  
+ Verify AWS credentials: `aws sts get-caller-identity` 
+ Check you have the required policies attached
+ Review caller permissions policy for detailed requirements

 **TypeScript compilation errors**   
Ensure your TypeScript configuration is correct:  
+ Verify `tsconfig.json` exists and has correct settings
+ Run `npm run build` locally to check for errors
+ Ensure `"type": "module"` is set in `package.json` 

 **Configuration validation errors**   
Check your project configuration:  
+ Run `agentcore validate` to check for configuration errors
+ Verify `agentcore/agentcore.json` has the correct agent entry
+ Ensure `codeLocation` points to the correct directory

 **Port 8080 in use (local only)**   
Find and stop processes that are using port 8080:  
Use `lsof -ti:8080` to get a list of process using port 8080.  
Use `kill -9 PID` to stop the process. Replace *PID* with the process ID.  
Alternatively, start the dev server on a different port: `agentcore dev --port 3000` 

 **Region mismatch**   
Verify the AWS Region with `aws configure get region` and make sure the region in `agentcore/aws-targets.json` matches

 **Module not found errors**   
Ensure your imports use the correct paths:  
+ Use `bedrock-agentcore/runtime` for the runtime module
+ Run `npm install` to ensure all dependencies are installed

## Advanced: Streaming responses
<a name="ts-streaming-responses"></a>

Your TypeScript agent can return streaming responses using async generators. This is useful for long-running operations or when you want to provide incremental updates to the client:

```
import { BedrockAgentCoreApp } from 'bedrock-agentcore/runtime';

// Streaming handler using async generator
const streamingHandler = async function* (request: unknown, context: { sessionId: string }) {
  yield { event: 'start', sessionId: context.sessionId };

  // Simulate processing steps
  for (let i = 0; i < 5; i++) {
    yield {
      event: 'progress',
      step: i + 1,
      data: `Processing step ${i + 1}`,
    };
  }

  yield { event: 'complete', result: 'done' };
};

const app = new BedrockAgentCoreApp({
  invocationHandler: { process: streamingHandler },
});

app.run();
```

The server automatically handles streaming responses using Server-Sent Events (SSE).

# Get started without the AgentCore CLI
<a name="getting-started-custom"></a>

You can create a AgentCore Runtime agent without the AgentCore CLI. Instead you can use a combination of command line tools to configure and deploy your agent to an AgentCore Runtime.

This tutorial shows how to deploy a custom agent without using the AgentCore CLI. A custom agent is an agent built without using the AgentCore Python SDK. In this tutorial, the custom agent is built using FastAPI and Docker. The custom agent follows the [AgentCore Runtime requirements](runtime-service-contract.md) , meaning the agent must expose `/invocations` POST and `/ping` GET endpoints and be packaged in a Docker container. Amazon Bedrock AgentCore requires ARM64 architecture for all deployed agents.

**Note**  
You can also use this approach for agents that you build with the AgentCore Python SDK.

## Quick start setup
<a name="quick-start-setup"></a>

### Enable observability for your agent
<a name="runtime-enable-observability-custom"></a>

 [Amazon Bedrock AgentCore Observability](observability.md) helps you trace, debug, and monitor agents that you host in AgentCore Runtime. To observe an agent, first enable CloudWatch Transaction Search by following the instructions at [Enabling AgentCore observability](observability-configure.md#observability-configure-builtin).

### Install uv
<a name="install-uv"></a>

For this example, we’ll use the `uv` package manager, though you can use any Python utility or package manager. To install `uv` on macOS:

```
curl -LsSf https://astral.sh/uv/install.sh | sh
```

For installation instructions on other platforms, refer to the [uv documentation](https://docs.astral.sh/uv/getting-started/installation/).

### Create your agent project
<a name="create-agent-project"></a>

<a name="create-agent-project"></a> **Setting up your project** 

1. Create and navigate to your project directory:

   ```
   mkdir my-custom-agent && cd my-custom-agent
   ```

1. Initialize the project with Python 3.11:

   ```
   uv init --python 3.11
   ```

1. Add the required dependencies (uv automatically creates a .venv):

   ```
   uv add fastapi 'uvicorn[standard]' pydantic httpx strands-agents
   ```

## Agent contract requirements
<a name="agent-contract-requirements"></a>

Your custom agent must fulfill these core requirements:
+  **/invocations Endpoint** : POST endpoint for agent interactions (REQUIRED)
+  **/ping Endpoint** : GET endpoint for health checks (REQUIRED)
+  **Docker Container** : ARM64 containerized deployment package

## Project structure
<a name="project-structure"></a>

 **Note:** For convenience, the example below uses **FastAPI Server** as the Web server framework for handling requests.

Your project should have the following structure:

```
my-custom-agent/
├── agent.py                 # FastAPI application
├── Dockerfile               # ARM64 container configuration
├── pyproject.toml           # Created by uv init
└── uv.lock                  # Created automatically by uv
```

## Complete strands agent example
<a name="complete-strands-agent-example"></a>

Create `agent.py` in your project root with the following content:

 **Example agent.py** 

```
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Dict, Any
from datetime import datetime
from strands import Agent

app = FastAPI(title="Strands Agent Server", version="1.0.0")

# Initialize Strands agent
strands_agent = Agent()

class InvocationRequest(BaseModel):
    input: Dict[str, Any]

class InvocationResponse(BaseModel):
    output: Dict[str, Any]

@app.post("/invocations", response_model=InvocationResponse)
async def invoke_agent(request: InvocationRequest):
    try:
        user_message = request.input.get("prompt", "")
        if not user_message:
            raise HTTPException(
                status_code=400,
                detail="No prompt found in input. Please provide a 'prompt' key in the input."
            )

        result = strands_agent(user_message)
        response = {
            "message": result.message,
            "timestamp": datetime.utcnow().isoformat()
        }

        return InvocationResponse(output=response)

    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Agent processing failed: {str(e)}")

@app.get("/ping")
async def ping():
    return {"status": "healthy"}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8080)
```

This implementation:
+ Creates a FastAPI application with the required endpoints
+ Initializes a Strands agent for processing user messages
+ Implements the `/invocations` POST endpoint for agent interactions
+ Implements the `/ping` GET endpoint for health checks
+ Configures the server to run on host `0.0.0.0` and port `8080` 

## Test locally
<a name="test-locally"></a>

<a name="test-locally"></a> **Testing your agent** 

1. Run the application:

   ```
   uv run uvicorn agent:app --host 0.0.0.0 --port 8080
   ```

1. Test the `/ping` endpoint (in another terminal):

   ```
   curl http://localhost:8080/ping
   ```

1. Test the `/invocations` endpoint:

   ```
   curl -X POST http://localhost:8080/invocations \
     -H "Content-Type: application/json" \
     -d '{
       "input": {"prompt": "What is artificial intelligence?"}
     }'
   ```

## Create dockerfile
<a name="create-dockerfile"></a>

Create `Dockerfile` in your project root with the following content:

 **Example Dockerfile** 

```
# Use uv's ARM64 Python base image
FROM --platform=linux/arm64 ghcr.io/astral-sh/uv:python3.11-bookworm-slim

WORKDIR /app

# Copy uv files
COPY pyproject.toml uv.lock ./

# Install dependencies (including strands-agents)
RUN uv sync --frozen --no-cache

# Copy agent file
COPY agent.py ./

# Expose port
EXPOSE 8080

# Run application
CMD ["uv", "run", "uvicorn", "agent:app", "--host", "0.0.0.0", "--port", "8080"]
```

This Dockerfile:
+ Uses an ARM64 Python base image (required by Amazon Bedrock AgentCore)
+ Sets up the working directory
+ Copies the dependency files and installs dependencies
+ Copies the agent code
+ Exposes port 8080
+ Configures the command to run the application

## Build and deploy ARM64 image
<a name="build-and-deploy-arm64-image"></a>

### Setup docker buildx
<a name="setup-docker-buildx"></a>

Docker buildx lets you build images for different architectures. Set it up with:

```
docker buildx create --use
```

### Build for ARM64 and test locally
<a name="build-for-arm64-and-test-locally"></a>

<a name="build-for-arm64-and-test-locally"></a> **Building and testing your image** 

1. Build the image locally for testing:

   ```
   docker buildx build --platform linux/arm64 -t my-agent:arm64 --load.
   ```

1. Test locally with credentials (Strands agents need AWS credentials):

   ```
   docker run --platform linux/arm64 -p 8080:8080 \
     -e AWS_ACCESS_KEY_ID="$AWS_ACCESS_KEY_ID" \
     -e AWS_SECRET_ACCESS_KEY="$AWS_SECRET_ACCESS_KEY" \
     -e AWS_SESSION_TOKEN="$AWS_SESSION_TOKEN" \
     -e AWS_REGION="$AWS_REGION" \
     my-agent:arm64
   ```

### Create ECR repository and deploy
<a name="create-ecr-repository-and-deploy"></a>

<a name="create-ecr-repository-and-deploy"></a> **Deploying to ECR** 

1. Create an ECR repository:

   ```
   aws ecr create-repository --repository-name my-strands-agent --region us-west-2
   ```

1. Log in to ECR:

   ```
   aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin account-id.dkr.ecr.us-west-2.amazonaws.com
   ```

1. Build and push to ECR:

   ```
   docker buildx build --platform linux/arm64 -t account-id.dkr.ecr.us-west-2.amazonaws.com/my-strands-agent:latest --push.
   ```

1. Verify the image was pushed:

   ```
   aws ecr describe-images --repository-name my-strands-agent --region us-west-2
   ```

## Deploy agent runtime
<a name="deploy-agent-runtime"></a>

Create a file named `deploy_agent.py` with the following content:

 **Example deploy\$1agent.py** 

```
import boto3

client = boto3.client('bedrock-agentcore-control', region_name='us-west-2')

response = client.create_agent_runtime(
    agentRuntimeName='strands_agent',
    agentRuntimeArtifact={
        'containerConfiguration': {
            'containerUri': 'account-id.dkr.ecr.us-west-2.amazonaws.com/my-strands-agent:latest'
        }
    },
    networkConfiguration={"networkMode": "PUBLIC"},
    roleArn='arn:aws:iam::account-id:role/AgentRuntimeRole',
    lifecycleConfiguration={
        'idleRuntimeSessionTimeout': 300,  # 5 min, configurable
        'maxLifetime': 1800                # 30 minutes, configurable
    },
)

print(f"Agent Runtime created successfully!")
print(f"Agent Runtime ARN: {response['agentRuntimeArn']}")
print(f"Status: {response['status']}")
```

Run the script to deploy your agent:

```
uv run deploy_agent.py
```

This script uses the `create_agent_runtime` operation to deploy your agent to Amazon Bedrock AgentCore. Make sure to replace *account-id* with your actual AWS account ID and ensure the IAM role has the necessary permissions. For more information, see [IAM Permissions for AgentCore Runtime](runtime-permissions.md).

## Invoke your agent
<a name="invoke-your-agent"></a>

Create a file named `invoke_agent.py` with the following content:

 **Example invoke\$1agent.py** 

```
import boto3
import json

agent_core_client = boto3.client('bedrock-agentcore', region_name='us-west-2')
payload = json.dumps({
    "input": {"prompt": "Explain machine learning in simple terms"}
})

response = agent_core_client.invoke_agent_runtime(
    agentRuntimeArn='arn:aws:bedrock-agentcore:us-west-2:account-id:runtime/myStrandsAgent-suffix',
    runtimeSessionId='dfmeoagmreaklgmrkleafremoigrmtesogmtrskhmtkrlshmt',  # Must be 33+ chars
    payload=payload,
    qualifier="DEFAULT"
)

response_body = response['response'].read()
response_data = json.loads(response_body)
print("Agent Response:", response_data)
```

Run the script to invoke your agent:

```
uv run invoke_agent.py
```

This script uses the [InvokeAgentRuntime](https://docs.aws.amazon.com/bedrock-agentcore/latest/APIReference/API_InvokeAgentRuntime.html) AWS SDK operation to send a request to your deployed agent. Make sure to replace *account-id* and *agentArn* with your actual values.

If you plan on integrating your agent with OAuth, you can’t use the AWS SDK to call `InvokeAgentRuntime` . Instead, make a HTTPS request to InvokeAgentRuntime. For more information, see [Authenticate and authorize with Inbound Auth and Outbound Auth](runtime-oauth.md).

## Expected response format
<a name="expected-response-format"></a>

When you invoke your agent, you’ll receive a response like this:

 **Example Sample response** 

```
{
  "output": {
    "message": {
      "role": "assistant",
      "content": [
        {
          "text": "# Artificial Intelligence in Simple Terms\n\nArtificial Intelligence (AI) is technology that allows computers to do tasks that normally need human intelligence. Think of it as teaching machines to:\n\n- Learn from information (like how you learn from experience)\n- Make decisions based on what they've learned\n- Recognize patterns (like identifying faces in photos)\n- Understand language (like when I respond to your questions)\n\nInstead of following specific step-by-step instructions for every situation, AI systems can adapt to new information and improve over time.\n\nExamples you might use every day include voice assistants like Siri, recommendation systems on streaming services, and email spam filters that learn which messages are unwanted."
        }
      ]
    },
    "timestamp": "2025-07-13T01:48:06.740668"
  }
}
```

## Stop runtime session
<a name="stop-runtime-session"></a>

To stop the running session before the configurable `IdleRuntimeSessionTimeout` (defaulted at 15 minutes) and save on any potential runaway costs, execute: `stop_runtime_session` 

Create a file named `stop_runtime_session.py` with the following content:

 **Example stop\$1runtime\$1session.py** 

```
import boto3

agent_core_client = boto3.client('bedrock-agentcore', region_name='us-west-2')
response = agent_core_client.stop_runtime_session(
    agentRuntimeArn='arn:aws:bedrock-agentcore:us-west-2:account-id:runtime/myStrandsAgent-suffix',
    runtimeSessionId='dfmeoagmreaklgmrkleafremoigrmtesogmtrskhmtkrlshmt',
    qualifier="DEFAULT"
)
```

## Amazon Bedrock AgentCore requirements summary
<a name="bedrock-agentcore-runtime-requirements"></a>
+  **Platform** : Must be `linux/arm64` 
+  **Endpoints** : `/invocations` POST and `/ping` GET are mandatory
+  **ECR** : Images must be deployed to ECR
+  **Port** : Application runs on port 8080
+  **Strands Integration** : Uses Strands Agent for AI processing
+  **Credentials** : Strands agents require AWS credentials for operation

## Conclusion
<a name="conclusion"></a>

In this guide, you’ve learned how to:
+ Set up a development environment for building custom agents
+ Create a FastAPI application that implements the required endpoints
+ Containerize your agent for ARM64 architecture
+ Test your agent locally
+ Deploy your agent to ECR
+ Create an agent runtime in Amazon Bedrock AgentCore
+ Invoke your deployed agent
+ Stop agent runtime session

By following these steps, you can create and deploy custom agents that leverage the power of Amazon Bedrock AgentCore while maintaining full control over your agent’s implementation.

# Get started with Amazon Bedrock AgentCore Runtime direct code deployment
<a name="runtime-get-started-code-deploy"></a>

Direct code deployment enables you to bring your Python-based agent to Amazon Bedrock AgentCore Runtime simply by packaging agent code and its dependencies in a .zip file archive. Your agent still needs to follow [AgentCore Runtime requirements](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-service-contract.html) : have an entrypoint .py file that either uses the `@app.entrypoint` annotation from [Amazon Bedrock AgentCore Python SDK](https://github.com/aws/bedrock-agentcore-sdk-python) or implements `/invocations` POST and `/ping` GET server endpoints.

To create your deployment package as .zip file archive, you can use [AgentCore CLI](https://github.com/aws/agentcore-cli) or follow the steps in the *Custom zip \$1 boto3* tab below, or any other .zip file utility such as [7zip](https://www.7-zip.org/download.html) . The examples shown in the following sections assume you’re using a command-line `zip` tool in a Linux or MacOS environment. To use the same commands in Windows, you can [install the Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10) to get a Windows-integrated version of Ubuntu and Bash.

Note that AgentCore Runtime uses POSIX file permissions, so you may need to [set permissions for the deployment package folder](http://aws.amazon.com/premiumsupport/knowledge-center/lambda-deployment-package-errors/) before you create the .zip file archive.

**Topics**
+ [

## Prerequisites
](#prerequisites)
+ [

## Step 1: Set up project and install dependencies
](#step-1-setup)
+ [

## Step 2: Create your agent project
](#step-2-create-agent)
+ [

## Step 3: Test locally
](#step-3-test-locally)
+ [

## Step 4: Enable observability for your agent
](#step-4-enable-observability)
+ [

## Step 5: Deploy to AgentCore Runtime and invoke
](#step-5-deploy)
+ [

## Step 6: Stop session, update, or cleanup
](#step-6-update-cleanup)
+ [

## Direct code deployment concepts
](#runtime-code-deploy-concepts)
+ [

## Common Issues
](#common-issues-direct-code-deploy)

## Prerequisites
<a name="prerequisites"></a>

Before you start, make sure you have:
+  ** AWS Account** with credentials configured. To configure your AWS credentials, see [Configuration and credential file settings in the AWS CLI.](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html) 
+  [Uv](https://docs.astral.sh/uv/getting-started/installation/) **installed** and [Python 3.10\$1](https://docs.astral.sh/uv/guides/install-python/) installed
+  ** AWS Permissions** : To create and deploy an agent with the AgentCore CLI, you must have appropriate permissions. For information, see [Use the AgentCore CLI](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-permissions.html#runtime-permissions-cli).
+  **Model access** : Anthropic Claude Sonnet 4.0 [enabled](https://docs.aws.amazon.com/bedrock/latest/userguide/model-access-modify.html) in the Amazon Bedrock console. For information about using a different model with the Strands Agents see the *Model Providers* section in the [Strands Agents SDK](https://strandsagents.com/latest/documentation/docs/) documentation.

## Step 1: Set up project and install dependencies
<a name="step-1-setup"></a>

Initialize your project with the following commands:

```
uv init agentcore_runtime_direct_deploy --python 3.13
cd agentcore_runtime_direct_deploy
```

Add core packages:

```
uv add bedrock-agentcore strands-agents
```

Install the AgentCore CLI (required for the steps that follow):

```
npm install -g @aws/agentcore
```

Package descriptions:
+  **bedrock-agentcore** - The Amazon Bedrock AgentCore SDK for building AI agents
+  **strands-agents** - The [Strands Agents](https://strandsagents.com/latest/) SDK
+  **@aws/agentcore** - The AgentCore CLI

Optionally, run `uv add aws-opentelemetry-distro` to enable [Amazon Bedrock AgentCore observability traces](https://docs.aws.amazon.com/xray/latest/devguide/xray-services-adot.html).

Uv will automatically create a `pyproject.toml` file with dependencies, `uv.lock` file with dependency closure and `.venv` directory.

## Step 2: Create your agent project
<a name="step-2-create-agent"></a>

Use the `agentcore create` command to set up a skeleton agent project with the framework of your choice:

```
agentcore create
```

The command will prompt you to:
+ Choose a framework (choose Strands Agents for this tutorial)
+ Provide a project name
+ Choose a template (basic or production)
+ Choose model provider and other options

This command generates:
+ Agent code with your selected framework
+ A `pyproject.toml` file with necessary dependencies
+ An `agentcore/agentcore.json` configuration file
+ Infrastructure as Code (IaC) files if production template is selected

## Step 3: Test locally
<a name="step-3-test-locally"></a>

Make sure port 8080 is free before starting. See *Port 8080 in use (local only)* in [Common issues and solutions](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-get-started-cli.html#common-issues).

Open a terminal window and start your agent with the following command:

```
agentcore dev
```

Test your agent by opening another terminal window and enter the following command:

```
curl -X POST http://localhost:8080/invocations \
  -H "Content-Type: application/json" \
  -d '{"prompt": "Hello!"}'
```

 **Success:** You should see a response like `{"result": "Hello! I’m here to help…​"}` . In the terminal window that’s running the agent, enter `Ctrl+C` to stop the agent.

## Step 4: Enable observability for your agent
<a name="step-4-enable-observability"></a>

 [Amazon Bedrock AgentCore Observability](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability.html) helps you trace, debug, and monitor agents that you host in AgentCore Runtime. First enable CloudWatch Transaction Search by following the instructions at [Enabling Amazon Bedrock AgentCore runtime observability](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability-configure.html#observability-configure-builtin) . To observe your agent, see [View observability data for your Amazon Bedrock AgentCore agents](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability-view.html).

## Step 5: Deploy to AgentCore Runtime and invoke
<a name="step-5-deploy"></a>

Deploy your agent using one of the following methods:

**Example**  

1. The following steps will be required to deploy an agent to AgentCore Runtime, refer to [Get started with the AgentCore CLI](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-get-started-cli.html) , for detailed steps. If Uv is available, the AgentCore CLI will recommend direct code deployment. Otherwise it will default to container deployment type.

   Once you have your agent set up using `agentcore create` , use the `deploy` command to create a zip deployment package, upload it to the specified bucket, and deploy the agent.

   ```
   agentcore deploy
   ```

   Let’s prompt the agent to tell a joke\$1

   ```
   agentcore invoke "Tell me a joke"
   ```

   The first deployment takes time to install dependencies but subsequent updates to the agent optimizes this by re-using zipped dependencies

    **Configuration management** 

   You can modify your agent configuration at any time using the `agentcore add` commands or by editing the `agentcore/agentcore.json` configuration file directly.

   The configuration file allows you to update deployment parameters such as your VPC configuration, execution roles, session timeouts, and OAuth authorizer settings.

1. Run `agentcore` to open the TUI, then select **deploy** . The deploy screen shows real-time progress as it validates your project, synthesizes CloudFormation, and provisions AWS resources:  
![\[AgentCore deploy progress showing CloudFormation stack updates\]](http://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/images/tui/code-deploy-progress.png)

   After deployment completes, use `agentcore invoke` to test your agent.

1. To download a wheel that’s compatible with AgentCore Runtime, you use the uv pip `--python-platform` option. AgentCore Runtime only supports **arm64** instruction set architecture, run the following command. Replace `--python 3.x` with the version of the Python runtime you are using.

   ```
   uv pip install \
   --python-platform aarch64-manylinux2014 \
   --python-version 3.13 \
   --target=deployment_package \
   --only-binary=:all: \
   -r pyproject.toml
   ```

   Create a .zip file with the installed libraries at the project root.

   ```
   cd deployment_package
   zip -r ../deployment_package.zip.
   ```

   Add the `main.py` file and other files in your package to the root of the .zip file.

   ```
   cd ..
   zip deployment_package.zip main.py
   ```

   After you have created your .zip deployment package, you can use it to create a new AgentCore Runtime or update an existing one. You can deploy your .zip package using AgentCore Runtime API, AgentCore Runtime console and AWS Command Line Interface. The AgentCore CLI will take care of above steps to create .zip.
**Note**  
. The maximum size for a .zip deployment package for AgentCore Runtime is 250 MB (zipped) and 750 MB (unzipped). Note that this limit applies to the combined size of all the files you upload. . The AgentCore Runtime needs permission to read the files in your deployment package. In Linux permissions octal notation, AgentCore Runtime needs 644 permissions for non-executable files (rw-r—r--) and 755 permissions (rwxr-xr-x) for directories and executable files. . In Linux and MacOS, use the `chmod` command to change file permissions on files and directories in your deployment package. For example, to give a non-executable file the correct permissions, run the following command, `chmod 644 <filepath>` . To change file permissions in Windows, see [Set, View, Change, or Remove Permissions on an Object](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc731667(v=ws.10)) in the Microsoft Windows documentation. \$1 .. If you don’t grant AgentCore Runtime the permissions it needs to access directories in your deployment package, AgentCore Runtime sets the permissions for those directories to 755 (rwxr-xr-x).

   A ZIP archive containing Linux **arm64** dependencies needs to be uploaded to S3 as a pre-requisite to Create Agent Runtime. The below code requires the specified S3 bucket to already exist. Please follow the AWS documentation [here](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3/client/create_bucket.html) to create an bucket using boto3. Following boto3 code will upload .zip file archive to a s3 and create Amazon Bedrock AgentCore runtime.

   ```
   import boto3
   
   account_id = "your aws account id"
   agent_name = "strands_10_23"
   
   s3_client = boto3.client('s3', region_name='us-west-2')
   print("Uploading deployment.zip to S3...")
   s3_client.upload_file(
       'deployment_package.zip', # archive on file system
       f"bedrock-agentcore-code-{account_id}-us-west-2", # bucket name
       f"{agent_name}/deployment_package.zip", # prefix
       ExtraArgs={'ExpectedBucketOwner': account_id} # ownership check
   )
   print("Upload completed successfully!")
   print(f"S3 Location: s3://bedrock-agentcore-code-{account_id}-us-west-2/deployment_package.zip")
   
   agentcore_client = boto3.client('bedrock-agentcore-control', region_name='us-west-2')
   response = agentcore_client.create_agent_runtime(
       agentRuntimeName=agent_name,
       agentRuntimeArtifact={
           'codeConfiguration': {
               'code': {
                   's3': {
                       'bucket': f"bedrock-agentcore-code-{account_id}-us-west-2",
                       'prefix': f"{agent_name}/deployment_package.zip"
                   }
               },
               'runtime': 'PYTHON_3_13',
               'entryPoint': ['opentelemetry-instrument', 'main.py']
           } # if not adding otel dependency, remove opentelemetry-instrument from entrypoint array
       },
       networkConfiguration={"networkMode": "PUBLIC"},
       roleArn=f"arn:aws:iam::{account_id}:role/AmazonBedrockAgentCoreSDKRuntime-us-west-2",
       lifecycleConfiguration={
           'idleRuntimeSessionTimeout': 300,  # 5 min, configurable
           'maxLifetime': 1800                # 30 minutes, configurable
       },
   )
   print(f"Agent Runtime created successfully!")
   print(f"Agent Runtime ARN: {response['agentRuntimeArn']}")
   print(f"Status: {response['status']}")
   ```

   To invoke an agent on Amazon Bedrock AgentCore runtime using boto3, refer: [https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-get-started-cli.html\$1invoke-programmatically](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-get-started-cli.html#invoke-programmatically) 

1. You can deploy your agent using the Amazon Bedrock AgentCore console with managed runtime support. The console provides an intuitive interface for uploading ZIP files and configuring agent settings.

   To deploy using the console, first create your deployment package following the steps in the *Custom zip \$1 boto3* tab above.

    **Create agent through console** 

   To create your agent:

1. From the Agents home page, click **Host Agent** 

1. Choose your source selection:
   +  **S3 Source** - Upload from S3 bucket
   +  **Local Upload** - Upload ZIP file from your computer
   +  **Templates** - Use pre-built agent templates

1. Configure your agent settings:
   + Agent name
   + Runtime version (Python 3.13 recommended)
   + Entry point (e.g., `main.py` )
   + Execution role (create new or use existing)

1. Click **Create Agent** to deploy

    **Create endpoint** 

   Click **Create Endpoint** to create a new endpoint for your agent. The endpoint name and associated version will be pre-filled.

    **Test endpoint** 

   Select an endpoint and click **Test Endpoint** to navigate to the Playground/Sandbox for testing.

    **Execution role requirements** 

   Your agent requires an execution role with appropriate permissions. For detailed information about execution roles and permissions, see [AgentCore Runtime permissions](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-permissions.html) . The execution role must include basic Amazon Bedrock AgentCore runtime permissions, S3 access permissions for your deployment package, and CloudWatch Logs permissions for observability.

## Step 6: Stop session, update, or cleanup
<a name="step-6-update-cleanup"></a>

Stop your runtime session, update, or cleanup your agent using one of the following methods:

**Example**  

1. To update previously deployed AgentCore Runtime, execute:

   ```
   agentcore deploy
   ```

   To stop a running session before the configurable `IdleRuntimeSessionTimeout` (defaulted at 15 minutes) and save on any potential runaway costs, use the [StopRuntimeSession](https://docs.aws.amazon.com/bedrock-agentcore/latest/APIReference/API_StopRuntimeSession.html) API operation. The AgentCore CLI does not currently support stopping sessions directly.

   To delete all resources related to a AgentCore Runtime, first remove all resources and then deploy to tear down AWS resources:

   ```
   agentcore remove all
   agentcore deploy
   ```

1. Following boto3 code will update an AgentCore Runtime.

   ```
   import boto3
   
   account_id = "your aws account id"
   agent_name = "strands_10_23"
   
   s3_client = boto3.client('s3', region_name='us-west-2')
   print("Uploading deployment.zip to S3...")
   s3_client.upload_file(
       'deployment_package.zip', # archive on file system
       f"bedrock-agentcore-code-{account_id}-us-west-2", # bucket name
       f"{agent_name}/deployment_package.zip", # prefix
       ExtraArgs={'ExpectedBucketOwner': account_id} # ownership check
   )
   print("Upload completed successfully!")
   print(f"S3 Location: s3://bedrock-agentcore-code-{account_id}-us-west-2/deployment_package.zip")
   
   bedrock_agentcore_client = boto3.client('bedrock-agentcore-control', region_name='us-west-2')
   response = bedrock_agentcore_client.update_agent_runtime(
       agentRuntimeId='<your-agent-id>',
       agentRuntimeArtifact={
           'codeConfiguration': {
               'code': {
                   's3': {
                       'bucket': f"bedrock-agentcore-code-{account_id}-us-west-2",
                       'prefix': 'strands/deployment_package.zip'
                   }
               },
               'runtime': 'PYTHON_3_12',
               'entryPoint': ['opentelemetry-instrument', 'main.py']
           } # if not adding otel dependency, remove opentelemetry-instrument from entrypoint array
       },
       networkConfiguration={"networkMode": "PUBLIC"},
       roleArn=f"arn:aws:iam::{account_id}:role/AmazonBedrockAgentCoreSDKRuntime-us-west-2"
   )
   
   print(f"Agent Runtime updated successfully!")
   print(f"Agent Runtime ARN: {response['agentRuntimeArn']}")
   print(f"Status: {response['status']}")
   ```

   To stop the running session before the configurable `IdleRuntimeSessionTimeout` (defaulted at 15 minutes) and save on any potential runaway costs, use the following boto3 code:

   ```
   import boto3
   
   agent_core_client = boto3.client('bedrock-agentcore', region_name='us-west-2')
   response = agent_core_client.stop_runtime_session(
       agentRuntimeArn='arn:aws:bedrock-agentcore:us-west-2:account-id:runtime/agent-name-suffix',
       runtimeSessionId='your-session-id',
       qualifier="DEFAULT"
   )
   ```

   Following boto3 code will delete Amazon Bedrock AgentCore runtime and .zip archive file in s3.

   ```
   import boto3
   
   account_id = "your aws account id"
   agent_name = "strands_10_23"
   
   bedrock_agentcore_client = boto3.client('bedrock-agentcore-control', region_name='us-west-2')
   print("Deleting Agent from Amazon Bedrock AgentCore Runtime!")
   response = bedrock_agentcore_client.delete_agent_runtime(
       agentRuntimeId='<agent-id>'
   )
   print(f"Agent Runtime delete successfully!")
   print(f"Status: {response['status']}")
   
   s3_client = boto3.client('s3', region_name='us-west-2')
   print("Deleting deployment archive from S3...")
   s3_client.delete_object(
       Bucket=f"bedrock-agentcore-code-{account_id}-us-west-2",
       Key=f"{agent_name}/deployment_package.zip",
       ExpectedBucketOwner=account_id
   )
   print("Archive deleted successfully from S3!")
   ```

1. ====== Update agent

   From the Agent details page, click **Update hosting** to create a new version with updated code or configuration.

    **Update endpoint** 

   Select an endpoint from the Endpoints table and click **Edit** to update the description or associated version.

    **Delete endpoint** 

   Select an endpoint and click **Delete** . You’ll need to type "delete" to confirm the deletion.

    **Delete agent** 

   From the agent list or details page, select your agent and click **Delete** to remove the agent and all associated resources.

## Direct code deployment concepts
<a name="runtime-code-deploy-concepts"></a>

Learn about key concepts when using direct code deployment with Amazon Bedrock AgentCore Runtime.

**Topics**

### Shared responsibility model for direct code deployment
<a name="concept-shared-responsibility"></a>

Amazon Bedrock AgentCore Runtime with direct code deployment uses a shared responsibility model similar to AWS Lambda. AgentCore Runtime manages the Python runtime environment and applies security patches automatically, while you focus on your agent code and dependencies.

If you’re using [container images to deploy your agents](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/getting-started-custom.html) , then AgentCore Runtime is responsible to patch only compute kernel. In this case, you’re responsible for rebuilding your agent’s container image from the latest secure image and redeploying the container image.

This is summarized in the following table:


| Deployment mode | AgentCore Runtime’s responsibility | Your responsibility | 
| --- | --- | --- | 
|  Direct deploy mode  |  Publish new language runtime version containing the latest patches for language runtime. Apply language runtime patches to existing AgentCore Runtime direct deploy.  |  Update your agent code, including dependencies, to address any security vulnerabilities.  | 
|  Container image  |  Automatically patch underlying compute OS kernel with latest version.  |  Update your agent code, including dependencies, to address any security vulnerabilities. Regularly re-build and re-deploy your container image using the latest base image.  | 

For more information about shared responsibility with AWS, see [Shared Responsibility Model](https://aws.amazon.com/compliance/shared-responsibility-model/).

AgentCore Runtime keeps each direct code deploy runtime up to date with security updates, bug fixes, new features, performance enhancements, and support for minor version releases. These runtime updates are published as *runtime versions* . AgentCore Runtime applies direct code deploy runtime updates to agents by migrating the agents from an earlier runtime version to a new runtime version.

For direct deploy runtimes, AgentCore Runtime applies runtime updates automatically. With automatic runtime updates, AgentCore Runtime takes on the operational burden of patching the runtime versions. For most customers, this should be a safe choice as only language runtime patches will be automatically applied and customers are responsible to bring and managed their code dependencies. Currently AgentCore Runtime doesn’t support changing this automated patching behavior.

AgentCore Runtime strives to provide runtime updates that are backward compatible with existing functions. However, as with software patching, there are rare cases in which a runtime update can negatively impact an existing function. For example, security patches can expose an underlying issue with an existing function that depends on the previous, insecure behavior. If in extremely rare cases this risk is not acceptable, please use [container images to deploy your agent](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/getting-started-custom.html).

### Supported language runtimes and deprecation policy
<a name="concept-supported-runtimes"></a>

The following table lists the supported AgentCore Runtime direct code deploy language runtimes and projected deprecation dates. After a language environment is deprecated, you’re still able to create and update functions for a limited period. The table provides the currently forecasted dates for runtime deprecation, based on our [Runtime deprecation policy](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html#runtime-support-policy) . These dates are provided for planning purposes and are subject to change.


| \$1 | Name | Identifier | Operating system | Deprecation date | Block function update | 
| --- | --- | --- | --- | --- | --- | 
|  1  |  Python 3.14  |   `PYTHON_3_14`   |  Amazon Linux 2023  |  6/30/2030  |  8/31/2030  | 
|  2  |  Python 3.13  |   `PYTHON_3_13`   |  Amazon Linux 2023  |  6/30/2029  |  8/31/2029  | 
|  3  |  Python 3.12  |   `PYTHON_3_12`   |  Amazon Linux 2023  |  10/31/2028  |  1/10/2029  | 
|  4  |  Python 3.11  |   `PYTHON_3_11`   |  Amazon Linux 2023  |  6/30/2026  |  8/31/2026  | 
|  5  |  Python 3.10  |   `PYTHON_3_10`   |  Amazon Linux 2023  |  6/30/2026  |  8/31/2026  | 

<a name="deprecation-policy"></a>==== Language environment deprecation policy

AgentCore Runtime direct code deploy for .zip file archives are built around a combination of operating system, programming language, and software libraries that are subject to maintenance and security updates. AgentCore Runtime standard deprecation policy is to deprecate a language runtime when any major component of the runtime reaches the end of community long-term support (LTS) and security updates are no longer available. Most usually, this is the language runtime, though in some cases, a runtime can be deprecated because the operating system (OS) reaches end of LTS.

After a runtime is deprecated, AWS may no longer apply security patches or updates to that runtime, and functions using that runtime are no longer eligible for technical support. Such deprecated runtimes are provided 'as-is', without any warranties, and may contain bugs, errors, defects, or other vulnerabilities.

**Important**  
AgentCore Runtime occasionally delays deprecation of a AgentCore Runtime direct code deploy programming language runtime for a limited period beyond the end of support date of the language version that the runtime supports. During this period, AgentCore Runtime only applies security patches to the runtime OS. AgentCore Runtime doesn’t apply security patches to programming language runtimes after they reach their end of support date.

### Container vs direct code deployment comparison
<a name="concept-container-vs-direct"></a>

Some of the dimensions of comparison to see how one option differs from the other, so it helps to choose the right option
+  **Deployment Process** : Direct code deployment deploys agents using ZIP files instead of containers, lending itself to faster development iterations.
+  **Deployment time** : Although there is not much difference during first deployment of an agent, subsequent updates to the agent are significantly faster with direct code deployment.
+  **Customization** : Direct code supports for custom dependencies through ZIP-based packaging while maintaining deployment simplicity while container based depends on a Docker file.
+  **Package size** : Direct code deployment limits the package size to 250MB whereas container based packages can be upto 1GB in size.
+  **Session creation rate** : The direct code deployment allows for higher session creation of 25 new sessions/second compared to 0.16 new sessions/second with container based deployments.

Our general guidance is
+ If the size of the deployment package exceeds 250MB, and you have existing container CI/CD pipelines, and you need highly specialized dependencies and packaging, then container based deployments is a good option to choose.
+ If the size of the deployment package is small, the code and package is not complex to build and uses common frameworks and languages, and you need rapid prototyping and iteration, then direct code deployment would be the option.

There can also be a hybrid option where developers use the direct code deployment to quickly experiment and prototype agents and then switch to container based deployments (for the above reasons) to develop, test and deploy to production.

### Dependency search path and runtime-included libraries
<a name="concept-dependency-search"></a>

When you use an `import` statement in your code, the Python runtime searches the directories in its search path until it finds the module or package. By default, the first location the runtime searches is the directory into which your .zip deployment package is decompressed and mounted ( `/var/task` ).

You can see the full search path for your AgentCore Runtime agent by adding the following code snippet.

```
import sys
search_path = sys.path
print(search_path)
```

You can also add dependencies in a separate folder inside your .zip package. For example, you might add a version of the Boto3 SDK to a folder in your .zip package called `common` . When your .zip package is decompressed and mounted, this folder is placed inside the `/var/task` directory. To use a dependency from a folder in your .zip deployment package in your code, use an `import from` statement. For example, to use a version of Boto3 from a folder named `common` in your .zip package, use the following statement.

```
from common import boto3
```

### Python bytecode and *pycache* folders
<a name="concept-pycache"></a>

We recommend that you don’t include ` pycache ` folders in your agent’s deployment package. Python bytecode that’s compiled on a build machine with a different architecture or operating system might not be compatible with the AgentCore Runtime execution environment.

### Deployment packages with native libraries
<a name="concept-native-libraries"></a>

If your function uses only pure Python packages and modules, you can use the `uv pip install` command to install your dependencies on any local build machine and create your .zip file. Many popular Python libraries, including NumPy and Pandas, are not pure Python and contain code written in C or C. When you add libraries containing C/C code to your deployment package, you must build your package correctly to make it compatible with the AgentCore Runtime execution environment.

Most packages available on the Python Package Index ( [PyPI](https://pypi.org/) ) are available as "wheels" (.whl files). A .whl file is a type of ZIP file which contains a built distribution with pre-compiled binaries for a particular operating system and instruction set architecture. To make your deployment package compatible with Amazon Bedrock AgentCore AgentCore Runtime, you install the wheel for Linux operating systems and **arm64** instruction set architecture.

Some packages may only be available as source distributions. For these packages, you need to compile and build the C/C\$1\$1 components yourself.

To see what distributions are available for your required package, do the following:

1. Search for the name of the package on the [Python Package Index main page](https://pypi.org/).

1. Choose the version of the package you want to use.

1. Choose **Download files**.

### Working with source distributions
<a name="concept-source-distributions"></a>

If your package is only available as a source distribution, you need to build the C/C\$1\$1 libraries yourself. To make your package compatible with the Amazon Bedrock AgentCore AgentCore Runtime execution environment, you need to build it in an environment that uses the same Amazon Linux operating system with **arm64** instruction set. You can do this by building your package in an Amazon Elastic Compute Cloud (Amazon EC2) Linux instance.

To learn how to launch and connect to an Amazon EC2 Linux instance, see [Get started with Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EC2_GetStarted.html) in the *Amazon EC2 User Guide*.

## Common Issues
<a name="common-issues-direct-code-deploy"></a>

Common issues and solutions when getting started with Amazon Bedrock AgentCore direct code deployment. For more troubleshooting information, see [Troubleshoot Amazon Bedrock AgentCore AgentCore Runtime](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-troubleshooting.html).

### Permission Issues - Insufficient S3 permissions
<a name="permission-issues-s3"></a>

 **When this occurs:** During agent creation or update with zipped artifact in S3 via console, SDK, or CLI

 **Why this happens:** The role used to call Create/UpdateAgentRuntime does not have s3:GetObject permissions on S3 uri passed in the API input.

 **Solution:** Add s3:GetObject permission in role used to call the Agentcore Runtime create/update API.

```
{
"Version": "2012-10-17",		 	 	 
  "Statement": [
    {
        "Effect": "Allow",
        "Action": "s3:GetObject",
        "Resource": "arn:aws:s3:::your-bucket-name/*"
    }
  ]
}
```

### Permission Issues - CMK Encrypted S3 Object Access
<a name="permission-issues-cmk"></a>

 **When this occurs:** During agent creation with CMK-encrypted S3 objects when the execution role lacks KMS decrypt permissions.

 **Why this happens:** The role used to call Create/UpdateAgentRuntime does not have kms:Decrypt permissions on the CMK used to encrypt the S3 object containing the agent code.

 **Solution:** Add kms:Decrypt permission to the role for the specific CMK:

```
{
"Version": "2012-10-17",		 	 	 
  "Statement": [
    {
        "Effect": "Allow",
        "Action": [
            "s3:GetObject",
            "kms:Decrypt"
        ],
        "Resource": [
            "arn:aws:s3:::your-bucket-name/*",
            "arn:aws:kms:us-west-2:your-account:key/your-cmk-key-id"
        ]
    }
  ]
}
```

### Code Package Compatibility Issues
<a name="code-package-compatibility"></a>

 **When this occurs:** During agent creation or update with incompatible code packages (wrong architecture, Python version, or package format).

 **Why this happens:** The uploaded ZIP file contains binaries compiled for wrong architecture (ARM64 vs x86\$164), incompatible Python version, or incorrect package structure that doesn’t match AgentCore Runtime requirements.

 **Solution:** 
+ Ensure code is compiled for arm64
+ Use compatible Python version (check AgentCore Runtime supported versions)
+ Verify ZIP structure contains proper entry points and dependencies
+ Rebuild packages on compatible runtime environment

 **Error indicators:** 
+ Agent status: CREATE\$1FAILED or runtime errors
+ Import errors or "cannot execute binary file" messages in cloudwatch logs
+ Architecture mismatch errors when you do getAgentRuntimeEndpoint.

# Get started with bidirectional streaming using WebSocket
<a name="runtime-get-started-websocket"></a>

Amazon Bedrock AgentCore Runtime lets you deploy agents that support WebSocket streaming for real-time bidirectional communication. This guide walks you through creating, testing, and deploying your first bidirectional streaming agent using WebSocket.

In this section, you learn:
+ How AgentCore Runtime supports WebSocket connections
+ How to create an agent application with bidirectional streaming capabilities
+ How to test your agent locally
+ How to deploy your agent to AWS 
+ How to invoke your deployed agent
+ How to use sessions with WebSocket connections

For more information about the WebSocket protocol, see [WebSocket RFC 6455](https://tools.ietf.org/html/rfc6455).

**Topics**
+ [

## How AgentCore Runtime supports WebSocket connections
](#websocket-support-overview)
+ [

## Using WebSocket with AgentCore Runtime
](#using-websocket-with-runtime)
+ [

## Session management
](#websocket-session-management)
+ [

## Observability
](#websocket-observability)
+ [

## Custom Headers
](#websocket-custom-headers)
+ [

## Appendix
](#websocket-appendix)

## How AgentCore Runtime supports WebSocket connections
<a name="websocket-support-overview"></a>

AgentCore Runtime’s WebSocket support enables persistent, bidirectional streaming connections between clients and agents. AgentCore Runtime expects containers to implement WebSocket endpoints on port `8080` at the `/ws` path, which aligns with standard WebSocket server practices.

AgentCore Runtime’s WebSocket support provides the same serverless, session isolation, identity, and observability capabilities as `InvokeAgentRuntime` . Additionally, it enables low-latency, real-time bidirectional streaming of messages through WebSocket connections using SigV4 or OAuth 2.0 authentication, making it ideal for applications such as real-time conversational voice agents.

### Supported WebSocket libraries
<a name="websocket-supported-libraries"></a>

Bidirectional streaming using WebSockets on AgentCore Runtime supports applications using any WebSocket language library. The only requirements are that clients connect to the service endpoint with a WebSocket protocol connection:

```
wss://bedrock-agentcore.<region>.amazonaws.com/runtimes/<agentRuntimeArn>/ws
```

using one of the supported authentication methods (SigV4 headers, SigV4 pre-signed URL, or OAuth 2.0) and that the agent application implements the WebSocket service contract as specified in [HTTP protocol contract](runtime-http-protocol-contract.md).

This flexibility allows you to use your preferred WebSocket implementation across different programming languages and frameworks, ensuring compatibility with existing codebases and development workflows.

## Using WebSocket with AgentCore Runtime
<a name="using-websocket-with-runtime"></a>

In this getting started tutorial you will create, test, and deploy an agent application that supports bidirectional streaming using the **bedrock-agentcore Python SDK** and the **AgentCore CLI** for deployment.

**Topics**
+ [

### Prerequisites
](#websocket-prerequisites)
+ [

### Step 1: Set up project and install dependencies
](#setup-websocket-project)
+ [

### Step 2: Create your bidirectional streaming agent
](#create-websocket-agent)
+ [

### Step 3: Test your bidirectional streaming agent locally
](#step-2-test-websocket-locally)
+ [

### Step 4: Deploy your bidirectional streaming agent to AgentCore Runtime
](#step-3-deploy-websocket-to-aws)
+ [

### Step 5: Invoke your deployed bidirectional streaming agent
](#step-4-invoke-deployed-websocket)

### Prerequisites
<a name="websocket-prerequisites"></a>

Before you start, make sure you have:
+  ** AWS Account** with credentials configured. To configure your AWS credentials, see [Configuration and credential file settings in the AWS CLI.](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html) 
+  **Python 3.10\$1** installed
+  ** AWS Permissions** : To create and deploy an agent with the AgentCore CLI, you must have appropriate permissions. For more information, see [Use the AgentCore CLI](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-permissions.html#runtime-permissions-cli).

### Step 1: Set up project and install dependencies
<a name="setup-websocket-project"></a>

Create a project folder and install the required packages:

```
mkdir agentcore-runtime-quickstart-websocket
cd agentcore-runtime-quickstart-websocket
python3 -m venv .venv
source .venv/bin/activate
```

Upgrade pip to the latest version:

```
pip install --upgrade pip
```

Install the following required packages:
+  **bedrock-agentcore** - The Amazon Bedrock AgentCore SDK for building AI agents, the python `websockets` library dependency is included

```
pip install bedrock-agentcore
```

### Step 2: Create your bidirectional streaming agent
<a name="create-websocket-agent"></a>

Create a source file for your bidirectional streaming agent code named `websocket_echo_agent.py` . Add the following code:

#### Bidirectional streaming agent implementation (websocket\$1echo\$1agent.py)
<a name="websocket-agent-code"></a>

```
from bedrock_agentcore import BedrockAgentCoreApp

app = BedrockAgentCoreApp()

@app.websocket
async def websocket_handler(websocket, context):
    """Simple echo WebSocket handler."""
    await websocket.accept()

    try:
        data = await websocket.receive_json()
        # Echo back
        await websocket.send_json({"echo": data})
    except Exception as e:
        print(f"Error: {e}")
    finally:
        await websocket.close()

if __name__ == "__main__":
    app.run(log_level="info")
```

Create `requirements.txt` and add the following:

```
bedrock-agentcore
```

The python `websockets` library dependency is included

#### Understanding the code
<a name="understanding-websocket-code"></a>
+  **BedrockAgentCoreApp** : Creates an agent application that extends Starlette for AI agent deployment, providing WebSocket support, HTTP routing, middleware, and exception handling capabilities
+  **WebSocket Decorator** : The `@app.websocket` decorator automatically handles connections at the `/ws` path on port 8080
+  **Echo Logic** : Sends back received data using `{"echo": data}` 
+  **Error Handling** : Uses try/except/finally structure to ensure proper error logging and graceful connection closure.

### Step 3: Test your bidirectional streaming agent locally
<a name="step-2-test-websocket-locally"></a>

#### Start your bidirectional streaming agent
<a name="start-websocket-server"></a>

Open a terminal window and start your bidirectional streaming agent with the following command:

```
python websocket_echo_agent.py
```

You should see output indicating the server is running on port 8080.

#### Test WebSocket connection
<a name="test-websocket-connection"></a>

Create a local WebSocket client named `websocket_agent_client.py` :

##### Local WebSocket client (websocket\$1agent\$1client.py)
<a name="websocket-test-client"></a>

```
import asyncio
import websockets
import json

async def local_websocket():
    uri = "ws://localhost:8080/ws"

    try:
        async with websockets.connect(uri) as websocket:
            # Send a message
            await websocket.send(json.dumps({"inputText": "Hello WebSocket!"}))

            # Receive the echo response
            response = await websocket.recv()
            print(f"Received: {response}")
    except Exception as e:
        print(f"Connection failed: {e}")

if __name__ == "__main__":
    asyncio.run(local_websocket())
```

Test your bidirectional streaming agent locally by opening another terminal window and running the client:

```
python websocket_agent_client.py
```

 **Success:** You should see a response like `Received: {"echo":{"inputText":"Hello WebSocket!"}}` . In the terminal window that’s running the agent, enter `Ctrl+C` to stop the agent.

### Step 4: Deploy your bidirectional streaming agent to AgentCore Runtime
<a name="step-3-deploy-websocket-to-aws"></a>

#### Install deployment tools
<a name="install-deployment-tools"></a>

Install the AgentCore CLI:

```
npm install -g @aws/agentcore
```

Verify installation:

```
agentcore --help
```

#### Create project and deploy to AWS
<a name="configure-and-deploy"></a>

Create a new project for your bidirectional streaming agent:

```
agentcore create
```

Deploy your agent:

```
agentcore deploy
```

**Note**  
Run these commands from your project directory ( `agentcore-runtime-quickstart-websocket` ) where your agent files are located.

After deployment, you’ll receive an agent runtime ARN that looks like:

```
arn:aws:bedrock-agentcore:us-west-2:accountId:runtime/websocket_echo_agent-xyz123
```

Save this ARN as you’ll need it to invoke your deployed agent.

### Step 5: Invoke your deployed bidirectional streaming agent
<a name="step-4-invoke-deployed-websocket"></a>

#### Set up environment variables
<a name="setup-environment-variables"></a>

Set up the required environment variables:

1. Export your agent ARN:

   ```
   export AGENT_ARN="arn:aws:bedrock-agentcore:us-west-2:accountId:runtime/websocket_echo_agent-xyz123"
   ```

1. If using OAuth, export your bearer token:

   ```
   export BEARER_TOKEN="your_oauth_token_here"
   ```

#### Authentication methods
<a name="websocket-authentication-methods"></a>

The `InvokeAgentRuntimeWithWebSocketStream` API action establishes a WebSocket connection that supports bidirectional streaming between the client and agent. You can authenticate WebSocket connections using the following methods:
+  ** AWS Signature Version 4 headers** : Sign the WebSocket handshake request headers using your AWS credentials
+  ** AWS Signature Version 4 Pre-signed URL** : Create a presigned WebSocket URL with SigV4 signature provided as query parameters
+  **OAuth Bearer token** : Pass an OAuth token in the Authorization header for external identity provider integration

**Tip**  
Make sure that you have `bedrock-agentcore:InvokeAgentRuntimeWithWebSocketStream` permissions.

#### Connect using SigV4 signed headers
<a name="websocket-sigv4-headers"></a>

The following example shows how to establish a WebSocket connection and communicate with an agent runtime using SigV4 signed headers:

##### WebSocket client with SigV4 headers (websocket\$1agent\$1client\$1sigv4\$1headers.py)
<a name="websocket-sigv4-example"></a>

```
from bedrock_agentcore.runtime import AgentCoreRuntimeClient
import websockets
import asyncio
import json
import os

async def main():
    # Get runtime ARN from environment variable
    runtime_arn = os.getenv('AGENT_ARN')
    if not runtime_arn:
        raise ValueError("AGENT_ARN environment variable is required")

    # Initialize client
    client = AgentCoreRuntimeClient(region="us-west-2")

    # Generate WebSocket connection with authentication
    ws_url, headers = client.generate_ws_connection(
        runtime_arn=runtime_arn
    )

    try:
        async with websockets.connect(ws_url, additional_headers=headers) as ws:
            # Send message
            await ws.send(json.dumps({"inputText": "Hello!"}))

            # Receive response
            response = await ws.recv()
            print(f"Received: {response}")
    except websockets.exceptions.InvalidStatus as e:
        print(f"WebSocket handshake failed with status code: {e.response.status_code}")
        print(f"Response headers: {e.response.headers}")
        print(f"Response body: {e.response.body.decode()}")
    except Exception as e:
        print(f"Connection failed: {e}")

if __name__ == "__main__":
    asyncio.run(main())
```

Run the client to test your deployed agent:

```
python websocket_agent_client_sigv4_headers.py
```

 **Success:** You should see a response like:

```
Received: {"echo":{"inputText":"Hello!"}}
```

#### Connect using pre-signed URL (SigV4 via query parameters)
<a name="websocket-sigv4-presigned"></a>

The following example shows how to create a WebSocket URL with SigV4 query parameters and establish a connection:

##### WebSocket client with pre-signed URL (websocket\$1agent\$1client\$1sigv4\$1presigned\$1url.py)
<a name="websocket-presigned-example"></a>

```
from bedrock_agentcore.runtime import AgentCoreRuntimeClient
import websockets
import asyncio
import json
import os

async def main():
    runtime_arn = os.getenv('AGENT_ARN')
    if not runtime_arn:
        raise ValueError("AGENT_ARN environment variable is required")

    client = AgentCoreRuntimeClient(region="us-west-2")

    # Generate WebSocket pre-signed URL (with SigV4 via query parameters)
    # wss://...amazonaws.com/runtimes/.../ws?X-Amz-Algorithm=AWS4-HMAC-SHA256
    #   &X-Amz-Credential=...&X-Amz-Date=...&X-Amz-Expires=300
    #   &X-Amz-SignedHeaders=...&X-Amz-Signature=...
    sigv4_url = client.generate_presigned_url(
        runtime_arn=runtime_arn,
        expires=300  # 5 minutes
    )

    try:
        async with websockets.connect(sigv4_url) as ws:
            await ws.send(json.dumps({"inputText": "Hello!"}))
            response = await ws.recv()
            print(f"Received: {response}")
    except websockets.exceptions.InvalidStatus as e:
        print(f"WebSocket handshake failed with status code: {e.response.status_code}")
        print(f"Response headers: {e.response.headers}")
        print(f"Response body: {e.response.body.decode()}")
    except Exception as e:
        print(f"Connection failed: {e}")

if __name__ == "__main__":
    asyncio.run(main())
```

Run the client to test your deployed agent:

```
python websocket_agent_client_sigv4_query_parameters.py
```

 **Success:** You should see a response like:

```
Received: {"echo":{"inputText":"Hello!"}}
```

#### Connect using OAuth
<a name="websocket-oauth"></a>

AgentCore Runtime supports OAuth Bearer token authentication for WebSocket connections. To use OAuth authentication, you need to configure your agent runtime with JWT authorization as described in the [JWT inbound authorization and OAuth outbound access sample](runtime-oauth.md#oauth-sample-overview) section of [Authenticate and authorize with Inbound Auth and Outbound Auth](runtime-oauth.md).

Once you have completed the OAuth setup and obtained a bearer token following [Step 4: Use bearer token to invoke your agent](runtime-oauth.md#oauth-invoke-agent) in the OAuth guide, you can use that token to establish WebSocket connections.

##### Python client with OAuth
<a name="websocket-oauth-python"></a>

The following example shows how to establish a WebSocket connection from Python using OAuth:

##### WebSocket client with OAuth authentication (websocket\$1agent\$1client\$1oauth.py)
<a name="websocket-oauth-example"></a>

```
from bedrock_agentcore.runtime import AgentCoreRuntimeClient
import websockets
import asyncio
import json
import os

async def main():
    # Get runtime ARN from environment variable
    runtime_arn = os.getenv('AGENT_ARN')
    if not runtime_arn:
        raise ValueError("AGENT_ARN environment variable is required")

    # Get OAuth bearer token from environment variable
    bearer_token = os.getenv('BEARER_TOKEN')
    if not bearer_token:
        raise ValueError("BEARER_TOKEN environment variable required for OAuth")

    # Initialize client
    client = AgentCoreRuntimeClient(region="us-west-2")

    # Generate WebSocket connection with OAuth
    ws_url, headers = client.generate_ws_connection_oauth(
        runtime_arn=runtime_arn,
        bearer_token=bearer_token
    )

    try:
        async with websockets.connect(ws_url, additional_headers=headers) as ws:
            # Send message
            await ws.send(json.dumps({"inputText": "Hello!"}))

            # Receive response
            response = await ws.recv()
            print(f"Received: {response}")
    except websockets.exceptions.InvalidStatus as e:
        print(f"WebSocket handshake failed with status code: {e.response.status_code}")
        print(f"Response headers: {e.response.headers}")
        print(f"Response body: {e.response.body.decode()}")
    except Exception as e:
        print(f"Connection failed: {e}")

if __name__ == "__main__":
    asyncio.run(main())
```

Run the client to test your deployed agent:

```
python websocket_agent_client_oauth.py
```

 **Success:** You should see a response like:

```
Received: {"echo":{"inputText":"Hello!"}}
```

##### Browser JavaScript client with OAuth
<a name="websocket-oauth-browser"></a>

The browser’s native WebSocket API does not provide a method to set custom headers during the handshake. To support OAuth authentication from browsers, AgentCore Runtime accepts the bearer token embedded in the `Sec-WebSocket-Protocol` header during the WebSocket handshake.

The token must be base64url-encoded and prefixed with `base64UrlBearerAuthorization.` , followed by the sentinel subprotocol `base64UrlBearerAuthorization`.

The following example shows how to establish a WebSocket connection from browser JavaScript using OAuth:

##### Browser WebSocket client with OAuth (index.html)
<a name="websocket-oauth-browser-example"></a>

```
<!DOCTYPE html>
<html>
<body>
    <button onclick="connect()">Connect</button>
    <div id="output"></div>

    <script>
        function connect() {
            const bearerToken = "your_oauth_token_here";
            const runtimeArn = "arn:aws:bedrock-agentcore:us-west-2:accountId:runtime/agent-xyz123";

            // Base64url encode token
            const base64url = btoa(bearerToken)
                .replace(/\+/g, '-')
                .replace(/\//g, '_')
                .replace(/=/g, '');

            const ws = new WebSocket(
                `wss://bedrock-agentcore.us-west-2.amazonaws.com/runtimes/${runtimeArn}/ws`,
                [`base64UrlBearerAuthorization.${base64url}`, "base64UrlBearerAuthorization"]
            );

            ws.onopen = () => ws.send(JSON.stringify({ inputText: "Hello!" }));
            ws.onmessage = (e) => document.getElementById("output").innerText = e.data;
        }
    </script>
</body>
</html>
```

**Note**  
This authentication method is for browser-based clients where setting custom headers is not possible. For non-browser clients (Python, Node.js servers, etc.), use OAuth header authentication shown in [Python client with OAuth](#websocket-oauth-python).

**Note**  
Subprotocols other than `base64UrlBearerAuthorization` are not yet supported.

**Important**  
This is a reference example. It is not recommended to hardcode tokens in production code.

## Session management
<a name="websocket-session-management"></a>

Providing a `session_id` ( `X-Amzn-Bedrock-AgentCore-Runtime-Session-Id` ) on the WebSocket connection (as either a URL query parameter or request header) routes the connection to an isolated runtime session. The agent can access conversation context stored within that session, to implement continuity for a conversation by referencing previous interactions. Different session IDs access separate isolated contexts, ensuring complete isolation between users or conversations.

For comprehensive session lifecycle management including tracking, cleanup, and error handling, see [Use isolated sessions for agents](runtime-sessions.md).

### Using sessions with WebSocket connections
<a name="websocket-with-sessions"></a>

To use sessions with WebSocket connections, generate a unique session ID for each user or conversation and pass it when establishing the connection:

**Example**  

1. 

   ```
   from bedrock_agentcore.runtime import AgentCoreRuntimeClient
   import websockets
   import asyncio
   import json
   import os
   
   async def websocket_with_session():
       client = AgentCoreRuntimeClient(region="us-west-2")
       session_id = "user-123-conversation-456"
       runtime_arn = os.getenv('AGENT_ARN')
   
       ws_url, headers = client.generate_ws_connection(
           runtime_arn=runtime_arn,
           session_id=session_id
       )
   
       try:
           async with websockets.connect(ws_url, additional_headers=headers) as ws:
               await ws.send(json.dumps({"inputText": "Hello!"}))
               response = await ws.recv()
               print(f"Response: {response}")
       except websockets.exceptions.InvalidStatus as e:
           print(f"WebSocket handshake failed with status code: {e.response.status_code}")
           print(f"Response headers: {e.response.headers}")
           print(f"Response body: {e.response.body.decode()}")
       except Exception as e:
           print(f"Connection failed: {e}")
   
   asyncio.run(websocket_with_session())
   ```

1. 

   ```
   from bedrock_agentcore.runtime import AgentCoreRuntimeClient
   import websockets
   import asyncio
   import json
   import os
   
   async def websocket_with_session():
       client = AgentCoreRuntimeClient(region="us-west-2")
       session_id = "user-123-conversation-456"
       runtime_arn = os.getenv('AGENT_ARN')
   
       presigned_url = client.generate_presigned_url(
           runtime_arn=runtime_arn,
           session_id=session_id,
           expires=300
       )
   
       try:
           async with websockets.connect(presigned_url) as ws:
               await ws.send(json.dumps({"inputText": "Hello!"}))
               response = await ws.recv()
               print(f"Response: {response}")
       except websockets.exceptions.InvalidStatus as e:
           print(f"WebSocket handshake failed with status code: {e.response.status_code}")
           print(f"Response headers: {e.response.headers}")
           print(f"Response body: {e.response.body.decode()}")
       except Exception as e:
           print(f"Connection failed: {e}")
   
   asyncio.run(websocket_with_session())
   ```

1. 

   ```
   from bedrock_agentcore.runtime import AgentCoreRuntimeClient
   import websockets
   import asyncio
   import json
   import os
   
   async def websocket_with_session():
       client = AgentCoreRuntimeClient(region="us-west-2")
       session_id = "user-123-conversation-456"
       runtime_arn = os.getenv('AGENT_ARN')
       bearer_token = os.getenv('BEARER_TOKEN')
   
       ws_url, headers = client.generate_ws_connection_oauth(
           runtime_arn=runtime_arn,
           session_id=session_id,
           bearer_token=bearer_token
       )
   
       try:
           async with websockets.connect(ws_url, additional_headers=headers) as ws:
               await ws.send(json.dumps({"inputText": "Hello!"}))
               response = await ws.recv()
               print(f"Response: {response}")
       except websockets.exceptions.InvalidStatus as e:
           print(f"WebSocket handshake failed with status code: {e.response.status_code}")
           print(f"Response headers: {e.response.headers}")
           print(f"Response body: {e.response.body.decode()}")
       except Exception as e:
           print(f"Connection failed: {e}")
   
   asyncio.run(websocket_with_session())
   ```

**Tip**  
For best results, use a UUID or other unique identifier for your session IDs to avoid collisions between different users or conversations.

By using the same session ID for related WebSocket connections, you ensure that context is maintained across the same conversation, allowing your agent to provide coherent responses that build on previous interactions.

### Session lifecycle with WebSocket connections
<a name="websocket-session-lifecycle"></a>

For WebSocket connections, the session’s idle timeout is reset each time there is message activity between the client and agent. This includes any WebSocket message exchange such as sending data from client to agent, receiving responses from agent to client, or WebSocket ping/pong frames. This means that active WebSocket conversations will keep the session alive as long as messages continue to flow, preventing premature session termination during ongoing interactions.

For more information about configuring lifecycle settings, see [Configure Amazon Bedrock AgentCore lifecycle settings](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-lifecycle-settings.html) . For more direct control of session lifecycle through agent health status, see [Runtime session lifecycle management](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-long-run.html#runtime-long-run-session-lifecycle).

### Stop runtime session
<a name="websocket-stop-session"></a>

To stop a running session before the configurable `IdleRuntimeSessionTimeout` (defaulted at 15 minutes), see [Stop a running session](runtime-stop-session.md).

## Observability
<a name="websocket-observability"></a>

 [Amazon Bedrock AgentCore Observability](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability.html) helps you trace, debug, and monitor agents that you host in Amazon Bedrock AgentCore Runtime. First enable CloudWatch Transaction Search by following the instructions at [Enabling Amazon Bedrock AgentCore runtime observability](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability-configure.html#observability-configure-builtin) . To observe your agent, see [View observability data for your Amazon Bedrock AgentCore agents](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability-view.html).

For WebSocket connections, a trace represents the complete connection session rather than individual message exchanges.

## Custom Headers
<a name="websocket-custom-headers"></a>

Custom headers let you pass contextual information from your application directly to your agent code on the initial WebSocket connection. For complete information about custom header support, configuration, and limitations, see [Pass custom headers to Amazon Bedrock AgentCore Runtime](runtime-header-allowlist.md).

Additionally, headers prefixed with `X-Amzn-Bedrock-AgentCore-Runtime-Custom-` can be passed as URL query parameters in WebSocket connections.

For example, you can pass custom headers as query parameters in the WebSocket URL:

```
wss://bedrock-agentcore.<region>.amazonaws.com/runtimes/<agentRuntimeArn>/ws?X-Amzn-Bedrock-AgentCore-Runtime-Custom-TestHeader=query-param-test-value
```

The agent application container will receive these as headers:

```
"headers": {
    "x-amzn-bedrock-agentcore-runtime-custom-testheader": "query-param-test-value"
  }
```

## Appendix
<a name="websocket-appendix"></a>

**Topics**
+ [

### Security considerations
](#security-considerations)
+ [

### Troubleshooting
](#websocket-troubleshooting)
+ [

### WebSocket vs other protocols
](#websocket-vs-other-protocols)
+ [

### Additional getting started examples
](#websocket-additional-examples)

### Security considerations
<a name="security-considerations"></a>

Authentication  
All WebSocket connections require proper AWS authentication through SigV4 or OAuth 2.0

Session Isolation  
Each session runs in isolated execution environments with dedicated resources

Transport Security  
All connections use WSS (WebSocket Secure) over HTTPS for encrypted communication

Access Control  
IAM policies control WebSocket connection permissions and access to specific agents

### Troubleshooting
<a name="websocket-troubleshooting"></a>

#### Common WebSocket-specific issues
<a name="common-websocket-issues"></a>

The following are common issues you might encounter:

Connection failures  
Verify that your agent application processes connection requests at `/ws` 

Authentication method mismatch  
Ensure your client uses the same authentication method (OAuth or SigV4) that the agent was configured with

Connection closed due to limit exceeded  
Connections are automatically closed if limits are exceeded, such as message frame rate or message frame size limits. For complete limit information, see [Quotas for Amazon Bedrock AgentCore](bedrock-agentcore-limits.md) 

Message frame size exceeded  
Configure message frame fragmentation or implement chunking to stay below the 32KB frame size limit. Split large messages into smaller chunks before sending

Health check failures  
Ensure your agent container implements the `/ping` endpoint as specified in [HTTP protocol contract](runtime-http-protocol-contract.md) . This endpoint verifies that your agent is operational and ready to handle requests, enabling service monitoring and automated recovery

#### Error handling
<a name="websocket-error-handling"></a>

WebSocket connections use standard close codes for error communication. Common close codes include:
+  `1000` - Normal closure
+  `1001` - Going away
+  `1008` - Policy violated (limit exceeded)
+  `1009` - Message too big (message frame size limit exceeded)
+  `1011` - Server error

### WebSocket vs other protocols
<a name="websocket-vs-other-protocols"></a>

 **When to use WebSocket** :
+ Real-time voice conversations with immediate audio streaming for natural conversation flow
+ Bidirectional audio/text/binary data flow (streaming data chunks from client to agent and vice versa)
+ Interrupt handling (user can interrupt agent mid-conversation)

 **When to use HTTP** :
+ HTTP for request-response patterns without bidirectional streaming needs

### Additional getting started examples
<a name="websocket-additional-examples"></a>

For additional examples using WebSocket bidirectional streaming with AgentCore Runtime, see the [WebSocket bidirectional streaming GitHub samples](https://github.com/awslabs/amazon-bedrock-agentcore-samples/tree/main/01-tutorials/01-AgentCore-runtime/06-bi-directional-streaming) :
+  **Sonic implementation (Python)** : Native Amazon Nova Sonic WebSocket implementation with real-time audio conversations, voice selection, and interruption support
+  **Strands implementation (Python)** : Framework-based implementation using the Strands BidiAgent for simplified real-time audio conversations with automatic session management and tool integration
+  **Echo implementation (Python)** : Simple echo server for testing WebSocket connectivity and authentication