使用说明
Remote MCP Server - Weather Information Service
A Python implementation of a Remote Model Context Protocol (MCP) server that provides weather information for cities over HTTP. This project demonstrates how to build and use an MCP server with Streamable HTTP transport using the FastMCP framework.
Built following the official MCP documentation
Features
- Weather information retrieval by city name
- Streamable HTTP transport - Remote MCP communication
- FastMCP framework - Simple, decorator-based tool registration
- Interactive command-line interface
- Mock weather data generation (temperature, conditions, humidity, wind)
Quick Start
# Create and activate virtual environment
virtualenv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install dependencies (just one!)
pip install -r requirements.txt
# Run the server (in one terminal)
python mcp_server.py
# Run the client (in another terminal)
source .venv/bin/activate
python mcp_client.py
Architecture
┌─────────────┐ Streamable HTTP ┌─────────────┐
│ │ ───────────────────▶ │ │
│ MCP Client │ (POST + SSE) │ MCP Server │
│ │ ◀─────────────────── │ (HTTP) │
└─────────────┘ └─────────────┘
Local Remote
(localhost:8000)
The server runs as an independent HTTP service accessible by multiple clients over the network.
Prerequisites
- Python 3.10 or higher
pip(Python package installer)virtualenv(for virtual environment)
Installation & Setup
1. Create Virtual Environment
virtualenv .venv
2. Activate Virtual Environment
macOS/Linux:
source .venv/bin/activate
Windows:
.venv\Scripts\activate
3. Install Dependencies
pip install -r requirements.txt
This installs the mcp package which includes FastMCP and all necessary dependencies (Uvicorn, Starlette, httpx, etc.).
Usage
Running the Server
Start the MCP server in one terminal:
python mcp_server.py
You should see:
Starting Weather MCP Server with Streamable HTTP...
Server will be available at: http://localhost:8000
MCP endpoint: http://localhost:8000/mcp
INFO: Started server process [12345]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
Running the Client
In a separate terminal, activate the virtual environment and run the client:
source .venv/bin/activate # On macOS/Linux
python mcp_client.py
You'll see:
Connecting to MCP weather server at http://localhost:8000...
Connected successfully!
============================================================
Welcome to the MCP Weather Client!
============================================================
Enter a city name to get weather information.
Type 'quit' to exit.
============================================================
Enter city name (or 'quit' to exit):
Example Session
Enter city name (or 'quit' to exit): London
Fetching weather for London...
Weather Report for London
==========================
Temperature: 18°C
Condition: Partly Cloudy
Humidity: 65%
Wind: 15 km/h SW
Enter city name (or 'quit' to exit): quit
Thank you for using the MCP Weather Client!
Connecting to a Remote Server
python mcp_client.py http://remote-server:8000
Project Structure
remote-mcp-server/
├── mcp_server.py # FastMCP server (57 lines)
├── mcp_client.py # Streamable HTTP client (81 lines)
├── requirements.txt # Single dependency: mcp
├── README.md # This file
└── .venv/ # Virtual environment
How It Works
Server Implementation
The server uses FastMCP with decorator-based tool registration:
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("weather-server")
@mcp.tool()
def get_weather(city: str) -> str:
"""Get current weather information for a specific city.
Args:
city: The name of the city to get weather for
"""
# Generate weather data...
return weather_report
mcp.run(transport='streamable-http')
Key Features:
- Automatic JSON schema generation from type hints and docstrings
- Built-in HTTP server (Uvicorn) - no manual configuration needed
- Automatic endpoint configuration at
/mcp - Just 57 lines of code!
Client Implementation
The client uses async context managers for clean resource management:
async with streamablehttp_client(mcp_endpoint) as (read, write, _):
async with ClientSession(read, write) as session:
await session.initialize()
# Call tools
result = await session.call_tool("get_weather",
arguments={"city": city})
print(result.content[0].text)
Customization
Adding More Tools
Simply add more decorated functions:
@mcp.tool()
def get_forecast(city: str, days: int = 5) -> str:
"""Get weather forecast for a city.
Args:
city: The name of the city
days: Number of days to forecast (1-7)
"""
# Your forecast logic here
return forecast_data
@mcp.tool()
def get_alerts(state: str) -> str:
"""Get weather alerts for a US state.
Args:
state: Two-letter US state code (e.g., CA, NY)
"""
# Your alerts logic here
return alerts_data
FastMCP automatically registers these tools and generates their schemas!
Integrating Real Weather Data
Replace the mock data generation with a real API call:
import httpx
@mcp.tool()
async def get_weather(city: str) -> str:
"""Get current weather for a city."""
api_key = "your_api_key_here"
url = f"https://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}&units=metric"
async with httpx.AsyncClient() as client:
response = await client.get(url)
data = response.json()
return f"""
Weather Report for {city}
Temperature: {data['main']['temp']}°C
Condition: {data['weather'][0]['description'].title()}
Humidity: {data['main']['humidity']}%
Wind: {data['wind']['speed']} m/s
"""
Changing the Server Port
FastMCP uses environment variables for configuration:
# Set custom port
export MCP_SERVER_PORT=9000
python mcp_server.py
Or modify the code to pass port to uvicorn (FastMCP uses uvicorn internally).
Deployment
Docker Deployment
Create a Dockerfile:
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY mcp_server.py .
EXPOSE 8000
CMD ["python", "mcp_server.py"]
Build and run:
docker build -t mcp-weather-server .
docker run -p 8000:8000 mcp-weather-server
Production Considerations
- Environment Variables: Store API keys and configuration in environment variables
- Logging: Configure appropriate logging levels for production
- Monitoring: Add health check endpoints and monitoring
- Security: Implement authentication if needed (MCP supports JWT)
- Reverse Proxy: Use nginx or similar for SSL termination and load balancing
Troubleshooting
"Connection refused" errors
- Make sure the server is running:
python mcp_server.py - Check if port 8000 is available
- Verify firewall settings
"Module not found" errors
Activate the virtual environment:
source .venv/bin/activate # macOS/Linux
.venv\Scripts\activate # Windows
Port already in use
Find and kill the process using port 8000:
# macOS/Linux
lsof -ti:8000 | xargs kill
# Windows
netstat -ano | findstr :8000
taskkill /PID <PID> /F
Technical Details
FastMCP Framework
This project uses FastMCP, the official high-level framework for building MCP servers:
- Decorator-based API: Use
@mcp.tool()to register tools - Automatic Schema Generation: Type hints → JSON schemas automatically
- Transport Flexibility: Supports
stdio,sse, andstreamable-http - Production Ready: Built-in server management and error handling
Streamable HTTP Transport
Streamable HTTP is the modern standard for remote MCP communication:
- Bidirectional: HTTP POST (client→server) + SSE (server→client)
- Session Management: Automatic session tracking
- Resumable: Optional event storage for reconnection
- Scalable: Supports multiple concurrent clients
- Network-friendly: Standard HTTP/HTTPS
Comparison: Local vs Remote
| Feature | stdio (Local) | Streamable HTTP (Remote) |
|---|---|---|
| Transport | Standard I/O | HTTP POST + SSE |
| Server Location | Same process | Separate process/machine |
| Multiple Clients | No | Yes |
| Network Access | No | Yes |
| Resumability | No | Yes (optional) |
| Use Case | Integrated tools | Distributed systems |
Resources
License
This project is provided as-is for educational and demonstration purposes.
Built with ❤️ using FastMCP and Streamable HTTP