Thank you for your interest in contributing to the best weather MCP server ever! This document provides guidelines and instructions for contributing.
- Python 3.11 or higher
- Git
- UV (recommended) or pip
- Fork and Clone
git clone https://github.com/YOUR_USERNAME/chuk-mcp-open-meteo.git
cd chuk-mcp-open-meteo- Install Dependencies
Using UV (recommended):
uv sync --devUsing pip:
pip install -e ".[dev]"- Verify Installation
make testgit checkout -b feature/your-feature-name
# or
git checkout -b fix/bug-descriptionFollow these guidelines:
- Write clear, descriptive commit messages
- Add tests for new functionality
- Update documentation as needed
- Follow the existing code style
# Run all tests
make test
# Run tests with coverage
make test-cov
# Run linting
make lint
# Run type checking
make typecheck
# Run all checks
make checkmake formatThis will auto-format your code using Ruff.
git add .
git commit -m "feat: add awesome new feature"Use conventional commit messages:
feat:- New featurefix:- Bug fixdocs:- Documentation changestest:- Test changesrefactor:- Code refactoringchore:- Maintenance tasks
git push origin feature/your-feature-nameThen create a Pull Request on GitHub.
We use Ruff for linting and formatting:
- Line length: 100 characters
- Type hints required for public APIs
- Docstrings for all public functions and classes
- Follow PEP 8 conventions
When adding a new weather tool:
- Add Pydantic models in
src/chuk_mcp_open_meteo/models.py - Add the tool function in the appropriate
src/chuk_mcp_open_meteo/tools/module (or create a new one):
from chuk_mcp_server import tool
from ..models import YourResponseModel
@tool
async def your_new_tool(
latitude: float,
longitude: float,
) -> YourResponseModel:
"""Clear description of what the tool does.
Args:
latitude: Latitude of the location
longitude: Longitude of the location
Returns:
YourResponseModel with the results
"""
async with httpx.AsyncClient() as client:
response = await client.get(API_URL, params=params)
response.raise_for_status()
return YourResponseModel(**response.json())- Re-export from
server.pyand add to__all__ - Add tests in
tests/test_server.py - Update documentation in README.md, CHANGELOG.md, and ROADMAP.md
Update these files when making changes:
README.md- Main documentationCONTRIBUTING.md- This fileexamples/usage_examples.md- Usage examples- Docstrings in code
Tests should be added to the tests/ directory (to be created):
# tests/test_server.py
import pytest
from chuk_mcp_open_meteo.server import get_weather_forecast
@pytest.mark.asyncio
async def test_get_weather_forecast():
result = await get_weather_forecast(
latitude=51.5072,
longitude=-0.1276
)
assert "latitude" in result
assert "current_weather" in result# All tests
make test
# With coverage
make test-cov
# Specific test file
pytest tests/test_server.py
# Specific test
pytest tests/test_server.py::test_get_weather_forecastReleases are automated via GitHub Actions:
- Bump Version
make bump-patch # 1.0.0 -> 1.0.1
make bump-minor # 1.0.0 -> 1.1.0
make bump-major # 1.0.0 -> 2.0.0- Commit Version Change
git add pyproject.toml
git commit -m "chore: bump version to X.Y.Z"
git push- Create Release
make publishThis will:
- Create and push a git tag
- Trigger GitHub Actions
- Create a GitHub release
- Publish to PyPI
chuk-mcp-open-meteo/
├── src/
│ └── chuk_mcp_open_meteo/
│ ├── __init__.py
│ ├── server.py # Thin entry point — imports tools, runs server
│ ├── models.py # All Pydantic v2 response models
│ ├── _constants.py # API URLs, default parameters, weather codes
│ ├── _batch.py # Generic batch fetch helper
│ └── tools/ # Domain-focused tool modules
│ ├── forecast.py # get_weather_forecast + batch_get_weather_forecasts
│ ├── geocoding.py # geocode_location + batch_geocode_locations
│ ├── historical.py # get_historical_weather + batch_get_historical_weather
│ ├── air_quality.py # get_air_quality + batch_get_air_quality
│ ├── marine.py # get_marine_forecast + batch_get_marine_forecasts
│ └── weather_codes.py # interpret_weather_code + batch_interpret_weather_codes
├── tests/ # Test files
├── examples/ # Usage examples
├── .github/
│ └── workflows/ # CI/CD workflows
├── pyproject.toml # Project configuration
├── Makefile # Development commands
├── Dockerfile # Docker configuration
├── fly.toml # Fly.io deployment config
└── README.md # Main documentation
- Use async/await for all API calls
- Always use
httpx.AsyncClient()as context manager - Set reasonable timeouts (30s default)
- Handle HTTP errors gracefully
- Follow Open-Meteo's fair use policy
- Simple by default: Provide sensible defaults
- Comprehensive when needed: Allow detailed customization
- Type-safe: Use proper type hints
- Well-documented: Clear docstrings with examples
- Error-friendly: Helpful error messages
- GitHub Issues: Report bugs or request features
- Discussions: Ask questions or share ideas
- Pull Requests: Contribute code or documentation
- Be respectful and inclusive
- Welcome newcomers
- Focus on constructive feedback
- Help others learn and grow
Contributors will be recognized in:
- GitHub contributors list
- Release notes
- Project documentation
Thank you for contributing to making this the best weather MCP server ever!