<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jamal</title>
    <description>The latest articles on DEV Community by Jamal (@d3vjamal).</description>
    <link>https://dev.to/d3vjamal</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F178582%2F47a8a424-59e1-477c-acf7-d0c541e27a3a.png</url>
      <title>DEV Community: Jamal</title>
      <link>https://dev.to/d3vjamal</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/d3vjamal"/>
    <language>en</language>
    <item>
      <title># 🤖 Lab 07: Building Multi-Agent Systems with an Orchestrator | Strands Agentic AI</title>
      <dc:creator>Jamal</dc:creator>
      <pubDate>Sun, 31 May 2026 06:06:09 +0000</pubDate>
      <link>https://dev.to/d3vjamal/-lab-07-building-multi-agent-systems-with-an-orchestrator-strands-agentic-ai-4o4h</link>
      <guid>https://dev.to/d3vjamal/-lab-07-building-multi-agent-systems-with-an-orchestrator-strands-agentic-ai-4o4h</guid>
      <description>&lt;p&gt;So far in this series, we've built agents, custom tools, MCP integrations, and MCP servers.&lt;/p&gt;

&lt;p&gt;But real-world AI applications often require multiple specialists working together.&lt;/p&gt;

&lt;p&gt;Instead of creating one giant agent responsible for everything, we can create multiple specialized agents and use a central orchestrator to route requests to the right expert.&lt;/p&gt;

&lt;p&gt;In this lab, we'll build:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Study Assistant&lt;/li&gt;
&lt;li&gt;An Expense Assistant&lt;/li&gt;
&lt;li&gt;An Orchestrator Agent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The orchestrator will decide which specialist should handle the user's request.&lt;/p&gt;

&lt;p&gt;By the end of this tutorial, you'll understand one of the most important patterns in Agentic AI: &lt;strong&gt;Multi-Agent Architectures&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  📚 Strands Agentic AI Lab Series
&lt;/h2&gt;

&lt;p&gt;⬅️ Previous: Lab 07: Build Your First MCP Server&lt;/p&gt;

&lt;p&gt;📍 Current: Lab 08: Building Multi-Agent Systems&lt;/p&gt;

&lt;p&gt;➡️ Next: Lab 09: Agent Collaboration &amp;amp; Sequential Workflows&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 What You'll Learn
&lt;/h2&gt;

&lt;p&gt;In this lab, you'll learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What multi-agent systems are&lt;/li&gt;
&lt;li&gt;Why specialized agents outperform general-purpose agents&lt;/li&gt;
&lt;li&gt;How to build reusable agents&lt;/li&gt;
&lt;li&gt;How to create an orchestrator agent&lt;/li&gt;
&lt;li&gt;How to route requests dynamically&lt;/li&gt;
&lt;li&gt;How to add logging for debugging&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤖 Why Multi-Agent Systems?
&lt;/h2&gt;

&lt;p&gt;Imagine building a personal assistant that can help with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Studying&lt;/li&gt;
&lt;li&gt;Budgeting&lt;/li&gt;
&lt;li&gt;Fitness&lt;/li&gt;
&lt;li&gt;Travel&lt;/li&gt;
&lt;li&gt;Career Advice&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You could create one massive prompt.&lt;/p&gt;

&lt;p&gt;Or you could create specialists.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```text id="w70n8v"&lt;br&gt;
User&lt;br&gt;
  ↓&lt;br&gt;
Orchestrator&lt;br&gt;
  ↓&lt;br&gt;
 ├── Study Agent&lt;br&gt;
 ├── Expense Agent&lt;br&gt;
 ├── Fitness Agent&lt;br&gt;
 └── Travel Agent&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


This approach is:

✅ Easier to maintain

✅ Easier to scale

✅ Easier to test

✅ More accurate

This architecture is commonly used in enterprise AI systems.

---

## 🛠️ Prerequisites

Before starting, make sure you have:

* Python 3.10+
* Strands SDK
* AWS Account
* Amazon Bedrock access
* AWS credentials configured
* uv installed

---

## 🏗️ Architecture Overview

Our application looks like this:



```text id="hkxgx6"
User
  ↓
Orchestrator Agent
  ↓
 ├── study_assistant()
 │      ↓
 │   Study Agent
 │
 └── expense_assistant()
        ↓
     Expense Agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The orchestrator never answers directly.&lt;/p&gt;

&lt;p&gt;Its job is to decide which specialist should handle the request.&lt;/p&gt;


&lt;h2&gt;
  
  
  📜 The Complete Script
&lt;/h2&gt;

&lt;p&gt;This lab introduces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reusable agent creation&lt;/li&gt;
&lt;li&gt;Specialized agents&lt;/li&gt;
&lt;li&gt;Tool-based routing&lt;/li&gt;
&lt;li&gt;Agent orchestration&lt;/li&gt;
&lt;li&gt;Structured logging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's break it down step by step.&lt;/p&gt;


&lt;h2&gt;
  
  
  ⚙️ Step 1: Configure Logging
&lt;/h2&gt;



&lt;p&gt;```python id="ej58br"&lt;br&gt;
logging.basicConfig(&lt;br&gt;
    level=logging.DEBUG,&lt;br&gt;
    format="%(asctime)s | %(levelname)s | %(message)s",&lt;br&gt;
)&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Logging helps us understand:

* Which agent was selected
* Which tool was called
* What response was generated
* Any errors that occurred

Example:



```text id="y4dkvh"
INFO | User query received
INFO | study_assistant called
DEBUG | Study response generated
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This becomes incredibly useful when debugging complex multi-agent systems.&lt;/p&gt;


&lt;h2&gt;
  
  
  ⚙️ Step 2: Configure the Bedrock Model
&lt;/h2&gt;



&lt;p&gt;```python id="h3c66o"&lt;br&gt;
bedrock_model = BedrockModel(&lt;br&gt;
    model_id="",&lt;br&gt;
    region_name="eu-west-2",&lt;br&gt;
    temperature=0.3,&lt;br&gt;
)&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


All agents in this lab share the same Bedrock model.

This keeps the architecture simple.

In production, different agents may use different models.

---

## ⚙️ Step 3: Create a Reusable Agent Factory



```python id="o5j5dr"
def create_agent(
    name: str,
    system_prompt: str
) -&amp;gt; Agent:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This helper function creates specialized agents.&lt;/p&gt;

&lt;p&gt;Benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Less code duplication&lt;/li&gt;
&lt;li&gt;Consistent configuration&lt;/li&gt;
&lt;li&gt;Easier maintenance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of repeating:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```python id="4mgv3u"&lt;br&gt;
Agent(...)&lt;br&gt;
Agent(...)&lt;br&gt;
Agent(...)&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


we centralize the logic.

---

## ⚙️ Step 4: Create Specialized Agents

### Study Agent



```python id="m9l6bf"
study_agent = create_agent(
    name="study_agent",
    system_prompt="""
    You are a study assistant.
    Help users create learning plans.
    """
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Responsibilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learning plans&lt;/li&gt;
&lt;li&gt;Courses&lt;/li&gt;
&lt;li&gt;Certifications&lt;/li&gt;
&lt;li&gt;Exams&lt;/li&gt;
&lt;li&gt;Technical concepts&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  Expense Agent
&lt;/h3&gt;



&lt;p&gt;```python id="sz9rj6"&lt;br&gt;
expense_agent = create_agent(&lt;br&gt;
    name="expense_agent",&lt;br&gt;
    system_prompt="""&lt;br&gt;
    You are an expense assistant.&lt;br&gt;
    Help users manage budgets.&lt;br&gt;
    """&lt;br&gt;
)&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Responsibilities:

* Budgeting
* Savings
* Spending analysis
* Cost reduction
* Financial planning

Each agent becomes an expert in its own domain.

---

## ⚙️ Step 5: Expose Agents as Tools

### Study Tool



```python id="e4qj98"
@tool
def study_assistant(
    query: str
) -&amp;gt; str:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This wraps the Study Agent as a tool.&lt;/p&gt;

&lt;p&gt;Workflow:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```text id="83lykw"&lt;br&gt;
Tool Call&lt;br&gt;
     ↓&lt;br&gt;
Study Agent&lt;br&gt;
     ↓&lt;br&gt;
Response&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


---

### Expense Tool



```python id="4vr1ig"
@tool
def expense_assistant(
    query: str
) -&amp;gt; str:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This wraps the Expense Agent.&lt;/p&gt;

&lt;p&gt;Workflow:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```text id="x4wozg"&lt;br&gt;
Tool Call&lt;br&gt;
     ↓&lt;br&gt;
Expense Agent&lt;br&gt;
     ↓&lt;br&gt;
Response&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Now the orchestrator can invoke either specialist.

---

## ⚙️ Step 6: Create the Orchestrator Prompt



```python id="ys8teq"
orchestrator_prompt = """
You are a router assistant.
"""
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This prompt defines routing rules.&lt;/p&gt;
&lt;h3&gt;
  
  
  Study Topics
&lt;/h3&gt;



&lt;p&gt;```text id="e80bvo"&lt;br&gt;
study&lt;br&gt;
learning&lt;br&gt;
courses&lt;br&gt;
practice&lt;br&gt;
certifications&lt;br&gt;
exams&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


### Expense Topics



```text id="rul44e"
budget
money
savings
spending
expenses
cost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The orchestrator's job is not to answer.&lt;/p&gt;

&lt;p&gt;Its job is to route.&lt;/p&gt;

&lt;p&gt;Think of it as a smart receptionist.&lt;/p&gt;


&lt;h2&gt;
  
  
  ⚙️ Step 7: Build the Orchestrator Agent
&lt;/h2&gt;



&lt;p&gt;```python id="v38nbe"&lt;br&gt;
orchestrator_agent = Agent(&lt;br&gt;
    system_prompt=orchestrator_prompt,&lt;br&gt;
    model=bedrock_model,&lt;br&gt;
    tools=[&lt;br&gt;
        study_assistant,&lt;br&gt;
        expense_assistant,&lt;br&gt;
    ],&lt;br&gt;
)&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


This is the brain of the system.

It receives the user request and chooses the correct specialist.

Architecture:



```text id="bx9qwf"
User
 ↓
Orchestrator
 ↓
Correct Tool
 ↓
Specialized Agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ▶️ Run the Application
&lt;/h2&gt;

&lt;p&gt;Execute:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```bash id="rxy1ii"&lt;br&gt;
python agent.py&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Or:



```bash id="k5d2nh"
uv run labs/08-multi-agent-orchestrator/agent.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📊 Example Interaction #1
&lt;/h2&gt;
&lt;h3&gt;
  
  
  User
&lt;/h3&gt;



&lt;p&gt;```text id="s9zn1s"&lt;br&gt;
Help me prepare for AWS Cloud Practitioner.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


### Routing



```text id="m6v00u"
Orchestrator
     ↓
study_assistant
     ↓
Study Agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Response
&lt;/h3&gt;



&lt;p&gt;```text id="yykx7m"&lt;br&gt;
Here's a 4-week AWS Cloud Practitioner study plan...&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


---

## 📊 Example Interaction #2

### User



```text id="hk0e5q"
How can I save ₹5000 every month?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Routing
&lt;/h3&gt;



&lt;p&gt;```text id="m7hd8x"&lt;br&gt;
Orchestrator&lt;br&gt;
     ↓&lt;br&gt;
expense_assistant&lt;br&gt;
     ↓&lt;br&gt;
Expense Agent&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


### Response



```text id="v9xl7r"
Let's review your monthly expenses and identify savings opportunities...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📊 Example Interaction #3
&lt;/h2&gt;
&lt;h3&gt;
  
  
  User
&lt;/h3&gt;



&lt;p&gt;```text id="3swmpx"&lt;br&gt;
I have an exam next month and need a budget for training materials.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


This query touches multiple domains.

The orchestrator may:

* Ask a clarification question
* Choose the dominant topic
* Route accordingly

This demonstrates why orchestration logic matters.

---

## 🔍 What Happened Behind the Scenes?

When a user submits a request:



```text id="vd6l7r"
User Query
     ↓
Orchestrator Agent
     ↓
Tool Selection
     ↓
Specialized Agent
     ↓
Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The orchestrator never becomes an expert.&lt;/p&gt;

&lt;p&gt;Instead, it delegates expertise.&lt;/p&gt;

&lt;p&gt;This pattern is called:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```text id="vvw7mt"&lt;br&gt;
Agent Orchestration&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


and is widely used in production AI systems.

---

## 💡 Why Developers Love This Pattern

Without Multi-Agent Systems:

❌ Huge prompts

❌ Mixed responsibilities

❌ Difficult maintenance

❌ Poor scalability

With Multi-Agent Systems:

✅ Specialized expertise

✅ Easier debugging

✅ Modular design

✅ Independent evolution

✅ Better scalability

Each agent focuses on one job and does it well.

---

## 🌍 Real-World Use Cases

This same architecture powers:

### Customer Support



```text id="n1e0y4"
Billing Agent
Technical Agent
Escalation Agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Healthcare
&lt;/h3&gt;



&lt;p&gt;```text id="slkj6g"&lt;br&gt;
Symptoms Agent&lt;br&gt;
Insurance Agent&lt;br&gt;
Appointment Agent&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


### Enterprise Operations



```text id="px0i6z"
HR Agent
Finance Agent
IT Agent
Legal Agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Personal Assistants
&lt;/h3&gt;



&lt;p&gt;```text id="4m98t8"&lt;br&gt;
Study Agent&lt;br&gt;
Budget Agent&lt;br&gt;
Fitness Agent&lt;br&gt;
Travel Agent&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


The possibilities are endless.

---

## 🎯 Key Takeaways

* Multi-agent systems separate responsibilities
* Specialized agents improve accuracy
* Orchestrators route requests intelligently
* Tools can act as wrappers around agents
* Logging makes orchestration easier to debug
* This pattern scales extremely well in production

---

## 📚 Source Code

GitHub Repository:

https://github.com/d3vjamal/strands-agents-labs

---

## 🔗 Continue Learning

⬅️ Previous Lab

[Lab 06: Build Your First MCP Server with Streamable HTTP | Strands Agentic AI](https://dev.to/d3vjamal/-lab-06-build-your-first-mcp-server-with-streamable-http-strands-agentic-ai-1995)


---

## 🚀 Next Lab

In the next tutorial, we'll move beyond simple routing and explore how multiple agents can collaborate together, passing information between each other to solve complex tasks that no single agent can handle alone.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
    </item>
    <item>
      <title># 🧮 Lab 06: Build Your First MCP Server with Streamable HTTP | Strands Agentic AI</title>
      <dc:creator>Jamal</dc:creator>
      <pubDate>Sun, 31 May 2026 04:48:00 +0000</pubDate>
      <link>https://dev.to/d3vjamal/-lab-06-build-your-first-mcp-server-with-streamable-http-strands-agentic-ai-1995</link>
      <guid>https://dev.to/d3vjamal/-lab-06-build-your-first-mcp-server-with-streamable-http-strands-agentic-ai-1995</guid>
      <description>&lt;p&gt;In the previous labs, we connected a Strands Agent to an existing MCP server and used its tools.&lt;/p&gt;

&lt;p&gt;But what if you want to create your own MCP server?&lt;/p&gt;

&lt;p&gt;That's exactly what we'll do in this lab.&lt;/p&gt;

&lt;p&gt;We'll build a Calculator MCP Server that exposes arithmetic operations such as addition, subtraction, multiplication, and division. Then we'll connect a Strands Agent to that server using Streamable HTTP transport.&lt;/p&gt;

&lt;p&gt;By the end of this tutorial, you'll understand both sides of the MCP ecosystem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MCP Server&lt;/li&gt;
&lt;li&gt;MCP Client&lt;/li&gt;
&lt;li&gt;Strands Agent&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📚 Strands Agentic AI Lab Series
&lt;/h2&gt;

&lt;p&gt;⬅️ Previous: Lab 06: Connecting to MCP with STDIO&lt;/p&gt;

&lt;p&gt;📍 Current: Lab 07: Build Your First MCP Server&lt;/p&gt;

&lt;p&gt;➡️ Next: Lab 08: Advanced MCP Tools &amp;amp; Multi-Tool Workflows&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 What You'll Learn
&lt;/h2&gt;

&lt;p&gt;In this lab, you'll learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to create an MCP Server&lt;/li&gt;
&lt;li&gt;How MCP tools are exposed&lt;/li&gt;
&lt;li&gt;How Streamable HTTP transport works&lt;/li&gt;
&lt;li&gt;How to connect a Strands Agent to a custom MCP server&lt;/li&gt;
&lt;li&gt;How agents invoke MCP tools automatically&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤖 Why Build Your Own MCP Server?
&lt;/h2&gt;

&lt;p&gt;Previously we consumed an existing MCP server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent
  ↓
AWS Documentation MCP Server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we'll build one ourselves.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent
  ↓
Your MCP Server
  ↓
Your Tools
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows you to expose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Internal APIs&lt;/li&gt;
&lt;li&gt;Databases&lt;/li&gt;
&lt;li&gt;Business Logic&lt;/li&gt;
&lt;li&gt;Enterprise Systems&lt;/li&gt;
&lt;li&gt;Custom Applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;through a standard MCP interface.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏗️ Architecture
&lt;/h2&gt;

&lt;p&gt;Our solution looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User
  ↓
Strands Agent
  ↓
MCP Client
  ↓
Calculator MCP Server
  ↓
Calculator Tools
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent doesn't perform calculations directly.&lt;/p&gt;

&lt;p&gt;Instead, it delegates them to MCP tools.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before starting, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python 3.10+&lt;/li&gt;
&lt;li&gt;Strands SDK&lt;/li&gt;
&lt;li&gt;MCP SDK&lt;/li&gt;
&lt;li&gt;AWS Bedrock access&lt;/li&gt;
&lt;li&gt;uv installed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Install dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;strands-agents
pip &lt;span class="nb"&gt;install &lt;/span&gt;mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📜 The Complete Script
&lt;/h2&gt;

&lt;p&gt;This example creates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An MCP Calculator Server&lt;/li&gt;
&lt;li&gt;Four calculator tools&lt;/li&gt;
&lt;li&gt;A Strands Agent&lt;/li&gt;
&lt;li&gt;An interactive chat loop&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The agent automatically uses MCP tools whenever calculations are required.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 1: Create the MCP Server
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;mcp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastMCP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Calculator Server&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This initializes a new MCP server.&lt;/p&gt;

&lt;p&gt;Think of it as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Web Framework
    ↓
Routes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but for AI tools.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MCP Server
    ↓
Tools
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⚙️ Step 2: Create MCP Tools
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Addition Tool
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@mcp.tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Add two numbers together&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Subtraction Tool
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@mcp.tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Subtract one number from another&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Multiplication Tool
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@mcp.tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Multiply two numbers together&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Division Tool
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@mcp.tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Divide one number by another&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Cannot divide by zero&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every tool becomes automatically discoverable through MCP.&lt;/p&gt;

&lt;p&gt;No additional registration is required.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 3: Start the MCP Server
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;mcp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;transport&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;streamable-http&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This launches the MCP server using Streamable HTTP transport.&lt;/p&gt;

&lt;p&gt;Server endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost:8000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now other MCP clients can connect.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 4: Run the Server in a Background Thread
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;server_thread&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;threading&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;start_calculator_server&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;daemon&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because we need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Calculator Server
      +
Strands Agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;running simultaneously.&lt;/p&gt;

&lt;p&gt;The background thread keeps the server alive while the agent runs.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 5: Connect the MCP Client
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_streamable_http_transport&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;streamablehttp_client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:8000/mcp/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates an MCP Client connection.&lt;/p&gt;

&lt;p&gt;Architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent
   ↓
MCP Client
   ↓
HTTP Transport
   ↓
Calculator Server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⚙️ Step 6: Discover Available Tools
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;streamable_http_mcp_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list_tools_sync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one of MCP's biggest advantages.&lt;/p&gt;

&lt;p&gt;Instead of manually registering tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the client automatically discovers them.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Available MCP tools:

add
subtract
multiply
divide
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⚙️ Step 7: Create the Agent
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bedrock_model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those tools came directly from the MCP Server.&lt;/p&gt;

&lt;p&gt;No custom integration required.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 8: Interactive Calculator Assistant
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;user_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Question: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a conversational calculator.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question:
What is 125 * 42?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;5250
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Behind the scenes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent
 ↓
multiply()
 ↓
5250
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ▶️ Run the Application
&lt;/h2&gt;

&lt;p&gt;Execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python agent.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv run labs/07-mcp-calculator-server/agent.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📊 Example Interaction
&lt;/h2&gt;

&lt;h3&gt;
  
  
  User
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What is 25 + 17?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Agent Workflow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question
   ↓
Agent Reasoning
   ↓
add Tool
   ↓
42
   ↓
Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Response
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;25 + 17 = 42
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔍 What Happened Behind the Scenes?
&lt;/h2&gt;

&lt;p&gt;When you asked:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What is 25 + 17?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the agent:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Understood the request.&lt;/li&gt;
&lt;li&gt;Found an MCP tool capable of addition.&lt;/li&gt;
&lt;li&gt;Invoked the tool.&lt;/li&gt;
&lt;li&gt;Received the result.&lt;/li&gt;
&lt;li&gt;Generated a response.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The actual calculation happened in the MCP Server.&lt;/p&gt;

&lt;p&gt;Not in the LLM.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Why This Matters
&lt;/h2&gt;

&lt;p&gt;This simple calculator demonstrates a powerful concept.&lt;/p&gt;

&lt;p&gt;Today:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;add()
subtract()
multiply()
divide()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tomorrow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create Customer
Generate Invoice
Query Database
Deploy Lambda
Update CRM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact same MCP architecture scales to enterprise applications.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;MCP Servers expose tools to AI agents&lt;/li&gt;
&lt;li&gt;FastMCP makes building servers simple&lt;/li&gt;
&lt;li&gt;Streamable HTTP enables remote communication&lt;/li&gt;
&lt;li&gt;Agents automatically discover tools&lt;/li&gt;
&lt;li&gt;MCP separates tool implementation from agent logic&lt;/li&gt;
&lt;li&gt;This pattern scales from calculators to enterprise systems&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📚 Source Code
&lt;/h2&gt;

&lt;p&gt;Lab Source Code:&lt;br&gt;
Your GitHub Repository&lt;/p&gt;




&lt;h2&gt;
  
  
  🔗 Continue Learning
&lt;/h2&gt;

&lt;p&gt;⬅️ Previous Lab&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/d3vjamal/-lab-06-connecting-to-an-mcp-server-with-stdio-transport-strands-agentic-ai-4c03"&gt;Lab 05: Connecting to an MCP Server with STDIO Transport | Strands Agentic AI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;➡️ Next Lab&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/d3vjamal/-lab-07-building-multi-agent-systems-with-an-orchestrator-strands-agentic-ai-4o4h"&gt;Lab 07:  Building Multi-Agent Systems with an Orchestrator | Strands Agentic AI&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Next Lab
&lt;/h2&gt;

&lt;p&gt;In the next tutorial, we'll build more sophisticated MCP tools, explore tool schemas, and learn how agents can choose between multiple MCP capabilities to solve complex tasks.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>strands</category>
      <category>agenticai</category>
      <category>bedrockaws</category>
    </item>
    <item>
      <title># 🚀 Lab 05: Connecting to an MCP Server with STDIO Transport | Strands Agentic AI</title>
      <dc:creator>Jamal</dc:creator>
      <pubDate>Sun, 31 May 2026 04:14:05 +0000</pubDate>
      <link>https://dev.to/d3vjamal/-lab-06-connecting-to-an-mcp-server-with-stdio-transport-strands-agentic-ai-4c03</link>
      <guid>https://dev.to/d3vjamal/-lab-06-connecting-to-an-mcp-server-with-stdio-transport-strands-agentic-ai-4c03</guid>
      <description>&lt;p&gt;In the previous lab, we learned what Model Context Protocol (MCP) is and why it is becoming the standard way for AI agents to access tools and external systems.&lt;/p&gt;

&lt;p&gt;Now it's time to build a real MCP-powered agent.&lt;/p&gt;

&lt;p&gt;In this lab, you'll connect a Strands Agent to the AWS Documentation MCP Server using STDIO transport and allow the agent to retrieve information directly from AWS documentation.&lt;/p&gt;

&lt;p&gt;By the end of this tutorial, you'll have an AWS Documentation Assistant capable of answering AWS questions using MCP-provided tools.&lt;/p&gt;




&lt;h2&gt;
  
  
  📚 Strands Agentic AI Lab Series
&lt;/h2&gt;

&lt;p&gt;⬅️ Previous: Lab 05: Introduction to MCP&lt;/p&gt;

&lt;p&gt;📍 Current: Lab 06: Connecting to an MCP Server with STDIO Transport&lt;/p&gt;

&lt;p&gt;➡️ Next: Lab 07: Exploring MCP Tools and Capabilities&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 What You'll Learn
&lt;/h2&gt;

&lt;p&gt;In this lab, you'll learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What STDIO transport is&lt;/li&gt;
&lt;li&gt;How MCP clients communicate with MCP servers&lt;/li&gt;
&lt;li&gt;How to connect to an AWS Documentation MCP Server&lt;/li&gt;
&lt;li&gt;How to discover available tools dynamically&lt;/li&gt;
&lt;li&gt;How to build an AI assistant powered by MCP tools&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤖 Why STDIO Transport?
&lt;/h2&gt;

&lt;p&gt;MCP supports multiple communication methods.&lt;/p&gt;

&lt;p&gt;The simplest is STDIO.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent
  ↓
STDIO
  ↓
MCP Server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of communicating over a network, the agent and MCP server communicate through standard input and output streams.&lt;/p&gt;

&lt;p&gt;Benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple setup&lt;/li&gt;
&lt;li&gt;Fast local development&lt;/li&gt;
&lt;li&gt;No network configuration&lt;/li&gt;
&lt;li&gt;Great for experimentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of STDIO as two applications having a direct private conversation.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before starting, make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python 3.10+&lt;/li&gt;
&lt;li&gt;AWS credentials configured&lt;/li&gt;
&lt;li&gt;Amazon Bedrock access&lt;/li&gt;
&lt;li&gt;uv installed&lt;/li&gt;
&lt;li&gt;Strands SDK installed&lt;/li&gt;
&lt;li&gt;MCP SDK installed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Install dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;strands-agents
pip &lt;span class="nb"&gt;install &lt;/span&gt;mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📜 The Script
&lt;/h2&gt;

&lt;p&gt;Let's start with the complete example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.models.bedrock&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BedrockModel&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.tools.mcp&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MCPClient&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mcp&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;stdio_client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;StdioServerParameters&lt;/span&gt;

&lt;span class="c1"&gt;# Bedrock
&lt;/span&gt;&lt;span class="n"&gt;bedrock_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BedrockModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;YOUR_MODEL_ID&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eu-west-2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Connect to an MCP server using stdio transport
&lt;/span&gt;&lt;span class="n"&gt;stdio_mcp_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MCPClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;stdio_client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;StdioServerParameters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;uvx&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;awslabs.aws-documentation-mcp-server@latest&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;stdio_mcp_client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stdio_mcp_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list_tools_sync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        You are an AWS Documentation expert.
        Use the tools that are available to provide factual information.
        &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bedrock_model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What is AWS Lambda?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's break it down.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 1: Import MCP Components
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.tools.mcp&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MCPClient&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mcp&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;stdio_client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;StdioServerParameters&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These imports provide the building blocks for MCP communication.&lt;/p&gt;

&lt;h3&gt;
  
  
  MCPClient
&lt;/h3&gt;

&lt;p&gt;Creates a bridge between Strands and the MCP server.&lt;/p&gt;

&lt;h3&gt;
  
  
  stdio_client
&lt;/h3&gt;

&lt;p&gt;Handles communication over standard input and output.&lt;/p&gt;

&lt;h3&gt;
  
  
  StdioServerParameters
&lt;/h3&gt;

&lt;p&gt;Defines how the MCP server should start.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 2: Configure the Bedrock Model
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;bedrock_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BedrockModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;YOUR_MODEL_ID&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eu-west-2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This model performs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reasoning&lt;/li&gt;
&lt;li&gt;Tool selection&lt;/li&gt;
&lt;li&gt;Response generation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The MCP server provides tools.&lt;/p&gt;

&lt;p&gt;The LLM decides how to use them.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 3: Configure the MCP Server
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;stdio_mcp_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MCPClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;stdio_client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nc"&gt;StdioServerParameters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;uvx&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;awslabs.aws-documentation-mcp-server@latest&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This launches the AWS Documentation MCP Server.&lt;/p&gt;

&lt;p&gt;Architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Strands Agent
       ↓
MCP Client
       ↓
AWS Documentation MCP Server
       ↓
AWS Documentation Tools
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The MCP server automatically exposes tools to the agent.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 4: Platform Differences
&lt;/h2&gt;

&lt;h3&gt;
  
  
  macOS/Linux
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;uvx&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;awslabs.aws-documentation-mcp-server@latest&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Windows
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;uvx&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--from&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;awslabs.aws-documentation-mcp-server@latest&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;awslabs.aws-documentation-mcp-server.exe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server package is the same.&lt;/p&gt;

&lt;p&gt;Only the launch syntax changes.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 5: Start the MCP Session
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;stdio_mcp_client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This starts the MCP server session.&lt;/p&gt;

&lt;p&gt;Once inside the context:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Server launches&lt;/li&gt;
&lt;li&gt;Connection is established&lt;/li&gt;
&lt;li&gt;Tools become available&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When execution completes, resources are cleaned up automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 6: Discover Available Tools
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stdio_mcp_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list_tools_sync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where MCP becomes powerful.&lt;/p&gt;

&lt;p&gt;Instead of manually creating tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_docs&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can simply discover tools provided by the server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Connect
    ↓
Discover
    ↓
Use
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No custom tool implementation required.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 7: Create the Agent
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    You are an AWS Documentation expert.
    Use the tools that are available to provide factual information.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bedrock_model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These tools come directly from the MCP server.&lt;/p&gt;

&lt;p&gt;The agent now has access to AWS documentation capabilities without any additional coding.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 8: Ask a Question
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What is AWS Lambda?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Question
       ↓
Agent Analysis
       ↓
MCP Tool Selection
       ↓
AWS Documentation Search
       ↓
Information Retrieved
       ↓
Final Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent uses official AWS documentation instead of relying only on model memory.&lt;/p&gt;




&lt;h2&gt;
  
  
  ▶️ Run the Agent
&lt;/h2&gt;

&lt;p&gt;Execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python agent.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv run labs/06-mcp-stdio-client/agent.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📊 Example Interaction
&lt;/h2&gt;

&lt;h3&gt;
  
  
  User
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What is AWS Lambda?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Agent Workflow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question Received
       ↓
Discover Documentation Tool
       ↓
Query AWS Documentation
       ↓
Retrieve Results
       ↓
Generate Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Response
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AWS Lambda is a serverless compute service that allows you to run code without provisioning or managing servers.

Lambda automatically scales your application and charges only for the compute time used.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔍 What Happened Behind the Scenes?
&lt;/h2&gt;

&lt;p&gt;When the question was asked:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The LLM analyzed the request.&lt;/li&gt;
&lt;li&gt;It discovered documentation tools.&lt;/li&gt;
&lt;li&gt;It selected the most relevant tool.&lt;/li&gt;
&lt;li&gt;The MCP server retrieved AWS documentation.&lt;/li&gt;
&lt;li&gt;Results were returned to the model.&lt;/li&gt;
&lt;li&gt;The model generated the final answer.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The agent never needed a custom Python function.&lt;/p&gt;

&lt;p&gt;The MCP server supplied everything.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Why Developers Love MCP
&lt;/h2&gt;

&lt;p&gt;Without MCP:&lt;/p&gt;

&lt;p&gt;❌ Build custom integrations&lt;/p&gt;

&lt;p&gt;❌ Maintain tools manually&lt;/p&gt;

&lt;p&gt;❌ Write wrappers for every service&lt;/p&gt;

&lt;p&gt;With MCP:&lt;/p&gt;

&lt;p&gt;✅ Connect once&lt;/p&gt;

&lt;p&gt;✅ Discover tools automatically&lt;/p&gt;

&lt;p&gt;✅ Reuse existing integrations&lt;/p&gt;

&lt;p&gt;✅ Build agents faster&lt;/p&gt;

&lt;p&gt;MCP turns integrations into plug-and-play components.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;STDIO is the simplest MCP transport&lt;/li&gt;
&lt;li&gt;MCP servers expose tools dynamically&lt;/li&gt;
&lt;li&gt;Agents can discover tools automatically&lt;/li&gt;
&lt;li&gt;AWS Documentation MCP Server provides factual AWS information&lt;/li&gt;
&lt;li&gt;MCP dramatically reduces integration effort&lt;/li&gt;
&lt;li&gt;Strands Agents integrate seamlessly with MCP&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📚 Source Code
&lt;/h2&gt;

&lt;p&gt;GitHub Repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/d3vjamal/strands-agents-labs" rel="noopener noreferrer"&gt;https://github.com/d3vjamal/strands-agents-labs&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🔗 Continue Learning
&lt;/h2&gt;

&lt;p&gt;⬅️ Previous Lab&lt;/p&gt;

&lt;p&gt;Lab 05: Introduction to MCP&lt;/p&gt;

&lt;p&gt;➡️ Next Lab&lt;/p&gt;

&lt;p&gt;Lab 07: Exploring MCP Tools and Capabilities&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Next Lab
&lt;/h2&gt;

&lt;p&gt;In the next tutorial, we'll inspect the tools exposed by an MCP server, understand their schemas, and learn how agents choose the right tool for a given task.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agenticai</category>
      <category>strands</category>
      <category>bedrockai</category>
    </item>
    <item>
      <title># 🔌 Lab 05: Using MCP (Model Context Protocol) with Strands Agents | Strands Agentic AI</title>
      <dc:creator>Jamal</dc:creator>
      <pubDate>Sun, 31 May 2026 04:05:33 +0000</pubDate>
      <link>https://dev.to/d3vjamal/-lab-05-using-mcp-model-context-protocol-with-strands-agents-strands-agentic-ai-49ca</link>
      <guid>https://dev.to/d3vjamal/-lab-05-using-mcp-model-context-protocol-with-strands-agents-strands-agentic-ai-49ca</guid>
      <description>&lt;p&gt;So far in this series, we've built custom tools and taught agents how to interact with the outside world.&lt;/p&gt;

&lt;p&gt;But what if someone else has already built the tools you need?&lt;/p&gt;

&lt;p&gt;Instead of writing every integration yourself, you can connect your AI agent to an MCP Server.&lt;/p&gt;

&lt;p&gt;Model Context Protocol (MCP) is an open standard that allows AI agents to discover and use tools provided by external systems.&lt;/p&gt;

&lt;p&gt;In this lab, you'll connect a Strands Agent to the AWS Documentation MCP Server and allow the agent to retrieve factual AWS documentation directly from official sources.&lt;/p&gt;

&lt;p&gt;By the end of this lab, you'll have an AWS Documentation Assistant powered by MCP.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 What You'll Learn
&lt;/h2&gt;

&lt;p&gt;In this lab, you'll learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What MCP (Model Context Protocol) is&lt;/li&gt;
&lt;li&gt;Why MCP is becoming important in Agentic AI&lt;/li&gt;
&lt;li&gt;How to connect to an MCP server&lt;/li&gt;
&lt;li&gt;How to use STDIO transport&lt;/li&gt;
&lt;li&gt;How agents automatically discover MCP tools&lt;/li&gt;
&lt;li&gt;How to build an AWS Documentation Assistant&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤖 What is MCP?
&lt;/h2&gt;

&lt;p&gt;Model Context Protocol (MCP) is an open protocol that allows AI models and agents to connect to external tools and data sources.&lt;/p&gt;

&lt;p&gt;Think of MCP as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;USB for AI Agents
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just as USB allows computers to connect to keyboards, printers, and storage devices, MCP allows AI agents to connect to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Documentation systems&lt;/li&gt;
&lt;li&gt;Databases&lt;/li&gt;
&lt;li&gt;APIs&lt;/li&gt;
&lt;li&gt;Search engines&lt;/li&gt;
&lt;li&gt;Internal tools&lt;/li&gt;
&lt;li&gt;Enterprise applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without MCP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent
  ↓
Custom Tool
  ↓
External System
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With MCP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent
  ↓
MCP Server
  ↓
Many Tools
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One connection can expose dozens of tools instantly.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before starting, make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python 3.10+&lt;/li&gt;
&lt;li&gt;AWS Account&lt;/li&gt;
&lt;li&gt;Amazon Bedrock access&lt;/li&gt;
&lt;li&gt;AWS credentials configured&lt;/li&gt;
&lt;li&gt;uv installed&lt;/li&gt;
&lt;li&gt;MCP SDK installed&lt;/li&gt;
&lt;li&gt;Strands SDK installed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Install dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;strands-agents
pip &lt;span class="nb"&gt;install &lt;/span&gt;mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🌟 Why MCP Matters
&lt;/h2&gt;

&lt;p&gt;Imagine you're building an AWS assistant.&lt;/p&gt;

&lt;p&gt;Without MCP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Build Tool #1
Build Tool #2
Build Tool #3
Build Tool #4
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You must create and maintain every integration yourself.&lt;/p&gt;

&lt;p&gt;With MCP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Connect MCP Server
Discover Tools
Start Using Them
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The MCP server handles the heavy lifting.&lt;/p&gt;

&lt;p&gt;Your agent simply consumes the available tools.&lt;/p&gt;

&lt;p&gt;This dramatically reduces development effort.&lt;/p&gt;




&lt;h2&gt;
  
  
  📜 The Script
&lt;/h2&gt;

&lt;p&gt;Let's start by looking at the complete example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.models.bedrock&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BedrockModel&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.tools.mcp&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MCPClient&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mcp&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;stdio_client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;StdioServerParameters&lt;/span&gt;

&lt;span class="c1"&gt;# Bedrock
&lt;/span&gt;&lt;span class="n"&gt;bedrock_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BedrockModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;YOUR_MODEL_ID&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eu-west-2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Connect to an MCP server using stdio transport
&lt;/span&gt;&lt;span class="n"&gt;stdio_mcp_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MCPClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;stdio_client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nc"&gt;StdioServerParameters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;uvx&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;awslabs.aws-documentation-mcp-server@latest&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;stdio_mcp_client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stdio_mcp_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list_tools_sync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        You are an AWS Documentation expert.
        Use the tools that are available to provide factual information.
        &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bedrock_model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What is AWS Lambda?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's break it down.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 1: Import MCP Components
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.tools.mcp&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MCPClient&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mcp&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;stdio_client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;StdioServerParameters&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These imports provide everything required to communicate with an MCP server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Components
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MCPClient&lt;/td&gt;
&lt;td&gt;Connects Strands to MCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;stdio_client&lt;/td&gt;
&lt;td&gt;Uses standard input/output transport&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;StdioServerParameters&lt;/td&gt;
&lt;td&gt;Configures the MCP server&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 2: Configure Amazon Bedrock
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;bedrock_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BedrockModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;YOUR_MODEL_ID&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eu-west-2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the reasoning engine behind our agent.&lt;/p&gt;

&lt;p&gt;The model decides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which tool to use&lt;/li&gt;
&lt;li&gt;What information to retrieve&lt;/li&gt;
&lt;li&gt;How to respond&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 3: Create the MCP Connection
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;stdio_mcp_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MCPClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;stdio_client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nc"&gt;StdioServerParameters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;uvx&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;awslabs.aws-documentation-mcp-server@latest&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This establishes a connection to the AWS Documentation MCP Server.&lt;/p&gt;

&lt;p&gt;Think of it as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent
  ↓
MCP Client
  ↓
AWS Documentation MCP Server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server exposes AWS documentation tools automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 4: Understanding STDIO Transport
&lt;/h2&gt;

&lt;p&gt;This lab uses STDIO transport.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent Process
      ⇅
Standard Input/Output
      ⇅
MCP Server Process
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;STDIO is ideal for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Local development&lt;/li&gt;
&lt;li&gt;Local testing&lt;/li&gt;
&lt;li&gt;Lightweight integrations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because communication happens through process streams, no network setup is required.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 5: Start the MCP Session
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;stdio_mcp_client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This opens a connection to the MCP server.&lt;/p&gt;

&lt;p&gt;Once inside the context manager:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Server starts&lt;/li&gt;
&lt;li&gt;Tools become available&lt;/li&gt;
&lt;li&gt;Agent can access them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When execution finishes, the connection closes automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 6: Discover Available Tools
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stdio_mcp_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list_tools_sync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one of the most powerful MCP features.&lt;/p&gt;

&lt;p&gt;Instead of manually creating tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stdio_mcp_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list_tools_sync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent automatically discovers everything exposed by the MCP server.&lt;/p&gt;

&lt;p&gt;Think of it like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Connect
    ↓
Discover Tools
    ↓
Use Tools
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No additional coding required.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 7: Create the Agent
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    You are an AWS Documentation expert.
    Use the tools that are available to provide factual information.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bedrock_model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice something interesting.&lt;/p&gt;

&lt;p&gt;We aren't manually registering tools.&lt;/p&gt;

&lt;p&gt;Instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;contains every tool discovered from the MCP server.&lt;/p&gt;

&lt;p&gt;The agent now has access to AWS documentation capabilities.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 8: Ask a Question
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What is AWS Lambda?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The workflow becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Question
       ↓
Agent Analysis
       ↓
MCP Tool Selection
       ↓
AWS Documentation Search
       ↓
Documentation Retrieved
       ↓
Final Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The answer comes from official AWS documentation rather than relying solely on model memory.&lt;/p&gt;




&lt;h2&gt;
  
  
  ▶️ Run the Agent
&lt;/h2&gt;

&lt;p&gt;Execute the script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python agent.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv run labs/05-mcp-introduction/agent.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📊 Example Interaction
&lt;/h2&gt;

&lt;h3&gt;
  
  
  User
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What is AWS Lambda?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Agent Workflow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question Received
       ↓
Discover Documentation Tool
       ↓
Query AWS Documentation
       ↓
Retrieve Information
       ↓
Generate Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Agent Response
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AWS Lambda is a serverless compute service that lets you run code without provisioning or managing servers.

You pay only for the compute time consumed and can automatically scale applications in response to demand.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact response may vary depending on the documentation version and model.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔍 What Makes MCP Different?
&lt;/h2&gt;

&lt;p&gt;Traditional Tool Approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Build Tool
Register Tool
Maintain Tool
Update Tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MCP Approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Connect Server
Discover Tools
Use Tools
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The MCP server owns the implementation.&lt;/p&gt;

&lt;p&gt;Your agent simply consumes capabilities.&lt;/p&gt;

&lt;p&gt;This dramatically improves scalability.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Real-World MCP Use Cases
&lt;/h2&gt;

&lt;p&gt;MCP is useful for connecting agents to:&lt;/p&gt;

&lt;h3&gt;
  
  
  Documentation Systems
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AWS Documentation
Azure Documentation
Internal Knowledge Bases
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Databases
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PostgreSQL
MySQL
MongoDB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Development Tools
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GitHub
GitLab
Jira
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Cloud Services
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AWS
Azure
Google Cloud
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Enterprise Systems
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CRM
ERP
HR Systems
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The possibilities are nearly endless.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 Why Developers Love MCP
&lt;/h2&gt;

&lt;p&gt;Without MCP:&lt;/p&gt;

&lt;p&gt;❌ Build every integration yourself&lt;/p&gt;

&lt;p&gt;❌ Maintain tool definitions&lt;/p&gt;

&lt;p&gt;❌ Handle protocol changes&lt;/p&gt;

&lt;p&gt;❌ Create custom wrappers&lt;/p&gt;

&lt;p&gt;With MCP:&lt;/p&gt;

&lt;p&gt;✅ Discover tools automatically&lt;/p&gt;

&lt;p&gt;✅ Reuse existing integrations&lt;/p&gt;

&lt;p&gt;✅ Standardized communication&lt;/p&gt;

&lt;p&gt;✅ Faster development&lt;/p&gt;

&lt;p&gt;✅ Easier maintenance&lt;/p&gt;

&lt;p&gt;MCP shifts focus from integration work to solving business problems.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;MCP stands for Model Context Protocol&lt;/li&gt;
&lt;li&gt;MCP allows agents to connect to external tool providers&lt;/li&gt;
&lt;li&gt;STDIO transport is perfect for local development&lt;/li&gt;
&lt;li&gt;Agents can automatically discover available tools&lt;/li&gt;
&lt;li&gt;MCP significantly reduces integration effort&lt;/li&gt;
&lt;li&gt;The AWS Documentation MCP Server provides direct access to official AWS information&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📚 Source Code
&lt;/h2&gt;

&lt;p&gt;GitHub Repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/d3vjamal/strands-agents-labs" rel="noopener noreferrer"&gt;https://github.com/d3vjamal/strands-agents-labs&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Next Lab
&lt;/h2&gt;

&lt;p&gt;In the next lab, we'll explore remote MCP servers and learn how agents can connect to tools running on different machines and services across the network.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔗 Continue Learning
&lt;/h2&gt;

&lt;p&gt;⬅️ &lt;strong&gt;Previous Lab&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/d3vjamal/-lab-04b-building-a-web-search-tool-for-ai-agents-strands-agentic-ai-5b30"&gt;Lab 04B: Building a Web Search Tool for AI Agents&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;➡️ &lt;strong&gt;Next Lab&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.toNEXT_ARTICLE_URL"&gt;Lab 06: Remote MCP Servers&lt;/a&gt;&lt;/p&gt;




</description>
      <category>strandsagent</category>
      <category>bedrockaws</category>
      <category>agentai</category>
    </item>
    <item>
      <title># 🌐 Lab 04B: Building a Web Search Tool for AI Agents | Strands Agentic AI</title>
      <dc:creator>Jamal</dc:creator>
      <pubDate>Sun, 31 May 2026 03:52:57 +0000</pubDate>
      <link>https://dev.to/d3vjamal/-lab-04b-building-a-web-search-tool-for-ai-agents-strands-agentic-ai-5b30</link>
      <guid>https://dev.to/d3vjamal/-lab-04b-building-a-web-search-tool-for-ai-agents-strands-agentic-ai-5b30</guid>
      <description>&lt;p&gt;Large Language Models are powerful, but they have one major limitation:&lt;/p&gt;

&lt;p&gt;They only know what they were trained on.&lt;/p&gt;

&lt;p&gt;What if you want your AI agent to access the latest information from the web?&lt;/p&gt;

&lt;p&gt;That's where custom tools become incredibly useful.&lt;/p&gt;

&lt;p&gt;In this lab, you'll build a custom web search tool using DuckDuckGo Search (DDGS) and connect it to a Strands Agent. This allows the agent to retrieve up-to-date information and provide responses based on real-time search results.&lt;/p&gt;

&lt;p&gt;By the end of this lab, you'll have a Recipe Assistant that can search the web for recipes and cooking information.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 What You'll Learn
&lt;/h2&gt;

&lt;p&gt;In this lab, you'll learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to create a custom web search tool&lt;/li&gt;
&lt;li&gt;How to integrate third-party Python libraries into Strands tools&lt;/li&gt;
&lt;li&gt;How agents use tools to access live information&lt;/li&gt;
&lt;li&gt;How to handle API errors gracefully&lt;/li&gt;
&lt;li&gt;How to build a specialized AI assistant&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤖 Why Web Search Matters
&lt;/h2&gt;

&lt;p&gt;LLMs have knowledge cutoffs.&lt;/p&gt;

&lt;p&gt;For example, an LLM may know:&lt;/p&gt;

&lt;p&gt;✅ How recipes work&lt;/p&gt;

&lt;p&gt;✅ Common cooking techniques&lt;/p&gt;

&lt;p&gt;✅ Popular dishes&lt;/p&gt;

&lt;p&gt;But it may not know:&lt;/p&gt;

&lt;p&gt;❌ Latest recipes&lt;/p&gt;

&lt;p&gt;❌ Current food trends&lt;/p&gt;

&lt;p&gt;❌ Newly published cooking content&lt;/p&gt;

&lt;p&gt;❌ Real-time information&lt;/p&gt;

&lt;p&gt;A web search tool solves this problem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Question
      ↓
Agent Analysis
      ↓
Web Search Tool
      ↓
Search Results
      ↓
Agent Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of relying only on training data, the agent can retrieve fresh information from the web.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before starting, make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python 3.10+&lt;/li&gt;
&lt;li&gt;AWS Account&lt;/li&gt;
&lt;li&gt;Amazon Bedrock access&lt;/li&gt;
&lt;li&gt;AWS credentials configured&lt;/li&gt;
&lt;li&gt;uv installed&lt;/li&gt;
&lt;li&gt;DDGS package installed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Install DDGS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;ddgs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📜 The Script
&lt;/h2&gt;

&lt;p&gt;Let's start by looking at the complete example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ddgs&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;DDGS&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ddgs.exceptions&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RatelimitException&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.models.bedrock&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BedrockModel&lt;/span&gt;

&lt;span class="c1"&gt;# Configure logging
&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;strands&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Define a websearch tool
&lt;/span&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;websearch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us-en&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Search the web to get updated information.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DDGS&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;max_results&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;max_results&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No results found.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;RatelimitException&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;RatelimitException: Please try again after a short delay.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Exception: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;


&lt;span class="c1"&gt;# Bedrock
&lt;/span&gt;&lt;span class="n"&gt;bedrock_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BedrockModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;YOUR_MODEL_ID&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eu-west-2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Create a recipe assistant agent
&lt;/span&gt;&lt;span class="n"&gt;recipe_agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bedrock_model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    You are RecipeBot, a helpful cooking assistant.
    Help users find recipes based on ingredients and answer cooking questions.
    Use the websearch tool to find recipes when users mention ingredients or to look up cooking information.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;websearch&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;recipe_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Suggest a recipe with chicken and capsicum.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Metrics : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's break it down step by step.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 1: Import Dependencies
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ddgs&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;DDGS&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ddgs.exceptions&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RatelimitException&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.models.bedrock&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BedrockModel&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We're importing:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Import&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Agent&lt;/td&gt;
&lt;td&gt;Creates the AI agent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tool&lt;/td&gt;
&lt;td&gt;Converts a Python function into a Strands tool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DDGS&lt;/td&gt;
&lt;td&gt;Performs DuckDuckGo searches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RatelimitException&lt;/td&gt;
&lt;td&gt;Handles search rate limits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;logging&lt;/td&gt;
&lt;td&gt;Displays runtime information&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BedrockModel&lt;/td&gt;
&lt;td&gt;Connects to Amazon Bedrock&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 2: Configure Logging
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;strands&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Logging helps us understand what the agent is doing during execution.&lt;/p&gt;

&lt;p&gt;Example output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INFO | strands.agent | Processing user request
INFO | strands.tools | Executing websearch tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During development, logs provide valuable visibility into agent behavior.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 3: Create the Web Search Tool
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;websearch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us-en&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function becomes a Strands tool through the &lt;code&gt;@tool&lt;/code&gt; decorator.&lt;/p&gt;

&lt;p&gt;The agent can now call this function whenever it needs information from the web.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parameters
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;keywords&lt;/td&gt;
&lt;td&gt;Search query&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;region&lt;/td&gt;
&lt;td&gt;Search region&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;max_results&lt;/td&gt;
&lt;td&gt;Maximum number of results&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;websearch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chicken capsicum recipe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⚙️ Step 4: Search Using DDGS
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DDGS&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_results&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;max_results&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;DDGS performs a DuckDuckGo search and returns matching results.&lt;/p&gt;

&lt;p&gt;These results are then sent back to the agent.&lt;/p&gt;

&lt;p&gt;The agent uses them to generate an informed response.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 5: Handle Errors Gracefully
&lt;/h2&gt;

&lt;p&gt;Production-ready tools should always handle failures.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rate Limit Handling
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;RatelimitException&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If too many requests are made, DDGS may temporarily block searches.&lt;/p&gt;

&lt;p&gt;Instead of crashing, the tool returns a helpful message.&lt;/p&gt;

&lt;h3&gt;
  
  
  General Error Handling
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unexpected failures are captured and returned safely.&lt;/p&gt;

&lt;p&gt;This improves reliability and user experience.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 Why the Docstring Matters
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Search the web to get updated information.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The docstring helps the LLM understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What the tool does&lt;/li&gt;
&lt;li&gt;When it should use it&lt;/li&gt;
&lt;li&gt;What kind of information it can retrieve&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of the docstring as instructions for the AI.&lt;/p&gt;

&lt;p&gt;A clear description leads to better tool selection.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 6: Configure Amazon Bedrock
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;bedrock_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BedrockModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;YOUR_MODEL_ID&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eu-west-2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This model powers the reasoning and decision-making process.&lt;/p&gt;

&lt;p&gt;The agent determines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whether web search is needed&lt;/li&gt;
&lt;li&gt;What search query to generate&lt;/li&gt;
&lt;li&gt;How to interpret results&lt;/li&gt;
&lt;li&gt;How to respond to users&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 7: Create a Specialized Recipe Agent
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;recipe_agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bedrock_model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    You are RecipeBot...
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;websearch&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This agent has a clear responsibility:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Find recipes
Answer cooking questions
Search the web when necessary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system prompt defines the agent's personality and capabilities.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 8: Ask the Agent a Question
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;recipe_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Suggest a recipe with chicken and capsicum.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent receives the request and reasons about how to solve it.&lt;/p&gt;

&lt;p&gt;Because recipe information may require fresh data, it can choose to invoke the web search tool.&lt;/p&gt;




&lt;h2&gt;
  
  
  ▶️ Run the Agent
&lt;/h2&gt;

&lt;p&gt;Execute the script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python agent.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv run labs/04b-websearch-tool/agent.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📊 Example Interaction
&lt;/h2&gt;

&lt;h3&gt;
  
  
  User
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Suggest a recipe with chicken and capsicum.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Agent Workflow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Request
      ↓
Agent Analysis
      ↓
Web Search Tool
      ↓
Recipe Search Results
      ↓
Response Generation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Agent Response
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You can make a Chicken Capsicum Stir Fry.

Ingredients:
- Chicken breast
- Capsicum
- Onion
- Garlic
- Soy sauce

Instructions:
1. Sauté garlic and onion.
2. Add chicken and cook thoroughly.
3. Add sliced capsicum.
4. Stir in soy sauce.
5. Serve hot with rice.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Actual responses may vary depending on model and search results.&lt;/p&gt;




&lt;h2&gt;
  
  
  📈 Understanding Agent Metrics
&lt;/h2&gt;

&lt;p&gt;At the end of the script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Metrics : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Metrics help monitor agent performance.&lt;/p&gt;

&lt;p&gt;You may see information such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Input Tokens
Output Tokens
Latency
Tool Calls
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These metrics become extremely useful when optimizing production agents.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔍 How Tool Calling Works
&lt;/h2&gt;

&lt;p&gt;When a user asks a question:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Prompt
      ↓
Agent Reasoning
      ↓
Tool Selection
      ↓
Web Search
      ↓
Results Returned
      ↓
Final Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent automatically decides whether the tool should be used.&lt;/p&gt;

&lt;p&gt;You don't need to manually call the function.&lt;/p&gt;

&lt;p&gt;This is what makes agentic systems powerful.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Real-World Use Cases
&lt;/h2&gt;

&lt;p&gt;The same approach can be used for:&lt;/p&gt;

&lt;h3&gt;
  
  
  News Assistant
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Search latest headlines
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Research Assistant
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Search technical documentation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Travel Assistant
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Search destinations and hotels
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Shopping Assistant
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Search products and reviews
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Support Assistant
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Search knowledge bases
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A web search tool unlocks countless possibilities.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Custom tools allow agents to access live information&lt;/li&gt;
&lt;li&gt;DDGS provides a simple web search capability&lt;/li&gt;
&lt;li&gt;Error handling improves reliability&lt;/li&gt;
&lt;li&gt;Docstrings help the LLM understand tool functionality&lt;/li&gt;
&lt;li&gt;Agents automatically decide when to invoke tools&lt;/li&gt;
&lt;li&gt;Tool-based architectures make AI assistants far more useful&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📚 Source Code
&lt;/h2&gt;

&lt;p&gt;GitHub Repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/d3vjamal/strands-agents-labs" rel="noopener noreferrer"&gt;https://github.com/d3vjamal/strands-agents-labs&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Previous Lab
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/d3vjamal/-lab-04a-creating-your-first-custom-tool-strands-agentic-ai-l7"&gt; Lab 04A: Creating Your First Custom Tool | Strands Agentic AI&lt;/a&gt;&lt;/p&gt;

</description>
      <category>stands</category>
      <category>awsbedrock</category>
      <category>agenticai</category>
    </item>
    <item>
      <title># 🛠️ Lab 04A: Creating Your First Custom Tool | Strands Agentic AI</title>
      <dc:creator>Jamal</dc:creator>
      <pubDate>Sun, 31 May 2026 03:48:47 +0000</pubDate>
      <link>https://dev.to/d3vjamal/-lab-04a-creating-your-first-custom-tool-strands-agentic-ai-l7</link>
      <guid>https://dev.to/d3vjamal/-lab-04a-creating-your-first-custom-tool-strands-agentic-ai-l7</guid>
      <description>&lt;p&gt;AI agents become truly powerful when they can perform actions beyond generating text.&lt;/p&gt;

&lt;p&gt;While large language models are great at reasoning, tools allow them to interact with the real world, process data, and execute custom logic.&lt;/p&gt;

&lt;p&gt;In this lab, you'll learn how to create your first custom tool using the &lt;code&gt;@tool&lt;/code&gt; decorator in Strands and expose it to an AI agent.&lt;/p&gt;

&lt;p&gt;By the end, your agent will be able to count words using your own Python function.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 What You'll Learn
&lt;/h2&gt;

&lt;p&gt;In this lab, you'll learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What tools are in Strands Agents&lt;/li&gt;
&lt;li&gt;How the &lt;code&gt;@tool&lt;/code&gt; decorator works&lt;/li&gt;
&lt;li&gt;How to create your own custom tool&lt;/li&gt;
&lt;li&gt;How agents automatically discover and use tools&lt;/li&gt;
&lt;li&gt;How tool docstrings help the LLM understand capabilities&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤖 Why Custom Tools Matter
&lt;/h2&gt;

&lt;p&gt;Without tools, an AI agent can only generate responses based on its training and reasoning.&lt;/p&gt;

&lt;p&gt;With tools, agents can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Query databases&lt;/li&gt;
&lt;li&gt;Call APIs&lt;/li&gt;
&lt;li&gt;Read files&lt;/li&gt;
&lt;li&gt;Write files&lt;/li&gt;
&lt;li&gt;Perform calculations&lt;/li&gt;
&lt;li&gt;Execute business logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of a language model as a brain.&lt;/p&gt;

&lt;p&gt;Tools are its hands.&lt;/p&gt;

&lt;p&gt;The brain can think about counting words, but a tool can perform the counting accurately and consistently.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before starting, make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python 3.10+&lt;/li&gt;
&lt;li&gt;AWS Account&lt;/li&gt;
&lt;li&gt;Amazon Bedrock access&lt;/li&gt;
&lt;li&gt;Access to a model such as &lt;code&gt;amazon.nova-2-lite-v1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;AWS credentials configured&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;uv&lt;/code&gt; installed&lt;/li&gt;
&lt;li&gt;Completed Lab 01 and Lab 02&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📜 The Script
&lt;/h2&gt;

&lt;p&gt;Let's start by looking at the complete example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Just an example of using creating your custom tool
&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.models.bedrock&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BedrockModel&lt;/span&gt;

&lt;span class="c1"&gt;# Bedrock
&lt;/span&gt;&lt;span class="n"&gt;bedrock_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BedrockModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="c1"&gt;# Set your preferred model ID here
&lt;/span&gt;    &lt;span class="n"&gt;model_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;YOUR_MODEL_ID&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eu-west-2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;word_count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Count words in text.

    This docstring is used by the LLM to understand the tool&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s purpose.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;


&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bedrock_model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;word_count&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;How many words are in this sentence?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's break it down step by step.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 1: Import Required Modules
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.models.bedrock&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BedrockModel&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We're importing:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Import&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Agent&lt;/td&gt;
&lt;td&gt;Creates the AI agent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tool&lt;/td&gt;
&lt;td&gt;Converts a Python function into a Strands tool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BedrockModel&lt;/td&gt;
&lt;td&gt;Connects the agent to Amazon Bedrock&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;tool&lt;/code&gt; decorator is the star of this lab.&lt;/p&gt;

&lt;p&gt;It allows Strands to expose a Python function to the language model.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 2: Configure Amazon Bedrock
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;bedrock_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BedrockModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;YOUR_MODEL_ID&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eu-west-2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates the model that powers the agent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parameters
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;model_id&lt;/td&gt;
&lt;td&gt;Bedrock model identifier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;region_name&lt;/td&gt;
&lt;td&gt;AWS region&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;temperature&lt;/td&gt;
&lt;td&gt;Controls creativity and randomness&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For utility tools, lower temperatures often produce more predictable results.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 3: Create a Custom Tool
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;word_count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Count words in text.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where the magic happens.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;@tool&lt;/code&gt; decorator transforms a normal Python function into a tool that the agent can invoke.&lt;/p&gt;

&lt;h3&gt;
  
  
  Function Breakdown
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;word_count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nb"&gt;int&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function simply splits text into words and returns the total count.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;word_count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hello world&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧠 Why the Docstring Matters
&lt;/h2&gt;

&lt;p&gt;One of the most important parts of a custom tool is the docstring.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Count words in text.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The LLM reads this description to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What the tool does&lt;/li&gt;
&lt;li&gt;When it should use it&lt;/li&gt;
&lt;li&gt;What inputs it expects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of the docstring as instructions for the AI.&lt;/p&gt;

&lt;p&gt;A clear docstring helps the model choose the correct tool at the correct time.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 4: Register the Tool
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bedrock_model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;word_count&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we provide the tool to the agent.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;word_count&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent now knows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The tool exists&lt;/li&gt;
&lt;li&gt;What it does&lt;/li&gt;
&lt;li&gt;How to call it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From this point forward, the model can decide when to use it.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 5: Ask the Agent a Question
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;How many words are in this sentence?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the agent receives this request, it reasons about the task.&lt;/p&gt;

&lt;p&gt;The model recognizes that counting words is exactly what the &lt;code&gt;word_count&lt;/code&gt; tool is designed to do.&lt;/p&gt;

&lt;p&gt;Instead of guessing, it invokes the tool and uses the result.&lt;/p&gt;




&lt;h2&gt;
  
  
  ▶️ Run the Agent
&lt;/h2&gt;

&lt;p&gt;Execute the script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv run labs/04a-custom-tool/agent.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python agent.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📊 Example Interaction
&lt;/h2&gt;

&lt;h3&gt;
  
  
  User
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;How many words are in this sentence?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Agent Reasoning
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This task requires counting words.
A tool named word_count is available.
I'll use the tool.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Tool Execution
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;word_count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;How many words are in this sentence?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Agent Response
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;There are 7 words in the sentence.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔍 How Tool Calling Works
&lt;/h2&gt;

&lt;p&gt;When a user sends a request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Prompt
     ↓
Agent Analysis
     ↓
Tool Selection
     ↓
Tool Execution
     ↓
Result Returned
     ↓
Final Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent automatically decides whether a tool should be used.&lt;/p&gt;

&lt;p&gt;You don't explicitly call the function yourself.&lt;/p&gt;

&lt;p&gt;The LLM handles that decision-making process.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Real-World Tool Examples
&lt;/h2&gt;

&lt;p&gt;The same pattern can be used to build more powerful tools:&lt;/p&gt;

&lt;h3&gt;
  
  
  Calculator Tool
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Date Tool
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;current_date&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Database Tool
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_customer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  AWS Tool
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;list_s3_buckets&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the foundation of building production-ready AI agents.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Tools extend the capabilities of AI agents&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;@tool&lt;/code&gt; decorator converts Python functions into agent tools&lt;/li&gt;
&lt;li&gt;Docstrings help the LLM understand tool functionality&lt;/li&gt;
&lt;li&gt;Agents automatically decide when to use tools&lt;/li&gt;
&lt;li&gt;Custom tools are the foundation of real-world agent workflows&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📚 Source Code
&lt;/h2&gt;

&lt;p&gt;Lab Source:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/d3vjamal/strands-agents-labs/tree/master/labs/04a-custom-tool" rel="noopener noreferrer"&gt;https://github.com/d3vjamal/strands-agents-labs/tree/master/labs/04a-custom-tool&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Next Lab
&lt;/h2&gt;

&lt;p&gt;In the next lab, we'll create more advanced tools with parameters and learn how agents can chain multiple tool calls together to solve complex tasks.&lt;/p&gt;

</description>
      <category>agenticai</category>
      <category>agents</category>
      <category>strandsagent</category>
      <category>awsbedrock</category>
    </item>
    <item>
      <title># 🔍 Lab 03: Logging and Debugging | Strands Agentic AI</title>
      <dc:creator>Jamal</dc:creator>
      <pubDate>Fri, 29 May 2026 19:32:16 +0000</pubDate>
      <link>https://dev.to/d3vjamal/-lab-03-logging-and-debugging-strands-agentic-ai-mk5</link>
      <guid>https://dev.to/d3vjamal/-lab-03-logging-and-debugging-strands-agentic-ai-mk5</guid>
      <description>&lt;p&gt;AI agents can perform complex tasks, call tools, and interact with external services. But what happens when something goes wrong?&lt;/p&gt;

&lt;p&gt;Without logging, debugging an AI agent can feel like trying to solve a puzzle with half the pieces missing.&lt;/p&gt;

&lt;p&gt;In this lab, you'll learn how to enable logging in Strands Agents so you can observe what's happening behind the scenes, understand agent behavior, and troubleshoot issues more effectively.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 What You'll Learn
&lt;/h2&gt;

&lt;p&gt;By the end of this lab, you'll understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How logging works in Strands Agents&lt;/li&gt;
&lt;li&gt;How to enable DEBUG logs&lt;/li&gt;
&lt;li&gt;How to inspect agent execution flow&lt;/li&gt;
&lt;li&gt;How to monitor tool invocations&lt;/li&gt;
&lt;li&gt;How logging helps troubleshoot agent issues&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤖 Why Logging Matters in Agentic AI
&lt;/h2&gt;

&lt;p&gt;Traditional applications usually follow a predictable flow.&lt;/p&gt;

&lt;p&gt;AI agents are different.&lt;/p&gt;

&lt;p&gt;A single prompt can trigger multiple reasoning steps, tool calls, and external API requests.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Prompt
     ↓
Agent Reasoning
     ↓
Tool Selection
     ↓
HTTP Request
     ↓
Response Processing
     ↓
Final Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If something fails during this process, logs help us understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which tool was selected&lt;/li&gt;
&lt;li&gt;What requests were sent&lt;/li&gt;
&lt;li&gt;What responses were received&lt;/li&gt;
&lt;li&gt;Where failures occurred&lt;/li&gt;
&lt;li&gt;How the agent reached its final answer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of logging as the flight recorder for your AI agent.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before starting, make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python 3.10+&lt;/li&gt;
&lt;li&gt;AWS Account&lt;/li&gt;
&lt;li&gt;Amazon Bedrock access&lt;/li&gt;
&lt;li&gt;Access to a model such as &lt;code&gt;amazon.nova-2-lite-v1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;AWS credentials configured&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;uv&lt;/code&gt; installed&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📜 The Script
&lt;/h2&gt;

&lt;p&gt;Let's start by looking at the complete example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# This lab is to teach you about logging
&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.models.bedrock&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BedrockModel&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands_tools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;file_read&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file_write&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http_request&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;

&lt;span class="c1"&gt;# Configure the root strands logger
&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;strands&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Add a handler to display logs in the terminal
&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;basicConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%(levelname)s | %(name)s | %(message)s&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;StreamHandler&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Configure the Bedrock model
&lt;/span&gt;&lt;span class="n"&gt;bedrock_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BedrockModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;YOUR_MODEL_ID&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eu-west-2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;system_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
Weather Information
    - You can also make HTTP requests to the National Weather Service API.
    - Process and display weather forecast data for locations in the United States.
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="c1"&gt;# Create the agent with tools
&lt;/span&gt;&lt;span class="n"&gt;local_agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bedrock_model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;http_request&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Ask the agent a question
&lt;/span&gt;&lt;span class="nf"&gt;local_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;what is the weather in new york?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's break it down.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 1: Configure Logging
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;

&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;strands&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;basicConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%(levelname)s | %(name)s | %(message)s&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;StreamHandler&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What is happening here?
&lt;/h3&gt;

&lt;p&gt;First, we configure Python's built-in logging module.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;strands&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells Strands to emit detailed debugging information.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;DEBUG&lt;/code&gt; level provides maximum visibility into agent execution.&lt;/p&gt;

&lt;p&gt;We then configure how logs appear in the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;basicConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%(levelname)s | %(name)s | %(message)s&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DEBUG | strands.agent | Processing user request
INFO | strands.tools | Executing HTTP request
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes logs easy to read and troubleshoot.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 2: Configure the Bedrock Model
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;bedrock_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BedrockModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;YOUR_MODEL_ID&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eu-west-2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we create the LLM that powers our agent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parameters
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;model_id&lt;/td&gt;
&lt;td&gt;Bedrock model identifier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;region_name&lt;/td&gt;
&lt;td&gt;AWS Region&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;temperature&lt;/td&gt;
&lt;td&gt;Controls response randomness&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A lower temperature produces more consistent and predictable responses.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 3: Define the Agent's Role
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;system_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
Weather Information
    - You can also make HTTP requests to the National Weather Service API.
    - Process and display weather forecast data for locations in the United States.
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system prompt acts as the agent's instructions.&lt;/p&gt;

&lt;p&gt;It tells the model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What task it should perform&lt;/li&gt;
&lt;li&gt;Which information sources are available&lt;/li&gt;
&lt;li&gt;How it should behave&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this case, the agent is focused on retrieving weather information.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 4: Add the HTTP Tool
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;http_request&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;http_request&lt;/code&gt; tool gives the agent the ability to access external APIs.&lt;/p&gt;

&lt;p&gt;Without tools, the agent can only rely on its training data.&lt;/p&gt;

&lt;p&gt;With tools, it can fetch live information from the internet.&lt;/p&gt;

&lt;p&gt;For weather data, the agent can query APIs and process real-time forecasts.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 5: Create the Agent
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;local_agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bedrock_model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;http_request&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This combines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The model&lt;/li&gt;
&lt;li&gt;The instructions&lt;/li&gt;
&lt;li&gt;The available tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;into a working AI agent.&lt;/p&gt;




&lt;h2&gt;
  
  
  ▶️ Run the Agent
&lt;/h2&gt;

&lt;p&gt;Invoke the agent using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;local_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;what is the weather in new york?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Analyze the request&lt;/li&gt;
&lt;li&gt;Decide whether a tool is needed&lt;/li&gt;
&lt;li&gt;Call the HTTP tool&lt;/li&gt;
&lt;li&gt;Retrieve weather information&lt;/li&gt;
&lt;li&gt;Generate a final response&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  📊 Example Debug Output
&lt;/h2&gt;

&lt;p&gt;When running the script, you'll see logs similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DEBUG | strands.agent | Processing user request
DEBUG | strands.agent | Selecting tool
INFO  | strands.tools | Executing HTTP request
INFO  | strands.tools | Response received
DEBUG | strands.agent | Generating final answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact output may vary depending on the model and SDK version.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔍 Understanding the Log Levels
&lt;/h2&gt;

&lt;h3&gt;
  
  
  DEBUG
&lt;/h3&gt;

&lt;p&gt;Most detailed level.&lt;/p&gt;

&lt;p&gt;Useful during development.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DEBUG | Agent selecting tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  INFO
&lt;/h3&gt;

&lt;p&gt;General execution information.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INFO | HTTP request executed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  WARNING
&lt;/h3&gt;

&lt;p&gt;Something unexpected happened, but execution continues.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WARNING | Missing optional parameter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  ERROR
&lt;/h3&gt;

&lt;p&gt;Execution failed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ERROR | Failed to call external API
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  💡 Why Developers Love Logs
&lt;/h2&gt;

&lt;p&gt;Imagine your agent gives an incorrect answer.&lt;/p&gt;

&lt;p&gt;Without logs:&lt;/p&gt;

&lt;p&gt;❌ No idea what happened.&lt;/p&gt;

&lt;p&gt;With logs:&lt;/p&gt;

&lt;p&gt;✅ See which tool was selected&lt;/p&gt;

&lt;p&gt;✅ Inspect API requests&lt;/p&gt;

&lt;p&gt;✅ Inspect responses&lt;/p&gt;

&lt;p&gt;✅ Find failures quickly&lt;/p&gt;

&lt;p&gt;✅ Improve prompts and tools&lt;/p&gt;

&lt;p&gt;Logs dramatically reduce debugging time.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Logging provides visibility into agent execution&lt;/li&gt;
&lt;li&gt;DEBUG logs help trace reasoning and tool usage&lt;/li&gt;
&lt;li&gt;Python's built-in logging module works seamlessly with Strands&lt;/li&gt;
&lt;li&gt;Logs make troubleshooting faster and easier&lt;/li&gt;
&lt;li&gt;Observability is essential for production-ready AI agents&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📚 Source Code
&lt;/h2&gt;

&lt;p&gt;GitHub Repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/d3vjamal/strands-agents-labs" rel="noopener noreferrer"&gt;https://github.com/d3vjamal/strands-agents-labs&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Next Lab
&lt;/h2&gt;

&lt;p&gt;In the next lab, we'll explore custom tools and learn how to extend Strands Agents with capabilities tailored to your own applications.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agenticai</category>
      <category>strands</category>
    </item>
    <item>
      <title>Lab 02 — HTTP Tools Integration; Strands Agentic AI</title>
      <dc:creator>Jamal</dc:creator>
      <pubDate>Fri, 29 May 2026 19:21:09 +0000</pubDate>
      <link>https://dev.to/d3vjamal/lab-02-http-tools-integration-strands-agentic-ai-415p</link>
      <guid>https://dev.to/d3vjamal/lab-02-http-tools-integration-strands-agentic-ai-415p</guid>
      <description>&lt;p&gt;Building My First AI Agent with Strands Agents: &lt;a href="https://dev.to/d3vjamal/building-my-first-ai-agent-with-strands-agents-3m0l"&gt;Part 1 link&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  🎯 Objective
&lt;/h2&gt;

&lt;p&gt;Give your agent the ability to &lt;strong&gt;fetch live data from the internet&lt;/strong&gt; using the &lt;code&gt;http_request&lt;/code&gt; tool. In this lab the agent calls the US National Weather Service API to answer a weather question.&lt;/p&gt;

&lt;h2&gt;
  
  
  📖 Background
&lt;/h2&gt;

&lt;p&gt;Most useful agents need to reach out to external services. The &lt;code&gt;http_request&lt;/code&gt; tool lets an agent make GET/POST/PUT/DELETE requests to any URL. The agent decides &lt;em&gt;which&lt;/em&gt; URL to call, parses the response, and presents it in natural language.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔑 Key Concepts
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;http_request&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Built-in Strands tool for making HTTP calls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;System Prompt&lt;/td&gt;
&lt;td&gt;Guides the agent on which APIs to use and how to interpret responses&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API chaining&lt;/td&gt;
&lt;td&gt;The agent may make multiple HTTP calls (e.g. get coordinates → get forecast)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  ⚙️ Prerequisites
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;AWS credentials configured&lt;/li&gt;
&lt;li&gt;Internet connectivity (the agent calls &lt;code&gt;api.weather.gov&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Dependencies installed (&lt;code&gt;uv sync&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Lab 02 : Agentic ai with http_request tool&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# This lab is to teach you about http_request tool
&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.models.bedrock&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BedrockModel&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands_tools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;file_read&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file_write&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http_request&lt;/span&gt;

&lt;span class="c1"&gt;# Configure the Bedrock model
&lt;/span&gt;&lt;span class="n"&gt;bedrock_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BedrockModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="c1"&gt;# Set your preferred model ID here (e.g., "global.amazon.nova-2-lite-v1:0")
&lt;/span&gt;    &lt;span class="n"&gt;model_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;YOUR_MODEL_ID&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eu-west-2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;system_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
Weather Information
    - You can also make HTTP requests to the National Weather Service API.
    - Process and display weather forecast data for locations in the United States.
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="c1"&gt;# - When retrieving weather information, first get coordinates using https://api.weather.gov/points/{latitude},{longitude},  or
#         https://api.weather.gov/points/{zipcode}, then use the returned forecast URL. You can make additional http requests as well.
&lt;/span&gt;
&lt;span class="c1"&gt;# Create the agent with tools
&lt;/span&gt;&lt;span class="n"&gt;local_agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Define a system Prompt
&lt;/span&gt;    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bedrock_model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;http_request&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;  &lt;span class="c1"&gt;# Add your custom tools here
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="nf"&gt;local_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;what is the weather in new york?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ▶️ How to Run
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv run labs/02-http-tools/agent.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧪 Exercises
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Try a different city&lt;/strong&gt; — Change &lt;code&gt;"new york"&lt;/code&gt; to another US city and see if the agent resolves the correct API endpoint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Combine tools&lt;/strong&gt; — Add &lt;code&gt;file_write&lt;/code&gt; so the agent saves the weather report to a file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non-US weather&lt;/strong&gt; — The NWS API only covers the US. Modify the system prompt to use a global weather API like OpenWeatherMap instead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error handling&lt;/strong&gt; — Disconnect from the internet and observe how the agent reacts.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;ALL LAB EXCERSIZE &lt;a href="https://github.com/d3vjamal/strands-agents-labs" rel="noopener noreferrer"&gt;GitHub Notes&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  📚 Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://strandsagents.com/latest/" rel="noopener noreferrer"&gt;Strands Tools — http_request&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.weather.gov/documentation/services-web-api" rel="noopener noreferrer"&gt;National Weather Service API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>agenticai</category>
      <category>strands</category>
      <category>aibuilding</category>
    </item>
    <item>
      <title>Building My First AI Agent with Strands Agents</title>
      <dc:creator>Jamal</dc:creator>
      <pubDate>Fri, 29 May 2026 19:06:35 +0000</pubDate>
      <link>https://dev.to/d3vjamal/building-my-first-ai-agent-with-strands-agents-3m0l</link>
      <guid>https://dev.to/d3vjamal/building-my-first-ai-agent-with-strands-agents-3m0l</guid>
      <description>&lt;p&gt;An agent is a program that uses a large-language model (LLM) to decide which actions to take based on a user's request. Strands Agents wraps this loop into a simple Python API.&lt;/p&gt;

&lt;p&gt;If you've been trying to build Agentic AI applications recently, you've probably noticed a major problem: &lt;strong&gt;boilerplate overload&lt;/strong&gt;. Frameworks like LangChain or LangGraph are incredibly powerful, but sometimes you just want a clean, fast, lightweight, and model-agnostic way to build production-ready agents.&lt;/p&gt;

&lt;p&gt;Enter &lt;strong&gt;Strands Agents&lt;/strong&gt;—a lean, modern open-source SDK designed to let developers build robust AI agents without the architectural bloat.&lt;/p&gt;

&lt;p&gt;In this 4-part series, we are going to explore how to take Strands from a blank screen to a production-grade multi-agent system. Let's get our hands dirty with Part 1!&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Quick Start
&lt;/h2&gt;

&lt;h2&gt;
  
  
  1. 🛠️ Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before we write code, let's set up a clean playground.&lt;/p&gt;

&lt;p&gt;Make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python 3.10+&lt;/li&gt;
&lt;li&gt;AWS account with access credentials (&lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt; and &lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt;) and access granted to the &lt;code&gt;amazon.nova-2-lite-v1&lt;/code&gt; (or another Bedrock model) on Amazon Bedrock&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.astral.sh/uv/getting-started/installation/" rel="noopener noreferrer"&gt;uv&lt;/a&gt; package manager&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. 🤖 What Is Agentic AI?
&lt;/h2&gt;

&lt;p&gt;Agentic AI refers to autonomous software systems powered by artificial intelligence that can perceive their environment, make decisions, and take actions independently to achieve specific goals.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. 📦 Installation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Clone the Repository
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/d3vjamal/strands-agents-labs.git
&lt;span class="nb"&gt;cd &lt;/span&gt;strands-agents-labs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;Lab 1: Run your first agent&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands_tools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;file_read&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file_write&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.models.bedrock&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BedrockModel&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;

&lt;span class="nf"&gt;load_dotenv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="n"&gt;bedrock_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BedrockModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="c1"&gt;# Set your preferred model ID here (e.g., "global.amazon.nova-2-lite-v1:0")
&lt;/span&gt;    &lt;span class="n"&gt;model_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;YOUR_MODEL_ID&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eu-west-2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;system_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are a an agent which can read and write files to current directory&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# Create the agent with tools
&lt;/span&gt;&lt;span class="n"&gt;local_agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Define a system Prompt
&lt;/span&gt;    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bedrock_model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;file_read&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file_write&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;  &lt;span class="c1"&gt;# Add your custom tools here
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="nf"&gt;local_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;can you create a weather.md file, with the content about current temperature in kolkata India right now?, if not able find weather put reason of it&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run your first lab :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv run labs/01-your-first-agent/agent.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📖 Background
&lt;/h2&gt;

&lt;p&gt;In this lab the agent is asked to create a markdown file with weather information. Because the agent does not have internet access, it must reason about what it &lt;em&gt;can&lt;/em&gt; do (write a file) and what it &lt;em&gt;cannot&lt;/em&gt; do (fetch live data) — a great first lesson in tool-aware reasoning.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔑 Key Concepts
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Agent&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The core class that ties together a model, tools, and a system prompt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;system_prompt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Instructions that shape the agent's personality and capabilities&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BedrockModel&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Model provider connecting to Amazon Bedrock&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;file_read&lt;/code&gt; / &lt;code&gt;file_write&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Built-in Strands tools for local file operations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;load_dotenv()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Loads AWS credentials from a &lt;code&gt;.env&lt;/code&gt; file&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Part 2 : &lt;a href="https://dev.to/d3vjamal/lab-02-http-tools-integration-strands-agentic-ai-415p"&gt;HTTP tool integration&lt;/a&gt;&lt;/p&gt;

</description>
      <category>agentic</category>
      <category>ai</category>
      <category>strandsagents</category>
    </item>
    <item>
      <title>Fix AWS amplify React app error on Access Denied error</title>
      <dc:creator>Jamal</dc:creator>
      <pubDate>Fri, 18 Dec 2020 03:07:32 +0000</pubDate>
      <link>https://dev.to/d3vjamal/fix-aws-amplify-react-app-error-on-access-denied-error-3cpj</link>
      <guid>https://dev.to/d3vjamal/fix-aws-amplify-react-app-error-on-access-denied-error-3cpj</guid>
      <description>&lt;p&gt;When I deployed my build react app on AWS amplify, the first landing page is able to load. However, when you defined a path in your router, and try to access it, you would hit Access Denied error:&lt;br&gt;
like /signin first page loaded but unable to go /signup route or any other routes .&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcrk8lrnzzqm7vfa7jp5h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcrk8lrnzzqm7vfa7jp5h.png" alt="Alt Text" width="800" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, what i did,&lt;/p&gt;

&lt;p&gt;Go AWS amplify console, select “ Rewrites and redirects ”, add a new rewrite and redirects, click on “ Open text editor ”, and add the below rule:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[{
    "source": "&amp;lt;/^[^.]+$|\\.(?!(css|gif|ico|jpg|js|png|txt|svg|woff|ttf)$)([^.]+$)/&amp;gt;",
    "target": "/index.html",
    "status": "200",
    "condition": null
}]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1a4dgc5htl6v5gih33in.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1a4dgc5htl6v5gih33in.png" alt="Alt Text" width="800" height="551"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Try again to access your url, it should work now.&lt;/p&gt;

&lt;p&gt;Stackoverflow answer:&lt;br&gt;
&lt;a href="https://stackoverflow.com/questions/63546586/access-denied-error-from-protected-routes-from-react-app-hosted-on-aws-amplify" rel="noopener noreferrer"&gt; https://stackoverflow.com/questions/63546586/access-denied-error-from-protected-routes-from-react-app-hosted-on-aws-amplify&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>react</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Docker Node Alpine Image Build Fails on node-gyp</title>
      <dc:creator>Jamal</dc:creator>
      <pubDate>Wed, 23 Sep 2020 09:23:28 +0000</pubDate>
      <link>https://dev.to/d3vjamal/docker-node-alpine-image-build-fails-on-node-gyp-585l</link>
      <guid>https://dev.to/d3vjamal/docker-node-alpine-image-build-fails-on-node-gyp-585l</guid>
      <description>&lt;h2&gt;
  
  
  Docker node:7.9-alpine unable to build package due python is not installed :Resolved
&lt;/h2&gt;

&lt;p&gt;I'm attempting to Dockerize a node.js application(Typescript). I'm using the node:12.18.4-alpine Docker image as a base.&lt;/p&gt;

&lt;p&gt;I go this&lt;/p&gt;

&lt;h2&gt;
  
  
  gyp ERR! configure error
&lt;/h2&gt;

&lt;p&gt;gyp ERR! stack Error: Can't find Python executable "python", you can set the PYTHON env variable.&lt;br&gt;
gyp ERR! stack at PythonFinder.failNoPython (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:484:19)&lt;br&gt;
gyp ERR! stack at PythonFinder. (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:406:16)&lt;br&gt;
gyp ERR! stack at F (/usr/local/lib/node_modules/npm/node_modules/which/which.js:68:16)&lt;br&gt;
gyp ERR! stack at E (/usr/local/lib/node_modules/npm/node_modules/which/which.js:80:29)&lt;br&gt;
gyp ERR! stack at /usr/local/lib/node_modules/npm/node_modules/which/which.js:89:16&lt;br&gt;
gyp ERR! stack at /usr/local/lib/node_modules/npm/node_modules/isexe/index.js:42:5&lt;br&gt;
gyp ERR! stack at /usr/local/lib/node_modules/npm/node_modules/isexe/mode.js:8:5&lt;br&gt;
gyp ERR! stack at FSReqCallback.oncomplete (fs.js:159:21)&lt;br&gt;
gyp ERR! System Linux 3.10.0-957.el7.x86_64&lt;br&gt;
gyp ERR! command "/usr/local/bin/node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "configure" "--fallback-to-build" "--module=/code/server/node_modules/bcrypt/lib/binding/bcrypt_lib.node" "--module_name=bcrypt_lib" "--module_path=/code/server/node_modules/bcrypt/lib/binding" "--napi_version=4" "--node_abi_napi=napi" "--napi_build_version=0" "--node_napi_label=node-v67"&lt;br&gt;
gyp ERR! cwd /code/server/node_modules/bcrypt&lt;br&gt;
gyp ERR! node -v v11.9.0&lt;br&gt;
gyp ERR! node-gyp -v v3.8.0&lt;br&gt;
gyp ERR! not ok&lt;br&gt;
node-pre-gyp ERR! build error&lt;br&gt;
node-pre-gyp ERR! stack Error: Failed to execute '/usr/local/bin/node /usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js configure --fallback-to-build --module=/code/server/node_modules/bcrypt/lib/binding/bcrypt_lib.node --module_name=bcrypt_lib --module_path=/code/server/node_modules/bcrypt/lib/binding --napi_version=4 --node_abi_napi=napi --napi_build_version=0 --node_napi_label=node-v67' (1)&lt;br&gt;
node-pre-gyp ERR! stack at ChildProcess. (/code/server/node_modules/bcrypt/node_modules/node-pre-gyp/lib/util/compile.js:83:29)&lt;br&gt;
node-pre-gyp ERR! stack at ChildProcess.emit (events.js:197:13)&lt;br&gt;
node-pre-gyp ERR! stack at maybeClose (internal/child_process.js:978:16)&lt;br&gt;
node-pre-gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:265:5)&lt;br&gt;
node-pre-gyp ERR! System Linux 3.10.0-957.el7.x86_64&lt;br&gt;
node-pre-gyp ERR! command "/usr/local/bin/node" "/code/server/node_modules/bcrypt/node_modules/.bin/node-pre-gyp" "install" "--fallback-to-build"&lt;br&gt;
node-pre-gyp ERR! cwd /code/server/node_modules/bcrypt&lt;br&gt;
node-pre-gyp ERR! node -v v11.9.0&lt;br&gt;
node-pre-gyp ERR! node-pre-gyp -v v0.12.0&lt;br&gt;
node-pre-gyp ERR! not ok&lt;br&gt;
Failed to execute '/usr/local/bin/node /usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js configure --fallback-to-build --module=/code/server/node_modules/bcrypt/lib/binding/bcrypt_lib.node --module_name=bcrypt_lib --module_path=/code/server/node_modules/bcrypt/lib/binding --napi_version=4 --node_abi_napi=napi --napi_build_version=0 --node_napi_label=node-v67' (1)&lt;br&gt;
npm WARN &lt;a href="mailto:backend-botmanagementservice@1.0.0"&gt;backend-botmanagementservice@1.0.0&lt;/a&gt; No description&lt;br&gt;
npm WARN &lt;a href="mailto:backend-botmanagementservice@1.0.0"&gt;backend-botmanagementservice@1.0.0&lt;/a&gt; No repository field.&lt;br&gt;
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: &lt;a href="mailto:fsevents@1.2.7"&gt;fsevents@1.2.7&lt;/a&gt; (node_modules/fsevents):&lt;br&gt;
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for &lt;a href="mailto:fsevents@1.2.7"&gt;fsevents@1.2.7&lt;/a&gt;: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})&lt;br&gt;
........&lt;/p&gt;

&lt;p&gt;my docker file was&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt; &lt;span class="c"&gt;#MY first stage, that is the Builder&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:12.18.4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;ts-sample-builder&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm run clean
&lt;span class="k"&gt;RUN &lt;/span&gt;npm run build
&lt;span class="c"&gt;# My Second stage, that creates an image for production&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:12.18.4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;ts-sample-prod&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=ts-sample-builder ./app/dist ./dist&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package* ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--production&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; npm run start-prod&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3001&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To reduce image size I change node version node:12.18.4-alpine then it caches issues as I mentioned above.&lt;/p&gt;

&lt;p&gt;When using alpine, you need to install build dependencies for some node modules to be able to be built natively. It should probably be documented&lt;br&gt;
Note:&lt;br&gt;
if just use the base as node:12 or any other version your image size will be more than 1GB some cases.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.freecodecamp.org/news/speed-up-node-re-builds-leveraging-docker-multi-stage-builds-and-save-money-65189a4ab115/" rel="noopener noreferrer"&gt;How to speed up Node re-builds by leveraging Docker multi-stage builds&lt;/a&gt;&lt;br&gt;
if you are using alpine, you need to install build dependencies for some node module to be able to be built natively.&lt;/p&gt;

&lt;p&gt;Example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:8.12-alpine&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8080&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="c"&gt;#python&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apk add &lt;span class="nt"&gt;--no-cache&lt;/span&gt; &lt;span class="nt"&gt;--virtual&lt;/span&gt; .gyp &lt;span class="se"&gt;\
&lt;/span&gt;        python &lt;span class="se"&gt;\
&lt;/span&gt;        make &lt;span class="se"&gt;\
&lt;/span&gt;        g++ &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apk del .gyp
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["npm", "start"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Docker and Node.js Best Practices&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md#node-gyp-alpine" rel="noopener noreferrer"&gt;Docker and Node.js Best Practices&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I will suggest you for checking bcrypt $ bcryptjs npm docs.&lt;br&gt;
&lt;a href="https://www.npmjs.com/package/bcrypt#dependencies" rel="noopener noreferrer"&gt;node-gyp only works with stable/released versions of node. Since the bcrypt module uses node-gyp to build and install, you'll need a stable version of node to use bcrypt. If you do not, you'll likely see an error that starts with:&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkrq1f7c8by3mnicz7r53.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkrq1f7c8by3mnicz7r53.png" alt="Alt Text" width="800" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the end, It resolves all issues like slow build  &amp;amp;Python is not installed &amp;amp;, etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#My first stage, that is the Builder
FROM  node:12.18.4-buster AS build
#RUN apk add --update --no-cache \
#    python \
#    make \
#    g++
COPY . .
# If you have native dependencies, you'll need extra tools
RUN npm install
#RUN npm install
RUN npm run build
RUN npm prune --production
#CMD npm run start-prod
#EXPOSE 3001
## My Second stage, that creates an image for production
FROM node:12.18.4-alpine
WORKDIR /app
COPY --from=build ./dist ./dist
COPY --from=build ./node_modules ./node_modules
CMD npm run start-prod
EXPOSE 3001
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It worked for me! &lt;/p&gt;

&lt;p&gt;learn more about multi staging.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/capital-one-tech/multi-stage-builds-and-dockerfile-b5866d9e2f84" rel="noopener noreferrer"&gt;Using Multi-Stage Builds to Simplify And Standardize Build Processes&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>beginners</category>
      <category>typescript</category>
      <category>node</category>
    </item>
    <item>
      <title>Add Me to Search: Google Launches Virtual Business Cards</title>
      <dc:creator>Jamal</dc:creator>
      <pubDate>Wed, 12 Aug 2020 17:01:47 +0000</pubDate>
      <link>https://dev.to/d3vjamal/add-me-to-search-google-launches-virtual-business-cards-gg3</link>
      <guid>https://dev.to/d3vjamal/add-me-to-search-google-launches-virtual-business-cards-gg3</guid>
      <description>&lt;p&gt;Google is testing virtual business cards in search results that show up when a person’s name is searched for.&lt;/p&gt;

&lt;p&gt;Now rolling out in India, Google’s new ‘people cards’ let individuals highlight themselves in search results like never before.&lt;br&gt;
For searchers, it can be challenging to find information about specific people if they don’t have a strong online presence.&lt;/p&gt;

&lt;p&gt;Google India Tweet :&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5upabs650uxn0zdwhp2l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5upabs650uxn0zdwhp2l.png" alt="Alt Text" width="581" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google aims to address these challenges with people cards:&lt;/p&gt;

&lt;p&gt;Today, we are solving these challenges with a new feature called people cards. It’s like a virtual visiting card, where you can highlight your existing website or social profiles you want people to visit, plus other information about yourself that you want others to know.&lt;/p&gt;

&lt;p&gt;People cards are designed for business professionals, performers, influencers, entrepreneurs, job hunters, freelancers, or anyone looking to grow their presence online.&lt;/p&gt;

&lt;p&gt;The prime purpose of people cards is to allow individuals to have a public profile on Google Search that will be displayed on top of all results. It was initially spotted as profile cards in February.&lt;/p&gt;

&lt;p&gt;Google claims that with people cards, it is aiming to provide “helpful and reliable information” to the public. Thus, it gives the option to all users to flag abuse, impersonation, or even low-quality content, if they find anything odd through people cards. The search giant is also touting to have a combination of human review and automated techniques in place to flag policy violating content. Furthermore, only one people card is allowed per Google Account to limit fake profiles.&lt;/p&gt;

&lt;p&gt;Individuals who have already created their cards on Google have the ability to opt-out of the experience anytime. In case of people who share the same name, Google Search will show multiple modules.&lt;/p&gt;

&lt;h1&gt;
  
  
  How secure is People Cards?
&lt;/h1&gt;

&lt;p&gt;To make sure people find reliable and helpful information, the tech giant has put together several protections and controls. It has also added safeguard mechanisms to protect against offensive content.&lt;/p&gt;

&lt;p&gt;There is a feedback button with the help of which users can identify and report low-quality information or a card that they believe was created by an impersonator.&lt;/p&gt;

&lt;p&gt;For people looking to find someone on Search with their name, the card will be available. There will be a module with the name, profession and location which users can tap to see their card.&lt;/p&gt;

&lt;p&gt;For people who share the same name, the Search will show multiple modules. The unique information will help users distinguish between different individuals to find accurate information.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to create your own people card on Google
&lt;/h2&gt;

&lt;p&gt;To create your own people card, sign into your Google Account and search for “add me to Search”. You'll now see a prompt saying, “Add yourself to Google Search.” Tap that prompt and then you'll be asked to provide your phone number that will be verified through a six-digit unique code to begin the process.&lt;/p&gt;

&lt;p&gt;Google said that for every new card, the user must authenticate the account with a unique mobile number. He/she will have complete control of the information to be included on the card and can opt-out of the experience anytime, which will stop their details from appearing in Search.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuixetedrov8kjxfhmnf1.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuixetedrov8kjxfhmnf1.jpeg" alt="Alt Text" width="300" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image credit:Google Image search&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to create your People Card on Google Search&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Step 1: To create a People Card, users will first need to sign in to their Google Account, search for their name on Google Search&lt;/p&gt;

&lt;p&gt;Step 2: Tap on the "add me to Search" option that appears on the page&lt;/p&gt;

&lt;p&gt;Step 3: Upload an image of yourself from your Google account, add a description and links to social profiles or websites. You can even include your phone number or email address if you want it on your virtual visiting card&lt;/p&gt;

&lt;p&gt;Step 4: Tap on the "save" option and that's it.&lt;/p&gt;

&lt;h5&gt;
  
  
  hope you find this informative
&lt;/h5&gt;

</description>
      <category>beginners</category>
      <category>social</category>
    </item>
  </channel>
</rss>
