<?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>Forem: Mindy Jen</title>
    <description>The latest articles on Forem by Mindy Jen (@mindy_jen_phd).</description>
    <link>https://forem.com/mindy_jen_phd</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%2F3819643%2F9d36d192-fe1e-4811-9b5a-b4aa2c8308c7.jpg</url>
      <title>Forem: Mindy Jen</title>
      <link>https://forem.com/mindy_jen_phd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mindy_jen_phd"/>
    <language>en</language>
    <item>
      <title>Building LinkedIN Job Application Agents - Part 3</title>
      <dc:creator>Mindy Jen</dc:creator>
      <pubDate>Sun, 05 Apr 2026 23:34:17 +0000</pubDate>
      <link>https://forem.com/mindy_jen_phd/building-linkedin-job-application-agents-part-3-in6</link>
      <guid>https://forem.com/mindy_jen_phd/building-linkedin-job-application-agents-part-3-in6</guid>
      <description>&lt;h2&gt;
  
  
  🎯 Project Overview
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;HunterAgent&lt;/code&gt; transforms the tedious job application process into an intelligent, automated workflow. Instead of spending hours crafting resumes and cover letters for each position, candidates can focus on interview preparation while AI handles the repetitive tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 AI Agent Architecture
&lt;/h2&gt;

&lt;p&gt;The system consists of 6 specialized AI agents, all using OpenAI’s Responses API:&lt;/p&gt;

&lt;p&gt;🔍 JobDiscoveryAgent: Real web search for job opportunities on LinkedIn, Indeed with URL validation&lt;br&gt;
📄 ResumeOptimizerAgent (ResumeManager): AI-powered resume customization with industry research and ATS optimization&lt;br&gt;
✍️ CoverLetterAgent (LetterWriter): Personalized cover letters with live company research and multiple tone variations&lt;br&gt;
🚀 ApplicationSubmitterAgent: Automated form filling and submission using Playwright MCP integration [planned; not implemented yet]&lt;br&gt;
📧 EmailNotificationAgent: Send a daily digest with all matching jobs to your Gmail. [Gmail MCP integration for workflow updates and application confirmations. (planned - not implemented yet)] &lt;br&gt;
👥 NetworkContactsAgent: Identify 3 people or the employee directory in the target company.&lt;/p&gt;

&lt;h2&gt;
  
  
  🛠️ Technology Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Frontend: Streamlit + Pandas (Python web framework)&lt;/li&gt;
&lt;li&gt;Backend: Integrated Python application&lt;/li&gt;
&lt;li&gt;Database: Supabase (PostgreSQL + Storage)&lt;/li&gt;
&lt;li&gt;AI: OpenAI SDK for intelligent agents&lt;/li&gt;
&lt;li&gt;LinkedIn Scraping: &lt;a href="https://github.com/stickerdaniel/linkedin-mcp-server" rel="noopener noreferrer"&gt;linkedin-mcp-server&lt;/a&gt; via MCP for web scraping&lt;/li&gt;
&lt;li&gt;Indeed Scraping: requests + BeautifulSoup4&lt;/li&gt;
&lt;li&gt;Browser Automation: Playwright&lt;/li&gt;
&lt;li&gt;Email: Python smtplib for notifications (Gmail SMTP)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🚀 Recent Achievements (April 5, 2026)&lt;/p&gt;

&lt;p&gt;✅ ALL 6 AI agents migrated to &lt;code&gt;OpenAI&lt;/code&gt; Responses API&lt;br&gt;
✅ Real web search integration working in production&lt;br&gt;
✅ Fixed all broken imports and API references&lt;br&gt;
✅ Complete multi-agent orchestration system implemented&lt;br&gt;
✅ Production-ready foundation for automated job applications&lt;/p&gt;

&lt;p&gt;📈 Technical Metrics&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agents: 6 production-ready AI agents&lt;/li&gt;
&lt;li&gt;API Migration: 100% Responses API adoption&lt;/li&gt;
&lt;li&gt;Web Search: Real-time job discovery implemented&lt;/li&gt;
&lt;li&gt;Import Issues: All resolved (0 broken imports)&lt;/li&gt;
&lt;li&gt;Test Coverage: All core components verified&lt;/li&gt;
&lt;li&gt;Architecture: Unified BaseAgent pattern established&lt;/li&gt;
&lt;/ul&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%2Fuploads%2Farticles%2Fyctg3zvau0llvec9pt88.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%2Fuploads%2Farticles%2Fyctg3zvau0llvec9pt88.png" alt=" " width="800" height="287"&gt;&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%2Fuploads%2Farticles%2Fuzd9ykimx8njaq1mbw2a.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%2Fuploads%2Farticles%2Fuzd9ykimx8njaq1mbw2a.png" alt=" " width="800" height="547"&gt;&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%2Fuploads%2Farticles%2Fg81cty1aww8wkb4snb71.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%2Fuploads%2Farticles%2Fg81cty1aww8wkb4snb71.png" alt=" " width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>openai</category>
      <category>automation</category>
    </item>
    <item>
      <title>Building LinkedIN Job Application Agents - Part 2</title>
      <dc:creator>Mindy Jen</dc:creator>
      <pubDate>Sat, 04 Apr 2026 22:32:21 +0000</pubDate>
      <link>https://forem.com/mindy_jen_phd/building-linkedin-job-application-agents-part-2-34af</link>
      <guid>https://forem.com/mindy_jen_phd/building-linkedin-job-application-agents-part-2-34af</guid>
      <description>&lt;h2&gt;
  
  
  The Technology Stack
&lt;/h2&gt;

&lt;p&gt;Here’s what I built the MVP with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Frontend: Streamlit + Pandas (Python web framework)&lt;/li&gt;
&lt;li&gt;Backend: Integrated Python application&lt;/li&gt;
&lt;li&gt;Database: Supabase (PostgreSQL + Storage)&lt;/li&gt;
&lt;li&gt;AI: OpenAI SDK for intelligent agents&lt;/li&gt;
&lt;li&gt;LinkedIn Scraping: &lt;a href="https://github.com/stickerdaniel/linkedin-mcp-server" rel="noopener noreferrer"&gt;linkedin-mcp-server&lt;/a&gt; via MCP for web scraping&lt;/li&gt;
&lt;li&gt;Indeed Scraping: requests + BeautifulSoup4&lt;/li&gt;
&lt;li&gt;Browser Automation: Playwright&lt;/li&gt;
&lt;li&gt;Email: Python smtplib for notifications (Gmail SMTP)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ Working Features:&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-page Streamlit Application
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Dashboard with metrics and analytics&lt;/li&gt;
&lt;li&gt;Navigation between Resume Manager, Job Search, Applications, etc.&lt;/li&gt;
&lt;li&gt;Clean, professional UI with sidebar navigation&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Database Layer with Smart Fallbacks
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Complete ORM with Supabase integration&lt;/li&gt;
&lt;li&gt;Mock mode for development without database&lt;/li&gt;
&lt;li&gt;Proper error handling and graceful degradation&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Configuration Management
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Environment-based configuration&lt;/li&gt;
&lt;li&gt;Secure credential storage &lt;/li&gt;
&lt;li&gt;Easy deployment setup&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Developer Experience
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Comprehensive test suite&lt;/li&gt;
&lt;li&gt;One-command startup script&lt;/li&gt;
&lt;li&gt;Automated health checks&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Resume Optimization Agent: AI that tailors resumes to job descriptions
&lt;/h2&gt;

&lt;p&gt;Stop Losing Jobs to &lt;code&gt;ATS&lt;/code&gt; Filters: How AI Resume Tailoring Changes Everything&lt;/p&gt;

&lt;p&gt;Getting past Applicant Tracking Systems (ATS) is one of the biggest challenges in today's job market. Even highly qualified candidates get filtered out simply because their resume doesn't contain the right keywords. That's where AI-powered resume tailoring makes a real difference.                                                                    &lt;/p&gt;

&lt;p&gt;With the &lt;code&gt;Resume Optimizer&lt;/code&gt;, you can tailor your resume to any specific job in seconds — no manual rewriting required.    &lt;/p&gt;

&lt;p&gt;Just navigate to the &lt;code&gt;Resume&lt;/code&gt; page, open the &lt;code&gt;Optimize&lt;/code&gt; tab, select a job from your list, and choose your &lt;code&gt;optimization mode&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Three modes are available depending on what your resume needs most:                                                     &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Keyword&lt;/code&gt; mode analyzes the job description and naturally injects missing ATS keywords into your existing content — without making it sound robotic or keyword-stuffed.                                                                   &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Skills&lt;/code&gt; mode intelligently reorders your skills section so the most relevant abilities appear first, instantly signaling to both ATS systems and recruiters that you're a strong match.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Experience&lt;/code&gt; mode rewrites your bullet points using language that mirrors the job description, highlighting achievements and responsibilities most relevant to the role.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each optimization preserves your actual experience — nothing is invented. The result is a resume that speaks the employer's language, passes ATS filters, and puts your best qualifications front and center.&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%2Fuploads%2Farticles%2F0reajo4dk1ta9m3t00ke.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%2Fuploads%2Farticles%2F0reajo4dk1ta9m3t00ke.png" alt=" " width="800" height="335"&gt;&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%2Fuploads%2Farticles%2Fzyxsi5ppai072vni09fr.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%2Fuploads%2Farticles%2Fzyxsi5ppai072vni09fr.png" alt=" " width="800" height="526"&gt;&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%2Fuploads%2Farticles%2F8jr6hx1itsc56caddjvl.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%2Fuploads%2Farticles%2F8jr6hx1itsc56caddjvl.png" alt=" " width="800" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Cover Letter Agent: Personalized cover letter generation
&lt;/h2&gt;

&lt;p&gt;Never Send a Generic Cover Letter Again: AI-Powered Personalization at Scale&lt;/p&gt;

&lt;p&gt;A great cover letter can be the difference between landing an interview and being overlooked. But writing a tailored letter for every application is exhausting — most job seekers either skip it or send the same generic template everywhere. AI changes that entirely.&lt;/p&gt;

&lt;p&gt;With the Cover Letter Generator, you can produce a fully &lt;strong&gt;personalized&lt;/strong&gt; cover letter for any job in seconds. Simply select a job from your scraped listings, choose a tone that matches your personality and the company culture, and let &lt;code&gt;GPT-4o-mini&lt;/code&gt; do the writing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Four tones&lt;/strong&gt; are available to suit any situation. &lt;code&gt;Professional&lt;/code&gt; delivers a formal, polished letter built around concrete achievements. &lt;code&gt;Enthusiastic&lt;/code&gt; channels genuine excitement about the role while staying appropriate. &lt;code&gt;Confident&lt;/code&gt; leads with impact statements and asserts your value directly. &lt;code&gt;Creative&lt;/code&gt; opens with a memorable hook that makes your application stand out.&lt;/p&gt;

&lt;p&gt;Behind the scenes, the generator researches the company — its culture, tech stack, and values — and cross-references your resume to highlight the most relevant experience. Every letter is three focused paragraphs, written specifically for that company and role.&lt;/p&gt;

&lt;p&gt;The result is a cover letter that feels human, reads naturally, and speaks directly to what the employer is looking for — generated in under 30 seconds.&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%2Fuploads%2Farticles%2Feq5agsi2xtksjda0bk5u.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%2Fuploads%2Farticles%2Feq5agsi2xtksjda0bk5u.png" alt=" " width="800" height="512"&gt;&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%2Fuploads%2Farticles%2F9ortmsa1yxs4nym8fjfx.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%2Fuploads%2Farticles%2F9ortmsa1yxs4nym8fjfx.png" alt=" " width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>openai</category>
      <category>automation</category>
    </item>
    <item>
      <title>Building LinkedIN Job Application Agents - Part 1</title>
      <dc:creator>Mindy Jen</dc:creator>
      <pubDate>Sat, 04 Apr 2026 15:49:46 +0000</pubDate>
      <link>https://forem.com/mindy_jen_phd/building-linkedin-job-application-agents-part-1-13k</link>
      <guid>https://forem.com/mindy_jen_phd/building-linkedin-job-application-agents-part-1-13k</guid>
      <description>&lt;h2&gt;
  
  
  The Problem: Job Applications Are a Time Sink
&lt;/h2&gt;

&lt;p&gt;Job searching is broken. Candidates spend hours crafting resumes for each position, writing personalized cover letters, and manually filling out repetitive application forms. What if we could automate this entire process using AI?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That’s exactly what I set out to build: HunterAgent&lt;/strong&gt; — an AI-powered system that automatically discovers jobs, optimizes resumes, generates cover letters, and submits applications on behalf of job seekers.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Plan (Mar. 2026): Full Automation Stack
&lt;/h2&gt;

&lt;p&gt;The vision was ambitious:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Job Discovery Agent: Scrape job sites using web automation&lt;/li&gt;
&lt;li&gt;Resume Optimization Agent: AI-powered resume customization for each job&lt;/li&gt;
&lt;li&gt;Cover Letter Agent: Generate personalized cover letters&lt;/li&gt;
&lt;li&gt;Application Submission Agent: Automate form filling and submission&lt;/li&gt;
&lt;li&gt;Email Notification Agent: Keep users informed of all activities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A technical deep-dive into integrating AI agents with &lt;code&gt;Streamlit&lt;/code&gt; UI and &lt;code&gt;Supabase&lt;/code&gt; for job application automation -&lt;/p&gt;

&lt;p&gt;The Journey So Far...&lt;/p&gt;

&lt;p&gt;Today marks a significant milestone in the HunterAgent project — I’ve successfully transformed three standalone AI agents into a fully integrated web application with persistent data storage. This blog post chronicles the technical challenges, architectural decisions, and breakthrough moments that brought our job application automation system to life.&lt;/p&gt;

&lt;p&gt;What had been Built Today:&lt;/p&gt;

&lt;p&gt;Core Achievement: Complete System Integration&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;3 AI Agents fully integrated with Streamlit UI&lt;/li&gt;
&lt;li&gt;Supabase Database with 11 production tables&lt;/li&gt;
&lt;li&gt;Real-time Processing with async/await patterns&lt;/li&gt;
&lt;li&gt;Persistent Data Storage for all agent results&lt;/li&gt;
&lt;li&gt;Production-Ready Application running at localhost:8501&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Three AI Agents
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Resume Optimization Agent
&lt;/h4&gt;

&lt;p&gt;Purpose: AI-powered resume customization for specific job applications&lt;/p&gt;

&lt;p&gt;Key Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Resume parsing and content extraction&lt;/li&gt;
&lt;li&gt;AI-powered optimization with company research&lt;/li&gt;
&lt;li&gt;Quality scoring and match analysis&lt;/li&gt;
&lt;li&gt;Multiple optimization approaches (keyword-focused, skills-based, experience-focused)&lt;/li&gt;
&lt;li&gt;Downloadable optimized resumes&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Cover Letter Generation Agent
&lt;/h4&gt;

&lt;p&gt;Purpose: Personalized cover letter creation with company research&lt;/p&gt;

&lt;p&gt;Key Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiple letter tones (professional, enthusiastic, confident, creative)&lt;/li&gt;
&lt;li&gt;Company research integration&lt;/li&gt;
&lt;li&gt;Candidate information processing&lt;/li&gt;
&lt;li&gt;Cover letter library with search and filtering&lt;/li&gt;
&lt;li&gt;Quality scoring and personalization metrics&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Job Discovery Agent
&lt;/h4&gt;

&lt;p&gt;Purpose: Intelligent job search with market analysis&lt;/p&gt;

&lt;p&gt;Key Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multi-criteria job search&lt;/li&gt;
&lt;li&gt;Market trend analysis&lt;/li&gt;
&lt;li&gt;Company research capabilities&lt;/li&gt;
&lt;li&gt;Saved jobs management&lt;/li&gt;
&lt;li&gt;Real-time filtering and sorting&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Technical Architecture
&lt;/h2&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%2Fuploads%2Farticles%2Fk7cqpcmvlsxrir9hx7d9.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%2Fuploads%2Farticles%2Fk7cqpcmvlsxrir9hx7d9.png" alt=" " width="800" height="282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  OpenAI Responses API Integration
&lt;/h3&gt;

&lt;p&gt;We chose OpenAI’s new Responses API for its structured output capabilities and web search integration. This allows our agents to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Access real-time company information&lt;/li&gt;
&lt;li&gt;Generate structured JSON responses&lt;/li&gt;
&lt;li&gt;Handle complex multi-step reasoning&lt;/li&gt;
&lt;li&gt;Integrate web search seamlessly &lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Streamlit UI Framework
&lt;/h3&gt;

&lt;p&gt;Streamlit provided the perfect balance of simplicity and functionality:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Rapid Development: Built complete UI in hours, not days&lt;/li&gt;
&lt;li&gt;Session State Management: Persistent data across user interactions&lt;/li&gt;
&lt;li&gt;Async Support: Native support for async/await patterns&lt;/li&gt;
&lt;li&gt;Component Ecosystem: Rich set of UI components out of the box&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Supabase Database Integration
&lt;/h3&gt;

&lt;p&gt;Supabase offered the ideal backend solution:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;PostgreSQL: Full SQL capabilities with JSON support&lt;/li&gt;
&lt;li&gt;Real-time Features: Live updates and subscriptions&lt;/li&gt;
&lt;li&gt;REST API: Easy integration with Python&lt;/li&gt;
&lt;li&gt;Row Level Security: Built-in security features
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;Database&lt;/span&gt; &lt;span class="k"&gt;Schema&lt;/span&gt; &lt;span class="n"&gt;Design&lt;/span&gt;

&lt;span class="n"&gt;Core&lt;/span&gt; &lt;span class="n"&gt;Tables&lt;/span&gt;
&lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="n"&gt;Users&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;full_name&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;avatar_url&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="n"&gt;TIMESTAMPTZ&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="n"&gt;updated_at&lt;/span&gt; &lt;span class="n"&gt;TIMESTAMPTZ&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="n"&gt;Resume&lt;/span&gt; &lt;span class="n"&gt;templates&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resume_templates&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;file_url&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;is_default&lt;/span&gt; &lt;span class="nb"&gt;BOOLEAN&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="k"&gt;FALSE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="n"&gt;TIMESTAMPTZ&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="n"&gt;updated_at&lt;/span&gt; &lt;span class="n"&gt;TIMESTAMPTZ&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;()&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="k"&gt;Specific&lt;/span&gt; &lt;span class="n"&gt;Tables&lt;/span&gt;
&lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agent_results&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;agent_type&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;task_type&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;input_data&lt;/span&gt; &lt;span class="n"&gt;JSONB&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;output_data&lt;/span&gt; &lt;span class="n"&gt;JSONB&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="nb"&gt;BOOLEAN&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;error_message&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="n"&gt;TIMESTAMPTZ&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="n"&gt;updated_at&lt;/span&gt; &lt;span class="n"&gt;TIMESTAMPTZ&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="n"&gt;Cover&lt;/span&gt; &lt;span class="n"&gt;letters&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cover_letters&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;job_title&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;company_name&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;cover_letter_content&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;quality_score&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;generation_type&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;agent_result_id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agent_results&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="n"&gt;TIMESTAMPTZ&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="n"&gt;updated_at&lt;/span&gt; &lt;span class="n"&gt;TIMESTAMPTZ&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="n"&gt;Optimized&lt;/span&gt; &lt;span class="n"&gt;resumes&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;optimized_resumes&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;original_resume_id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resume_templates&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;job_title&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;company_name&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;optimized_content&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;job_match_score&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;optimization_type&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;agent_result_id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agent_results&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="n"&gt;TIMESTAMPTZ&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="n"&gt;updated_at&lt;/span&gt; &lt;span class="n"&gt;TIMESTAMPTZ&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;NOW&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;h2&gt;
  
  
  Technical Challenges Overcome
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;LinkedIn scraping via Windows MCP server (repost + 100-applicant filter active)&lt;/li&gt;
&lt;li&gt;Job scoring with GPT-4o-mini (ATS fit score 0–100)
&lt;/li&gt;
&lt;li&gt;Resume tailoring + cover letter generation with GPT-4o-mini                                                                                                                                         4. LinkedIn Easy Apply automation (Playwright)
&lt;/li&gt;
&lt;li&gt;Email digest
&lt;/li&gt;
&lt;li&gt;Dashboard with full pipeline button
                                                                                                                                                                                                       Before each session, start the MCP server in Windows PowerShell:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uvx linkedin-scraper-mcp &lt;span class="nt"&gt;--transport&lt;/span&gt; streamable-http &lt;span class="nt"&gt;--host&lt;/span&gt; 0.0.0.0 &lt;span class="nt"&gt;--port&lt;/span&gt; 8765  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  HunterAgent — Step-by-Step Guide
&lt;/h2&gt;

&lt;p&gt;First-Time Setup (do once)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start the LinkedIn MCP server — open Windows PowerShell and run:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uvx linkedin-scraper-mcp &lt;span class="nt"&gt;--transport&lt;/span&gt; streamable-http &lt;span class="nt"&gt;--host&lt;/span&gt; 0.0.0.0 &lt;span class="nt"&gt;--port&lt;/span&gt; 8765
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Leave this window open in the background.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start the app — in your terminal:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;streamlit run streamlit_app.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Check the dashboard — confirm the green LinkedIn MCP server: connected status&lt;/li&gt;
&lt;/ul&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%2Fuploads%2Farticles%2F4dd0da7qa7f4fpoxqd4n.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%2Fuploads%2Farticles%2F4dd0da7qa7f4fpoxqd4n.png" alt=" " width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure your profile — open the app and go to Settings:

&lt;ul&gt;
&lt;li&gt;Keywords: software engineer, python developer (comma-separated)&lt;/li&gt;
&lt;li&gt;Location: Remote or New York, NY&lt;/li&gt;
&lt;li&gt;Resume Text: paste your full resume&lt;/li&gt;
&lt;li&gt;Companies Not Included: any companies to skip&lt;/li&gt;
&lt;li&gt;Notification Email: your Gmail address&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&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%2Fuploads%2Farticles%2Fyqwzbfm5btu14zd0lrhb.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%2Fuploads%2Farticles%2Fyqwzbfm5btu14zd0lrhb.png" alt=" " width="800" height="419"&gt;&lt;/a&gt;  &lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>claude</category>
      <category>programming</category>
    </item>
    <item>
      <title>Boost Your Agents with MCPs - Launch First Real-world Agentic App</title>
      <dc:creator>Mindy Jen</dc:creator>
      <pubDate>Fri, 27 Mar 2026 17:21:56 +0000</pubDate>
      <link>https://forem.com/mindy_jen_phd/boost-your-agents-with-mcps-launch-first-real-world-agentic-app-3lbc</link>
      <guid>https://forem.com/mindy_jen_phd/boost-your-agents-with-mcps-launch-first-real-world-agentic-app-3lbc</guid>
      <description>&lt;h2&gt;
  
  
  Why MCP?
&lt;/h2&gt;

&lt;p&gt;MCP stands for &lt;strong&gt;Model Context Protocol&lt;/strong&gt;. Think of it as a standardised USB-C port for AI tools. Instead of every AI application inventing its own plugin system, MCP defines a common interface: a server exposes tools, a client (our agent here) discovers and calls them. The beauty is that the same MCP server can be reused by Claude Desktop, by a Strands agent, by any MCP-compatible client — without changing a single line of server code. This is the interoperability that the ecosystem has been missing. Here, we use FastMCP, a Python library that reduces an MCP server to almost nothing:&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;mcp.server&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastMCP&lt;/span&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;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;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;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;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__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;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&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;stdio&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;That is a fully functional MCP server. The decorator &lt;a class="mentioned-user" href="https://dev.to/mcp"&gt;@mcp&lt;/a&gt;.tool is all you need to expose a function to any MCP client.&lt;/p&gt;

&lt;h2&gt;
  
  
  Review: Our Analyst (Sub-agent)
&lt;/h2&gt;

&lt;p&gt;We start with creating our first toolkit: an analyst. Running two terminals — one for the server, the other for the client — we immediately see the protocol in action.&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%2Fuploads%2Farticles%2Fss2olkv8zdgz9ee8q8u3.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%2Fuploads%2Farticles%2Fss2olkv8zdgz9ee8q8u3.png" alt=" " width="606" height="1183"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The client (our agent here) connects, discovers the available tools (addition, subtraction, multiplication, and division), and calls them through the protocol (MCP). The agent calls a function without knowing whether the toolkit lives in a separate process or not.&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%2Fuploads%2Farticles%2F8vedfdty5ub98gyzznfh.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%2Fuploads%2Farticles%2F8vedfdty5ub98gyzznfh.png" alt=" " width="800" height="601"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The toolkit definitely resides within a server. The client (our agent here) receives a structured description and autonomously decides when and how to invoke the tool. No prompt engineering is needed to explain what the &lt;code&gt;addition&lt;/code&gt; does. &lt;/p&gt;

&lt;h2&gt;
  
  
  Review: Our Weather Forecaster (Sub-agent)
&lt;/h2&gt;

&lt;p&gt;The second toolkit is to introduce a weather forecaster that speaks the National Weather Service API. &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%2Fuploads%2Farticles%2F4qkubyabqpr9eyagqar2.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%2Fuploads%2Farticles%2F4qkubyabqpr9eyagqar2.png" alt=" " width="800" height="519"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The weather forecaster on a server exposes three tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;get_alerts&lt;/code&gt;(state) - active weather alerts by US state code&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_forecast&lt;/code&gt;(latitude, longitude) - multi-period forecast for a location&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_current_weather&lt;/code&gt;(latitude, longitude) - live conditions from the nearest observation station&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The implementation of the toolkit is fully &lt;code&gt;async&lt;/code&gt;, using &lt;code&gt;httpx&lt;/code&gt; for HTTP calls. We can call any external API, read from a database, run a subprocess - whatever our agent needs. The MCP layer is one communication contract between the agent (client) and a server where toolkits reside.&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;@mcp.tool&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_forecast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;latitude&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;longitude&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;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;Get weather forecast for a location.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;points_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;NWS_API_BASE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/points/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;latitude&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;longitude&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;points_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;make_nws_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;points_url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;forecast_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;points_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;properties&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;forecast&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;forecast_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;make_nws_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;forecast_url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# format and return
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Supervisor Agent (Head)
&lt;/h2&gt;

&lt;p&gt;Now we connect the dots. A supervisor-mode Strands agent built upon the Amazon Bedrock (Claude Sonnet) is given access to controlling multiple toolkits simultaneously via MCP. When we ask the supervisor something like: “What should I have for lunch given today’s weather in New York?”, the supervisor will leverage the magic power of MCP to pass along the command to different toolkits (sub-agents). &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%2Fuploads%2Farticles%2Ff029yjfomyl5713h420z.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%2Fuploads%2Farticles%2Ff029yjfomyl5713h420z.png" alt=" " width="800" height="1014"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;The supervisor figures out that s/he needs to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Calls the weather forecaster to get current conditions in New York&lt;/li&gt;
&lt;li&gt;Reasons which food delivery service makes sense in terms of the current temperature and traffic conditions&lt;/li&gt;
&lt;li&gt;Returns a recommendation&lt;/li&gt;
&lt;/ol&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%2Fuploads%2Farticles%2Fb1mk7xv82wsdbtj96mna.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%2Fuploads%2Farticles%2Fb1mk7xv82wsdbtj96mna.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, the agent is not just completing the prompt texts. Instead, it is orchestrating tool calls, chaining results, and synthesising an answer. The Strands SDK handles the entire tool call loop:&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.models&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="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="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;anthropic.claude-sonnet-4-5&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="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;calculator_tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;weather_tools&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;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 should I eat for lunch in New York today?&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;
  
  
  Build A Text Analyzer (Sub-agent) From Scratch
&lt;/h2&gt;

&lt;p&gt;We can build a text analyzer to shorten the length of a URL. More importantly, we can internalize the URL pattern.&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%2Fuploads%2Farticles%2Fml8a788n07lupt7s1acz.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%2Fuploads%2Farticles%2Fml8a788n07lupt7s1acz.png" alt=" " width="800" height="505"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The server exposes four tools: &lt;code&gt;shorten_url&lt;/code&gt;, &lt;code&gt;expand_url&lt;/code&gt;, &lt;code&gt;get_url_stats&lt;/code&gt;, and &lt;code&gt;analyze_text&lt;/code&gt;. The implementation uses an in-memory JSON store (with a note that production code would use a real database). Here is the shortener:&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;@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;Shorten a long URL into a compact format&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;shorten_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&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;custom_code&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="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="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="si"&gt;}{&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;isoformat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;short_code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;md5&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;hexdigest&lt;/span&gt;&lt;span class="p"&gt;()[:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="c1"&gt;# store and return
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;short_url&lt;/span&gt;&lt;span class="sh"&gt;"&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;short.ly/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;short_code&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;&lt;strong&gt;Key Takeaway&lt;/strong&gt;: Any Python function can become an AI tool in minutes. Have a legacy internal API? Wrap it. Have a spreadsheet formula? Wrap it. The barrier is almost zero.&lt;/p&gt;

&lt;h2&gt;
  
  
  Launch Our Agentic App (Research Analyzer) via Bedrock AgentCore
&lt;/h2&gt;

&lt;p&gt;From the development, we have our agent access toolkits via MCP locally over the &lt;code&gt;stdio&lt;/code&gt; transport. On the other hand, the real production systems need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Persistent&lt;/strong&gt; endpoints accessible over HTTPS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IAM-based&lt;/strong&gt; authentication (no open endpoints)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Container&lt;/strong&gt; packaging for reproducible deployments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-scaling&lt;/strong&gt; based on load&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Amazon Bedrock AgentCore Runtime handles all of this. The deployment script is deceptively short:&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;bedrock_agentcore_starter_toolkit&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Runtime&lt;/span&gt;

&lt;span class="n"&gt;agentcore_runtime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Runtime&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="n"&gt;agentcore_runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;entrypoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text_utils_server.py&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;auto_create_execution_role&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;span class="n"&gt;auto_create_ecr&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;span class="n"&gt;requirements_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;requirements.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;protocol&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MCP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;agent_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;text_utils_mcp&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="n"&gt;launch_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agentcore_runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&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;Agent ARN: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;launch_result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agent_arn&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;&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%2Fuploads%2Farticles%2F7zjcz46m3j5nous0fq5p.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%2Fuploads%2Farticles%2F7zjcz46m3j5nous0fq5p.png" alt=" " width="800" height="598"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Under the hood, the &lt;code&gt;bedrock_agentcore_starter_toolkit&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Packages your server and its dependencies into a Docker container&lt;/li&gt;
&lt;li&gt;Pushes it to ECR (auto-created if it does not exist)&lt;/li&gt;
&lt;li&gt;Creates an IAM execution role with least-privilege permissions&lt;/li&gt;
&lt;li&gt;Deploys to AgentCore Runtime and returns a live ARN&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After deployment (around 3–5 minutes), we update our agentic App configuration to point to the remote endpoint.&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%2Fuploads%2Farticles%2F27f4bj5rs7z2smxxgqlo.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%2Fuploads%2Farticles%2F27f4bj5rs7z2smxxgqlo.png" alt=" " width="800" height="823"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The remote MCP server is protected by &lt;strong&gt;AWS IAM via SigV4 signatures&lt;/strong&gt; — the same signing mechanism used by every other AWS API. Here, we include a custom transport class that handles this transparently:&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SigV4HTTPXAuth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;httpx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Auth&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;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;service&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="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;signer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SigV4Auth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;service&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;auth_flow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;aws_request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AWSRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;signer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_auth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;aws_request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;aws_request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This extends HTTPX’s auth interface and plugs directly into the MCP &lt;code&gt;StreamableHTTPTransport&lt;/code&gt;. Our agentic App continues to call tools with the exact same code - authentication is completely transparent at the transport layer. No API keys in environment variables, no token rotation to manage.&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%2Fuploads%2Farticles%2F1y6enx6ibu44p6l5numo.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%2Fuploads%2Farticles%2F1y6enx6ibu44p6l5numo.png" alt=" " width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the remote server is alive, activating it in the agentic app is a toggle:&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%2Fuploads%2Farticles%2Fte5r5kt0qotm9fmmf1lx.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%2Fuploads%2Farticles%2Fte5r5kt0qotm9fmmf1lx.png" alt=" " width="800" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Putting Everything Altogether - Our Agentic App (Research Analyzer)
&lt;/h2&gt;

&lt;p&gt;With the full stack in place — local servers, remote AgentCore server, SigV4 auth — our agentic app that combines all tools is now formed:&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%2Fuploads%2Farticles%2Ficp80juade7ztwhrpjzs.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%2Fuploads%2Farticles%2Ficp80juade7ztwhrpjzs.png" alt=" " width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The "Research Analyzer" can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fetch and summarise web content&lt;/li&gt;
&lt;li&gt;Analyse and transform text (via the remote AgentCore server)&lt;/li&gt;
&lt;li&gt;Shorten URLs from its research&lt;/li&gt;
&lt;li&gt;Check the weather for context-aware suggestions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All from natural language. All with tools that any developer could have written in an afternoon.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Multi-Tool Orchestration Layer
&lt;/h2&gt;

&lt;p&gt;Now, let's explore advanced implementation patterns — how to structure agents that manage many tools gracefully, handle tool failures, and maintain context across a conversation.&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%2Fuploads%2Farticles%2Fa1nrkpc04siyl760zdsb.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%2Fuploads%2Farticles%2Fa1nrkpc04siyl760zdsb.png" alt=" " width="800" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A few things worth highlighting from &lt;code&gt;main.py&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Tool cache with TTL&lt;/code&gt;: tools are loaded once at startup and refreshed on demand, avoiding re-negotiation on every request&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Session-scoped agents&lt;/code&gt;: each user session gets its own agent instance with isolated memory&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Structured logging per server&lt;/code&gt;: each MCP server has its own log stream, invaluable for debugging multi-server interactions
&lt;/li&gt;
&lt;/ul&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;refresh_tools_cache&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="n"&gt;cached_tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools_last_updated&lt;/span&gt;
    &lt;span class="n"&gt;cached_tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mcp_manager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_all_tools&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;active_only&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;span class="n"&gt;tools_last_updated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern, loading tools once and reusing them, becomes critical at scale. Negotiating the MCP protocol on every request adds latency; &lt;strong&gt;caching eliminates it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaways&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;MCP is the right abstraction. The separation between tool definition (server) and tool consumption (client/agent) is clean and powerful. It enables a genuine ecosystem of reusable tools.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;FastMCP&lt;/code&gt; makes it trivial to start. Going from idea to working MCP server takes minutes, not days. The barrier to contributing tools to the ecosystem is essentially zero.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;AgentCore&lt;/code&gt; closes the last mile. The hardest part of agentic AI in production is not the model or the tools — it is infrastructure: endpoints, auth, containers, scaling. AgentCore Runtime handles all of it with three lines of configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;SigV4&lt;/code&gt; is the right auth for AWS-native stacks. No secret management overhead, no token rotation, automatic credential refresh. If your infrastructure is already on AWS, this is the obvious choice.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>mcp</category>
      <category>python</category>
    </item>
    <item>
      <title>Boost Your Agents with MCPs - Productivity Customized Tools</title>
      <dc:creator>Mindy Jen</dc:creator>
      <pubDate>Sun, 22 Mar 2026 04:45:10 +0000</pubDate>
      <link>https://forem.com/mindy_jen_phd/boost-your-agents-with-mcps-productivity-customized-tools-3k7l</link>
      <guid>https://forem.com/mindy_jen_phd/boost-your-agents-with-mcps-productivity-customized-tools-3k7l</guid>
      <description>&lt;h2&gt;
  
  
  A. Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  a. Calendar Integration
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Intelligence&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;create_event&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Schedule new meetings/appointments&lt;/td&gt;
&lt;td&gt;Conflict detection, optimal time suggestions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;list_events&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;View calendar for specific dates&lt;/td&gt;
&lt;td&gt;Smart filtering, availability analysis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;check_availability&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Find free time slots&lt;/td&gt;
&lt;td&gt;Multi-day search, duration-aware&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;delete_event&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Remove scheduled events&lt;/td&gt;
&lt;td&gt;Cascade handling, notification support&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  b. Weather Intelligence
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Intelligence&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;get_alerts&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Get weather alerts for US states&lt;/td&gt;
&lt;td&gt;Real-time severe weather notifications&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;get_forecast&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Multi-day weather predictions&lt;/td&gt;
&lt;td&gt;Official NWS forecasts with detailed periods&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;get_current_weather&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Current observation data&lt;/td&gt;
&lt;td&gt;Real-time conditions from weather stations&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  c. Analyzer
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Intelligence&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;add&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Add two numbers together&lt;/td&gt;
&lt;td&gt;Total&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;subtract&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Subtract second number from first number&lt;/td&gt;
&lt;td&gt;Comparison&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;multiply&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Multiply two numbers together&lt;/td&gt;
&lt;td&gt;multiplication&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;divide&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Divide first number by second number&lt;/td&gt;
&lt;td&gt;Percentage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;power&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;power of a number&lt;/td&gt;
&lt;td&gt;Repitition&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;factorial&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;factorial of positive number&lt;/td&gt;
&lt;td&gt;Is It A Prime Number?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  B. Testing
&lt;/h2&gt;

&lt;h3&gt;
  
  
  a. Calendar
&lt;/h3&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%2Fuploads%2Farticles%2Fodfhbi4bgbob3jmc6pc0.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%2Fuploads%2Farticles%2Fodfhbi4bgbob3jmc6pc0.png" alt=" " width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Natural Language Queries
&lt;/h4&gt;

&lt;p&gt;Try these conversational requests:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Query&lt;/th&gt;
&lt;th&gt;Expected Behavior&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;"Schedule a team meeting tomorrow at 2pm"&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Creates event, checks conflicts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;"Do I have anything on Friday afternoon?"&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Lists events for specified time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;"Find me 30 minutes free time this week"&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Suggests available slots&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;"Cancel my 3pm meeting today"&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Finds and removes matching event&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  2. Complex Scenarios
&lt;/h4&gt;

&lt;p&gt;The AI agent can handle complex requests as well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I need to schedule a 90-minute project review with the team. I'm free Tuesday and Wednesday afternoons. What works best?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent Process:
1. Calls check_availability() for Tuesday/Wednesday afternoons
2. Finds optimal 90-minute slots
3. Suggests best options based on preferences
4. Creates event when user confirms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Error Handling
&lt;/h4&gt;

&lt;p&gt;The calendar server handles various edge cases:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Error Type&lt;/th&gt;
&lt;th&gt;Handling&lt;/th&gt;
&lt;th&gt;User Experience&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Invalid Date Format&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Parse error with format help&lt;/td&gt;
&lt;td&gt;"Please use format: YYYY-MM-DD HH:MM"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Past Date Scheduling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Validation with warning&lt;/td&gt;
&lt;td&gt;"Cannot schedule events in the past"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;File Corruption&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Backup and recovery&lt;/td&gt;
&lt;td&gt;Graceful fallback to empty calendar&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Concurrent Access&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;File locking&lt;/td&gt;
&lt;td&gt;Prevents data corruption&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  b. Weather
&lt;/h3&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%2Fuploads%2Farticles%2Fs9zk4xefl67r8w7amafg.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%2Fuploads%2Farticles%2Fs9zk4xefl67r8w7amafg.png" alt=" " width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Natural Language Queries
&lt;/h4&gt;

&lt;p&gt;Try these conversational weather requests:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Query&lt;/th&gt;
&lt;th&gt;Expected Behavior&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;"Get current weather for Seattle"&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Current conditions from nearest station&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;"Show me the forecast for San Francisco"&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;5-day detailed forecast periods&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;"Are there any weather alerts in California?"&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Active severe weather alerts for CA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;"What's the weather like in New York?"&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Current observations with temperature&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  2. Error Handling
&lt;/h4&gt;

&lt;p&gt;The server handles various failure modes gracefully:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Network timeouts: 30-second timeout prevents hanging&lt;/li&gt;
&lt;li&gt;Invalid coordinates: Clear error messages for bad inputs&lt;/li&gt;
&lt;li&gt;API unavailable: Graceful degradation with error messages&lt;/li&gt;
&lt;li&gt;Missing data: Handles null/missing fields safely&lt;/li&gt;
&lt;li&gt;State code validation: Validates US state codes for alerts&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  c. Analyzer
&lt;/h3&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%2Fuploads%2Farticles%2Fhw31gikunqme4zzn1lge.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%2Fuploads%2Farticles%2Fhw31gikunqme4zzn1lge.png" alt=" " width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Natural Language Queries (Natural Language → Tool Mapping)
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Query&lt;/th&gt;
&lt;th&gt;Expected Behavior&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;"add 25 and 17"&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;→ add(x=25, y=17)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;"25 plus 17"&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;→ add(x=25, y=17)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;"what's 25 + 17"&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;→ add(x=25, y=17)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;"sum of 25 and 17"&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;→ add(x=25, y=17)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;"15% of 200"&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;→ percentage(number=200, percent=15)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;"what is 15 percent of 200"&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;→ percentage(number=200, percent=15)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;"square root of 64"&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;→ square_root(x=64)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;"sqrt(64)"&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;→ square_root(x=64)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  2. Complex Query Handling
&lt;/h4&gt;

&lt;p&gt;For complex queries like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I have $1000, spend $234 on groceries and $156 on gas. How much is left?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent breaks down the problem
Calls subtract(1000, 234) → 766
Calls subtract(766, 156) → 610
Responds: "You have $610 left"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Error Handling
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Provides clear error messages&lt;/li&gt;
&lt;li&gt;Prevents invalid operations&lt;/li&gt;
&lt;li&gt;Errors are automatically sent back to AI agent&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>mcp</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Boost Your Agents with MCPs - MCP Fundamentals</title>
      <dc:creator>Mindy Jen</dc:creator>
      <pubDate>Sun, 22 Mar 2026 00:42:44 +0000</pubDate>
      <link>https://forem.com/mindy_jen_phd/boost-your-agents-with-mcps-mcp-fundamentals-14ok</link>
      <guid>https://forem.com/mindy_jen_phd/boost-your-agents-with-mcps-mcp-fundamentals-14ok</guid>
      <description>&lt;p&gt;We want to get every reader familiar with using MCP as a tool with LLMs to accomplish productivity tasks for our daily needs. We will see how LLMs can use multiple tools in concert to accomplish more advanced tasks.&lt;/p&gt;

&lt;p&gt;We will first learn the core concepts of MCP by building our first intelligent tool - an analyst that understands natural language and provides contextual responses. This exercise will introduce everyone to MCP, the universal open standard for connecting AI systems with data sources and demonstrate its capabilities.&lt;/p&gt;

&lt;p&gt;An analyst MCP server that goes beyond simple arithmetic:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Natural Language Processing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Understands conversational math/statistics queries&lt;/td&gt;
&lt;td&gt;"What's 15% of 250?" → Calculation + explanation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Context Awareness&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Remembers previous analyses&lt;/td&gt;
&lt;td&gt;References earlier results in conversation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Error Handling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Graceful handling of invalid inputs&lt;/td&gt;
&lt;td&gt;Clear messages for division by zero, invalid syntax&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rich Responses&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Detailed explanations with breakdowns&lt;/td&gt;
&lt;td&gt;Step-by-step calculation process&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What we need to do...
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;MCP Architecture: Understand how MCP connects AI models to tools&lt;/li&gt;
&lt;li&gt;Server Implementation: Build a working MCP server from scratch&lt;/li&gt;
&lt;li&gt;Tool Registration: Register functions that AI models can discover&lt;/li&gt;
&lt;li&gt;Response Formatting: Structure responses for optimal AI interaction&lt;/li&gt;
&lt;li&gt;Integration Testing: Test our server with the application&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  A. MCP Protocol Overview
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Model Context Protocol (MCP)&lt;/strong&gt; is an open standard designed to create a universal interface between AI models and external tools, data, and services. By using &lt;strong&gt;Bedrock AgentCore Runtime&lt;/strong&gt;, developers can transition these tools from local functions to secure, enterprise-grade managed microservices.&lt;/p&gt;

&lt;h4&gt;
  
  
  Core Concepts of MCP
&lt;/h4&gt;

&lt;p&gt;The protocol replaces custom, one-off integrations with a standardized request-response pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Standardization&lt;/strong&gt;: Provides a single protocol for all tools (e.g., same interface for analysis or weather tools).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interoperability&lt;/strong&gt;: Works across different models (Claude, GPT, Nova) using the same toolset.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: Implements sandboxed execution, parameter validation via JSON Schema, and controlled access patterns.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Communication &amp;amp; Message Types
&lt;/h4&gt;

&lt;p&gt;MCP follows a structured flow to ensure the AI model understands and executes tools correctly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tool &lt;strong&gt;Discovery&lt;/strong&gt; (&lt;code&gt;tools/list&lt;/code&gt;): The model identifies accessible tools and their required parameters (schemas).&lt;/li&gt;
&lt;li&gt;Tool &lt;strong&gt;Execution&lt;/strong&gt; (&lt;code&gt;tools/call&lt;/code&gt;): The model sends structured arguments to a specific tool to perform tasks beyond its internal knowledge.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transport&lt;/strong&gt; Methods: Supports &lt;strong&gt;stdio&lt;/strong&gt; (standard input/output) for local development, as well as &lt;strong&gt;HTTP&lt;/strong&gt; and &lt;strong&gt;WebSockets&lt;/strong&gt; for remote or real-time applications.&lt;/li&gt;
&lt;/ul&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%2Fuploads%2Farticles%2Fh7g5aaibu3073zvwxkh5.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%2Fuploads%2Farticles%2Fh7g5aaibu3073zvwxkh5.png" alt=" " width="800" height="888"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Production Deployment with AgentCore
&lt;/h4&gt;

&lt;p&gt;While local tools are useful for development, &lt;code&gt;Bedrock AgentCore Runtime&lt;/code&gt; provides the infrastructure for production scaling:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Managed Infrastructure&lt;/strong&gt;: Moves tools to managed services, removing the burden of server maintenance and scaling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced Security&lt;/strong&gt;: Integrates with Amazon Cognito to enforce strict authentication, ensuring only authorized agents can trigger sensitive operations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplified Integration&lt;/strong&gt;: A Strands Agent can connect to a remote MCP server and handle authentication handshakes automatically, consuming cloud tools as if they were local functions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Summary Table: Benefits of Managed MCP&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Local MCP (stdio)&lt;/th&gt;
&lt;th&gt;Managed AgentCore Runtime&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Primary Use&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Development &amp;amp; testing&lt;/td&gt;
&lt;td&gt;Enterprise-scale production&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Security&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Local process isolation&lt;/td&gt;
&lt;td&gt;Amazon Cognito Authentication&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scaling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Manual/Local&lt;/td&gt;
&lt;td&gt;AWS-handled auto-scaling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Accessibility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Limited to one machine&lt;/td&gt;
&lt;td&gt;Shareable across teams/agents&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaway&lt;/strong&gt;: This architecture allows developers to build a reusable library of secure MCP tools that any agent in an organization can invoke with minimal code.&lt;/p&gt;

&lt;h3&gt;
  
  
  B. Key MCP Concepts
&lt;/h3&gt;

&lt;p&gt;Deploying custom tools at scale requires moving beyond local functions to a managed infrastructure that is secure, authenticated, and scalable. &lt;strong&gt;Bedrock AgentCore Runtime&lt;/strong&gt; enables the deployment of &lt;strong&gt;Model Context Protocol (MCP)&lt;/strong&gt; servers as managed services, transitioning tools from local Python decorators to enterprise-grade microservices.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Building and Deploying an MCP Server
&lt;/h4&gt;

&lt;p&gt;The development process is simplified using the &lt;code&gt;FastMCP&lt;/code&gt; framework, which automates protocol message formatting and JSON Schema generation.&lt;/p&gt;

&lt;h5&gt;
  
  
  a. Define the Local Server
&lt;/h5&gt;

&lt;p&gt;Using &lt;code&gt;FastMCP&lt;/code&gt;, you can quickly define tools with standard Python &lt;strong&gt;type hints&lt;/strong&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;mcp.server&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastMCP&lt;/span&gt;

&lt;span class="c1"&gt;# Create the MCP server instance
&lt;/span&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;Analyzer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Register a tool; FastMCP handles the schema generation automatically
&lt;/span&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&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;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;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;span class="c1"&gt;# Run using stdio for local testing
&lt;/span&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;stdio&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;h5&gt;
  
  
  b. Deploy to AgentCore Runtime
&lt;/h5&gt;

&lt;p&gt;Once containerized, the server is registered with the Runtime Client to become a managed cloud service:&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;bedrock_agentcore.tools.runtime_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RuntimeClient&lt;/span&gt;

&lt;span class="n"&gt;runtime_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RuntimeClient&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Deploy with Cognito security
&lt;/span&gt;&lt;span class="n"&gt;mcp_server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;runtime_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_mcp_server&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;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;SearchService&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your-docker-image-uri&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;auth_config&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;type&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;COGNITO&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;user_pool_id&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;us-east-1_xxxxxxxxx&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;client_id&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;xxxxxxxxxxxxxxxx&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Connecting a Strands Agent to a Remote Tool
&lt;/h4&gt;

&lt;p&gt;Strands Agents leverage the &lt;code&gt;AgentCoreRuntime&lt;/code&gt; to connect to these remote services. The agent automatically manages the authentication handshake, treating the remote MCP server as a local capability.&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.models&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.runtime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AgentCoreRuntime&lt;/span&gt;

&lt;span class="c1"&gt;# Connect to the deployed runtime
&lt;/span&gt;&lt;span class="n"&gt;agentcore_runtime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AgentCoreRuntime&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Create agent using the remote managed tool
&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="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;us.amazon.nova-pro-v1:0&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;agentcore_runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mcp_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server_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;SearchService&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="c1"&gt;# Execution: Discovery -&amp;gt; Intent Recognition -&amp;gt; Parameter Extraction -&amp;gt; Execution
&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 are the key highlights from the latest AWS Re:Invent?&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;&lt;strong&gt;Summary of MCP Implementation&lt;/strong&gt;&lt;/p&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;Role&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Frontend&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;User interface and real-time chat&lt;/td&gt;
&lt;td&gt;React&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Backend&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Agent orchestration&lt;/td&gt;
&lt;td&gt;FastAPI with Strands Agents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MCP Servers&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Tool implementations&lt;/td&gt;
&lt;td&gt;Python with &lt;code&gt;FastMCP&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AI Models&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Natural language processing&lt;/td&gt;
&lt;td&gt;Amazon Nova Pro / Claude&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaway&lt;/strong&gt;: Bedrock AgentCore Runtime acts as the "production glue" for AI agents. It shifts the responsibility for security, scaling, and server management to AWS, allowing organizations to maintain a secure library of reusable tools accessible via a single line of code.&lt;/p&gt;

&lt;h3&gt;
  
  
  C. Building an Analyst MCP Server
&lt;/h3&gt;

&lt;p&gt;An Analyzer MCP Server is created using the &lt;code&gt;FastMCP&lt;/code&gt; framework. It demonstrates how to turn standard Python functions into tools that an AI agent can use to solve natural language math problems. Let's build our first MCP server - an analyst that handles natural language math queries with context and error handling.&lt;/p&gt;

&lt;p&gt;A short excerpt of this code is shown below:&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;mcp.server&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastMCP&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;

&lt;span class="c1"&gt;# Create MCP server instance
&lt;/span&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;Analyzer Server&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&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;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="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Add two numbers and return the result.&lt;/span&gt;&lt;span class="sh"&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;span class="bp"&gt;...&lt;/span&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 first number by second number&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="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Divide x by y and return the result.&lt;/span&gt;&lt;span class="sh"&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;span class="bp"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__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;__main__&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;🔢 Starting Analyzer MCP Server...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&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;stdio&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;To build a successful MCP server, focus on these four pillars:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pillar&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Why it Matters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Context&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Use detailed docstrings and descriptions.&lt;/td&gt;
&lt;td&gt;Helps the AI choose the right tool for a natural language query.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Validation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Always use Python type hints (&lt;code&gt;x: float&lt;/code&gt;).&lt;/td&gt;
&lt;td&gt;Prevents the AI from sending "garbage" data that crashes your code.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Resilience&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Raise specific errors (e.g., &lt;code&gt;ValueError&lt;/code&gt;).&lt;/td&gt;
&lt;td&gt;Allows the AI to explain the error to the user rather than failing silently.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Chaining&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Design tools to be composable.&lt;/td&gt;
&lt;td&gt;Enables the agent to solve complex, multi-step problems (e.g., Compound Interest).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  1. Key Implementation Details
&lt;/h4&gt;

&lt;h5&gt;
  
  
  a. Server Creation (Core Implementation Flow)
&lt;/h5&gt;

&lt;p&gt;The server is built by defining a &lt;code&gt;FastMCP&lt;/code&gt; instance and decorating functions to expose them as tools.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Initialization&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creates a new MCP server with a descriptive name&lt;/li&gt;
&lt;li&gt;The name helps with debugging and tool discovery
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&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;Analyzer 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;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Transport&lt;/strong&gt;: Uses &lt;code&gt;stdio&lt;/code&gt; (Standard Input/Output) for local communication between the AI and the server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Registration&lt;/strong&gt;: The &lt;code&gt;@mcp.tool&lt;/code&gt; decorator tells the AI what the tool does and what inputs it requires.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  b. Tool Registration (Essential Tool Components)
&lt;/h5&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;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To ensure the AI uses our tools correctly, every function should include:&lt;/p&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;&lt;strong&gt;&lt;code&gt;@mcp.tool()&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Registers function as MCP tool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;description&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Helps AI understand tool purpose&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;Type hints&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Enables automatic parameter validation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;Docstring&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Provides additional context&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h5&gt;
  
  
  c. Intelligence Error Handling
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Provides clear error messages (Natural Language Mapping) The AI automatically maps user phrases like "sum of 25 and 17" or "25 plus 17" to the &lt;code&gt;add(x=25, y=17)&lt;/code&gt; function.&lt;/li&gt;
&lt;li&gt;Prevents invalid operations (Complex Queries): The agent can "chain" tools. For a budget query, it might call &lt;code&gt;subtract()&lt;/code&gt; multiple times to reach a final answer. &lt;/li&gt;
&lt;li&gt;Errors are automatically sent back to AI agent (Graceful Failures): By raising a &lt;code&gt;ValueError("Cannot divide by zero")&lt;/code&gt;, the error message is passed directly back to the AI, allowing it to explain the mistake to the user rather than just crashing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  d: Best Practices for Developers
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;Be &lt;strong&gt;Specific&lt;/strong&gt;: Use clear descriptions like "Calculate 15% of 200" instead of "Does percentage stuff."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Strict&lt;/strong&gt; Typing: Always use Python type hints to prevent the AI from sending the wrong data formats.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logging&lt;/strong&gt;: Use import logging to track how the AI invokes our tools in the background.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory&lt;/strong&gt;: We can add "Context Awareness" by storing results in a list (e.g., calculation_history) so the agent can reference previous answers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaway&lt;/strong&gt;: The Model Context Protocol (MCP) transforms isolated Python functions into intelligent, conversational tools that an AI agent can understand and execute. The transition from a local script to an enterprise-grade tool happens in three stages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Standardization (Local)&lt;/strong&gt;: Using &lt;code&gt;FastMCP&lt;/code&gt;, we wrap standard Python functions with decorators. By providing strict &lt;strong&gt;type hints&lt;/strong&gt; and &lt;strong&gt;descriptions&lt;/strong&gt;, you create a "contract" that the AI model (like Claude or Nova) can read to understand exactly how to perform math/analysis or data tasks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalability (Managed)&lt;/strong&gt;: You move from running a script on your machine to deploying a containerized image via &lt;strong&gt;Bedrock AgentCore Runtime&lt;/strong&gt;. This shifts the burden of server maintenance and scaling to AWS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security (Enterprise)&lt;/strong&gt;: By integrating &lt;strong&gt;Amazon Cognito&lt;/strong&gt;, you ensure that only authorized agents can trigger your tools, protecting sensitive operations like database searches or proprietary calculations.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;MCP isn't just about math; it's the &lt;strong&gt;universal glue&lt;/strong&gt; for the AI era. Whether we are building a simple analyzer or a complex anomaly detection system, MCP allows us to build our logic once and use it across any AI model or team in our organization.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>ai</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Boost Your Agents with MCPs - Set up First Real-World Agentic App</title>
      <dc:creator>Mindy Jen</dc:creator>
      <pubDate>Sat, 21 Mar 2026 19:36:53 +0000</pubDate>
      <link>https://forem.com/mindy_jen_phd/boost-your-agents-with-mcps-set-up-first-real-world-app-2p7l</link>
      <guid>https://forem.com/mindy_jen_phd/boost-your-agents-with-mcps-set-up-first-real-world-app-2p7l</guid>
      <description>&lt;p&gt;People use AI-powered tools for various purposes - from simple text completion to writing full reports. But what if your AI assistant could do more? What if it could check your calendar, get weather updates, or connect to your business systems?&lt;/p&gt;

&lt;p&gt;The answer is: Using MCP to connect to external tools like weather APIs and calendars can empower your AI assistant to do whatever you like!&lt;/p&gt;

&lt;h2&gt;
  
  
  About This Product
&lt;/h2&gt;

&lt;p&gt;In this week’s blog series, we highlight practical, real‑world applications that you can put into use immediately. We'll build a complete set of AI-powered productivity tools:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;What It Does&lt;/th&gt;
&lt;th&gt;Key Features&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Smart Communicator&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Performs advanced math/statistics operations&lt;/td&gt;
&lt;td&gt;Understands natural language, handles complex data analyses&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Calendar Assistant&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Manages your schedule intelligently&lt;/td&gt;
&lt;td&gt;Detects conflicts, suggests optimal meeting times&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Weather Advisor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Provides smart weather forecasts&lt;/td&gt;
&lt;td&gt;Recommends activities based on conditions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bring Your Own MCP (BYOM) Server&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Custom functionality you design&lt;/td&gt;
&lt;td&gt;Build tools specific to your needs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;All integrated into a pre-built React application - so we can focus on building the intelligence, not the UI! "&lt;strong&gt;UI is Ready, Focus on the Intelligence&lt;/strong&gt;" - A complete frontend is provided in advance so we can focus on building the AI-powered backend tools that make a real difference in productivity. In the end, we'll have built multiple MCP servers with hands-on experience, production-ready code we can use daily, and practical patterns for building real-world AI applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Environment Overview
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pre-Installed Tools
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Version&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Python&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Backend development&lt;/td&gt;
&lt;td&gt;3.11+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Node.js&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Frontend dependencies&lt;/td&gt;
&lt;td&gt;18+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AWS CLI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AWS service access&lt;/td&gt;
&lt;td&gt;Latest&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Git&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Version control&lt;/td&gt;
&lt;td&gt;Latest&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  AWS Services Configured
&lt;/h3&gt;

&lt;p&gt;Our environment has access to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Amazon Bedrock: AI model access (Amazon Nova, Anthropic Claude)&lt;/li&gt;
&lt;li&gt;CloudWatch: Logging and monitoring&lt;/li&gt;
&lt;li&gt;Secrets Manager: Secure credential storage&lt;/li&gt;
&lt;li&gt;EC2: Compute resources&lt;/li&gt;
&lt;li&gt;VPC: Networking&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Frontend (React)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Modern chat interface&lt;/li&gt;
&lt;li&gt;Real-time message streaming&lt;/li&gt;
&lt;li&gt;Token usage tracking&lt;/li&gt;
&lt;li&gt;Session history&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Backend (FastAPI)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Strands Agents integration&lt;/li&gt;
&lt;li&gt;MCP server management&lt;/li&gt;
&lt;li&gt;Bedrock model access&lt;/li&gt;
&lt;li&gt;WebSocket support&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Launching Application
&lt;/h3&gt;

&lt;p&gt;This is the application...&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%2Fuploads%2Farticles%2Fu4g3ehiugvh6asto9a3s.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%2Fuploads%2Farticles%2Fu4g3ehiugvh6asto9a3s.png" alt=" " width="800" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Left Navigation Panel
&lt;/h4&gt;

&lt;p&gt;On the left side, we have a navigation panel where we can choose the foundation model and and turn on/off MCP servers.&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%2Fuploads%2Farticles%2Fy20vnw9frculcrg48mlc.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%2Fuploads%2Farticles%2Fy20vnw9frculcrg48mlc.png" alt=" " width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Chat Interface
&lt;/h4&gt;

&lt;p&gt;In the center of the application, we have a chat interface where we can type and see responses from the foundation model.&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%2Fuploads%2Farticles%2Fiu2gjjp1cnqbto61ce9a.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%2Fuploads%2Farticles%2Fiu2gjjp1cnqbto61ce9a.png" alt=" " width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Server logs
&lt;/h4&gt;

&lt;p&gt;On the right side, we have a panel with the server logs. We have the ability to filter through the different type of logs generated by our server. &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%2Fuploads%2Farticles%2Fg4yk1qv21n8r7fwo2i3o.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%2Fuploads%2Farticles%2Fg4yk1qv21n8r7fwo2i3o.png" alt=" " width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Accessing the Application
&lt;/h3&gt;

&lt;p&gt;Once started, we can access the application at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Frontend: CloudFront URL + /proxy/3000/ (e.g., &lt;a href="https://abc123.cloudfront.net/proxy/3000/" rel="noopener noreferrer"&gt;https://abc123.cloudfront.net/proxy/3000/&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Backend API: CloudFront URL + /proxy/8000/ (e.g., &lt;a href="https://abc123.cloudfront.net/proxy/8000/" rel="noopener noreferrer"&gt;https://abc123.cloudfront.net/proxy/8000/&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can find the &lt;code&gt;CloudFront URL&lt;/code&gt; under the PORTS tab. Then, click on the globe icon next to the URL to open the page directly in the browser.&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%2Fuploads%2Farticles%2Fvz5mmsvpvyrcsrx2ds92.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%2Fuploads%2Farticles%2Fvz5mmsvpvyrcsrx2ds92.png" alt=" " width="800" height="128"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Troubleshooting Common Issues
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Important: Only use the following commands when you are facing an issue&lt;/code&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Issue&lt;/th&gt;
&lt;th&gt;Solution&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Port already in use&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Run `pkill -f "python\&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Permission denied&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Run {% raw %}&lt;code&gt;chmod +x start.sh&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Module not found&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Activate virtual environment: &lt;code&gt;source .venv/bin/activate&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AWS access denied&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Environment should be pre-configured, contact instructor&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Verification
&lt;/h3&gt;

&lt;p&gt;Once our environment is running:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify Application: Access the frontend using CloudFront URL + /proxy/3000/&lt;/li&gt;
&lt;li&gt;Test Chat Interface: Send a simple message&lt;/li&gt;
&lt;li&gt;Check Backend: Ensure API responds at CloudFront URL + /proxy/8000/&lt;/li&gt;
&lt;li&gt;Review Code Structure: Explore the ui/backend/mcp_servers/ directory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Environment Ready: Our development environment is configured and ready for building MCP servers!&lt;/strong&gt; &lt;/p&gt;

</description>
      <category>ai</category>
      <category>aws</category>
      <category>agents</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Get Your Hands Dirty - AgentCore - Gateway</title>
      <dc:creator>Mindy Jen</dc:creator>
      <pubDate>Sun, 15 Mar 2026 01:50:04 +0000</pubDate>
      <link>https://forem.com/mindy_jen_phd/get-your-hands-dirty-agentcore-gateway-1omp</link>
      <guid>https://forem.com/mindy_jen_phd/get-your-hands-dirty-agentcore-gateway-1omp</guid>
      <description>&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%2Fuploads%2Farticles%2Fepigon730n33kcjbzsbu.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%2Fuploads%2Farticles%2Fepigon730n33kcjbzsbu.png" alt=" " width="800" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Automating Tool Creation with Bedrock AgentCore Gateway
&lt;/h1&gt;

&lt;p&gt;One of the biggest hurdles in agent development is manually writing "glue code" for every external API. &lt;strong&gt;Bedrock AgentCore Gateway&lt;/strong&gt; eliminates this by providing a "zero-code" path to tool creation. By pointing the Gateway to a standard &lt;strong&gt;OpenAPI specification&lt;/strong&gt; (Swagger), it automatically generates a Model Context Protocol (MCP) server. This allows your Strands Agent to understand and interact with any REST API—complete with complex request schemas and authentication—without you writing a single line of integration logic.&lt;/p&gt;

&lt;p&gt;The Gateway also handles enterprise-grade security by managing the handshake between your agent and the external service. You can configure JWT-based authentication for the agent itself and link it to &lt;strong&gt;AgentCore Identity&lt;/strong&gt; to securely inject the external API keys (like Exa or Slack) into the headers of every outgoing request.&lt;/p&gt;

&lt;h2&gt;
  
  
  A. Generating MCP Tools from an OpenAPI Spec
&lt;/h2&gt;

&lt;p&gt;Instead of writing Python functions, you simply register the API's OpenAPI URL. The Gateway parses the specification and instantly exposes every endpoint as a callable tool for 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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;bedrock_agentcore.tools.gateway_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;GatewayClient&lt;/span&gt;

&lt;span class="c1"&gt;# Initialize the Gateway Client
&lt;/span&gt;&lt;span class="n"&gt;gateway_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GatewayClient&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Create a Gateway that converts an OpenAPI spec into MCP tools
&lt;/span&gt;&lt;span class="n"&gt;gateway&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gateway_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_gateway&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;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;ExaSearchGateway&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;auth_config&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;type&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;JWT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="c1"&gt;# Secure the gateway itself
&lt;/span&gt;    &lt;span class="n"&gt;targets&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;name&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;ExaAPI&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;openapi_url&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;https://api.exa.ai/openapi.json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# The "source of truth"
&lt;/span&gt;        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;credential_provider_id&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;your-secure-credential-id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;# Injected securely
&lt;/span&gt;    &lt;span class="p"&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;Gateway generated MCP endpoint: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;gateway&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;endpoint&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&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;h2&gt;
  
  
  B. Using Generated Tools in a Strands Agent
&lt;/h2&gt;

&lt;p&gt;The Strands Agent treats the Gateway like any other toolset. Because the Gateway provides full semantic descriptions from the OpenAPI spec, the agent knows exactly which parameters to send to the external API to get the job done.&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.models&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.gateway&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AgentCoreGateway&lt;/span&gt;

&lt;span class="c1"&gt;# Connect the Strands Agent to the Gateway
&lt;/span&gt;&lt;span class="n"&gt;agentcore_gateway&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AgentCoreGateway&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gateway_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;gateway&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&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="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;us.amazon.nova-pro-v1:0&lt;/span&gt;&lt;span class="sh"&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 research assistant. Use the Exa tools to find live data.&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;agentcore_gateway&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gateway&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# All OpenAPI endpoints are now tools
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# The agent automatically picks the correct 'search' endpoint from the spec
&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;Search for the top 5 trending research papers in Quantum Computing from this week.&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;&lt;strong&gt;Key Takeaway&lt;/strong&gt;: Bedrock AgentCore Gateway is the ultimate bridge between AI and the existing web. It turns standard documentation into functional code, allowing you to scale an agent's capabilities from a single tool to an entire ecosystem of APIs in minutes. By moving from manual coding to specification-driven integration, you ensure your agents are always aligned with the latest version of the services they consume.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>ai</category>
      <category>agents</category>
      <category>apigateway</category>
    </item>
    <item>
      <title>Get Your Hands Dirty - AgentCore - Memory</title>
      <dc:creator>Mindy Jen</dc:creator>
      <pubDate>Sun, 15 Mar 2026 01:20:45 +0000</pubDate>
      <link>https://forem.com/mindy_jen_phd/get-your-hands-dirty-agentcore-memory-8bf</link>
      <guid>https://forem.com/mindy_jen_phd/get-your-hands-dirty-agentcore-memory-8bf</guid>
      <description>&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%2Fuploads%2Farticles%2Fn4dojx2rxjxv83h5u3k6.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%2Fuploads%2Farticles%2Fn4dojx2rxjxv83h5u3k6.png" alt=" " width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Persistent Context with Bedrock AgentCore Memory
&lt;/h1&gt;

&lt;p&gt;Standard AI agents often suffer from "goldfish memory"—they forget everything once a session ends. &lt;strong&gt;Bedrock AgentCore Memory&lt;/strong&gt; solves this by providing a managed vector-based storage layer that persists across different conversations. By integrating this with &lt;strong&gt;Strands Agents&lt;/strong&gt;, you can create personalized assistants that remember user preferences, past decisions, and key semantic facts over days, weeks, or months.&lt;/p&gt;

&lt;p&gt;The framework supports multiple retrieval strategies, such as &lt;strong&gt;Summarization&lt;/strong&gt; (to recap long histories), &lt;strong&gt;Preferences&lt;/strong&gt; (to remember how a user likes their data formatted), and &lt;strong&gt;Semantic Facts&lt;/strong&gt; (to store specific data points like "The user's favorite stock is AMZN"). This allows the agent to inject relevant long-term context into the prompt window only when needed, keeping the conversation efficient and relevant.&lt;/p&gt;

&lt;h2&gt;
  
  
  A. Initializing a Managed Memory Store
&lt;/h2&gt;

&lt;p&gt;First, you create a memory resource in AgentCore. This setup defines how the agent should summarize and store incoming information into the underlying vector database.&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;bedrock_agentcore.tools.memory_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MemoryClient&lt;/span&gt;

&lt;span class="c1"&gt;# Initialize the Memory Client
&lt;/span&gt;&lt;span class="n"&gt;memory_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MemoryClient&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Create a memory resource with specialized strategies
&lt;/span&gt;&lt;span class="n"&gt;memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;memory_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_memory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;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;UserPersonaMemory&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;storage_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;VECTOR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;strategies&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&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;type&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;SUMMARY&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;description&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;Summarize the key points of the conversation.&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&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;PREFERENCE&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;description&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;Extract user-specific settings or likes.&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&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;SEMANTIC_FACT&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;description&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;Store specific facts mentioned by the user.&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="n"&gt;memory_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&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;Memory Store created with ID: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;memory_id&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;h2&gt;
  
  
  B. Building an Agent with Cross-Session Continuity
&lt;/h2&gt;

&lt;p&gt;By attaching the &lt;code&gt;AgentCoreMemory&lt;/code&gt; tool to a Strands Agent, the agent automatically saves conversation events to the cloud. When a new session starts for the same user, the agent queries its memory to "remember" who it is talking to.&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.models&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.memory&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AgentCoreMemory&lt;/span&gt;

&lt;span class="c1"&gt;# Initialize the memory tool for the agent
&lt;/span&gt;&lt;span class="n"&gt;agentcore_memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AgentCoreMemory&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;memory_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;memory_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Create the agent with memory capabilities
&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="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;us.amazon.nova-pro-v1:0&lt;/span&gt;&lt;span class="sh"&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 personal assistant. Use your memory to provide personalized help.&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;agentcore_memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Session 1: User shares information
&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;Hi, my name is Alex and I prefer all financial reports in Markdown format.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Session 2 (Later): Agent remembers the user
&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;Can you generate a summary of the latest market trends for me?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Output: "Certainly, Alex! I've prepared that market trend summary in your preferred Markdown format..."
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Takeaway&lt;/strong&gt;: Bedrock AgentCore Memory transforms stateless bots into long-term digital companions. It manages the complex logic of vector embedding and retrieval behind the scenes, allowing developers to focus on building agents that provide a truly continuous and personalized user experience.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>aws</category>
      <category>agents</category>
      <category>memory</category>
    </item>
    <item>
      <title>Get Your Hands Dirty - AgentCore - Runtime / Observability Deployment</title>
      <dc:creator>Mindy Jen</dc:creator>
      <pubDate>Sat, 14 Mar 2026 23:55:02 +0000</pubDate>
      <link>https://forem.com/mindy_jen_phd/get-your-hands-dirty-agentcore-runtime-observability-deployment-aom</link>
      <guid>https://forem.com/mindy_jen_phd/get-your-hands-dirty-agentcore-runtime-observability-deployment-aom</guid>
      <description>&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%2Fuploads%2Farticles%2Faad8xhnw8t8937fi44qb.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%2Fuploads%2Farticles%2Faad8xhnw8t8937fi44qb.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Deploying a local agent into a production environment requires more than just code; it requires a managed infrastructure that handles scaling, session isolation, and comprehensive monitoring. &lt;strong&gt;Bedrock AgentCore Runtime&lt;/strong&gt; allows you to package your &lt;strong&gt;Strands Agent&lt;/strong&gt;—complete with its system prompts and tools—into a managed "Agent Definition." Once deployed, the agent runs in a secure, isolated cloud environment that can be invoked via standard AWS SDKs (boto3), making it easy to integrate into existing applications.&lt;/p&gt;

&lt;p&gt;Beyond deployment, AgentCore provides built-in &lt;strong&gt;Generative AI Observability&lt;/strong&gt;. By integrating with &lt;strong&gt;Amazon CloudWatch&lt;/strong&gt;, it automatically captures detailed execution traces, including reasoning steps, tool calls, and model latency. This transparency allows developers to debug complex agent behaviors and monitor the reliability of production workloads without adding manual logging overhead.&lt;/p&gt;

&lt;h2&gt;
  
  
  A. Deploying the Strands Agent to the Cloud
&lt;/h2&gt;

&lt;p&gt;You can transition your local Strands Agent to a managed cloud resource by creating an agent definition. This definition includes the container image and environment configurations needed to run your agent autonomously.&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;bedrock_agentcore.tools.runtime_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RuntimeClient&lt;/span&gt;

&lt;span class="c1"&gt;# Initialize the Runtime Client
&lt;/span&gt;&lt;span class="n"&gt;runtime_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RuntimeClient&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Create a managed Agent Definition
&lt;/span&gt;&lt;span class="n"&gt;agent_definition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;runtime_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;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;ProductionAssistant&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your-docker-image-uri&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# Image containing your Strands Agent code
&lt;/span&gt;    &lt;span class="n"&gt;environment_vars&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;MODEL_ID&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;us.amazon.nova-pro-v1:0&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;SYSTEM_PROMPT&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;You are a production-grade research assistant.&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="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;Agent deployed! ID: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;agent_definition&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&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;h2&gt;
  
  
  B. Invoking the Remote Agent and Monitoring Traces
&lt;/h2&gt;

&lt;p&gt;Once deployed, you don't need the Strands library on the client side to interact with your agent. You can use &lt;code&gt;boto3&lt;/code&gt; to send messages and retrieve responses. Simultaneously, the Runtime environment generates traces that you can inspect in CloudWatch to understand the agent's internal reasoning.&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;import&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;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;bedrock-agent-runtime&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;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Invoke the remote agent within a specific session
&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;agentId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;agent_definition&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;agentAliasId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PROD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;sessionId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user-session-123&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;inputText&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Analyze the quarterly results for the provided dataset.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Access observability traces (simplified example)
# In the AWS Console, you would see step-by-step traces:
# Step 1: Reasoning -&amp;gt; "I need to use the data_analyzer tool."
# Step 2: Tool Call -&amp;gt; data_analyzer(file='results.csv')
# Step 3: Final Response -&amp;gt; "The quarterly growth was 15%."
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Takeaway&lt;/strong&gt;: Bedrock AgentCore Runtime transforms your Strands Agent into an enterprise-ready microservice. It provides a "zero-ops" experience for session management and security, while the integrated observability tools ensure you have the full visibility required to move from experimental prototypes to mission-critical AI applications.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>ai</category>
      <category>monitoring</category>
      <category>agents</category>
    </item>
    <item>
      <title>Get Your Hands Dirty - AgentCore - Runtime / MCP Server Deployment</title>
      <dc:creator>Mindy Jen</dc:creator>
      <pubDate>Sat, 14 Mar 2026 23:15:32 +0000</pubDate>
      <link>https://forem.com/mindy_jen_phd/get-your-hands-dirty-agentcore-runtime-4mi6</link>
      <guid>https://forem.com/mindy_jen_phd/get-your-hands-dirty-agentcore-runtime-4mi6</guid>
      <description>&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%2Fuploads%2Farticles%2Fxw5b5pd2neoolb0gdf2r.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%2Fuploads%2Farticles%2Fxw5b5pd2neoolb0gdf2r.png" alt=" " width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Production-Ready Tools with Bedrock AgentCore Runtime
&lt;/h1&gt;

&lt;p&gt;Deploying custom tools at scale requires more than just local functions; it requires managed infrastructure that is secure, authenticated, and scalable. &lt;strong&gt;Bedrock AgentCore Runtime&lt;/strong&gt; allows you to deploy &lt;strong&gt;Model Context Protocol (MCP)&lt;/strong&gt; servers as managed services. This transition moves your tools from local Python decorators to enterprise-grade microservices that can be shared across multiple agents and teams.&lt;/p&gt;

&lt;p&gt;By combining AgentCore Runtime with &lt;strong&gt;Amazon Cognito&lt;/strong&gt;, you can enforce strict authentication on your tools. This setup ensures that only authorized agents can trigger sensitive operations, such as searching internal databases or executing proprietary business logic, all while AWS handles the underlying server scaling and maintenance.&lt;/p&gt;

&lt;h2&gt;
  
  
  A. Deploying a Managed MCP Server
&lt;/h2&gt;

&lt;p&gt;To deploy a tool to the cloud, you first define your MCP server and then register it with the AgentCore Runtime. In this example, we assume an MCP server (like a DuckDuckGo search service) has been containerized and is ready for deployment.&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;bedrock_agentcore.tools.runtime_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RuntimeClient&lt;/span&gt;

&lt;span class="c1"&gt;# Initialize the Runtime Client
&lt;/span&gt;&lt;span class="n"&gt;runtime_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RuntimeClient&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Deploy a managed MCP server with Cognito authentication
&lt;/span&gt;&lt;span class="n"&gt;mcp_server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;runtime_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_mcp_server&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;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;SearchService&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your-docker-image-uri&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;auth_config&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;type&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;COGNITO&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;user_pool_id&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;us-east-1_xxxxxxxxx&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;client_id&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;xxxxxxxxxxxxxxxx&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="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;MCP Server deployed at: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;mcp_server&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;endpoint&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&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;h2&gt;
  
  
  B. Connecting a Strands Agent to a Remote Tool
&lt;/h2&gt;

&lt;p&gt;Once deployed, the Strands Agent connects to the remote MCP server using the &lt;code&gt;AgentCoreRuntime&lt;/code&gt; tool. The agent handles the authentication handshake automatically, allowing it to use the remote "Search" tool as if it were a local function.&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.models&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.runtime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AgentCoreRuntime&lt;/span&gt;

&lt;span class="c1"&gt;# Initialize connection to the deployed runtime
&lt;/span&gt;&lt;span class="n"&gt;agentcore_runtime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AgentCoreRuntime&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Create an agent that uses the remote managed search tool
&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="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;us.amazon.nova-pro-v1:0&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;agentcore_runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mcp_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server_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;SearchService&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="c1"&gt;# The agent invokes the remote MCP server securely to answer the query
&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 are the key highlights from the latest AWS Re:Invent?&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;&lt;strong&gt;Key Takeaway&lt;/strong&gt;: Bedrock AgentCore Runtime provides the "production glue" for AI agents. It shifts the burden of server management, security, and scaling from the developer to AWS. This allows you to build a library of secure, reusable MCP tools that any Strands Agent in your organization can consume with just a single line of code.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>aws</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Get Your Hands Dirty - AgentCore - Identity</title>
      <dc:creator>Mindy Jen</dc:creator>
      <pubDate>Sat, 14 Mar 2026 22:37:13 +0000</pubDate>
      <link>https://forem.com/mindy_jen_phd/get-your-hands-dirty-agentcore-identity-b99</link>
      <guid>https://forem.com/mindy_jen_phd/get-your-hands-dirty-agentcore-identity-b99</guid>
      <description>&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%2Fuploads%2Farticles%2F8l96k2o49bcxl9w9deoo.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%2Fuploads%2Farticles%2F8l96k2o49bcxl9w9deoo.png" alt=" " width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Secure Credentials with Bedrock AgentCore Identity
&lt;/h1&gt;

&lt;p&gt;Building production-grade agents requires integrating with third-party services like &lt;strong&gt;Exa&lt;/strong&gt; for web search or &lt;strong&gt;Slack&lt;/strong&gt; for messaging. The biggest challenge is doing so without hardcoding sensitive API keys. &lt;strong&gt;Bedrock AgentCore Identity&lt;/strong&gt; provides a secure, encrypted credential store that allows agents to retrieve secrets just-in-time during execution, eliminating the risk of accidental exposure in code or logs.&lt;/p&gt;

&lt;p&gt;By using the &lt;code&gt;IdentityClient&lt;/code&gt;, you can create "Credential Providers" that map specific secrets to your agent’s runtime. This ensures a complete audit trail and fine-grained access control, moving your agent architecture from "proof-of-concept" to "security-compliant."&lt;/p&gt;

&lt;h2&gt;
  
  
  A. Provisioning a Secure Credential
&lt;/h2&gt;

&lt;p&gt;Instead of using environment variables, you register your API keys directly into the AgentCore managed identity store. This only needs to be done once during the setup phase.&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;bedrock_agentcore.tools.identity_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;IdentityClient&lt;/span&gt;

&lt;span class="c1"&gt;# Initialize the Identity Client
&lt;/span&gt;&lt;span class="n"&gt;identity_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;IdentityClient&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Securely store an API key (e.g., for Exa Search)
&lt;/span&gt;&lt;span class="n"&gt;credential_provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;identity_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_api_key_credential_provider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;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;ExaAPIKey&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your-actual-secret-key-here&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;# This value is encrypted immediately
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;credential_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;credential_provider&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&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;Credential registered with ID: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;credential_id&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;h2&gt;
  
  
  B. Integrating Secure Search into a Strands Agent
&lt;/h2&gt;

&lt;p&gt;Once the credential is stored, your agent tools can fetch the key dynamically. In this example, we wrap a search function that retrieves the key via AgentCore Identity right before making the request.&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="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;secure_search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&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;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;Perform a web search using a securely stored Exa API key.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="c1"&gt;# Retrieve the key from the secure store at runtime
&lt;/span&gt;    &lt;span class="n"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;identity_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_credential_provider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;credential_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;api_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;apiKey&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# Handled securely behind the scenes
&lt;/span&gt;
    &lt;span class="c1"&gt;# Use the key for the external API call (logic simplified for demo)
&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;Search results for &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; using secure key.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# Initialize the agent with the secure tool
&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us.amazon.nova-pro-v1:0&lt;/span&gt;&lt;span class="sh"&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 research assistant with secure web access.&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;secure_search&lt;/span&gt;&lt;span class="p"&gt;]&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;Find the latest whitepapers on AI Security.&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;&lt;strong&gt;Key Takeaway&lt;/strong&gt;: Bedrock AgentCore Identity solves the "secret sprawl" problem. Agents no longer need access to long-lived environment variables; instead, they retrieve encrypted credentials only when a tool specifically requests them, ensuring your infrastructure remains "Zero-Trust" by design.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>ai</category>
      <category>python</category>
      <category>agents</category>
    </item>
  </channel>
</rss>
