Skip to main content
Glama
sritajkumarpatel

Weather Service MCP

README.md
# MCP Learning Project 2025 ๐Ÿš€

![Python](https://img.shields.io/badge/Python-3.13+-3776AB?style=for-the-badge&logo=python&logoColor=white)
![MCP](https://img.shields.io/badge/MCP-Protocol-orange?style=for-the-badge)
![FastMCP](https://img.shields.io/badge/FastMCP-Server-blue?style=for-the-badge)
![UV](https://img.shields.io/badge/UV-Package_Manager-purple?style=for-the-badge)
![License](https://img.shields.io/badge/License-Learning-green?style=for-the-badge)

> A hands-on project to demonstrate building and deploying **Model Context Protocol (MCP)** servers. Learn how to create custom MCP tools, configure them for AI assistants, and integrate them with Claude Desktop, Continue, and other MCP-compatible applications.

## ๐ŸŽฏ What You'll Learn

- ๐Ÿ› ๏ธ Build custom MCP servers from scratch
- ๐Ÿ”Œ Integrate MCP tools with AI assistants
- ๐Ÿงช Test and debug using MCP Inspector and MCP Studio
- ๐Ÿ“ฆ Manage dependencies with UV or pip
- ๐Ÿš€ Deploy production-ready MCP servers
- ๐ŸŽจ Create type-safe tools with Pydantic
- ๐ŸŒ Use streamable HTTP transport for advanced scenarios

## ๐Ÿ—๏ธ Tech Stack

| Category | Technology | Purpose |
|----------|------------|---------|
| **Language** | Python 3.13+ | Core programming language |
| **Protocol** | MCP (Model Context Protocol) | Standardized AI-tool communication |
| **Framework** | FastMCP | Rapid MCP server development |
| **Package Manager** | UV or pip + venv | Dependency management |
| **Validation** | Pydantic | Data validation and type safety |
| **Server** | Uvicorn | ASGI server for MCP |
| **Testing** | MCP Inspector & MCP Studio | Interactive testing and debugging |

## ๐Ÿ“‹ Prerequisites

Before diving in, make sure you have:

- โœ… **Python 3.13+** installed on your system
- โœ… **UV** (recommended) or **pip + venv** for package management
- โœ… **VS Code** (optional but recommended for MCP configuration)
- โœ… **Git** for version control
- โœ… **Terminal** access (PowerShell, CMD, or Bash)

## ๐Ÿš€ Installation

<table>
<tr>
<th width="50%">Using UV (Recommended)</th>
<th width="50%">Using pip + venv</th>
</tr>
<tr>
<td>

**1. Install UV:**
```bash
# Windows (PowerShell)
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
```

**2. Initialize project:**
```bash
# Create new project
uv init learn-mcp-2025
cd learn-mcp-2025

# Or in existing directory
uv init
```

**3. Add MCP dependencies:**
```bash
# Add MCP with CLI tools
uv add "mcp[cli]"

# This creates/updates:
# - pyproject.toml
# - uv.lock
```

**4. Install all dependencies:**
```bash
uv sync
```

</td>
<td>

**1. Navigate to project:**
```bash
cd learn-mcp-2025
```

**2. Create virtual environment:**
```bash
python -m venv .venv
```

**3. Activate virtual environment:**
```bash
# Windows (PowerShell)
.venv\Scripts\Activate.ps1

# Windows (CMD)
.venv\Scripts\activate.bat
```

**4. Install dependencies:**
```bash
# From requirements.txt
pip install -r requirements.txt

# Or install package in editable mode
pip install -e .
```

</td>
</tr>
</table>

### Generated Files

| UV | pip + venv |
|----|------------|
| `pyproject.toml` - Project metadata and dependencies | `requirements.txt` - Pinned dependencies |
| `uv.lock` - Locked dependency versions | `.venv/` - Virtual environment directory |

## โš™๏ธ MCP Server Configuration

To integrate your MCP server with AI clients (like Claude Desktop), create a configuration file:

### Create `.vscode/mcp.json`

```json
{
    "servers": {
        "weather-service": {
            "command": "python",
            "args": ["weather.py"],
            "env": {}
        }
    }
}
```

### Multi-Server Configuration

```json
{
    "servers": {
        "weather-service": {
            "command": "python",
            "args": ["weather.py"],
            "env": {}
        },
        "winget-mcp": {
            "type": "stdio",
            "command": "C:\\Users\\YourUser\\AppData\\Local\\Microsoft\\WindowsApps\\...\\WindowsPackageManagerMCPServer.exe"
        }
    }
}
```

### Configuration Options

| Field | Description | Example |
|-------|-------------|---------|
| `command` | Executable to run | `python`, `node`, `uv` |
| `args` | Arguments passed to command | `["weather.py"]`, `["run", "server.py"]` |
| `env` | Environment variables | `{"API_KEY": "value"}` |
| `type` | Communication type | `stdio` (default) |

## ๐ŸŽฎ Running the MCP Server

### Method 1: Quick Testing โšก (Direct Function Call)

Test individual functions without starting the full MCP server:

<table>
<tr>
<th width="50%">Using UV</th>
<th width="50%">Using pip + venv</th>
</tr>
<tr>
<td>

```bash
uv run python -c "from weather import get_weather; print(get_weather('London'))"
```

**Output:**
```
The current weather in London is sunny with a temperature of 25ยฐC.
```

</td>
<td>

```bash
# Activate venv first
.venv\Scripts\Activate.ps1

# Then run
python -c "from weather import get_weather; print(get_weather('London'))"
```

**Output:**
```
The current weather in London is sunny with a temperature of 25ยฐC.
```

</td>
</tr>
</table>

**When to use:**
- โœ… Fast iteration during development
- โœ… Unit testing individual tools
- โœ… Debugging function logic
- โŒ Won't work with MCP clients

### Method 2: Production Mode ๐Ÿš€ (Full MCP Server)

Run as a complete MCP server for AI assistant integration:

<table>
<tr>
<th width="50%">Using UV</th>
<th width="50%">Using pip + venv</th>
</tr>
<tr>
<td>

```bash
# Start MCP server
uv run python weather.py

# The server will start and listen for MCP requests
```

</td>
<td>

```bash
# Activate venv first
.venv\Scripts\Activate.ps1

# Start MCP server
python weather.py
```

</td>
</tr>
</table>

**When to use:**
- โœ… Integration with AI assistants (Claude, Continue, etc.)
- โœ… Production deployments
- โœ… Multi-tool servers
- โœ… Standardized MCP protocol communication

### Method 3: MCP Inspector ๐Ÿ” (Development & Debugging)

Use the MCP Inspector to interactively test your server with a web UI:

<table>
<tr>
<th width="50%">Using Python MCP CLI</th>
<th width="50%">Using Node.js npx (Recommended)</th>
</tr>
<tr>
<td>

**With UV:**
```bash
# Start MCP dev mode
uv run mcp dev <your-server.py>
```

**With pip + venv:**
```bash
# Activate venv first
.venv\Scripts\Activate.ps1

# Start MCP dev mode
mcp dev <your-server.py>
```

**Features:**
- Terminal-based debugging
- Log output in console
- Quick server validation
- โŒ No web UI

</td>
<td>

**With UV:**
```bash
# No installation needed - npx downloads temporarily
npx @modelcontextprotocol/inspector uv run <your-server.py>
```

**With pip + venv:**
```bash
# Activate venv first
.venv\Scripts\Activate.ps1

# Run inspector with Python
npx @modelcontextprotocol/inspector python <your-server.py>
```

**Features:**
- โœ… Interactive web UI
- โœ… Visual tool explorer
- โœ… Request/response inspection
- โœ… Real-time testing
- โœ… Always latest version

</td>
</tr>
</table>

**MCP Inspector Features:**
- ๐Ÿ” Interactive tool testing in browser
- ๐Ÿ“Š Request/response inspection
- ๐Ÿ› Real-time debugging
- ๐Ÿ“ Schema validation
- ๐ŸŽจ Visual interface for all MCP tools

**Access Inspector:**
```
Open browser: http://localhost:5173
```

**Example with weather.py:**
```bash
$ npx @modelcontextprotocol/inspector uv run weather.py
MCP Inspector running at http://localhost:5173
Server: Weather Service
Tools available: get_weather
```

### Method 4: Python Client ๐Ÿ (Programmatic Access)

Use Python code to connect to MCP servers programmatically:

**Example 1: Connect to Weather Service (Python Server)**

```bash
# Run the weather client
python client.py
```

**Example 2: Connect to Airbnb Service (Node.js Server)**

```bash
# Run the Airbnb client (connects to Node.js server via npx)
python client_airbnb.py
```

**Client Features:**
- ๐Ÿ“ก Programmatic MCP server connections
- ๐Ÿ”„ Async/await communication patterns
- ๐ŸŒ Cross-language support (Python โ†” Node.js)
- ๐Ÿ› ๏ธ Direct tool invocation from code
- ๐Ÿ“‹ Dynamic tool discovery with `list_tools()`

**When to use:**
- โœ… Building MCP-powered applications
- โœ… Automating tool calls in scripts
- โœ… Testing server integrations
- โœ… Creating custom MCP workflows
- โœ… Connecting to third-party MCP servers

### Method 5: MCP Studio ๐Ÿ› ๏ธ (Advanced Testing & Streamable Transport)

MCP Studio provides advanced debugging capabilities, especially for streamable HTTP transports and complex server integrations.

#### Setup MCP Studio

**1. Install MCP Studio:**
```bash
npm install -g @modelcontextprotocol/studio
```

**2. Configure Remote Server in `.vscode/mcp.json`:**
```json
{
  "servers": {
    "remote-example": {
      "command": "npx",
      "args": ["mcp-remote", "http://127.0.0.1:8000"]
    }
  }
}
```

**3. Run Streamable Server:**
```bash
# Start the streamable server on HTTP transport
uv run python sample_mcp_streamable_server.py
# Server runs on http://127.0.0.1:8000 (or configured port)
```

**4. Connect with MCP Studio:**
```bash
# Launch MCP Studio and connect to remote server
mcp-studio --remote http://127.0.0.1:8000
```

**MCP Studio Benefits:**
- **Visual Debugging**: Interactive UI for tool calls and responses
- **Streamable Transport Support**: Handles HTTP/SSE connections for streamable servers
- **Real-time Monitoring**: Live logs and error tracking
- **Multi-Server Testing**: Test multiple servers simultaneously
- **Integration Testing**: Simulate AI assistant interactions

**When to use MCP Studio:**
- โœ… Testing streamable HTTP servers
- โœ… Complex multi-tool integrations
- โœ… Production-like testing scenarios
- โœ… Debugging connection issues

## ๐Ÿ“ Project Structure

```
learn-mcp-2025/
โ”œโ”€โ”€ .github/
โ”‚   โ”œโ”€โ”€ copilot-instructions.md    # AI agent development guidelines
โ”‚   โ””โ”€โ”€ prompts/                   # Reusable prompt templates
โ”œโ”€โ”€ .vscode/
โ”‚   โ””โ”€โ”€ mcp.json                   # MCP server configuration for VS Code/AI assistants
โ”œโ”€โ”€ .venv/                         # Virtual environment (pip only)
โ”‚
โ”œโ”€โ”€ MCP Servers (Tools for AI Assistants)
โ”œโ”€โ”€ weather__mcp_server.py         # ๐Ÿ”ง Weather service tools
โ”œโ”€โ”€ crypto_mcp_server.py           # ๐Ÿ”ง Cryptocurrency price tools
โ”œโ”€โ”€ local_notes_mcp_server.py      # ๐Ÿ”ง Local notes management (add/get)
โ”œโ”€โ”€ screenshot_tool.py             # ๐Ÿ”ง Screenshot capture tool
โ”œโ”€โ”€ pydantic_schema_person_server.py # ๐Ÿ”ง Person data schema & processing
โ”œโ”€โ”€ resources_mcp_server.py        # ๐Ÿ”ง Resource management (coffee inventory)
โ”œโ”€โ”€ websearch_mcp_server.py        # ๐Ÿ”ง Web search functionality
โ”œโ”€โ”€ sample_mcp_streamable_server.py # ๐Ÿ”ง Streamable HTTP transport example
โ”‚
โ”œโ”€โ”€ MCP Clients (Test & Integration)
โ”œโ”€โ”€ weather_mcp_client.py          # ๐Ÿ”Œ Client for weather server
โ”œโ”€โ”€ airbnb_mcp_client.py           # ๐Ÿ”Œ Client for Airbnb server (Node.js)
โ”œโ”€โ”€ resources_mcp_client.py        # ๐Ÿ”Œ Client for resources server
โ”‚
โ”œโ”€โ”€ Configuration & Dependencies
โ”œโ”€โ”€ pyproject.toml                 # Project metadata & dependencies (UV)
โ”œโ”€โ”€ requirements.txt               # Pinned dependencies (pip)
โ”œโ”€โ”€ uv.lock                        # Locked dependency versions (UV)
โ”œโ”€โ”€ .python-version                # Python version specification
โ”œโ”€โ”€ .gitignore                     # Git ignore rules
โ”œโ”€โ”€ notes.txt                      # Data file for local_notes_mcp_server
โ”œโ”€โ”€ log.txt                        # Log file for person data
โ””โ”€โ”€ README.md                      # This file
```

### Key Files Explained

| File | Type | Purpose |
|------|------|---------|
| `weather__mcp_server.py` | **MCP Server** | Weather service with mock weather data tools |
| `crypto_mcp_server.py` | **MCP Server** | Cryptocurrency price lookup tools |
| `local_notes_mcp_server.py` | **MCP Server** | File-based notes management (add/get) |
| `screenshot_tool.py` | **MCP Server** | Screenshot capture using Pillow |
| `pydantic_schema_person_server.py` | **MCP Server** | Person data schema & processing with validation |
| `resources_mcp_server.py` | **MCP Server** | Resource management (coffee inventory example) |
| `websearch_mcp_server.py` | **MCP Server** | Web search functionality |
| `sample_mcp_streamable_server.py` | **MCP Server** | Streamable HTTP transport example |
| `weather_mcp_client.py` | **MCP Client** | Python client connecting to weather server |
| `airbnb_mcp_client.py` | **MCP Client** | Python client connecting to Node.js Airbnb server |
| `resources_mcp_client.py` | **MCP Client** | Python client for resources server |
| `pyproject.toml` | Config | Modern Python project configuration (PEP 621) |
| `requirements.txt` | Config | Traditional pip dependency list (auto-generated) |
| `uv.lock` | Config | UV's deterministic dependency lock file |
| `.vscode/mcp.json` | Config | MCP server registry for VS Code/Claude Desktop |

## ๐Ÿ“š Quick Command Reference

### UV Commands ๐Ÿ”ฎ

| Command | Description |
|---------|-------------|
| `uv init` | Initialize new Python project |
| `uv add <package>` | Add dependency to project |
| `uv remove <package>` | Remove dependency |
| `uv sync` | Install/sync all dependencies |
| `uv run <command>` | Run command in project environment |
| `uv pip list` | List installed packages |
| `uv pip show <package>` | Show package details |
| `uv lock` | Update lock file |
| `uv python install <ver>` | Install Python version |
| `uv python list` | List available Python versions |

### pip + venv Commands ๐Ÿ

| Command | Description |
|---------|-------------|
| `python -m venv .venv` | Create virtual environment |
| `.venv\Scripts\Activate.ps1` | Activate venv (PowerShell) |
| `.venv\Scripts\activate.bat` | Activate venv (CMD) |
| `pip install -r requirements.txt` | Install dependencies |
| `pip install -e .` | Install package in editable mode |
| `pip install <package>` | Install single package |
| `pip uninstall <package>` | Remove package |
| `pip list` | List installed packages |
| `pip show <package>` | Show package details |
| `pip freeze > requirements.txt` | Export dependencies |
| `deactivate` | Deactivate virtual environment |

### MCP Commands ๐Ÿ”ง

| Command | Description |
|---------|-------------|
| `mcp dev <file>` | Start MCP Inspector for development |
| `mcp --version` | Check MCP CLI version |
| `python <file>.py` | Start MCP server in production |
| `npx @modelcontextprotocol/inspector uv run <file>` | Interactive MCP testing |
| `mcp-studio --remote <url>` | Advanced MCP Studio testing |

## ๐Ÿ’ก Development Examples

### Example 1: Adding a New Weather Tool ๐ŸŒค๏ธ

Edit `weather.py`:

```python
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("Weather Service")

@mcp.tool()
def get_weather(location: str) -> str:
    """Get current weather for a location."""
    return f"The current weather in {location} is sunny with a temperature of 25ยฐC."

@mcp.tool()
def get_forecast(location: str, days: int = 7) -> str:
    """Get weather forecast for the next N days."""
    return f"Forecast for {location} for the next {days} days: Mostly sunny"

@mcp.tool()
def get_temperature(location: str, unit: str = "celsius") -> str:
    """Get current temperature in specified unit."""
    temp = 25 if unit == "celsius" else 77
    return f"Temperature in {location}: {temp}ยฐ{unit[0].upper()}"

if __name__ == "__main__":
    mcp.run()
```

### Example 2: Testing New Tools โœ…

```bash
# Test with UV
uv run python -c "from weather import get_forecast; print(get_forecast('Paris', 5))"

# Test with pip/venv
python -c "from weather import get_forecast; print(get_forecast('Paris', 5))"
```

### Example 3: Adding Type Safety ๐Ÿ”’

```python
from typing import Literal
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("Weather Service")

@mcp.tool()
def get_temperature(
    location: str, 
    unit: Literal["celsius", "fahrenheit"] = "celsius"
) -> str:
    """Get temperature with validated unit parameter."""
    temp = 25 if unit == "celsius" else 77
    return f"Temperature in {location}: {temp}ยฐ{unit[0].upper()}"
```

### Example 4: Building a Python MCP Client ๐Ÿ”Œ

```python
# client.py
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
import asyncio

server_params = StdioServerParameters(
    command="uv",
    args=["run", "weather.py"]
)

async def main():
    async with stdio_client(server_params) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()
            
            # Call a tool
            result = await session.call_tool(
                "get_weather", 
                arguments={"location": "Tokyo"}
            )
            print(result)
            
            # List all available tools
            tools = await session.list_tools()
            print(f"Available tools: {tools}")

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

### Example 5: Cross-Language MCP Integration ๐ŸŒ

Connect Python client to Node.js MCP server:

```python
# client_airbnb.py
server_params = StdioServerParameters(
    command="npx",
    args=["-y", "@openbnb/mcp-server-airbnb"]
)

async def main():
    async with stdio_client(server_params) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()
            
            # Discover tools from Node.js server
            tools = await session.list_tools()
            print(f"Airbnb MCP Tools: {tools}")
```

### Example 6: Streamable HTTP Transport ๐ŸŒ

For advanced scenarios requiring HTTP-based communication:

```python
# sample_mcp_streamable_server.py
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("Streamable MCP Server")

@mcp.tool()
def greet(name: str) -> str:
    """Greets the user with their name."""
    return f"Hello, {name}! Hope you're having a great day! ๐Ÿ˜Š"

if __name__ == "__main__":
    # Use streamable HTTP transport for advanced scenarios
    mcp.run(transport="streamable-http")
```

**Testing Streamable Servers:**
```bash
# Start server
uv run python sample_mcp_streamable_server.py

# Test with MCP Studio (in another terminal)
mcp-studio --remote http://127.0.0.1:8000
```

### Example 7: Debugging & Verification ๐Ÿ›

```bash
# List all tools in your server
uv run python -c "from weather import mcp; print(mcp.list_tools())"

# Check Python version
uv run python --version

# Verify MCP package
uv pip show mcp

# Test imports
uv run python -c "from weather import mcp; print('MCP initialized successfully')"

# Run client tests
python client.py
python client_airbnb.py
```

## ๐Ÿค Contributing

This is a learning project! Feel free to:
- ๐Ÿ› Report bugs or issues
- ๐Ÿ’ก Suggest new MCP tools
- ๐Ÿ“ Improve documentation
- ๐Ÿ”€ Submit pull requests

## ๐Ÿ“„ License

This project is for learning purposes.

---

<div align="center">

**Built with โค๏ธ for learning MCP**

โญ Star this repo if you found it helpful!

[๐Ÿ™ GitHub](https://github.com/sritajkumarpatel/learn_mcp_2025) โ€ข [๐Ÿ“š MCP Docs](https://modelcontextprotocol.io) โ€ข [๐Ÿ”ง FastMCP](https://github.com/jlowin/fastmcp)

</div>

TDQS

B3.1/5.0

Scored across 1 tool

Disambiguation5/5

With only one tool, there is no possibility of ambiguity or overlap between tools. The single tool has a clear, distinct purpose that cannot be confused with any other tool in the set.

Naming Consistency5/5

The single tool follows a clear verb_noun pattern (get_weather), and with only one tool, there is perfect consistency. There are no other tools to create naming conflicts or inconsistencies.

Tool Count2/5

A single tool is too few for a weather service domain, which typically requires operations like forecasts, historical data, or multiple location queries. This feels thin and incomplete for the apparent scope of a weather service.

Completeness2/5

The tool surface is severely incomplete for a weather service. While get_weather provides current conditions, there are obvious gaps such as missing forecast retrieval, historical weather data, or multi-location queries, which will limit agent capabilities in this domain.

Maintenance

ActivityInactive
ResponsivenessNo issues