|
| 1 | +FastMCP — Weather MCP Server |
| 2 | +============================ |
| 3 | + |
| 4 | +Overview |
| 5 | +-------- |
| 6 | +This directory contains a FastMCP weather server example and a companion client. The server provides real-time weather information and forecasts using the free Open-Meteo API. It demonstrates a practical implementation of an MCP-compatible service (Model Context Protocol) for weather data, intended for local testing and quick deployment to [IBM Cloud Code Engine](https://www.ibm.com/products/code-engine). |
| 7 | + |
| 8 | + |
| 9 | + |
| 10 | +About MCP and FastMCP |
| 11 | +--------------------- |
| 12 | + |
| 13 | +MCP (Model Context Protocol) is a lightweight, transport-agnostic convention for exchanging model prompts, context, and responses between clients and model-serving services. It emphasizes: |
| 14 | + |
| 15 | +- **Transport flexibility**: works over HTTP, SSE, WebSocket, stdio and other streamable transports. |
| 16 | +- **Streaming-first behavior**: supports incremental/streaming responses for low-latency UX. |
| 17 | +- **Simple JSON semantics**: easy to implement and interoperate between services. |
| 18 | + |
| 19 | +**[FastMCP](https://gofastmcp.com/getting-started/welcome) is the standard framework for building MCP applications.** |
| 20 | + |
| 21 | +The [Direct Http Server](https://gofastmcp.com/deployment/http#direct-http-server) example provides a minimal reference implementation meant for experimentation and quick deployments. It focuses on a very small API surface and fast startup so you can iterate locally or run tiny instances in cloud platforms like Code Engine. |
| 22 | + |
| 23 | + |
| 24 | +Why Code Engine? |
| 25 | +----------------- |
| 26 | + |
| 27 | +[IBM Cloud Code Engine](https://www.ibm.com/products/code-engine) is a great fit for containerized MCP Servers because it provides: |
| 28 | + |
| 29 | +- **Serverless containers**: Deploy container images without managing infrastructure. |
| 30 | +- **Automatic scaling**: Scale to zero when idle and scale up on demand. |
| 31 | +- **Pay-per-use pricing**: Cost-efficient for intermittent workloads common to agents. |
| 32 | +- **Simple deployment**: Integrates with container registries and CI/CD pipelines. |
| 33 | +- **Managed endpoint**: Provides a secure http endpoint with a managed certificate. |
| 34 | + |
| 35 | +Weather MCP Server Features |
| 36 | +--------------------------- |
| 37 | + |
| 38 | +The server provides three weather-related tools: |
| 39 | + |
| 40 | +1. **search_location**: Search for locations by name to get coordinates |
| 41 | +2. **get_current_weather**: Get current weather conditions for specific coordinates |
| 42 | +3. **get_weather_forecast**: Get weather forecast for 1-16 days |
| 43 | + |
| 44 | +The Python source code for the MCP server is located in [./server/main.py](./server/main.py): |
| 45 | + |
| 46 | +```python |
| 47 | +from typing import Any |
| 48 | +from fastmcp import FastMCP |
| 49 | +import weather_api |
| 50 | + |
| 51 | +mcp = FastMCP("Weather MCP Server on Code Engine") |
| 52 | + |
| 53 | +@mcp.tool |
| 54 | +async def search_location(query: str) -> str: |
| 55 | + """ |
| 56 | + Search for a location by name to get coordinates for weather queries. |
| 57 | + |
| 58 | + Args: |
| 59 | + query: The location name to search for (e.g., "London", "New York", "Tokyo") |
| 60 | + |
| 61 | + Returns: |
| 62 | + A formatted string with matching locations and their coordinates |
| 63 | + """ |
| 64 | + try: |
| 65 | + data = await weather_api.search_location(query) |
| 66 | + return weather_api.format_location_results(data) |
| 67 | + except Exception as e: |
| 68 | + return f"Error searching for location: {str(e)}" |
| 69 | + |
| 70 | +@mcp.tool |
| 71 | +async def get_current_weather(latitude: float, longitude: float) -> str: |
| 72 | + """ |
| 73 | + Get the current weather conditions for a specific location. |
| 74 | + |
| 75 | + Args: |
| 76 | + latitude: The latitude of the location (e.g., 51.5074 for London) |
| 77 | + longitude: The longitude of the location (e.g., -0.1278 for London) |
| 78 | + |
| 79 | + Returns: |
| 80 | + A formatted string with current weather information |
| 81 | + """ |
| 82 | + try: |
| 83 | + data = await weather_api.get_current_weather(latitude, longitude) |
| 84 | + return weather_api.format_current_weather(data) |
| 85 | + except Exception as e: |
| 86 | + return f"Error getting current weather: {str(e)}" |
| 87 | + |
| 88 | +@mcp.tool |
| 89 | +async def get_weather_forecast(latitude: float, longitude: float, days: int = 7) -> str: |
| 90 | + """ |
| 91 | + Get the weather forecast for a specific location. |
| 92 | + |
| 93 | + Args: |
| 94 | + latitude: The latitude of the location |
| 95 | + longitude: The longitude of the location |
| 96 | + days: Number of days to forecast (1-16, default: 7) |
| 97 | + |
| 98 | + Returns: |
| 99 | + A formatted string with daily weather forecast |
| 100 | + """ |
| 101 | + try: |
| 102 | + data = await weather_api.get_weather_forecast(latitude, longitude, days) |
| 103 | + return weather_api.format_weather_forecast(data) |
| 104 | + except Exception as e: |
| 105 | + return f"Error getting weather forecast: {str(e)}" |
| 106 | + |
| 107 | +if __name__ == "__main__": |
| 108 | + mcp.run(transport="http", host="0.0.0.0", port=8080) |
| 109 | +``` |
| 110 | + |
| 111 | +The weather API functions are separated in [./server/weather_api.py](./server/weather_api.py) and use the free Open-Meteo API (no API key required). |
| 112 | + |
| 113 | +Deploying the server to Code Engine |
| 114 | +---------------------------------- |
| 115 | + |
| 116 | +**Prerequisites** |
| 117 | +Create an IBM Cloud account and [login into your IBM Cloud account using the IBM Cloud CLI](https://cloud.ibm.com/docs/codeengine?topic=codeengine-install-cli). |
| 118 | + |
| 119 | +**Deploy** |
| 120 | + |
| 121 | +1. Authenticate and login to IBM Cloud: |
| 122 | + |
| 123 | +```bash |
| 124 | +ibmcloud login --sso |
| 125 | +ibmcloud login --apikey "$IBMCLOUD_APIKEY" -r us-south |
| 126 | + |
| 127 | +``` |
| 128 | + |
| 129 | +2. Run the included deploy script from this folder. The script creates a new Code Engine project in the specified region and automates build/push/deploy steps to create a new application in Code Engine. |
| 130 | + |
| 131 | +```bash |
| 132 | +NAME_PREFIX=ce-fastmcp REGION=eu-de ./deploy.sh |
| 133 | +``` |
| 134 | + |
| 135 | +3. The deploy script will print the URL under which the MCP Server is publicly accessible |
| 136 | + |
| 137 | +``` |
| 138 | +FastMCP application is reachable under the following url: |
| 139 | +https://fastmcp.26n4g2nfyw7s.eu-de.codeengine.appdomain.cloud/mcp |
| 140 | +``` |
| 141 | + |
| 142 | +🚀 The example was successful and you can now use the MCP server in your chat application 🚀 |
| 143 | + |
| 144 | +Testing the deployed server with call_tool.sh |
| 145 | +--------------------------------------------- |
| 146 | +The `call_tool.sh` script provides a quick way to test your deployed MCP server directly from the command line. It demonstrates the complete MCP protocol flow with weather data for Stuttgart: |
| 147 | + |
| 148 | +1. Initializes an MCP session with the server |
| 149 | +2. Lists all available tools |
| 150 | +3. Searches for Stuttgart location |
| 151 | +4. Gets current weather for Stuttgart (coordinates: 48.7758, 9.1829) |
| 152 | +5. Gets 7-day weather forecast for Stuttgart |
| 153 | + |
| 154 | +Run the script from the `mcp_server_fastmcp` directory: |
| 155 | + |
| 156 | +```bash |
| 157 | +./call_tool.sh |
| 158 | +``` |
| 159 | + |
| 160 | +The script will automatically connect to your deployed FastMCP application and execute weather queries for Stuttgart. You should see output similar to: |
| 161 | + |
| 162 | +``` |
| 163 | +FastMCP application is reachable under the following url: |
| 164 | +https://fastmcp.26n4g2nfyw7s.eu-de.codeengine.appdomain.cloud/mcp |
| 165 | +
|
| 166 | +initialize session |
| 167 | +Session initialized: <session-id> |
| 168 | +
|
| 169 | +List tools |
| 170 | +
|
| 171 | +========================================== |
| 172 | +WEATHER TOOLS DEMONSTRATION FOR STUTTGART |
| 173 | +========================================== |
| 174 | +
|
| 175 | +1. Search for 'Stuttgart' location |
| 176 | +Stuttgart, Baden-Württemberg, Germany (lat: 48.7758, lon: 9.1829) |
| 177 | +
|
| 178 | +2. Get current weather for Stuttgart |
| 179 | +Current Weather: |
| 180 | +Condition: Partly cloudy |
| 181 | +Temperature: 15.2°C |
| 182 | +Feels like: 14.8°C |
| 183 | +Humidity: 65% |
| 184 | +Wind Speed: 12.5 km/h |
| 185 | +Precipitation: 0.0 mm |
| 186 | +
|
| 187 | +3. Get 7-day weather forecast for Stuttgart |
| 188 | +Weather Forecast: |
| 189 | +
|
| 190 | +2026-03-20: |
| 191 | + Condition: Partly cloudy |
| 192 | + Temperature: 8.5°C - 16.2°C |
| 193 | + Precipitation: 0.2 mm (probability: 20%) |
| 194 | + Max Wind Speed: 18.5 km/h |
| 195 | +... |
| 196 | +
|
| 197 | +SUCCESS |
| 198 | +``` |
| 199 | + |
| 200 | + |
| 201 | +Using this example with Claude Desktop |
| 202 | +------------------------------------- |
| 203 | +Claude Desktop can connect to local or remote MCP servers by registering them in its `claude_desktop_config.json` (Claude -> Settings -> Developer -> Edit Config). |
| 204 | + |
| 205 | + |
| 206 | +Example `claude_desktop_config.json` entry that point to your deployed application URL: |
| 207 | + |
| 208 | +```json |
| 209 | +{ |
| 210 | + "mcpServer": { |
| 211 | + "Weather FastMCP (Code Engine)": { |
| 212 | + "command": "npx", |
| 213 | + "args": [ |
| 214 | + "mcp-remote", |
| 215 | + "https://fastmcp.26n4g2nfyw7s.eu-de.codeengine.appdomain.cloud/mcp" |
| 216 | + ] |
| 217 | + } |
| 218 | + } |
| 219 | +} |
| 220 | +``` |
| 221 | + |
| 222 | +Save settings and restart Claude Desktop; the remote MCP server should appear as a selectable tool in Claude Desktop. |
| 223 | + |
| 224 | + |
| 225 | + |
| 226 | +You can now chat with the MCP Server, e.g. |
| 227 | + |
| 228 | +**_"Get the current weather and forecast of New York using the tool deployed in Code Engine :-)"_** |
| 229 | + |
| 230 | +Claude will detect the appropriate weather tools and call them to provide current weather conditions or forecasts for the requested locations. |
| 231 | + |
| 232 | + |
| 233 | + |
| 234 | +Building and using the Python client |
| 235 | +----------------------------- |
| 236 | +The `client` directory contains a small Python client to exercise the weather server. |
| 237 | + |
| 238 | +1. Create a virtual environment and install dependencies: |
| 239 | + |
| 240 | +```bash |
| 241 | +cd client |
| 242 | +python3 -m venv .venv |
| 243 | +source .venv/bin/activate |
| 244 | +pip install -r requirements.txt |
| 245 | +``` |
| 246 | + |
| 247 | +2. Run the client |
| 248 | + |
| 249 | +Start the client by replacing the application URL from above as the `MCP_SERVER_URL` environment variable, e.g. |
| 250 | + |
| 251 | +```bash |
| 252 | +MCP_SERVER_URL="https://fastmcp.26n4g2nfyw7s.eu-de.codeengine.appdomain.cloud/mcp" python client.py |
| 253 | +``` |
| 254 | + |
| 255 | +The client will demonstrate all three weather tools using Stuttgart as an example location: |
| 256 | +- Search for Stuttgart location |
| 257 | +- Get current weather for Stuttgart |
| 258 | +- Get 7-day weather forecast for Stuttgart |
| 259 | + |
| 260 | +3. Inspect and adapt |
| 261 | +- Open `client.py` to find example calls. The client demonstrates how to use all weather tools and can be adapted to query different locations or forecast periods. |
| 262 | + |
| 263 | + |
| 264 | +What's next? |
| 265 | +------------ |
| 266 | + |
| 267 | +You now have a very simple reference architecture to deploy any MCP server of your choice. |
0 commit comments