@@ -6,15 +6,15 @@ description: "Create a simple MCP server in Python in 15 minutes"
6
6
Let's build your first MCP server in Python! We'll create a weather server that provides current weather data as a resource and lets Claude fetch forecasts using tools.
7
7
8
8
<Note >
9
- This guide uses the OpenWeatherMap API. You'll need a free API key from [ OpenWeatherMap] ( https://openweathermap.org/api ) to follow along.
9
+ This guide uses the OpenWeatherMap API. You'll need a free API key from [ OpenWeatherMap] ( https://openweathermap.org/api ) to follow along.
10
10
</Note >
11
11
12
12
## Prerequisites
13
13
14
14
<Steps >
15
15
<Step title = " Install Python" >
16
- You'll need Python 3.9 or higher:
17
-
16
+ You'll need Python 3.10 or higher:
17
+
18
18
``` bash
19
19
python --version # Should be 3.9 or higher
20
20
pip --version
@@ -25,19 +25,19 @@ This guide uses the OpenWeatherMap API. You'll need a free API key from [OpenWea
25
25
``` bash
26
26
mkdir weather-server
27
27
cd weather-server
28
- python -m venv venv
29
- source venv/bin/activate # On Windows use: venv\Scripts\activate
28
+ uv init --package --app --name weather-server
30
29
```
31
30
</Step >
32
31
33
32
<Step title = " Install dependencies" >
34
33
``` bash
35
- pip install modelcontextprotocol requests python-dotenv
34
+ uv add mcp
36
35
```
37
36
</Step >
38
37
39
38
<Step title = " Set up environment" >
40
39
Create ` .env ` :
40
+
41
41
``` bash
42
42
OPENWEATHER_API_KEY=your-api-key-here
43
43
```
@@ -61,7 +61,7 @@ This guide uses the OpenWeatherMap API. You'll need a free API key from [OpenWea
61
61
import json
62
62
from datetime import datetime
63
63
from typing import Any, Dict, List, Optional
64
-
64
+
65
65
import requests
66
66
from dotenv import load_dotenv
67
67
from modelcontextprotocol import Server, StdioServerTransport
@@ -127,7 +127,7 @@ This guide uses the OpenWeatherMap API. You'll need a free API key from [OpenWea
127
127
print (" Weather MCP server running on stdio" , flush = True )
128
128
129
129
# Handler implementations will continue in next sections
130
- ```
130
+ ```
131
131
</Step >
132
132
133
133
<Step title = " Add resource handlers" >
@@ -298,6 +298,7 @@ This guide uses the OpenWeatherMap API. You'll need a free API key from [OpenWea
298
298
```
299
299
300
300
Create ` setup.py ` :
301
+
301
302
``` python
302
303
from setuptools import setup
303
304
@@ -331,6 +332,7 @@ This guide uses the OpenWeatherMap API. You'll need a free API key from [OpenWea
331
332
) -> Dict[str , Any]:
332
333
# ...
333
334
```
335
+
334
336
Python type hints help catch errors early and improve code maintainability.
335
337
</Tab >
336
338
@@ -348,6 +350,7 @@ This guide uses the OpenWeatherMap API. You'll need a free API key from [OpenWea
348
350
}]
349
351
}
350
352
```
353
+
351
354
Resources provide data that Claude can access as context.
352
355
</Tab >
353
356
@@ -365,17 +368,15 @@ This guide uses the OpenWeatherMap API. You'll need a free API key from [OpenWea
365
368
}
366
369
}
367
370
```
371
+
368
372
Tools let Claude take actions through your server with validated inputs.
369
373
</Tab >
370
374
</Tabs >
371
375
372
376
## Best practices
373
377
374
378
<CardGroup cols = { 1 } >
375
- <Card
376
- title = " Error Handling"
377
- icon = " shield"
378
- >
379
+ <Card title = " Error Handling" icon = " shield" >
379
380
``` python
380
381
try :
381
382
response = self .session.get(... )
@@ -388,10 +389,7 @@ This guide uses the OpenWeatherMap API. You'll need a free API key from [OpenWea
388
389
```
389
390
</Card >
390
391
391
- <Card
392
- title = " Type Validation"
393
- icon = " check"
394
- >
392
+ <Card title = " Type Validation" icon = " check" >
395
393
``` python
396
394
if not isinstance (args, dict ) or " city" not in args:
397
395
raise McpError(
@@ -401,20 +399,14 @@ This guide uses the OpenWeatherMap API. You'll need a free API key from [OpenWea
401
399
```
402
400
</Card >
403
401
404
- <Card
405
- title = " Environment Variables"
406
- icon = " gear"
407
- >
402
+ <Card title = " Environment Variables" icon = " gear" >
408
403
``` python
409
404
if not API_KEY :
410
405
raise ValueError (" OPENWEATHER_API_KEY is required" )
411
406
```
412
407
</Card >
413
408
414
- <Card
415
- title = " Constants"
416
- icon = " box"
417
- >
409
+ <Card title = " Constants" icon = " box" >
418
410
``` python
419
411
API_CONFIG = {
420
412
" BASE_URL" : " ..." ,
@@ -432,12 +424,14 @@ This guide uses the OpenWeatherMap API. You'll need a free API key from [OpenWea
432
424
While this guide uses stdio transport, MCP supports multiple transport options:
433
425
434
426
### WebSocket
427
+
435
428
``` python
436
429
from modelcontextprotocol import WebSocketServerTransport
437
430
transport = WebSocketServerTransport()
438
431
```
439
432
440
433
### SSE (Server-Sent Events)
434
+
441
435
``` python
442
436
from modelcontextprotocol import SSEServerTransport
443
437
transport = SSEServerTransport(" /events" , response)
@@ -446,6 +440,7 @@ transport = SSEServerTransport("/events", response)
446
440
## Troubleshooting
447
441
448
442
### Installation issues
443
+
449
444
``` bash
450
445
# Check Python version
451
446
python --version
@@ -456,13 +451,15 @@ pip install -r requirements.txt
456
451
```
457
452
458
453
### Runtime errors
454
+
459
455
``` bash
460
456
# Enable debug logging
461
457
export MCP_LOG_LEVEL=DEBUG
462
458
python weather_server.py
463
459
```
464
460
465
461
### Type checking
462
+
466
463
``` bash
467
464
# Install mypy
468
465
pip install mypy
@@ -493,7 +490,9 @@ mypy weather_server.py
493
490
494
491
<Step title = " Restart Claude" >
495
492
1 . Quit Claude completely
493
+
496
494
2 . Start Claude again
495
+
497
496
3 . Look for your weather server in the 🔌 menu
498
497
</Step >
499
498
</Steps >
@@ -503,20 +502,23 @@ mypy weather_server.py
503
502
<AccordionGroup >
504
503
<Accordion title = " Check Current Weather" active >
505
504
Ask Claude:
505
+
506
506
```
507
507
What's the current weather in San Francisco? Can you analyze the conditions and tell me if it's a good day for outdoor activities?
508
508
```
509
509
</Accordion >
510
510
511
511
<Accordion title = " Get a Forecast" >
512
512
Ask Claude:
513
+
513
514
```
514
515
Can you get me a 5-day forecast for Tokyo and help me plan what clothes to pack for my trip?
515
516
```
516
517
</Accordion >
517
518
518
519
<Accordion title = " Compare Weather" >
519
520
Ask Claude:
521
+
520
522
```
521
523
Can you analyze the forecast for both Tokyo and San Francisco and tell me which city would be better for outdoor photography this week?
522
524
```
@@ -692,27 +694,21 @@ mypy weather_server.py
692
694
## Deployment
693
695
694
696
<CardGroup cols = { 1 } >
695
- <Card
696
- title = " Docker"
697
- icon = " docker"
698
- >
697
+ <Card title = " Docker" icon = " docker" >
699
698
``` dockerfile
700
699
FROM python:3.11-slim
701
-
700
+
702
701
WORKDIR /app
703
702
COPY requirements.txt .
704
703
RUN pip install -r requirements.txt
705
-
704
+
706
705
COPY . .
707
-
706
+
708
707
CMD ["python" , "weather_server.py" ]
709
708
```
710
709
</Card >
711
710
712
- <Card
713
- title = " Systemd Service"
714
- icon = " server"
715
- >
711
+ <Card title = " Systemd Service" icon = " server" >
716
712
``` ini
717
713
[Unit]
718
714
Description =Weather MCP Server
@@ -732,19 +728,11 @@ mypy weather_server.py
732
728
## Next steps
733
729
734
730
<CardGroup cols = { 2 } >
735
- <Card
736
- title = " Architecture overview"
737
- icon = " sitemap"
738
- href = " /docs/concepts/architecture"
739
- >
731
+ <Card title = " Architecture overview" icon = " sitemap" href = " /docs/concepts/architecture" >
740
732
Learn more about the MCP architecture
741
733
</Card >
742
734
743
- <Card
744
- title = " Python SDK"
745
- icon = " python"
746
- href = " /api-reference/python/class-reference"
747
- >
735
+ <Card title = " Python SDK" icon = " python" href = " /api-reference/python/class-reference" >
748
736
Read more about the Python SDK
749
737
</Card >
750
738
</CardGroup >
0 commit comments