Skip to content

Code for the workshop From Intelligent to Agentic Apps: Using MCP to Support Agentic Behaviors in Your Applications

Notifications You must be signed in to change notification settings

kylestratis/making-intelligent-apps-agentic

Repository files navigation

Making Apps Intelligent: Building MCP Clients

A hands-on workshop that teaches you how to build Model Context Protocol (MCP) clients by progressively enhancing a simple chat application. Learn how to integrate tools, resources, and prompts to create intelligent applications that can interact with external systems.

What You'll Learn

This workshop demonstrates how to transform a basic Claude chat agent into a full-featured MCP client that can:

  • Connect to MCP servers via stdio
  • Discover and use server-provided tools
  • Load and inject contextual resources
  • Apply prompt templates for behavior guidance
  • Implement the agentic loop pattern

Prerequisites

  • Python 3.12 or higher
  • An Anthropic API key (get one here)
  • Basic familiarity with Python and async/await

Installation

1. Install uv

This project uses uv for fast, reliable Python dependency management.

# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

# Or with pip
pip install uv

2. Clone the Repository

git clone <repository-url>
cd making-apps-intelligent

3. Install Dependencies

uv sync

4. Configure Your API Key

# Copy the example environment file
cp .env.example .env

# Edit .env and add your Anthropic API key
# ANTHROPIC_API_KEY=your_api_key_here

Repository Structure

The workshop is organized into progressive steps, each building on the previous one:

making-apps-intelligent/
├── 00_base_application/       # Simple chat agent (baseline)
├── 01_create_client_module/   # MCP client with connection lifecycle
├── 02_supporting_tools/       # Tool discovery and execution
├── 03_supporting_resources/   # Resource loading and context injection
├── 04_supporting_prompts/     # Prompt templates and complete integration
├── calculator_server.py       # Example MCP server for testing
├── pyproject.toml             # Project dependencies
└── .env.example               # API key template

About the Example Server

The calculator_server.py is a simple MCP server that provides:

  • Tools: Mathematical operations (add, subtract, multiply, divide)
  • Resources: Math constants (pi, e, golden ratio) and formulas
  • Prompts: Templates for step-by-step problem solving

This server allows you to test all MCP client functionality without needing external services.


Workshop Steps

Step 0: Base Application

What's New:

  • Simple CLI chat interface
  • Conversation history management
  • Basic Claude API integration

Concepts Implemented:

  • Synchronous message exchange with Claude
  • User input/output handling
  • Conversation context maintenance

How to Run:

uv run python 00_base_application/agent.py

Example Queries to Try:

You: Hello! How are you?
You: What is the capital of France?
You: Can you explain what gravity is?

What to Notice:

  • The agent maintains conversation history
  • No access to tools or external knowledge
  • Simple request/response pattern

Step 1: Create Client Module

What's New:

  • MCPClient class with connection management
  • Async/await pattern implementation
  • Stdio server connection setup

Concepts Implemented:

  • MCP client initialization and lifecycle
  • AsyncExitStack for resource cleanup
  • Subprocess-based server communication
  • Session handshake and initialization

How to Run:

uv run python 01_create_client_module/agent.py

Example Queries to Try:

You: Hello! Can you help me with math?
You: What can you do?

What to Notice:

  • Application converts to async (asyncio.run)
  • Client connects to calculator server on startup
  • Graceful disconnect on exit
  • No functional difference yet - tools not used

Step 2: Supporting Tools

What's New:

  • get_available_tools() - Discover server capabilities
  • use_tool() - Execute tools and handle results
  • Agentic loop pattern implementation

Concepts Implemented:

  • Tool discovery and formatting for Claude API
  • Tool execution via MCP protocol
  • Agentic loop (Claude decides when to use tools)
  • Multi-turn tool use conversations
  • Content type handling (text, images, resources)

How to Run:

uv run python 02_supporting_tools/agent.py

Example Queries to Try:

You: What is 25 multiplied by 17?
You: Calculate (45 + 67) * 3
You: If I have 1000 dollars and spend 234, how much is left?
You: What's 15 divided by 3, then add 10?

What to Notice:

  • Server tools are displayed on startup
  • [Using tool: ...] messages show tool execution
  • Claude decides when tools are needed
  • Multiple tools can be used in sequence
  • Results are integrated into Claude's response

Step 3: Supporting Resources

What's New:

  • get_available_resources() - List available data
  • get_resource(uri) - Fetch resource content
  • Resource context injection pattern

Concepts Implemented:

  • Resource discovery and metadata retrieval
  • URI-based resource access
  • Context injection into user messages
  • Multi-modal content (text and images)
  • Difference between tools (agentic) and resources (context)

How to Run:

uv run python 03_supporting_resources/agent.py

Example Queries to Try:

You: What is the value of pi?
You: Tell me about the golden ratio
You: What's the quadratic formula?
You: How does Euler's number relate to compound interest?

What to Notice:

  • Resources are loaded before each query
  • [Loading resource: ...] messages show what's loaded
  • Claude has access to math constants and formulas
  • Resources provide background knowledge
  • Can answer questions about resource content without tool use

Step 4: Supporting Prompts

What's New:

  • get_available_prompts() - List prompt templates
  • load_prompt(name, arguments) - Fetch and render prompts
  • Complete integration of all three MCP primitives

Concepts Implemented:

  • Prompt template discovery
  • Parameterized prompt loading
  • Prompts as system instructions
  • Three MCP primitive types working together:
    • Tools: Agentic execution (Claude decides when)
    • Resources: Background context (pre-loaded)
    • Prompts: Behavior guidance (system instructions)

How to Run:

uv run python 04_supporting_prompts/agent.py

Example Queries to Try:

You: What is 156 times 23?
You: Calculate the area of a circle with radius 5
You: Solve: 2x + 5 = 13
You: What's the difference between pi and e?
You: Help me solve: (3 + 4) * (10 - 2)

What to Notice:

  • All server capabilities displayed on startup
  • [Loading prompt: ...] shows prompt usage
  • Prompts guide how Claude approaches problems
  • Complete integration: prompts guide, resources inform, tools execute
  • Claude can combine all three for complex queries

Understanding MCP Primitives

Tools

When to Use: For actions and computations

  • Claude decides when to execute them
  • Used dynamically during conversation
  • Examples: Calculator functions, API calls, file operations

Resources

When to Use: For background information

  • Pre-loaded before sending message
  • Provide context that's always available
  • Examples: Documentation, constants, configuration data

Prompts

When to Use: For behavior guidance

  • Define how the assistant should behave
  • Can be parameterized for different scenarios
  • Examples: Tone settings, response formats, domain expertise

Next Steps

After completing this workshop, you can:

  1. Connect to Existing Servers

    • Explore the MCP Servers Repository
    • Connect to databases, APIs, and file systems
    • Combine multiple servers in one client
  2. Enhance the Client

    • Add intelligent resource selection
    • Implement prompt switching based on context
    • Add support for streaming responses
    • Build a more sophisticated UI
    • Connect to the new MCP registry
    • Build client-provided capabilities, like roots and elicitations. The test server can use them as-is.

Troubleshooting

"ANTHROPIC_API_KEY not set" error

Make sure you've created a .env file with your API key:

cp .env.example .env
# Edit .env and add: ANTHROPIC_API_KEY=your_actual_key

Import errors or missing dependencies

Reinstall dependencies:

uv sync --force

Calculator server not connecting

The server is started automatically by the client. If you see connection errors:

  1. Ensure calculator_server.py exists in the project root
  2. Check that uv can run Python scripts: uv run python --version

Resources

About

Code for the workshop From Intelligent to Agentic Apps: Using MCP to Support Agentic Behaviors in Your Applications

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages