AWS Builder Center
Bedrock AgentCore - Equip Your AI Agent With Code Writing and  Execution Ability Leveraging AgentCore Code Interpreter With a Few Lines of Code

Bedrock AgentCore - Equip Your AI Agent With Code Writing and Execution Ability Leveraging AgentCore Code Interpreter With a Few Lines of Code

AI Agents can become a lot more powerful when they have the ability to write and execute code on the user's behalf in a safe and secure manner. Once they have that ability they can run complex math, do post extraction data processing and a lot other useful tasks. In this blog post you will get to learn how to leverage AgentCore Code Interpreter to equip our AI Agent with code writing and interpreting abilities with a few lines of code

This blog is part of full series on  Bedrock AgentCore :

Introduction

Large Language Models (LLM) often struggle with complex math, even simple math can be challenging for lighter models. The ability to operate on a large dataset with structure data, doing post extraction data processing, or data manipulation, is another LLMs generally have. A good example is if you are pulling orders for a database using an agent tool and want them sorted by amount or date, or having them totaled or averaged. These are all operations that are much easier to do with code. Now imagine if our agent has access to a sandbox environment where it can execute code safely and securely with session isolation and logging, wouldn't that be great. How more powerful would that make our agent?
The answer to all of that is  AgentCore Code Interpreter , another element of the Bedrock AgentCore family. The Amazon Bedrock AgentCore Code Interpreter enables AI agents to write and execute code securely in sandbox environments, enhancing their accuracy and expanding their ability to solve complex end-to-end tasks. This is critical in Agentic AI applications where the agents may execute arbitrary code that can lead to data compromise or security risks. The AgentCore Code Interpreter tool provides secure code execution, which helps you avoid running into these issues. It also integrates with AgentCore Identity, IAM, AgentCore Observibility to simplify end-to-end integration

AgentCore Code Interpreter can be introduced to your AI Agent as a tool to use when building and executing code.
Now that we know the why and how, let's get building!

Integrating AgentCore Code Interpreter with our agent

In the past three blogs we have launched our first AI Agent into AgentCore Runtime, equipped it with tools through the use of an AgentCore Gateway, added long/short-term memory to it, and now we are going to upgrade our same agent to have the ability to write and execute code!

1- System prompt and code execution tool definition

We start by creating or modifying our system prompt to steer our agent towards validating mathematical and code related aspects through the use of a code execution tool. Then we will and a tool definition to our agent code.
Then we move on to defining a function for code execution, basically the actual tool that will leverage Code Interpreter. The tool definition tells the Agent how to create a session with AgentCore Code Interpreter, the expected input parameters, and the output format. Each Code Interpreter session is an isolated sandbox for the agent to run code in a specific programing language runtime. AgentCore Code Interpreter supports various programming languages including Python, JavaScript, and TypeScript, making it versatile enough for different use cases. For the purpose of this exercise we will use Python as our runtime
plaintext
# Build our setup for code execution

#Define the detailed system prompt for the assistant
SYSTEM_PROMPT = """You are a helpful AI assistant that validates all answers through code execution.

VALIDATION PRINCIPLES:
1. When making claims about code, algorithms, or calculations - write code to verify them
2. Use execute_python to test mathematical calculations, algorithms, and logic
3. Create test scripts to validate your understanding before giving answers
4. Always show your work with actual code execution
5. If uncertain, explicitly state limitations and validate what you can

APPROACH:
- If asked about a programming concept, implement it in code to demonstrate
- If asked for calculations, compute them programmatically AND show the code
- If implementing algorithms, include test cases to prove correctness
- Document your validation process for transparency
- The state is maintained between executions, so you can refer to previous results

TOOL AVAILABLE:
- execute_python: Run Python code and see output

RESPONSE FORMAT: The execute_python tool returns a JSON response with:
- sessionId: The code interpreter session ID
- id: Request ID
- isError: Boolean indicating if there was an error
- content: Array of content objects with type and text/data
- structuredContent: For code execution, includes stdout, stderr, exitCode, executionTime

For successful code execution, the output will be in content[0].text and also in structuredContent.stdout.
Check isError field to see if there was an error.

Be thorough, accurate, and always validate your answers when possible."""

#Define and configure the code interpreter tool
@tool
def execute_python(code: str, description: str = "") -> str:
"""Execute Python code and return results"""
if description:
code = f"# {description}\n{code}"
print(f"\nExecuting code: {code}")
try:
with code_session("us-west-2") as code_client:
response = code_client.invoke("executeCode", {
"code": code,
"language": "python",
"clearContext": False
})
# Process all events in the stream
results = []
for event in response["stream"]:
if "result" in event:
results.append(event["result"])
# Return the last result or combine all results
if results:
final_result = results[-1] # Get the last result
# Check for errors
if final_result.get("isError", False):
error_content = final_result.get("content", [])
error_msg = error_content[0].get("text", "Unknown error") if error_content else "Unknown error"
return f"Error executing code: {error_msg}"
# Return successful output
content = final_result.get("content", [])
if content and len(content) > 0:
return content[0].get("text", "No output")
else:
return "Code executed successfully but no output"
else:
return "No results from code execution"
except Exception as e:
return f"Failed to execute code: {str(e)}"


2- Lets add any missing imports needed

Now that we are bringing everything together, Gateway, Memory, and Code Interpretation. We need to make sure we have all what we need of imports in place. Let's confirm that
plaintext
from bedrock_agentcore.runtime import BedrockAgentCoreApp
from datetime import datetime
from strands import Agent, tool
import logging
from strands.models import BedrockModel
from strands.tools import mcp
from strands.tools.mcp.mcp_client import MCPClient
from mcp.client.streamable_http import streamablehttp_client
from bedrock_agentcore_starter_toolkit.operations.gateway.client import GatewayClient
import os
import time
from bedrock_agentcore.memory import MemoryClient
from strands_tools.agent_core_memory import AgentCoreMemoryToolProvider
import functools
from bedrock_agentcore.tools.code_interpreter_client import code_session
import asyncio
import json

3- Integrating our code execution tool

At this point we are ready to integrate our code execution tool. We will simply update our agent_run function by appending the execute_python tool we have just create
 tools = tools + [execute_python] 
We will also add the SYSTEM_PROMPT to our agent definition. Here is how our updated run_agent function should look like
plaintext
def run_agent(mcp_url: str, access_token: str, user_id: str, session_id: str, user_message: str):
try:
mcp_client = MCPClient(lambda: create_streamable_http_transport(mcp_url, access_token))
actorId=user_id
strands_provider = AgentCoreMemoryToolProvider(
memory_id=memory_id,
actor_id=user_id,
session_id=session_id,
namespace=f"/strategies/{memoryStrategyId}/actors/{actorId}",
region="us-west-2"
)
with mcp_client:
tools = get_full_tools_list(mcp_client)
tools = tools + strands_provider.tools
tools = tools + [execute_python]
print(f"Found the following tools: {[tool.tool_name for tool in tools]}")
agent = Agent(model=bedrockmodel,system_prompt=SYSTEM_PROMPT,tools=tools, callback_handler=None)
print("\nThinking...\n")
result = agent(user_message)
return result
except Exception as e:
print(f"Error in run_agent: {e}")
return {"message": f"Error processing request: {str(e)}"}

4- Putting it all together

Now let's take a look at how this comes all together for a full agent code sample that integrates short-term and long-term Memory, an AgentCore Gateway with a dummy Lambda tool behind it, and a code execution sandbox using AgentCore Code Interpreter.

a- Full agent code my_full_agent.py

plaintext
from bedrock_agentcore.runtime import BedrockAgentCoreApp
from datetime import datetime
from strands import Agent, tool
import logging
from strands.models import BedrockModel
from strands.tools import mcp
from strands.tools.mcp.mcp_client import MCPClient
from mcp.client.streamable_http import streamablehttp_client
from bedrock_agentcore_starter_toolkit.operations.gateway.client import GatewayClient
import os
import time
from bedrock_agentcore.memory import MemoryClient
from strands_tools.agent_core_memory import AgentCoreMemoryToolProvider
import functools
from bedrock_agentcore.tools.code_interpreter_client import code_session
import asyncio
import json

# Define our app referencing the pre-built BedrockAgentCoreApp
app = BedrockAgentCoreApp()

# GateWay URL:
mcp_url ="https://<YourGateway-sufix>.gateway.bedrock-agentcore.us-east-1.amazonaws.com/mcp"

# Cognito parameters:
user_pool_id = "your_cognito_user_pool"
client_id = "your_cognito_user_pool_client_id"
client_secret = "your_cogneto_client_secret"
scopeString = "<YourGatewayName>/invoke"
token_endpoint = "https://<your_userpool_domain>.auth.us-west-2.amazoncognito.com/oauth2/token"

region = "us-west-2"

memory_id_configuration = "your-memory_id"
memory_strategy_id = "your-memory_strategy_id"

model_id = "us.anthropic.claude-sonnet-4-20250514-v1:0"
bedrockmodel = BedrockModel(
inference_profile_id= model_id,
temperature=0,
streaming=True,
)

# Defining client as our GatewayClient
client = GatewayClient(region_name=region)
client.logger.setLevel(logging.DEBUG)

# Get token
client_config = {
"user_pool_id": user_pool_id,
"client_id": client_id,
"client_secret": client_secret,
"scope": scopeString,
"region": region,
"token_endpoint": token_endpoint
}

token_response = client.get_access_token_for_cognito(client_config)
access_token = token_response
print(access_token)

# Build our setup for code execution

#Define the detailed system prompt for the assistant
SYSTEM_PROMPT = """You are a helpful AI assistant that validates all answers through code execution.

VALIDATION PRINCIPLES:
1. When making claims about code, algorithms, or calculations - write code to verify them
2. Use execute_python to test mathematical calculations, algorithms, and logic
3. Create test scripts to validate your understanding before giving answers
4. Always show your work with actual code execution
5. If uncertain, explicitly state limitations and validate what you can

APPROACH:
- If asked about a programming concept, implement it in code to demonstrate
- If asked for calculations, compute them programmatically AND show the code
- If implementing algorithms, include test cases to prove correctness
- Document your validation process for transparency
- The state is maintained between executions, so you can refer to previous results

TOOL AVAILABLE:
- execute_python: Run Python code and see output

RESPONSE FORMAT: The execute_python tool returns a JSON response with:
- sessionId: The code interpreter session ID
- id: Request ID
- isError: Boolean indicating if there was an error
- content: Array of content objects with type and text/data
- structuredContent: For code execution, includes stdout, stderr, exitCode, executionTime

For successful code execution, the output will be in content[0].text and also in structuredContent.stdout.
Check isError field to see if there was an error.

Be thorough, accurate, and always validate your answers when possible."""

#Define and configure the code interpreter tool
@tool
def execute_python(code: str, description: str = "") -> str:
"""Execute Python code and return results"""
if description:
code = f"# {description}\n{code}"
print(f"\nExecuting code: {code}")
try:
with code_session("us-west-2") as code_client:
response = code_client.invoke("executeCode", {
"code": code,
"language": "python",
"clearContext": False
})
# Process all events in the stream
results = []
for event in response["stream"]:
if "result" in event:
results.append(event["result"])
# Return the last result or combine all results
if results:
final_result = results[-1] # Get the last result
# Check for errors
if final_result.get("isError", False):
error_content = final_result.get("content", [])
error_msg = error_content[0].get("text", "Unknown error") if error_content else "Unknown error"
return f"Error executing code: {error_msg}"
# Return successful output
content = final_result.get("content", [])
if content and len(content) > 0:
return content[0].get("text", "No output")
else:
return "Code executed successfully but no output"
else:
return "No results from code execution"
except Exception as e:
return f"Failed to execute code: {str(e)}"

# Get Gateway tools
def create_streamable_http_transport(mcp_url: str, access_token: str):
return streamablehttp_client(mcp_url, headers={"Authorization": f"Bearer {access_token}"})
def get_full_tools_list(client):
more_tools = True
tools = []
pagination_token = None
while more_tools:
tmp_tools = client.list_tools_sync(pagination_token=pagination_token)
tools.extend(tmp_tools)
if tmp_tools.pagination_token is None:
more_tools = False
else:
more_tools = True
pagination_token = tmp_tools.pagination_token
return tools

"""Parameters for memory provider """
memory_id = memory_id_configuration
memoryStrategyId = memory_strategy_id

def run_agent(mcp_url: str, access_token: str, user_id: str, session_id: str, user_message: str):
try:
mcp_client = MCPClient(lambda: create_streamable_http_transport(mcp_url, access_token))
actorId=user_id
strands_provider = AgentCoreMemoryToolProvider(
memory_id=memory_id,
actor_id=user_id,
session_id=session_id,
namespace=f"/strategies/{memoryStrategyId}/actors/{actorId}",
region="us-west-2"
)
with mcp_client:
tools = get_full_tools_list(mcp_client)
tools = tools + strands_provider.tools
tools = tools + [execute_python]
print(f"Found the following tools: {[tool.tool_name for tool in tools]}")
agent = Agent(model=bedrockmodel,system_prompt=SYSTEM_PROMPT,tools=tools, callback_handler=None)
print("\nThinking...\n")
result = agent(user_message)
return result
except Exception as e:
print(f"Error in run_agent: {e}")
return {"message": f"Error processing request: {str(e)}"}

@app.entrypoint
def invoke(payload):
try:
"""Process user input and return a response"""
user_message = payload.get("prompt", "Hello")
payload_user_id = payload.get("user_id", "default_user")
payload_session_id = payload.get("session_id", "default_session")

"""Parameters for memory provider """
user_id = payload_user_id
session_id = payload_session_id

result = run_agent(mcp_url, access_token, user_id, session_id, user_message)
return {"result": result.message}
except Exception as e:
return {"result": f"Error: {str(e)}"}

if __name__ == "__main__":
app.run()


b- Let's build our Dockerfile and other supporting files

Dockerfile
plaintext
FROM ghcr.io/astral-sh/uv:python3.11-bookworm-slim
WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-cache
COPY my_full_agent.py ./
EXPOSE 8080
CMD ["uv", "run", "uvicorn", "my_full_agent:app", "--host", "0.0.0.0", "--port", "8080"]

deploy_my_full_agent.py
plaintext
import boto3

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

response = client.create_agent_runtime(
agentRuntimeName='my_full_agent',
agentRuntimeArtifact={
'containerConfiguration': {
'containerUri': '<account-id>.dkr.ecr.us-west-2.amazonaws.com/my_full_agent:latest'
}
},
networkConfiguration={"networkMode": "PUBLIC"},
roleArn='arn:aws:iam::<account-id>:role/<AgentRuntimeRole>'
)

print(f"Agent Runtime created successfully!")
print(f"Agent Runtime ARN: {response['agentRuntimeArn']}")
print(f"Status: {response['status']}")
invoke_my_full_agent.py
It is worth noting that we have added the session_id and user_id to the invoke call. do not forget to replace the agent ARN with your own Agent ARN
plaintext
import boto3
import json

agent_core_client = boto3.client('bedrock-agentcore', region_name='us-west-2')
payload = json.dumps({"prompt":"What is square root of [(12+3-7)*6]/4? explain how you got to the answer and what tool you used", "user_id":"your-user-id-156", "session_id":"your-session-id-123ljldkfjljfghgjslkfjslfk798789797979879"})

response = agent_core_client.invoke_agent_runtime(
agentRuntimeArn='arn:aws:bedrock-agentcore:us-west-2:409945352356:runtime/<my_full_agent_suffix>',
runtimeSessionId='your-session-id-123ljldkfjljfghgjslkfjslfk798789797979879', # Must be 33+ chars
runtimeUserId= 'your-user-id-156',
payload=payload,
qualifier="DEFAULT"
)

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

c- Testing our full agent locally

 uv run uvicorn my_full_agent:app —host 0.0.0.0 —port 8080 
Ping health check:
Curl a full request in:
Notice we have added the session_id and user_id to the request for memory to work properly
plaintext
curl -X POST http://localhost:8080/invocations \
-H "Content-Type: application/json" \
-H "X-Amzn-Bedrock-AgentCore-Runtime-Session-Id: your-session-id-123ljldkfjljfslkfjslfk798789797979879" \
-H "X-Amzn-Bedrock-AgentCore-Runtime-User-Id: your-user-id-156" \
-d '{"prompt":"What is the height of the CN Tower?", "user_id":"your-user-id-156", "session_id":"your-session-id-123ljldkfjljfslkfjslfk798789797979879"}'
Building a container locally and running it for testing
plaintext
docker buildx create --use

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

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

Testing the container
plaintext
curl -X POST http://localhost:8080/invocations \
-H "Content-Type: application/json" \
-H "X-Amzn-Bedrock-AgentCore-Runtime-Session-Id: your-session-id-123ljldkfjljfslkfjslfk798789797979879" \
-H "X-Amzn-Bedrock-AgentCore-Runtime-User-Id: your-user-id-156" \
-d '{"prompt":"What is the height of the CN Tower?", "user_id":"your-user-id-156", "session_id":"your-session-id-123ljldkfjljfslkfjslfk798789797979879"}'

d- Pushing the container image

Pushing the container image
plaintext
# Create an ECR repository:
aws ecr create-repository --repository-name my_full_agent --region us-west-2

# Login to ECR
- do not forget to replace the <account-id> with your account_id
aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin <account-id>.dkr.ecr.us-west-2.amazonaws.com

# Build and push our docker image to ECR:
- do not forget to replace the <account-id> with your account_id

docker buildx build --platform linux/arm64 -t <account-id>.dkr.ecr.us-west-2.amazonaws.com/my_full_agent:latest --push .

# Verify the image was pushed:

aws ecr describe-images --repository-name my_full_agent --region us-west-2


e- launching and invoking our agent

 uv run deploy_my_full_agent.py 
Now you should be able to see our new agent my_full_agent if you go to the AgentCore Runtime console
Invoke our agent (do not forget to include the agent ARN in your invoke file)
 uv run invoke_my_full_agent.py 
The message response should contain a body that looks like this:
plaintext
"content": [
{
"text": "## Answer\n\nThe square root of [(12+3-7)*6]/4 is **2√3** (approximately 3.464102).\n\n## How I got there:\n\n**Tool used:** I used the `execute_python` tool to write and run Python code that calculated this step-by-step.\n\n**Step-by-step calculation:**\n1. **Inner parentheses first:** 12 + 3 - 7 = 8\n2. **Multiply by 6:** 8 × 6 = 48 \n3. **Divide by 4:** 48 ÷ 4 = 12\n4. **Take square root:** √12 = 3.4641016151377544\n\n**Simplified form:** Since √12 = √(4 × 3) = √4 × √3 = 2√3, the exact answer is **2√3**.\n\nI validated this calculation by:\n- Computing it step-by-step to show the work\n- Verifying with a direct calculation of the entire expression\n- Confirming that 2√3 equals the same decimal value\n- Using Python's math library to ensure precision\n\nThis approach ensures accuracy and shows exactly how the calculation was performed programmatically."
}
]
}
}

Congratulation!
Your AgentCore AI Agent is now capable of doing everything you need. It has long/short-term memory, have access to an AgentCore Gateway with a Lambda target with two tools, get_weather, and get_time, and finally now it is also able to write and execute code!!



Thank you for tagging along on the four blogs journey. Hope it was rewarding!
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article