A Model Context Protocol (MCP) demo that exposes an Australian weather tool via a remote API.
MCP Client (client.py)
│ stdio
▼
MCP Server (server.py)
│ HTTPS POST
▼
Weather API
| File | Purpose |
|---|---|
server.py |
MCP server — exposes the get_weather tool |
client.py |
MCP client — launches the server and calls the tool |
tests/test_server.py |
Unit tests for the server |
tests/test_client.py |
Unit tests for the client |
pyproject.toml |
Project metadata and dependencies |
uv.lock |
Locked dependency versions (committed, do not edit manually) |
- Python 3.10 or later
- uv — install with
curl -LsSf https://astral.sh/uv/install.sh | sh
Install dependencies and create the virtual environment:
uv syncThe client starts the server automatically as a subprocess over stdio, then calls get_weather.
# Default city: Sydney
uv run python client.py
# Specify a city
uv run python client.py Brisbane
uv run python client.py Perth
uv run python client.py DarwinExample output:
Available tools:
- get_weather: Get the current weather for an Australian city.
Calling get_weather(city='Sydney') ...
The current weather in Sydney is 25°C with sunny and clear skies.
The server uses stdio transport and is designed to run only as a subprocess on the local machine. At startup it checks whether stdin is a TTY — if so, it exits immediately with an error:
ERROR: This MCP server must be launched by a local MCP host via stdio, not run interactively.
This prevents the server being run directly in a shell, over SSH, or in any context where it is not piped to a local MCP client.
The server speaks the MCP stdio protocol and is not intended to be run directly. Attempting to do so will trigger the local-only guard above. The correct entry point is client.py, which spawns the server automatically.
The server reads two environment variables. Both have working defaults pointing at the deployed PoC endpoint.
| Variable | Default | Description |
|---|---|---|
WEATHER_API_ENDPOINT |
https://nhy6ulzhfj.execute-api.ap-southeast-2.amazonaws.com/prod/weather |
Weather API endpoint URL |
WEATHER_API_TOKEN |
weather-poc-token-2026 |
Bearer token sent in the Authorization header |
Override them to point at a different environment:
export WEATHER_API_ENDPOINT=https://your-endpoint/prod/weather
export WEATHER_API_TOKEN=your-token
uv run python client.py SydneyGet the current weather for an Australian city.
Input
| Parameter | Type | Description |
|---|---|---|
city |
string |
City name, e.g. Sydney, Melbourne, Brisbane, Perth, Darwin |
Output
A plain-text string with the weather description returned by the weather API.
Error responses
| Condition | Returned string |
|---|---|
| HTTP error from the weather API | API error <status>: <body> |
| Network / timeout failure | Request failed: <message> |
uv run --dev pytestAll 33 tests run offline using mocks — no credentials or network access required.
============================= test session starts ==============================
collected 29 items
tests/test_client.py::TestRun::test_calls_initialize PASSED
tests/test_client.py::TestRun::test_calls_list_tools PASSED
...
tests/test_server.py::TestGetWeather::test_accepts_all_australian_capitals[Darwin] PASSED
============================== 29 passed in 0.62s ==============================