This guide builds upon the Calculator example. Now, we will give Claude the power to reach out to the internet and fetch real-world data.
We will build a Weather Server that fetches the forecast from Open-Meteo (a free weather API).
- Claude Desktop App: Download here.
- You have completed the Calculator Guide.
- uv is installed.
-
Create a new directory:
mkdir weather-mcp cd weather-mcp -
Initialize the project:
uv init
-
Add dependencies: We need
mcp(for the server) andrequests(to make simple web requests).uv add "mcp[cli]" requests
Create a file named weather.py.
Notice how this code looks just like a normal Python function. No async or await is needed here!
# weather.py
from mcp.server.fastmcp import FastMCP
import requests
# 1. Initialize the Server
mcp = FastMCP("Weather")
@mcp.tool()
def get_weather(latitude: float, longitude: float) -> str:
"""
Get the current weather for a specific location.
Args:
latitude: The latitude of the location.
longitude: The longitude of the location.
"""
# Using Open-Meteo: A free weather API that doesn't need a key
url = f"https://api.open-meteo.com/v1/forecast?latitude={latitude}&longitude={longitude}¤t_weather=true"
# Make the request and get the data
response = requests.get(url)
data = response.json()
# Extract the current temperature
temp = data["current_weather"]["temperature"]
return f"The current temperature at {latitude}, {longitude} is {temp}°C."
@mcp.tool()
def get_coordinates(city_name: str) -> str:
"""
Find the latitude and longitude for a city name.
Args:
city_name: The name of the city (e.g., "Paris", "San Francisco").
"""
# Use Open-Meteo's Geocoding API to find the location
url = f"https://geocoding-api.open-meteo.com/v1/search?name={city_name}&count=1&language=en&format=json"
response = requests.get(url)
data = response.json()
if "results" in data:
result = data["results"][0]
lat = result["latitude"]
lon = result["longitude"]
return f"{lat},{lon}"
else:
return "City not found."
if __name__ == "__main__":
mcp.run(transport="stdio")-
Open your config:
code ~/Library/Application\ Support/Claude/claude_desktop_config.json
-
Add the "weather" server: Add a new entry to your
mcpServerslist. (Replace/Users/YOUR_NAME/...with your actual path){ "mcpServers": { "my_calculator": { ... }, "weather": { "command": "uv", "args": [ "--directory", "/Users/YOUR_NAME/path/to/weather-mcp", "run", "weather.py" ] } } } -
Restart Claude.
-
Check the 🔌 icon. You should see both Calculator and Weather.
-
Ask Claude:
"What is the weather in San Francisco?"
-
Watch the Magic (Tool Chaining):
- Claude sees it has a
get_weathertool, but that tool needs coordinates. - It sees it has a
get_coordinatestool that takes a city name. - Step 1: Claude calls
get_coordinates("San Francisco")-> gets "37.77,-122.41". - Step 2: Claude takes that result and calls
get_weather(37.77, -122.41). - Step 3: It tells you the answer.
You didn't have to program this logic. Claude figured out the workflow on its own!
- Claude sees it has a
- Tool Chaining: You saw how Claude automatically used one tool (
get_coordinates) to get the data it needed for another tool (get_weather). - External APIs: This MCP server acts as a bridge. Claude asks the server, the server calls Open-Meteo, and the answer flows back.
- Multiple Servers: You can have as many MCP servers running as you want (Calculator + Weather + Files, etc.).